Class ArkadePsbtExtensions
Helpers that link the existing ArkCoin + PSBT spend flow to the emulator co-signing service. The integration points:
public static class ArkadePsbtExtensions
- Inheritance
-
ArkadePsbtExtensions
- Inherited Members
Remarks
- BuildEmulatorPackets(IReadOnlyList<ArkCoin>) — produces the EmulatorPacket(s) pinning each arkade-bound input's script bytes + witness, for the generic spend path to merge into the single Extension OP_RETURN. That output must be appended to the tx before any input is signed, since signatures commit to the full output set.
- CoSignWithEmulatorAsync(PSBT, IEmulatorProvider, CancellationToken) — submits the partially- signed PSBT to the emulator and returns the PSBT with the emulator's signatures added. Call after the user signer has attached its own partial sigs.
-
AttachPrevArkTxsAsync(PSBT, IReadOnlyList<PSBT>, IPrevArkTxProvider, CancellationToken) / AttachIntentPrevArkTxsAsync(PSBT, IPrevArkTxProvider, CancellationToken) —
annotate each input with the transaction that funded it, which the emulator
requires on every submitted input. These write to the PSBT's
unknownmap, so they run after signing, just before submission.
Detection is type-driven via IArkadeBoundScriptBuilder —
any ArkCoin whose SpendingScriptBuilder implements
the interface is treated as arkade-bound. Spends that mix arkade and
non-arkade inputs are supported: only the arkade-bound inputs become
entries in the EmulatorPacket.
Methods
AttachIntentPrevArkTxsAsync(PSBT, IPrevArkTxProvider, CancellationToken)
Attaches the prevarktx ark field to every VTXO input of an intent proof bound for
the emulator's POST /v1/intent, resolving each previous transaction through
prevArkTxProvider.
public static Task AttachIntentPrevArkTxsAsync(this PSBT intentProof, IPrevArkTxProvider prevArkTxProvider, CancellationToken cancellationToken = default)
Parameters
intentProofPSBTThe intent proof PSBT to annotate, mutated in place.
prevArkTxProviderIPrevArkTxProviderResolver for the previous Arkade transactions.
cancellationTokenCancellationTokenCancellation token.
Returns
Remarks
Input 0 of a BIP322 intent proof is the message input: it carries no value and mirrors the first real input's script, and the emulator synthesises its prevout itself. Inputs 1..N are the VTXOs being registered, and each needs the transaction that created its outpoint.
Exceptions
- InvalidOperationException
The proof has fewer than two inputs, or a previous Arkade transaction could not be resolved.
AttachPrevArkTxsAsync(PSBT, IReadOnlyList<PSBT>, IPrevArkTxProvider, CancellationToken)
Attaches the prevarktx ark field to every input of an Arkade transaction bound
for the emulator's POST /v1/tx, resolving each previous transaction through
prevArkTxProvider. Call after signing and immediately before submitting.
public static Task AttachPrevArkTxsAsync(this PSBT arkTx, IReadOnlyList<PSBT> checkpoints, IPrevArkTxProvider prevArkTxProvider, CancellationToken cancellationToken = default)
Parameters
arkTxPSBTThe Arkade transaction to annotate, mutated in place.
checkpointsIReadOnlyList<PSBT>The spend's checkpoint transactions, one per Arkade input.
prevArkTxProviderIPrevArkTxProviderResolver for the previous Arkade transactions.
cancellationTokenCancellationTokenCancellation token.
Returns
Remarks
Emulator v0.0.7 requires the field on every input, whether or not that input's
ArkadeScript introspects a previous output; without it the submission is rejected with
missing prevout tx for input N. Older emulators validate the field when present
and ignore it otherwise, so attaching it is safe against any version.
The transaction attached to Arkade input i is not the one that created
that input's outpoint — that outpoint is the checkpoint, which the emulator already holds.
It is the transaction funding the checkpoint's single input, i.e. the VTXO the spend
actually consumes. The emulator reconciles it against the checkpoint's witness utxo.
The field lives in the PSBT's unknown map, which no signature commits to, so
attaching it after the wallet has signed does not invalidate anything. An input that
already carries the field is left alone — the emulator rejects an input bearing two,
so a caller-supplied value wins outright.
Exceptions
- InvalidOperationException
A checkpoint is missing or malformed, or a previous Arkade transaction could not be resolved — either would have the emulator reject the spend, so it fails here instead with the input index and txid named.
BuildEmulatorPackets(IReadOnlyList<ArkCoin>)
Build the EmulatorPacket(s) for the arkade-bound inputs of a
spend, without wrapping them in an Extension/OP_RETURN — so the generic
spend path (NArk.Core) can merge them with the asset packet into a
single Extension via ISpendExtensionPacketProvider.
Returns an empty list when no input is arkade-bound.
public static IReadOnlyList<IExtensionPacket> BuildEmulatorPackets(IReadOnlyList<ArkCoin> coinsByVin)
Parameters
coinsByVinIReadOnlyList<ArkCoin>The spend inputs in transaction-input-index order — index
iin this list corresponds tovin = ion the resulting tx.
Returns
CoSignWithEmulatorAsync(PSBT, IEmulatorProvider, CancellationToken)
Submit a partially-signed PSBT (already carrying the user's sigs and the EmulatorPacket OP_RETURN output) to the emulator and return the PSBT with the emulator's signatures merged in.
public static Task<PSBT> CoSignWithEmulatorAsync(this PSBT psbt, IEmulatorProvider emulator, CancellationToken cancellationToken = default)
Parameters
psbtPSBTPSBT with user partial sigs already attached.
emulatorIEmulatorProviderProvider client for the configured emulator instance.
cancellationTokenCancellationTokenCancellation token.
Returns
- Task<PSBT>
The co-signed Arkade transaction PSBT.
Remarks
The emulator signs only inputs whose attached scripts pass its validation; non-arkade inputs are passed through untouched. The returned PSBT is the union of (input PSBT) + (emulator partial sigs) — assembled server-side, so this method is a thin wrapper over SubmitTxAsync(string, IReadOnlyList<string>, CancellationToken).
Deliberately carries no checkpoint parameter: it would only be able to return the
co-signed Arkade transaction, silently dropping the emulator's signed_checkpoint_txs.
Callers that submit checkpoints — ArkadeEmulatorSpendSubmitter — call
SubmitTxAsync(string, IReadOnlyList<string>, CancellationToken) directly and consume both halves.
Does not attach prevarktx. Emulator v0.0.7+ requires that field on
every input and rejects the submission with missing prevout tx for input N
without it, so call AttachPrevArkTxsAsync(PSBT, IReadOnlyList<PSBT>, IPrevArkTxProvider, CancellationToken) (or
AttachIntentPrevArkTxsAsync(PSBT, IPrevArkTxProvider, CancellationToken) for an intent proof) on the PSBT first. It
also submits an empty checkpoint list, which that same version rejects for an Arkade
transaction — this helper is for callers driving the emulator themselves against a
submission shape it accepts.
Exceptions
- InvalidOperationException
The emulator returned no signed Arkade transaction, so the input was not co-signed.
RequiresEmulatorCoSigning(IEnumerable<ArkCoin>)
True if the spend uses at least one arkade-bound coin and therefore needs both the EmulatorPacket OP_RETURN attachment and the post-sign emulator REST round-trip.
public static bool RequiresEmulatorCoSigning(IEnumerable<ArkCoin> coins)
Parameters
coinsIEnumerable<ArkCoin>