Table of Contents

Class OfferRestore

Namespace
NArk.ArkadeIntents.Assets
Assembly
NArk.ArkadeIntents.dll

Rebuilding asset-swap rows from the chain after the store that held them is gone.

public static class OfferRestore
Inheritance
OfferRestore
Inherited Members

Remarks

The swap store dies with its storage backend, but nothing in an asset swap is only in that store: the funding transaction carries the offer as an extension packet, the covenant VTXO at the offer's script holds the deposit, and that VTXO's spender says what became of it. So the row is recomputable, and this recomputes it.

A restored swap cannot be cancelled. The wire offer carries the maker's x-only key, which is enough to rebuild the address and not enough to sign — the spendable descriptor was only ever local. That is a property of the offer format, not a shortcoming here, and it is reported rather than discovered: CancelSwap(string, CancellationToken) refuses a row with no maker descriptor, and Cancellable says so in advance. A restored swap can still be watched, and still be filled by the solver, which is the outcome it was waiting for.

The scan is incremental by design: it takes the candidate txids and returns those it answered, so a caller can persist that set and never fetch the same transaction twice. A txid it could not reach is left out of both lists, which is what keeps a read failure from being remembered as an answer.

Methods

ClassifySpend(Offer, OutputDescriptor, Network, PSBT, OutPoint)

Classify a spend by the covenant leaf it took.

public static OfferSpendKind ClassifySpend(Offer offer, OutputDescriptor server, Network network, PSBT spend, OutPoint deposit)

Parameters

offer Offer

The offer whose covenant was spent.

server OutputDescriptor

The Arkade server key the covenant was funded against.

network Network

The network the descriptors belong to.

spend PSBT

The transaction that spent the deposit.

deposit OutPoint

The deposit outpoint.

Returns

OfferSpendKind

What became of the deposit.

Remarks

The vocabulary is what became of the deposit, not which key moved it. fulfill is the solver paying for it; cancel and exit both hand it back, differing only in who had to agree — cooperatively with the signer, or the maker alone after a delay. The outcome is the same and that is the question being answered.

Read from the leaf rather than from what the transaction moved, because the amounts stop answering once the covenant is a registered contract: the deposit then joins the wallet's own coins, every wallet-level figure becomes a net delta, and an asset offer's cancel — asset out of the covenant, same asset back — nets to zero and reads exactly like its fill. Leaves have no such failure mode, and they survive batching: a solver filling several offers in one transaction gives each input its own leaf.

A server key that has rotated since funding rebuilds a different script, and this answers Indeterminate rather than guessing against the wrong tree.

OfferIn(Transaction)

Read the offer out of a funding transaction's extension packet, if it carries one.

public static Offer? OfferIn(Transaction tx)

Parameters

tx Transaction

The funding transaction.

Returns

Offer

The offer, or null when this transaction is not an offer funding.

Remarks

Answers null rather than throwing for anything that is simply not an offer — most transactions in a wallet's history are not, and a scan over them is the normal caller. A packet that IS an offer and will not decode is a different matter and is left to throw, because that is a malformed record on the money path rather than an absent one.

RestoreAsync(IClientTransport, IArkadeIntentStorage, IVtxoStorage, string, IReadOnlyCollection<string>, ArkServerInfo, ILogger?, CancellationToken)

Rebuild asset-swap rows from candidate funding transactions.

public static Task<OfferRestoreResult> RestoreAsync(IClientTransport transport, IArkadeIntentStorage intentStorage, IVtxoStorage vtxoStorage, string walletId, IReadOnlyCollection<string> candidateTxids, ArkServerInfo serverInfo, ILogger? logger = null, CancellationToken cancellationToken = default)

Parameters

transport IClientTransport

Where virtual transactions are fetched from.

intentStorage IArkadeIntentStorage

Where rebuilt rows are written.

vtxoStorage IVtxoStorage

The chain view a deposit's fate is read from.

walletId string

The wallet the rebuilt rows belong to.

candidateTxids IReadOnlyCollection<string>

Transactions worth looking at — a wallet's sent history, minus whatever a previous pass already answered. Supplied rather than discovered, so any history source serves and this takes no opinion on how a caller enumerates its own past.

serverInfo ArkServerInfo

The Arkade server's current terms, for the key and the network.

logger ILogger

Optional logger.

cancellationToken CancellationToken

Cancels between transactions.

Returns

Task<OfferRestoreResult>

What was rebuilt, what was answered, and what still has no outcome.

Remarks

Rows already present are left completely alone, matched by id — an asset swap's id is its funding txid, so a restore cannot overwrite a live row with a reconstruction that knows less than it does. In particular it would drop the maker descriptor, and with it the ability to cancel.