Architecture
opnet Library Architecture Diagram
Contract Layer
The contract layer provides the classes and interfaces required to represent and interact with smart contracts deployed on OP_NET. Each contract instance is bound to an Application Binary Interface (ABI) definition that enforces type-safe method calls. Under the hood, contract instances communicate with OP_NET nodes through the provider, which handles calldata encoding, network transport, and response decoding transparently.
Creating a Contract
The getContract() factory function is the recommended approach for creating type-safe contract instances. This factory binds ABI methods to the contract address and configures the underlying provider for network communication. The resulting contract instance exposes all defined methods as strongly-typed functions, providing full IntelliSense support and compile-time parameter validation.
import { getContract, IOP20Contract, OP_20_ABI } from 'opnet';
const token = getContract<IOP20Contract>(
contractAddress,
OP_20_ABI,
provider,
network
);
// Type-safe method calls
const name = await token.name();
const balance = await token.balanceOf(address);ABIs (Application Binary Interface)
ABIs define the contract interface by specifying the available methods and events. For detailed information, refer to the Understanding ABIs section.
The library includes pre-built ABIs for standard contract types. For a complete list, refer to the Importing ABI section.
Type Safety
The library provides full TypeScript support with generics, enabling type-safe contract interactions.
// Type-safe contract interface
interface IMyToken extends IOP20Contract {
mint(to: Address, amount: bigint): Promise<CallResult<never>>;
}
// Generic contract instantiation
const token = getContract<IMyToken>(
address,
myTokenABI,
provider,
network
);
// Type-checked method calls
const result = await token.mint(recipient, 1000n);
// ^^^^^ TypeScript knows this returns CallResult<never>Provider Layer
RPC providers handle communication with OP_NET nodes by abstracting the underlying network protocol and managing request serialization, response parsing, and connection handling. Providers can be configured to connect to different nodes or networks, enabling seamless transitions between development, testing, and production environments without modifying application code.
Refers to the Choosing a Network section for detailed information about available networks.
Since Bitcoin uses UTXOs instead of account balances, the provider layer includes a UTXOsManager for UTXO fetching and tracking.
The library offers two provider types:
- JSONRpcProvider: HTTP-based with a request/response pattern.
- WebSocketRpcProvider(experimental): Supports real-time subscriptions and notifications.
import { JSONRpcProvider } from 'opnet';
import { networks } from '@btc-vision/bitcoin';
// JSON-RPC for standard operations
const provider = new JSONRpcProvider({
url: 'https://regtest.opnet.org',
network: networks.regtest
});
// Get blockchain state
const blockNumber = await provider.getBlockNumber();
const balance = await provider.getBalance('bc1q...');
// Get UTXOs for an address
const utxos = await provider.utxoManager.getUTXOs({
address: 'bc1q...',
optimize: true,
});Data Layer
The data layer provides classes for managing core blockchain data including blocks, transactions, and epochs. Rather than accessing node data directly, this layer defines the types that represent blockchain data across all interactions with the OP_NET network.
This separation ensures type safety throughout the application while delegating network communication to other layers. When data is fetched or operations are performed, responses are deserialized into the corresponding data layer types, providing strongly-typed objects for application consumption.
Blocks
Blocks in OP_NET correspond directly to Bitcoin blocks and contain all OP_NET transactions processed within that block. The data layer provides access to block information including block height, hash, timestamp, and the decoded OP_NET transactions contained within.
import { JSONRpcProvider } from 'opnet';
import { networks } from '@btc-vision/bitcoin';
const provider = new JSONRpcProvider({
url: 'https://regtest.opnet.org',
network: networks.regtest
});
const blockNumber = await provider.getBlockNumber();
console.log('Current block:', blockNumber);Transactions
Every operation on OP_NET is ultimately expressed as a Bitcoin transaction. The protocol distinguishes between three transaction types:
- Deployment: Publishes a new smart contract to the network.
- Interaction: Invokes a method on a deployed smart contract.
- Generic: A standard Bitcoin transfer that carries no smart contract payload.
For detailed information of each type, refer to the Transaction Types Explained section.
Epochs
OP_NET uses epochs for consensus, where each epoch represents a mining cycle during which participants submit SHA-1 collision solutions. The data layer exposes epoch information including mining status, rewards, and finalization state.
For detailed information, refer to the About Epochs section.
import { JSONRpcProvider } from 'opnet';
import { networks } from '@btc-vision/bitcoin';
// JSON-RPC for standard operations
const provider = new JSONRpcProvider({
url: 'https://regtest.opnet.org',
network: networks.regtest
});
const epoch = await provider.getLatestEpoch(true);
console.log('Epoch:', epoch.epochNumber);
console.log('Proposer:', epoch.proposer?.publicKey);Library Modules
The library exposes its functionality through a set of exports. All public classes, interfaces, types, and utility functions are accessible from the main package entry point.
import {
// Providers
JSONRpcProvider,
WebSocketRpcProvider,
// Contracts
getContract,
CallResult,
OPNetEvent,
// ABIs
OP_20_ABI,
OP_721_ABI,
MOTOSWAP_ROUTER_ABI,
// Types
IOP20Contract,
IOP721Contract,
// Data Classes
Block,
Epoch,
Transaction,
// Utils
BitcoinUtils,
RevertDecoder,
} from 'opnet';