Skip to main content
You’re viewing an old version of the Arkade contracts documentation. Go to Your first contract for the current version.
This tab shows how to write custom spending conditions for virtual outputs as raw tapscript, then spend them, with @arkade-os/sdk 0.4. Every example runs on Mutinynet, a Bitcoin test network. The Experimental pages describe Arkade Script contracts, which an emulator enforces, not the operator: Compiler, Functions, Non-Interactive Swaps, and Lightning Channels.

Contracts are Taproot trees

A contract is a Taproot output whose key path is disabled. Each leaf of its script tree is one spending path. Two kinds of spending path matter:
  • A collaborative path includes the operator’s key. The operator cosigns a spend through it right away, offchain, and refuses to cosign a spend of an output that is already spent.
  • An exit path has no operator key and waits for a relative delay (CSV). It is for unilateral exit: if the operator is unavailable, the owners unroll the virtual output onchain and spend it through this path.
The smallest useful contract has one path of each kind. It uses serverPubkey, exitTimelock, and CSVMultisigTapscript from Set Up Your Project.

Spending path rules

When you spend a contract, the operator parses every path of its tree, not only the one you spend. If one path breaks a rule, the operator refuses every spend of the contract. Funds sent to such an address can leave only onchain, through unilateral exit. Each path must have one of these five shapes. The SDK helper of the same name writes it. The operator also checks these rules:
  • A path without a CSV delay must include the operator’s key (serverPubkey).
  • A CSV delay must be at least the operator’s unilateralExitDelay. A path with CSV is an exit path, so a collaborative path that needs a time lock uses CLTV instead.
  • Delays and lock times are in seconds. Block-based values work only when the operator’s batches expire by block height, as in some regtest setups.
  • A path’s keys must all sign (N-of-N).
  • A condition cannot contain signature or time lock opcodes.
Include at least one exit path without the operator’s key. The operator accepts a contract without one, but then every path needs the operator’s signature.

How a spend reaches the operator

A spend within Arkade is a virtual transaction plus one checkpoint transaction per input. The checkpoint spends your output through the path you chose. The virtual transaction spends the checkpoint and pays your outputs.
  1. You sign the virtual transaction and submit it with the checkpoints. The operator checks them, cosigns, and returns the checkpoints with its signature.
  2. You sign the checkpoints and submit them. The operator finalizes the transaction, and its outputs can be spent at once.
signAndSubmitOffchainTx runs both steps, and checks the checkpoints the operator returns before it signs them. The Escrow page shows a complete spend.