Supplemental Economics Example¶
This example focuses only on economics support behavior.
It does not change protocol authority semantics.
import {
assembleDirectSpendTx,
buildDirectSpendPlan,
type DirectSpendWalletRuntimeExecutorV1,
} from "@bch-stealth/direct-spend-wallet";
import {
prepareDirectSpendProofInput,
proveDirectSpend,
verifyDirectSpend,
} from "@bch-stealth/prover-runtime";
type EconomicsInputs = {
authoritativeProtocolSourceOutpointRef: string;
protocolAuthorityInputSats: number;
continuationShellOutputSats: number;
minerFeeSats: number;
piv1Bytes: Uint8Array;
witnessBytes: Uint8Array;
};
type SupplementalFundingResolution =
| { used: false }
| { used: true; outpointRef: string; inputSats: number; changeSats: number };
function resolveSupplementalEconomics(inputs: EconomicsInputs): SupplementalFundingResolution {
const required = inputs.continuationShellOutputSats + inputs.minerFeeSats;
if (inputs.protocolAuthorityInputSats >= required) {
return { used: false };
}
// Example static resolver: replace with wallet/provider resolver implementation.
const requiredAdditionalSats = required - inputs.protocolAuthorityInputSats;
const resolvedInputSats = requiredAdditionalSats + 1000;
const changeSats = resolvedInputSats - requiredAdditionalSats;
return {
used: true,
outpointRef: "replace-with-supplemental-utxo-txid:vout",
inputSats: resolvedInputSats,
changeSats,
};
}
export async function runDirectSpendWithOptionalSupplementalTopUp(
inputs: EconomicsInputs,
) {
const proofInput = prepareDirectSpendProofInput({
piv1Bytes: inputs.piv1Bytes,
witnessBytes: inputs.witnessBytes,
determinism: { mode: "deterministic" },
});
const proved = await proveDirectSpend(proofInput);
const verify = await verifyDirectSpend(proved);
if (!verify.ok) throw new Error(verify.reason ?? "verifyDirectSpend failed");
const runtimeExecutor: DirectSpendWalletRuntimeExecutorV1 = async () => ({
request: proofInput,
estimate: {
backendId: proved.prove.backendId,
estimatedProofBytes: proved.prove.estimatedProofBytes,
estimatedProofBlobBytes: proved.prove.pbv1Bytes.length,
},
prove: proved.prove,
verify,
});
const supplemental = resolveSupplementalEconomics(inputs);
const plan = buildDirectSpendPlan({
request: proofInput,
runtimeExecutor,
hostChecks: {
transcriptBinding: () => undefined,
ofm2v2: () => undefined,
continuationShell: () => undefined,
malformedCarrier: () => undefined,
routingCompatibility: () => undefined,
},
assembleTx: (run) => ({
protocolAuthorityOutpointRef: inputs.authoritativeProtocolSourceOutpointRef,
supplementalEconomicsOutpointRef: supplemental.used ? supplemental.outpointRef : null,
proofBytes: run.prove.proofBytes,
pbv1Bytes: run.prove.pbv1Bytes,
}),
broadcastTx: async (txPlan) => ({
txidHex: "replace-with-broadcast-txid",
txPlan,
}),
});
return {
supplemental,
assembled: await assembleDirectSpendTx(plan),
};
}
Truth Requirements¶
- Supplemental input supports shell + fee feasibility only.
- It is not hidden transfer semantics.
- External integrations should use package-root façade exports only, not deep
src/*imports. - Artifacts should separately expose:
- protocol authority source
- supplemental funding usage and amounts
- continuation shell sats
- miner fee sats