Architecture

opnet Library Architecture Diagram

opnet Client Library Architecture Application Your Code OP_NET Library Contract Layer Contract CallResult ABI System Provider Layer AbstractRpcProvider UTXOsManager JSONRpcProvider WebSocketRpcProvider extends extends Data Layer Blocks Transactions Epochs OP_NET Node JSON-RPC API WebSocket API Bitcoin Network Bitcoin

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.

typescript
Using getContract
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.

typescript
Type-safe Contract Interface
// 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.
typescript
Using JSONRpcProvider and UTXOsManager
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.

typescript
Accessing Block Data
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.

typescript
Fetching the Latest Epoch
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.

typescript
Importing opnet client library
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';