@arkade-os/sdk Documentation - v0.5.0-rc.11
    Preparing search index...

    Variable VHTLCV2ContractHandlerConst

    VHTLCV2ContractHandler: ContractHandler<VHTLCV2ContractParams, ScriptV2> & TapscriptDeriving<
        ScriptV2,
    > = ...

    Handler for VHTLC.ScriptV2 — the VHTLC whose preimage leaves carry an explicit OP_SIZE 32 OP_EQUALVERIFY before the hash check, and which the RFQ swap corridor builds (@arkade-os/swap's lightningSendContract).

    Why a separate type string rather than a flag on vhtlc. A handler's type names the script class it derives, the way every other registered type does (default → DefaultVtxo.Script, vhtlc → VHTLC.Script, boarding, arkade). V1 and V2 produce different script bytes — and so different pkScripts — for identical participant keys, and upsertContractRow derives the script from params and refuses any row whose supplied script does not match. One type cannot serve both. vhtlc-v2 also cannot COLLIDE with vhtlc: a colliding row needs one pkScript claimed by two types, and the two versions' preimage conditions differ in every tree, so no parameters make them equal. A use-named type (swap-lockup) was the alternative and is worse: contracts are keyed by script, so the moment a second use registered the same ScriptV2 the two uses would fight over one row.

    Which leaves this offers, and why the set is smaller than the ladder. ScriptV2 has nine leaves; a wallet holding ONE of the two participant keys can satisfy four of them, and offering a leaf whose signature the caller cannot produce is worse than offering fewer — it turns a refusal into a transaction that gets built and then rejected.

    leaf needs offered
    claim receiver + server, preimage yes, to the receiver
    refund sender + receiver + server no — needs the counterparty live
    refundWithoutReceiver sender + server, CLTV yes, to the sender
    unilateralClaim receiver, CSV yes, to the receiver
    unilateralRefund sender + receiver, CSV no — needs the counterparty live
    unilateralRefundWithoutReceiver sender, CSV yes, to the sender
    nonInteractiveClaim server + emulator no — the wallet holds neither key
    nonInteractiveRefund server + receiver + emulator no — the wallet holds neither key
    nonInteractiveRefundWithoutReceiver server + emulator, CLTV no — the wallet holds neither key

    The two omitted interactive leaves are the same two the vhtlc handler omits, for the same reason: refund and unilateralRefund both need the OTHER party's signature, and this protocol has no message that asks for one (see @arkade-os/swap's refund.ts module doc). The two covenant leaves are pushed by the emulator on the counterparty's behalf and are not this wallet's to build at all.

    So refundWithoutReceiver is the sender's only collaborative way out, gated on the CLTV the quote committed to — which is exactly the leaf pushRefundWithoutReceiver builds. The CSV leaves are offered only in the non-collaborative context, where the caller has already accepted that spending them means a real unilateral exit first.

    The selection discipline is deliberately identical to the vhtlc handler's, and test/contracts/vhtlcV2-handler.test.ts pins the two against each other rung-for-rung across every role and timelock context so they cannot drift.