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
offerOfferThe offer whose covenant was spent.
serverOutputDescriptorThe Arkade server key the covenant was funded against.
networkNetworkThe network the descriptors belong to.
spendPSBTThe transaction that spent the deposit.
depositOutPointThe 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
txTransactionThe funding transaction.
Returns
- Offer
The offer, or
nullwhen 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
transportIClientTransportWhere virtual transactions are fetched from.
intentStorageIArkadeIntentStorageWhere rebuilt rows are written.
vtxoStorageIVtxoStorageThe chain view a deposit's fate is read from.
walletIdstringThe wallet the rebuilt rows belong to.
candidateTxidsIReadOnlyCollection<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.
serverInfoArkServerInfoThe Arkade server's current terms, for the key and the network.
loggerILoggerOptional logger.
cancellationTokenCancellationTokenCancels 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.