OPNet Development Skill
Critical Architecture Facts
OPNet is a Bitcoin L1 consensus layer (not a metaprotocol) that enables smart contracts directly on Bitcoin using WebAssembly. It does not have a gas token; it uses bitcoin directly. Contracts are non-custodial: they never hold BTC, cannot receive blockchain.tx.value, and cannot send blockchain.transfer(). All financial logic follows a "verify, don't custody" pattern where the contract verifies the user's L1 transaction outputs against internal state.
OPNet does NOT use OP_RETURN. OPNet embeds transaction data in SegWit witness fields using P2WDA (Pay-to-Witness-Data-Authentication), which exploits the witness discount where witness bytes weigh 1 unit instead of 4. This makes OPNet data embedding ~75% cheaper than OP_RETURN. Some reference files discuss OP_RETURN in the context of raw Bitcoin script opcodes that contracts can construct, but that is a general Bitcoin scripting capability, not OPNet's data embedding mechanism. Never describe OPNet as using OP_RETURN for its consensus layer or transaction data.
Transactions containing BTC on OPNet can partially revert: only the consensus-layer execution reverts, while Bitcoin transfers remain valid since they are always valid when included in blocks. OPNet is fully trustless, permissionless, and decentralized, relying on Bitcoin PoW and OPNet epoch SHA-1 mining. After 20 blocks an epoch is buried deep enough that changing it requires rewriting Bitcoin's history at millions of dollars per hour. The checksum root for each epoch is a cryptographic fingerprint of the entire state; if even one bit differs, the checksum completely changes, making silent state corruption impossible.
Packages
Install specific versions for compatibility:
npm i @btc-vision/transaction@1.8.0-beta.9 opnet@1.8.1-beta.6 @btc-vision/ecpair@4.0.2 @btc-vision/bip32@7.0.2 @btc-vision/bitcoin@7.0.0-alpha.10
For smart contract development (AssemblyScript, compiles to WASM):
npm i @btc-vision/btc-runtime
TypeScript target must be ES2025. Node.js >= 22.0.0. All amounts are bigint.
Reference Documentation
Read the appropriate reference file(s) based on the task. All references are in references/ relative to this file. Every file is a 1:1 copy from official packages with nothing omitted.
MANDATORY: Read Before Writing Any Code
| When |
Reference File |
| Writing or auditing ANY OPNet contract |
example-contracts.md — Complete production source code for OP20, OP721, stablecoin, pegged WBTC, multi-oracle stablecoin, BTC name resolver, package registry, all events, constants, asconfig.json, package.json |
| Writing ANY TypeScript code |
typescript-law.md — TypeScript Law 2026: strict type system, forbidden types, defensive programming, error handling, class design, async patterns, security, BigInt for financials |
Runtime: Getting Started (@btc-vision/btc-runtime)
Runtime: Core Concepts
Runtime: Contracts
Runtime: Storage
Runtime: Types
Runtime: API Reference
Runtime: Advanced
Runtime: Examples
Client: Getting Started (opnet package)
Client: Providers
Client: Contract Interactions
Client: ABI Reference
Client: Bitcoin Operations
Client: Blocks
Client: Epochs
Client: Storage, Transactions, Public Keys, Utils
Client: Examples
Client: API Reference
Transaction Building (@btc-vision/transaction)
Transaction: Quantum Support (ML-DSA)
Package READMEs
Additional Package Documentation
TypeScript Configurations
Key Patterns
Client: Read a token balance
import { getContract, IOP20Contract, JSONRpcProvider, OP_20_ABI } from 'opnet';
import { Address } from '@btc-vision/transaction';
import { networks } from '@btc-vision/bitcoin';
const provider = new JSONRpcProvider('https://regtest.opnet.org', networks.regtest);
const token = getContract<IOP20Contract>(Address.fromString('0x...'), OP_20_ABI, provider, networks.regtest);
const result = await token.balanceOf(Address.fromString('0x...'));
console.log(result.properties.balance); // bigint
Client: Send a token transfer
import { TransactionParameters } from 'opnet';
import { Mnemonic, MLDSASecurityLevel, AddressTypes } from '@btc-vision/transaction';
const mnemonic = new Mnemonic('seed phrase...', '', network, MLDSASecurityLevel.LEVEL2);
const wallet = mnemonic.deriveUnisat(AddressTypes.P2TR, 0);
const simulation = await token.transfer(recipient, amount, new Uint8Array(0));
if (simulation.revert) throw new Error(simulation.revert);
const tx = await simulation.sendTransaction({
signer: wallet.keypair,
mldsaSigner: wallet.mldsaKeypair,
refundTo: wallet.p2tr,
maximumAllowedSatToSpend: 10000n,
feeRate: 10,
network,
});
Smart Contract: Minimal OP20 token
import { u256 } from '@btc-vision/as-bignum/assembly';
import { Blockchain, BytesWriter, Calldata, OP20, OP20InitParameters } from '@btc-vision/btc-runtime/runtime';
@final
export class MyToken extends OP20 {
public constructor() { super(); }
public override onDeployment(_calldata: Calldata): void {
const maxSupply = u256.fromString('100000000000000000000000000');
this.instantiate(new OP20InitParameters(maxSupply, 18, 'MyToken', 'MTK'));
this._mint(Blockchain.tx.origin, maxSupply);
}
}
Critical Warnings
- Constructor runs every call: In OPNet, the constructor runs on every contract interaction, not just deployment. Never put initialization logic in the constructor; use
onDeployment() instead.
- Always simulate before sending: Call the contract method first to get a
CallResult, check .revert, then call .sendTransaction().
- Non-custodial contracts: Contracts cannot hold or transfer BTC. They verify transaction outputs against state.
- Partial reverts: Consensus-layer execution can revert while Bitcoin transfers in the same transaction remain valid.
- Use Mnemonic, not WIF: Always use
Mnemonic class with deriveUnisat() for OPWallet compatibility and ML-DSA quantum support.
- BigInt everywhere: All token amounts, gas values, and satoshi amounts are
bigint.
- Pointer uniqueness: Each storage variable in a contract must have a unique pointer. Pointer collisions corrupt state silently.
- Do not read the UTXO Manager example: It is not a recommended reference.
- MANDATORY: Read example-contracts.md before writing or auditing any OPNet contract. It contains production-grade source code for all standard contract types with correct patterns for storage pointers, payment verification, event emission, access control, and two-step ownership transfers.
- MANDATORY: Read typescript-law.md before writing ANY TypeScript code. It defines strict coding standards including forbidden types, defensive programming requirements, error handling patterns, and security rules that all code must follow.
- MANDATORY: Read btc-runtime docs before writing any smart contract. The runtime-* reference files contain the complete API for Blockchain, storage, events, types, cross-contract calls, plugins, reentrancy guards, and all contract base classes. These are essential for correct contract development.
- OPNet does NOT use OP_RETURN. OPNet uses P2WDA (witness data authentication) to embed data in SegWit witness fields at ~75% lower cost than OP_RETURN. References to OP_RETURN in the bitcoin-scripts and transaction-configuration docs describe raw Bitcoin script capabilities that contracts can construct, not OPNet's own data embedding. Never state or imply that OPNet uses OP_RETURN.