Architecture
Transaction Architecture Diagram
Main Concepts
Dual Environment Support
The library operates identically in both Node.js and browser environments. In the browser, MessageSigner auto-detects installed OP_WALLET extensions and methods such as signMessageAuto() and signMLDSAMessageAuto() automatically delegate signing to the browser wallet when available, falling back to a locally provided keypair otherwise. This allows the same application code to work seamlessly across server-side scripts and client-facing dApps without conditional logic.
Multiple Transaction Types
The library supports several transaction types, each serving a distinct purpose. The TransactionType enum defines the complete set of supported transactions:
export enum TransactionType {
GENERIC = 0,
FUNDING = 1,
DEPLOYMENT = 2,
INTERACTION = 3,
MULTI_SIG = 4,
CUSTOM_CODE = 5,
CANCEL = 6,
CONSOLIDATED_SETUP = 7,
CONSOLIDATED_REVEAL = 8,
}| Type | Value | Description | TX Count |
|---|---|---|---|
| GENERIC | 0 | Generic transaction (base type) | -- |
| FUNDING | 1 | Simple BTC transfer between addresses | 1 |
| DEPLOYMENT | 2 | Deploy a smart contract (WASM bytecode) | 2 |
| INTERACTION | 3 | Call a function on a deployed contract | 2 |
| MULTI_SIG | 4 | Multi-signature transaction (M-of-N) | 2 |
| CUSTOM_CODE | 5 | Execute a custom Bitcoin script | 2 |
| CANCEL | 6 | Cancel/recover a stuck transaction | 1 |
| CONSOLIDATED_SETUP | 7 | CHCT setup phase (anti-censorship) | 1 (pair) |
| CONSOLIDATED_REVEAL | 8 | CHCT reveal phase (anti-censorship) | 1 (pair) |
The Two-Transaction Model
The TransactionFactory handles the two-transaction construction automatically: you provide the parameters, and it returns both the interaction transaction and the funding transaction fully signed and ready to broadcast.
Simple Bitcoin transfers that do not involve smart contract logic use a single transaction and do not require this pairing.
For more details on the Two-Transaction Model, see Understanding the Protocol Design.
UTXO-Based Model
Bitcoin operates on a UTXO model rather than an account-based balance system. Every transaction consumes one or more existing UTXOs as inputs and produces new UTXOs as outputs. The library handles UTXO selection, change calculation, and fee estimation internally. Each method on TransactionFactory returns the resulting UTXOs (nextUTXOs) that your application must track and pass as inputs to subsequent transactions. Failure to do so will result in double-spend rejections.
Offline Transaction Signing
Transactions can be constructed in an online environment where UTXO data and network access are available but private keys are not present, then exported as a serialized binary payload and transferred to a network-isolated signing device. After signing, the completed transaction is returned to the online machine for broadcast. The OfflineTransactionManager orchestrates this workflow, handling serialization, deserialization, and state management across both environments.
Network Support
The library supports multiple Bitcoin networks and chains, configured through the networks object from @btc-vision/bitcoin and the ChainId enum. The chainId parameter is optional when constructing transactions. When omitted, it defaults to ChainId.Bitcoin (mainnet).
Address Systems
OP_NET uses two complementary address systems. Bitcoin addresses (P2TR by default, with optional P2MR support) handle on-chain transaction inputs and outputs. OP_NET addresses, derived from the SHA-256 hash of the ML-DSA public key, serve as universal identifiers within the smart contract layer.
Bitcoin Addresses (On-Chain)
Standard Bitcoin addresses used for transaction inputs and outputs. The library generates Taproot (P2TR) addresses by default, with optional P2MR (BIP 360) support:
| Format | Prefix | Example |
|---|---|---|
| P2TR (Taproot) | bc1p | bc1p5d7rjq7g6rdk2yhzks9smlaqtedr4dekq08ge8ztwac72sfr9rusxg3297 |
| P2MR (Merkle Root) | bc1z | bc1z... (quantum-safe, no key-path spend) |
| P2WPKH (SegWit) | bc1q | bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4 |
| P2PKH (Legacy) | 1 | 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa |
OP_NET Addresses (Protocol Identity)
The OP_NET address is the SHA-256 hash of the ML-DSA public key, represented as 32 bytes. This serves as the user's universal identifier within the OP_NET smart contract layer.
Address Relationship
Both addresses derive from the same Wallet, which is derived from a single BIP39 mnemonic via parallel derivation paths:
- Classical path: m/84'/0'/0'/0/0 (BIP84 for secp256k1)
- Quantum path: m/360'/0'/0'/0/0 (BIP360 for ML-DSA)