Providers Reference
Providers are the SDK’s abstraction over blockchain access. Every contract interaction — deploying, calling, querying UTXOs — goes through a Provider. The SDK ships four implementations suited to different stages of development.
The Provider Interface
All providers implement the Provider interface defined in runar-sdk/providers/provider.ts. Here is the full contract:
import type { Transaction } from '@bsv/sdk';
import type { TransactionData, UTXO } from '../types.js';
export interface Provider {
getTransaction(txid: string): Promise<TransactionData>;
broadcast(tx: Transaction): Promise<string>;
getUtxos(address: string): Promise<UTXO[]>;
getContractUtxo(scriptHash: string): Promise<UTXO | null>;
getNetwork(): 'mainnet' | 'testnet';
getFeeRate(): Promise<number>;
getRawTransaction(txid: string): Promise<string>;
}
Method Summary
| Method | Returns | Description |
|---|---|---|
getTransaction(txid: string) | Promise<TransactionData> | Fetch a transaction by txid as a plain data shape. |
broadcast(tx: Transaction) | Promise<string> | Broadcast a @bsv/sdk Transaction object. Returns the txid on success. |
getUtxos(address: string) | Promise<UTXO[]> | Get all UTXOs for a given address. |
getContractUtxo(scriptHash: string) | Promise<UTXO | null> | Get the UTXO holding a contract identified by its script hash. Returns null if none is found. |
getNetwork() | 'mainnet' | 'testnet' | Return the network this provider is connected to. |
getFeeRate() | Promise<number> | Get the current fee rate in satoshis per KB (1000 bytes). |
getRawTransaction(txid: string) | Promise<string> | Fetch the raw transaction hex by txid. |
Supporting Types
The TransactionData and UTXO types referenced above are defined in runar-sdk/types.ts:
interface TransactionData {
txid: string;
version: number;
inputs: TxInput[];
outputs: TxOutput[];
locktime: number;
raw?: string; // raw hex
}
interface TxInput {
txid: string;
outputIndex: number;
script: string; // hex
sequence: number;
}
interface TxOutput {
satoshis: number;
script: string; // hex
}
interface UTXO {
txid: string;
outputIndex: number;
satoshis: number;
script: string;
}
WhatsOnChainProvider
HTTP-based provider that queries the WhatsOnChain API. This is the standard choice for mainnet and testnet deployments.
import { WhatsOnChainProvider } from 'runar-sdk';
const provider = new WhatsOnChainProvider('mainnet');
Constructor
constructor(network: 'mainnet' | 'testnet' = 'mainnet')
The network parameter defaults to 'mainnet'. It determines the base URL:
- mainnet —
https://api.whatsonchain.com/v1/bsv/main - testnet —
https://api.whatsonchain.com/v1/bsv/test
Method Implementations
getTransaction(txid: string): Promise<TransactionData>
Fetches from GET /tx/hash/{txid}. Converts the WoC response into a TransactionData shape. Output values are converted from BTC to satoshis via Math.round(value * 1e8).
broadcast(tx: Transaction): Promise<string>
Posts the transaction hex (via tx.toHex()) to POST /tx/raw as JSON { txhex: rawTx }. Returns the txid string from the response.
getUtxos(address: string): Promise<UTXO[]>
Fetches from GET /address/{address}/unspent. Note that WoC does not return locking scripts in the UTXO list, so the script field on each returned UTXO is set to ''.
getContractUtxo(scriptHash: string): Promise<UTXO | null>
Fetches from GET /script/{scriptHash}/unspent. Returns the first entry if any exist, or null if the list is empty or the endpoint returns 404. As with getUtxos, the script field is ''.
getNetwork(): 'mainnet' | 'testnet'
Returns the network passed to the constructor.
getRawTransaction(txid: string): Promise<string>
Fetches from GET /tx/{txid}/hex and returns the trimmed text response.
getFeeRate(): Promise<number>
Always returns 100 (the BSV standard relay fee of 0.1 sat/byte, expressed as 100 sat/KB).
MockProvider
In-memory provider for unit tests and local development. It stores transactions and UTXOs in memory, and records every broadcast for test assertions.
import { MockProvider } from 'runar-sdk';
const provider = new MockProvider('testnet');
Constructor
constructor(network: 'mainnet' | 'testnet' = 'testnet')
Defaults to 'testnet'. Initializes empty internal maps for transactions, UTXOs, and contract UTXOs, plus an empty broadcast log.
Test Data Injection Methods
These methods let you seed the mock with data before running your tests.
addTransaction(tx: TransactionData): void
Stores a TransactionData object by its txid. If tx.raw is present, the raw hex is also stored for getRawTransaction lookups.
provider.addTransaction({
txid: 'abc123...',
version: 1,
inputs: [],
outputs: [{ satoshis: 5000, script: '76a914...' }],
locktime: 0,
raw: '0100000001...',
});
addUtxo(address: string, utxo: UTXO): void
Appends a UTXO to the list for a given address. Multiple calls for the same address accumulate.
provider.addUtxo('1A1zP1...', {
txid: 'abc123...',
outputIndex: 0,
satoshis: 10000,
script: '76a914...',
});
addContractUtxo(scriptHash: string, utxo: UTXO): void
Sets the contract UTXO for a given script hash. Overwrites any previously stored UTXO for that hash.
provider.addContractUtxo('e3b0c4...', {
txid: 'def456...',
outputIndex: 0,
satoshis: 1,
script: '5101...',
});
Inspection Methods
Use these after running contract operations to verify what happened.
getBroadcastedTxs(): readonly string[]
Returns a read-only array of all raw transaction hex strings that were broadcast through this provider. Each entry is the result of tx.toHex() at broadcast time.
getBroadcastedTxObjects(): readonly Transaction[]
Returns a read-only array of all @bsv/sdk Transaction objects that were broadcast. Useful when you need to inspect the structured transaction rather than raw hex.
Configuration Methods
setFeeRate(rate: number): void
Overrides the fee rate returned by getFeeRate(). Defaults to 100.
provider.setFeeRate(50); // 50 sat/KB
const rate = await provider.getFeeRate(); // 50
Provider Interface Methods
getTransaction(txid: string): Promise<TransactionData>
Returns the stored TransactionData for the given txid. Throws if not found.
broadcast(tx: Transaction): Promise<string>
Records the raw hex (tx.toHex()) and the Transaction object in the broadcast log, increments the internal broadcast counter, and returns a deterministic fake txid derived from the raw hex. The raw hex is also auto-stored for subsequent getRawTransaction lookups.
getUtxos(address: string): Promise<UTXO[]>
Returns the UTXOs previously added via addUtxo for the given address. Returns [] if none were added.
getContractUtxo(scriptHash: string): Promise<UTXO | null>
Returns the UTXO previously set via addContractUtxo, or null if none was set for that script hash.
getNetwork(): 'mainnet' | 'testnet'
Returns the network passed to the constructor.
getRawTransaction(txid: string): Promise<string>
Looks up the raw hex by txid. Checks the raw transaction map first (populated by addTransaction and broadcast), then falls back to the raw field on stored TransactionData. Throws if not found or if the stored transaction has no raw field.
getFeeRate(): Promise<number>
Returns the current fee rate (default 100, changeable via setFeeRate).
Example: Testing a Contract Deploy
import { MockProvider } from 'runar-sdk';
import { LocalSigner } from 'runar-sdk';
import { RunarContract } from 'runar-sdk';
import artifact from './artifacts/Counter.json';
const provider = new MockProvider();
const signer = new LocalSigner(provider, 'your-private-key-wif');
// Seed funding UTXOs
const address = await signer.getAddress();
provider.addUtxo(address, {
txid: 'a'.repeat(64),
outputIndex: 0,
satoshis: 100_000,
script: '76a914...',
});
// Deploy
const contract = new RunarContract(artifact, [0]);
contract.connect(provider, signer);
const deployTx = await contract.deploy();
// Assert broadcast happened
const broadcasts = provider.getBroadcastedTxs();
console.log(`Broadcast count: ${broadcasts.length}`); // 1
RPCProvider
JSON-RPC provider that communicates directly with a Bitcoin node. Ideal for regtest and testnet integration testing where you run your own node.
import { RPCProvider } from 'runar-sdk';
const provider = new RPCProvider(
'http://localhost:18332',
'rpcuser',
'rpcpassword',
{ autoMine: true, network: 'testnet' }
);
Constructor
constructor(
url: string,
user: string,
pass: string,
options?: RPCProviderOptions
)
| Parameter | Type | Description |
|---|---|---|
url | string | The JSON-RPC endpoint URL of the Bitcoin node (e.g., http://localhost:18332). |
user | string | RPC username for Basic authentication. |
pass | string | RPC password for Basic authentication. |
options | RPCProviderOptions | Optional configuration object (see below). |
RPCProviderOptions
interface RPCProviderOptions {
autoMine?: boolean;
mineAddress?: string;
network?: 'mainnet' | 'testnet';
}
| Option | Type | Default | Description |
|---|---|---|---|
autoMine | boolean | false | When true, automatically mine 1 block after every broadcast() call. Useful for regtest where transactions need to be mined to appear in UTXO queries. |
mineAddress | string | '' | Mining address for generatetoaddress. If empty, falls back to the generate RPC method. |
network | 'mainnet' | 'testnet' | 'testnet' | Network name returned by getNetwork(). |
Method Implementations
getTransaction(txid: string): Promise<TransactionData>
Calls getrawtransaction with verbose=true. Parses the output values from BTC to satoshis via Math.round(valBTC * 1e8). Note: the returned TransactionData has an empty inputs array, version hardcoded to 1, and locktime hardcoded to 0. The raw field contains the full raw hex.
broadcast(tx: Transaction): Promise<string>
Calls sendrawtransaction with tx.toHex(). If autoMine is enabled, mines 1 block immediately after. Returns the txid.
getUtxos(address: string): Promise<UTXO[]>
Calls listunspent with parameters (0, 9999999, [address]) to include unconfirmed UTXOs. Converts amounts from BTC to satoshis.
getContractUtxo(_scriptHash: string): Promise<UTXO | null>
Always returns null. Script hash lookups are not supported via standard Bitcoin RPC.
getNetwork(): 'mainnet' | 'testnet'
Returns the network from options (default 'testnet').
getRawTransaction(txid: string): Promise<string>
Calls getrawtransaction with verbose=false to get the raw hex string.
getFeeRate(): Promise<number>
Always returns 100 (standard BSV relay fee).
RPC Connection Details
The provider uses HTTP Basic authentication, constructing the Authorization header from the user and pass parameters. All RPC calls use JSON-RPC 1.0 format with an id of 'runar'. Requests have a 10-minute timeout (AbortSignal.timeout(600_000)).
WalletProvider
The WalletProvider integrates with a BRC-100 wallet for UTXO management and uses GorillaPool ARC for broadcast in EF (Extended Format). It is designed for production applications that use wallet-based signing.
For full documentation on configuring and using WalletProvider, including its WalletProviderOptions, ensureFunding() method, overlay service integration, and cacheTx() helper, see the Wallet Integration page.
import { WalletProvider } from 'runar-sdk';
const provider = new WalletProvider({
wallet: myWalletClient,
signer: myWalletSigner,
basket: 'my-app',
});
When to Use Which Provider
| Scenario | Provider | Why |
|---|---|---|
| Unit tests | MockProvider | No network calls. Seed exact UTXOs and transactions, then assert on broadcasts. Deterministic and fast. |
| Regtest integration tests | RPCProvider | Talks to a local Bitcoin node. Use autoMine: true to mine blocks automatically after each broadcast. |
| Testnet / Mainnet (simple) | WhatsOnChainProvider | HTTP-based, no infrastructure to run. Works out of the box for 'mainnet' and 'testnet'. |
| Production with wallet | WalletProvider | BRC-100 wallet integration with ARC broadcast (EF format), basket-based UTXO management, and optional overlay indexing. |
A typical project progression:
- Start with
MockProviderfor fast unit tests during contract development. - Move to
RPCProviderwith a local regtest node for integration tests that verify real transaction behavior. - Deploy to testnet with
WhatsOnChainProviderfor pre-production validation. - Ship to mainnet with either
WhatsOnChainProvider(for backend services) orWalletProvider(for user-facing apps with wallet signing).