Class OnchainHtlcState
- Namespace
- NArk.ArkadeIntents.Onchain
- Assembly
- NArk.ArkadeIntents.dll
Reading an L1 HTLC's state back off the chain, for a client that no longer knows it.
public static class OnchainHtlcState
- Inheritance
-
OnchainHtlcState
- Inherited Members
Remarks
The corridor's normal path never needs this: it drives forward from a row it wrote itself. This is for the case where that row is gone or stale — a restored wallet, a process that was down across the window, an operator asking what actually happened. The distinction matters because the answers differ in kind: the drive path asks "may I act yet", and recovery asks "what is true".
Everything here is derived from the chain and the contract, never from a counterparty's account of either.
Methods
AwaitFillAsync(IBitcoinBlockchain, OnchainHtlc, int, TimeSpan, TimeSpan?, CancellationToken)
Wait until the HTLC holds enough confirmed value to act on, or give up.
public static Task<OnchainHtlcStatus> AwaitFillAsync(IBitcoinBlockchain blockchain, OnchainHtlc htlc, int minConfirmations, TimeSpan within, TimeSpan? poll = null, CancellationToken cancellationToken = default)
Parameters
blockchainIBitcoinBlockchainWhere to read from.
htlcOnchainHtlcThe HTLC to watch.
minConfirmationsintThe count this swap was quoted at.
withinTimeSpanHow long to keep looking.
pollTimeSpan?How often to look. Defaults to five seconds.
cancellationTokenCancellationTokenCancels the wait.
Returns
- Task<OnchainHtlcStatus>
The status once it is claimable, or the last one seen when the time ran out — Empty when nothing ever arrived while this was watching.
Remarks
Polling, because an L1 funding raises no event this SDK subscribes to — which is the same reason the advance pass proposes its onchain actions on every tick rather than on a trigger. Returning the last status rather than throwing keeps "it never arrived" an answer the caller can branch on alongside the others.
ClassifyAsync(IBitcoinBlockchain, OnchainHtlc, int, CancellationToken)
Classify an HTLC from the chain.
public static Task<OnchainHtlcStatus> ClassifyAsync(IBitcoinBlockchain blockchain, OnchainHtlc htlc, int minConfirmations, CancellationToken cancellationToken = default)
Parameters
blockchainIBitcoinBlockchainWhere to read outputs and the tip from.
htlcOnchainHtlcThe HTLC to look at.
minConfirmationsintThe count this swap was quoted at.
cancellationTokenCancellationTokenCancels the lookups.
Returns
- Task<OnchainHtlcStatus>
The phase, and the outputs behind it.
Remarks
Maturity is judged against the tip's median time past, which is the clock consensus applies to CLTV and which trails wall clock by roughly an hour. Classifying against a local clock would report Refundable for up to that long before a refund would actually be accepted — and, worse in the other direction, would call a window closed while a claim could still have landed.
ExtractPreimage(Transaction, uint256)
Recover a preimage from the transaction that spent an HTLC.
public static byte[]? ExtractPreimage(Transaction tx, uint256 paymentHash)
Parameters
txTransactionThe spending transaction.
paymentHashuint256The hash it must open, as the swap recorded it.
Returns
- byte[]
The preimage, or
nullwhen this transaction proved none.
Remarks
The L1 counterpart of SwapPreimageReader, which reads Arkade spends through the indexer and so cannot answer for a Bitcoin transaction.
Every candidate is checked against the hash before it is believed. A 32-byte push is not evidence; one that hashes to this swap's payment hash is, and it is evidence nobody can forge — which is what makes it safe to act on without trusting whoever built the spend.
A null answer is not proof of a refund. A transaction that carried no preimage and one
this failed to parse are the same silence here, and both mean only that the spend is not
provably a claim.