Table of Contents

Class OnchainRefundBuilder

Namespace
NArk.ArkadeIntents.Onchain
Assembly
NArk.ArkadeIntents.dll

Builds the Bitcoin-L1 transaction that takes an HTLC back once its refund leaf has matured.

public static class OnchainRefundBuilder
Inheritance
OnchainRefundBuilder
Inherited Members

Remarks

The on-board corridor's only recourse. There the client funds the L1 HTLC first, so if the solver never funds the Arkade side there is nothing to claim and nothing to refund on Arkade — the sats are on L1, behind this leaf, and no counterparty signature reaches them.

Two things separate this from OnchainClaimBuilder, and both are consensus rules rather than conventions: the transaction carries the leaf's locktime in its own nLockTime, and its inputs must be non-final for OP_CHECKLOCKTIMEVERIFY to be evaluated at all. Miss either and the script fails on a transaction that is otherwise correct.

Fields

TimelockedSequence

The input sequence a timelocked spend must carry.

public const uint TimelockedSequence = 4294967294

Field Value

uint

Remarks

OP_CHECKLOCKTIMEVERIFY is a no-op on an input whose sequence is 0xFFFFFFFF — the script would pass with any locktime at all, and the transaction would then be rejected as non-final by the node instead. 0xFFFFFFFE is the usual choice: non-final, and still opting out of BIP-125 replaceability.

Methods

BuildAsync(OnchainHtlc, IReadOnlyList<BoardingUtxo>, BitcoinAddress, FeeRate, Func<uint256, Task<SecpSchnorrSignature>>, CancellationToken)

Build and sign the refund.

public static Task<Transaction> BuildAsync(OnchainHtlc htlc, IReadOnlyList<BoardingUtxo> inputs, BitcoinAddress refundAddress, FeeRate feeRate, Func<uint256, Task<SecpSchnorrSignature>> signAsync, CancellationToken cancellationToken = default)

Parameters

htlc OnchainHtlc

The HTLC being refunded.

inputs IReadOnlyList<BoardingUtxo>

The outputs at its address to sweep. All of them, not the largest.

refundAddress BitcoinAddress

Where the sweep pays.

feeRate FeeRate

What to pay for the weight.

signAsync Func<uint256, Task<SecpSchnorrSignature>>

Produces a BIP-340 signature over a sighash.

cancellationToken CancellationToken

Cancels between signatures.

Returns

Task<Transaction>

The signed transaction, ready to broadcast.

Remarks

Whether the leaf has actually matured is deliberately not checked here: maturity is measured against the chain's median time past, which this has no way to read, and inventing a wall clock comparison would produce a transaction that looks due and is refused as non-final. Ask RefundIsDue(long, long) with the tip's median time past first.

Exceptions

InvalidOperationException

There is nothing at the HTLC, or the fee leaves nothing worth paying out.

VirtualSize(OnchainHtlc, int, BitcoinAddress)

The signed transaction's virtual size, in vbytes.

public static int VirtualSize(OnchainHtlc htlc, int inputCount, BitcoinAddress refundAddress)

Parameters

htlc OnchainHtlc

The HTLC being refunded.

inputCount int

How many of its outputs are being swept.

refundAddress BitcoinAddress

Where the sweep pays.

Returns

int

The size in vbytes.

Remarks

Computed rather than measured, for the reason VirtualSize(OnchainHtlc, int, BitcoinAddress) gives: the fee has to be known before the signatures exist. Three witness items here rather than four — the refund leaf takes no preimage.