Rúnar

SDK API

This page provides a complete reference for all public classes, methods, and types exposed by the runar-sdk package. Use it as a companion to the conceptual guides in the SDK section.

RunarContract

The main class for interacting with deployed contracts.

Constructor

new RunarContract(artifact: RunarArtifact, constructorArgs: unknown[])
ParameterTypeDescription
artifactRunarArtifactThe compiled JSON artifact from runar compile
constructorArgsunknown[]Constructor arguments as an array, matching the order in the artifact’s abi.constructor.params
const contract = new RunarContract(artifact, [pubKeyHash]);

Static Methods

fromTxId()

Reconstruct a contract instance from an existing on-chain deployment.

static async fromTxId(
  artifact: RunarArtifact,
  txId: string,
  outputIndex: number,
  provider: Provider
): Promise<RunarContract>

Fetches the transaction from the network, extracts the locking script from the specified output, and recreates the contract instance with its current state.

const contract = await RunarContract.fromTxId(
  artifact,
  'a1b2c3d4e5f6...',
  0,
  provider
);
console.log('Current state:', contract.state);

Instance Methods

deploy()

Deploy the contract to the network. Has two overloads: pass provider/signer explicitly, or use a previously connected provider/signer via connect().

// Overload 1: explicit provider and signer
async deploy(provider: Provider, signer: Signer, options?: DeployOptions): Promise<DeployResult>

// Overload 2: use connected provider/signer
async deploy(options: DeployOptions): Promise<DeployResult>
interface DeployOptions {
  satoshis?: number;
  changeAddress?: string;
}

interface DeployResult {
  txid: string;
  tx: TransactionData;
}
// With explicit provider/signer:
const result = await contract.deploy(provider, signer, { satoshis: 10000 });

// Or with connect():
contract.connect(provider, signer);
const result = await contract.deploy({ satoshis: 10000 });

call()

Invoke a public method on the deployed contract. Has two overloads matching deploy().

// Overload 1: explicit provider and signer
async call(
  methodName: string,
  args: unknown[],
  provider: Provider,
  signer: Signer,
  options?: CallOptions,
): Promise<CallResult>

// Overload 2: use connected provider/signer
async call(
  methodName: string,
  args: unknown[],
  options?: CallOptions,
): Promise<CallResult>
interface CallOptions {
  satoshis?: number;
  changeAddress?: string;
  newState?: Record<string, unknown>;
}

interface CallResult {
  txid: string;
  tx: TransactionData;
}
const result = await contract.call(
  'unlock',
  [null, signer.publicKey],  // null = auto-sign with signer
  provider,
  signer,
);

connect()

Store a provider and signer on the contract so they do not need to be passed to every deploy() and call() invocation.

connect(provider: Provider, signer: Signer): void

Mutates the contract instance in-place, storing the given provider and signer. Both provider and signer are required.

contract.connect(mainnetProvider, mainnetSigner);

setState()

Manually set the contract state. Useful for testing or resuming from a known state.

setState(state: Record<string, any>): void
contract.setState({ count: 42n, owner: '02aabb...' });

state (getter)

Read the current contract state.

get state: Record<string, any>
console.log('Count:', contract.state.count);
console.log('Owner:', contract.state.owner);

getLockingScript()

Get the compiled locking script with constructor arguments substituted.

getLockingScript(): string

Returns a hex-encoded Bitcoin Script string. Constructor arguments are already substituted from the values passed to the RunarContract constructor.

buildUnlockingScript()

Build the unlocking script for a given method call.

buildUnlockingScript(
  methodName: string,
  args: unknown[]
): string

Returns a hex-encoded unlocking script. This is useful for manual transaction construction.

Providers

Providers handle network communication — fetching UTXOs, broadcasting transactions, and querying the blockchain.

WhatsOnChainProvider

Connects to the WhatsOnChain API.

new WhatsOnChainProvider(network: 'mainnet' | 'testnet')
const provider = new WhatsOnChainProvider('testnet');
const provider = new WhatsOnChainProvider('mainnet');

Methods:

MethodSignatureDescription
getUtxos(address: string) => Promise<UTXO[]>Fetch UTXOs for an address
broadcast(rawTx: string) => Promise<string>Broadcast a raw transaction, returns TxID
getTransaction(txid: string) => Promise<Transaction>Fetch a transaction by ID
getBlockHeight() => Promise<number>Get the current block height

MockProvider

An in-memory provider for testing. Does not connect to any network.

new MockProvider()
const mock = new MockProvider();
// Pre-load UTXOs for testing
mock.addUtxo({
  txId: 'abc123...',
  outputIndex: 0,
  script: '76a914...88ac',
  satoshis: 10000,
});

Additional methods:

MethodSignatureDescription
addUtxo(utxo: UTXO) => voidAdd a UTXO to the mock state
getMempool() => Transaction[]Get all broadcast transactions
reset() => voidClear all mock state

