Class OnchainHtlc
- Namespace
- NArk.ArkadeIntents.Onchain
- Assembly
- NArk.ArkadeIntents.dll
The Bitcoin-L1 half of an onchain corridor swap: a two-leaf taproot HTLC.
public sealed record OnchainHtlc : IEquatable<OnchainHtlc>
- Inheritance
-
OnchainHtlc
- Implements
- Inherited Members
Remarks
The internal key is the BIP-341 NUMS point, so there is no key-path spend, ever — the only ways out are the two leaves, and both are visible to whoever holds the address.
Both sides of a swap derive this independently and must land on the same address, so every byte
here is part of the wire contract. NArk.Tests/ArkadeIntents/Fixtures/onchain_htlc.json
pins it against the counterparty's own derivation; a drift is an address one side cannot spend.
Constructors
OnchainHtlc(BitcoinAddress, Script, Script, Script, ControlBlock, ControlBlock, uint256, LockTime)
The Bitcoin-L1 half of an onchain corridor swap: a two-leaf taproot HTLC.
public OnchainHtlc(BitcoinAddress Address, Script PkScript, Script ClaimLeaf, Script RefundLeaf, ControlBlock ClaimControlBlock, ControlBlock RefundControlBlock, uint256 PaymentHash, LockTime RefundLocktime)
Parameters
AddressBitcoinAddressPkScriptScriptClaimLeafScriptRefundLeafScriptClaimControlBlockControlBlockRefundControlBlockControlBlockPaymentHashuint256RefundLocktimeLockTime
Remarks
The internal key is the BIP-341 NUMS point, so there is no key-path spend, ever — the only ways out are the two leaves, and both are visible to whoever holds the address.
Both sides of a swap derive this independently and must land on the same address, so every byte
here is part of the wire contract. NArk.Tests/ArkadeIntents/Fixtures/onchain_htlc.json
pins it against the counterparty's own derivation; a drift is an address one side cannot spend.
Fields
LockTimeThreshold
Below this, a locktime means a block height rather than a timestamp (BIP-65).
public const long LockTimeThreshold = 500000000
Field Value
PreimageSize
The preimage length the claim leaf accepts, in bytes.
public const int PreimageSize = 32
Field Value
Properties
Address
public BitcoinAddress Address { get; init; }
Property Value
- BitcoinAddress
ClaimControlBlock
public ControlBlock ClaimControlBlock { get; init; }
Property Value
- ControlBlock
ClaimLeaf
public Script ClaimLeaf { get; init; }
Property Value
- Script
PaymentHash
public uint256 PaymentHash { get; init; }
Property Value
- uint256
PkScript
public Script PkScript { get; init; }
Property Value
- Script
RefundControlBlock
public ControlBlock RefundControlBlock { get; init; }
Property Value
- ControlBlock
RefundLeaf
public Script RefundLeaf { get; init; }
Property Value
- Script
RefundLocktime
public LockTime RefundLocktime { get; init; }
Property Value
- LockTime
Methods
Derive(uint256, ECXOnlyPubKey, ECXOnlyPubKey, long, Network)
Derive the HTLC both sides of the swap must agree on.
public static OnchainHtlc Derive(uint256 paymentHash, ECXOnlyPubKey claimKey, ECXOnlyPubKey refundKey, long refundLocktime, Network network)
Parameters
paymentHashuint256SHA-256 of the preimage; the leaf commits to its HASH160.
claimKeyECXOnlyPubKeyThe x-only key that spends by revealing the preimage.
refundKeyECXOnlyPubKeyThe x-only key that spends after
refundLocktime.refundLocktimelongAbsolute unix seconds; consensus matures it against median time past.
networkNetworkThe L1 network the address is rendered for.
Returns
- OnchainHtlc
The derived HTLC.
Remarks
The claim leaf is OP_SIZE 32 OP_EQUALVERIFY OP_HASH160 <h160> OP_EQUALVERIFY
<claimKey> OP_CHECKSIG, the refund leaf <locktime> OP_CLTV OP_DROP
<refundKey> OP_CHECKSIG.
The length check on the claim leaf is not decoration: without it the leaf accepts any witness value whose HASH160 matches, and this contract's preimage is exactly 32 bytes by construction — the same prefix real HTLC scripts carry, for the same reason.
Exceptions
- ArgumentOutOfRangeException
refundLocktimeis not a positive timestamp, or is height-shaped.