Class UnilateralExitService
Orchestrates unilateral exit for VTXOs. Broadcasts the chain of virtual txs from commitment to leaf, waits for CSV timelock, then claims funds on-chain.
public class UnilateralExitService
- Inheritance
-
UnilateralExitService
- Inherited Members
Constructors
UnilateralExitService(IClientTransport, IVirtualTxStorage, IExitSessionStorage, IVtxoStorage, IContractStorage, IBitcoinBlockchain, IWalletProvider, VirtualTxService, IVtxoChainProofProvider, IFeeWallet?, ILogger<UnilateralExitService>?)
Orchestrates unilateral exit for VTXOs. Broadcasts the chain of virtual txs from commitment to leaf, waits for CSV timelock, then claims funds on-chain.
public UnilateralExitService(IClientTransport transport, IVirtualTxStorage virtualTxStorage, IExitSessionStorage exitSessionStorage, IVtxoStorage vtxoStorage, IContractStorage contractStorage, IBitcoinBlockchain blockchain, IWalletProvider walletProvider, VirtualTxService virtualTxService, IVtxoChainProofProvider proofProvider, IFeeWallet? feeWallet = null, ILogger<UnilateralExitService>? logger = null)
Parameters
transportIClientTransportvirtualTxStorageIVirtualTxStorageexitSessionStorageIExitSessionStoragevtxoStorageIVtxoStoragecontractStorageIContractStorageblockchainIBitcoinBlockchainwalletProviderIWalletProvidervirtualTxServiceVirtualTxServiceproofProviderIVtxoChainProofProviderfeeWalletIFeeWalletloggerILogger<UnilateralExitService>
Methods
BroadcastExitChainAsync(string, OutPoint, BitcoinAddress, CancellationToken)
Stateless equivalent of StartExitAsync(string, IReadOnlyCollection<OutPoint>, BitcoinAddress, CancellationToken) + the Broadcasting phase of ProgressExitsAsync(CancellationToken): fetches the virtual-tx chain from arkd, broadcasts the next off-chain row that isn't already on-chain, and returns an ExitPlan the caller persists in whatever form they prefer.
public Task<ExitPlan> BroadcastExitChainAsync(string walletId, OutPoint vtxoOutpoint, BitcoinAddress claimAddress, CancellationToken cancellationToken = default)
Parameters
walletIdstringvtxoOutpointOutPointclaimAddressBitcoinAddresscancellationTokenCancellationToken
Returns
Remarks
The SDK doesn't write anything exit-specific in this call — IExitSessionStorage and IVirtualTxStorage are not touched.
Broadcasts at most one off-chain row per call, not the whole chain.
Bitcoin Core's TRUC/v3 policy (BIP 431) caps a transaction at 1
unconfirmed descendant; since every off-chain row gets its own CPFP
child, broadcasting two chained rows before the first confirms would
give it a second unconfirmed descendant and get rejected — the same
constraint go-sdk and ts-sdk's unroll sessions are built around.
Callers must call this repeatedly (polling GetTxStatusAsync or
simply retrying on an interval) until the whole chain has confirmed.
Once the leaf-tx confirms on-chain and the CSV timelock has matured, feed the returned ExitPlan to ClaimMaturedExitAsync(ExitPlan, CancellationToken) to finalise the exit.
ClaimMaturedExitAsync(ExitPlan, CancellationToken)
Stateless counterpart to the Claimable phase of
ProgressExitsAsync(CancellationToken). Verifies the leaf tx referenced by
plan is confirmed and that the CSV timelock has
matured, then builds, signs, and broadcasts the claim transaction.
public Task<string?> ClaimMaturedExitAsync(ExitPlan plan, CancellationToken cancellationToken = default)
Parameters
planExitPlancancellationTokenCancellationToken
Returns
- Task<string>
Txid of the broadcast claim transaction, or
nullwhen CSV hasn't matured yet (caller should poll again later).
Remarks
The server's unilateral-exit delay is a BIP-68 relative timelock and may be height- or time-based. Maturity is evaluated accordingly (heights for the former, median time past for the latter) — see CsvMaturity.
Exceptions
- InvalidOperationException
VTXO / contract / signer state required to build the claim is unavailable, the leaf tx is not yet confirmed at all (callers should distinguish "not yet" from a hard failure via the message), or the exit delay is time-based and the backend could not resolve the leaf block's median time past.
- NotSupportedException
The exit delay is time-based and the configured IBitcoinBlockchain does not implement GetMedianTimePastAsync(uint, CancellationToken).
GetActiveSessionsAsync(string?, CancellationToken)
Get current exit sessions, optionally filtered by wallet.
public Task<IReadOnlyList<ExitSession>> GetActiveSessionsAsync(string? walletId = null, CancellationToken cancellationToken = default)
Parameters
walletIdstringcancellationTokenCancellationToken
Returns
ProgressExitsAsync(CancellationToken)
Progress all active exit sessions. Call this periodically. Advances sessions through: Broadcasting → AwaitingCsvDelay → Claimable → Claiming → Completed.
public Task ProgressExitsAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
StartExitAsync(string, IReadOnlyCollection<OutPoint>, BitcoinAddress, CancellationToken)
Start unilateral exit for specific VTXOs.
public Task<IReadOnlyList<ExitSession>> StartExitAsync(string walletId, IReadOnlyCollection<OutPoint> vtxoOutpoints, BitcoinAddress claimAddress, CancellationToken cancellationToken = default)
Parameters
walletIdstringvtxoOutpointsIReadOnlyCollection<OutPoint>claimAddressBitcoinAddresscancellationTokenCancellationToken
Returns
StartExitForWalletAsync(string, BitcoinAddress, CancellationToken)
Start unilateral exit for all unspent VTXOs in a wallet.
public Task<IReadOnlyList<ExitSession>> StartExitForWalletAsync(string walletId, BitcoinAddress claimAddress, CancellationToken cancellationToken = default)
Parameters
walletIdstringclaimAddressBitcoinAddresscancellationTokenCancellationToken