RPCProvider

Connects to a BSV node via JSON-RPC.

new RPCProvider(url: string, user: string, pass: string, options?: RPCProviderOptions)
const provider = new RPCProvider(
  'http://localhost:8332',
  'rpcuser',
  'rpcpassword',
);

Supports all the same methods as WhatsOnChainProvider plus additional RPC-specific methods like getRawMempool() and getBlock().

Signers

Signers produce signatures for transactions.

LocalSigner

Signs with a private key held in memory.

new LocalSigner(privateKeyWIF: string)
const signer = new LocalSigner('cN1r3...');
console.log('Address:', signer.address);
console.log('Public key:', signer.publicKey);

Properties and methods:

MemberTypeDescription
publicKeystringThe signer’s public key (hex)
addressstringThe signer’s BSV address
sign(tx)(tx: Transaction) => Promise<Sig>Sign a transaction
signMessage(msg)(msg: string) => Promise<string>Sign an arbitrary message

ExternalSigner

Delegates signing to an external service or hardware device.

new ExternalSigner(pubKeyHex: string, addressStr: string, signFn: SignCallback)
type SignCallback = (txHex: string, inputIndex: number) => Promise<string>;

const signer = new ExternalSigner(
  '02aabb...',      // public key hex
  'mAddress...',    // BSV address
  async (txHex, inputIndex) => {
    // Send to hardware wallet, external API, etc.
    return await hardwareWallet.sign(txHex, inputIndex);
  },
);

WalletSigner

Integrates with BRC-100 compatible wallets using the WalletClient interface from @bsv/sdk.

new WalletSigner(options: WalletSignerOptions)
interface WalletSignerOptions {
  protocolID: [SecurityLevel, string];
  keyID: string;
  wallet?: WalletClient;  // defaults to the standard BRC-100 wallet
}

const signer = new WalletSigner({
  protocolID: [0, 'runar'],
  keyID: '1',
});

TokenWallet

Manages fungible token UTXOs and provides high-level token operations.

new TokenWallet(options: TokenWalletOptions)
interface TokenWalletOptions {
  tokenId: string;       // Minting transaction ID
  provider: Provider;
  signer: Signer;
}

Methods

getBalance()

async getBalance(): Promise<bigint>

Returns the total token balance across all owned UTXOs.

transfer()

async transfer(
  recipient: PubKey,
  amount: bigint,
  options?: TransferOptions
): Promise<TransferResult>

Transfers tokens to a recipient. Automatically selects UTXOs and splits/merges as needed.

merge()

async merge(options?: MergeOptions): Promise<MergeResult>

Consolidates multiple token UTXOs into fewer, larger UTXOs.

interface MergeOptions {
  minAmount?: bigint;  // Only merge UTXOs below this amount
  maxInputs?: number;  // Max UTXOs to merge per transaction (default: 2)
}

getUtxos()

async getUtxos(): Promise<TokenUTXO[]>

Returns all token UTXOs owned by the signer.

interface TokenUTXO {
  txId: string;
  outputIndex: number;
  amount: bigint;
  script: string;
}

Utility Functions

State Serialization

// Serialize a state object to a ByteString for embedding in script
function serializeState(state: Record<string, any>): string;

// Deserialize state from a ByteString back to an object
function deserializeState(data: string, abi: ABI): Record<string, any>;

// Extract state from an on-chain locking script
function extractStateFromScript(script: string, abi: ABI): Record<string, any>;

Transaction Building

// Compute the OP_PUSH_TX preimage for a transaction
function computeOpPushTx(
  tx: Transaction,
  inputIndex: number,
  sigHashType: number
): string;

// Build a deployment transaction
function buildDeployTransaction(
  lockingScript: string,
  utxos: UTXO[],
  satoshis: number,
  changeAddress: string,
  changeScript: string,
  feeRate?: number
): Transaction;

// Build a method call transaction
function buildCallTransaction(
  contract: RunarContract,
  methodName: string,
  args: unknown[],
  utxos: UTXO[],
  changeAddress: string
): Transaction;

UTXO Selection

// Select UTXOs to cover a target amount plus fees
function selectUtxos(
  utxos: UTXO[],
  targetAmount: number,
  feeRate?: number
): UTXO[];

// Estimate the fee for deploying a contract
function estimateDeployFee(
  numInputs: number,
  lockingScriptByteLen: number,
  feeRate?: number
): number;

Code Generation

// Generate TypeScript type definitions from a compiled artifact
function generateTypescript(artifact: ContractArtifact): string;

Produces a .d.ts file with typed method signatures, constructor parameters, and state fields. Useful for IDE autocompletion when interacting with contracts.

import { generateTypescript } from 'runar-sdk';

const types = generateTypescript(artifact);
writeFileSync('./types/P2PKH.d.ts', types);