Bitcoin
Effectstream supports connecting directly to the Bitcoin network (including Regtest for development). This allows you to build dApps that react to native Bitcoin transactions, such as ordinals, runes, or standard payments.
1. Configuration (Read)
Network Definition
Configure the connection to a Bitcoin Core node (RPC).
.buildNetworks(builder =>
builder.addNetwork({
name: "bitcoin",
type: ConfigNetworkType.BITCOIN,
rpcUrl: "http://127.0.0.1:18443",
rpcAuth: {
username: "dev",
password: "devpassword",
},
network: "regtest", // or mainnet, testnet
})
)
Sync Protocol
Use BITCOIN_RPC_PARALLEL to poll the Bitcoin node for blocks.
.addParallel(
(networks) => networks.bitcoin,
(network, deployments) => ({
name: "parallelBitcoin",
type: ConfigSyncProtocolType.BITCOIN_RPC_PARALLEL,
rpcUrl: "http://127.0.0.1:18443",
startBlockHeight: 0,
pollingInterval: 10_000,
confirmationDepth: 1,
})
)
Primitives
PrimitiveTypeBitcoinAddress: Monitors a specific Bitcoin address, where some pattern as (P2PKH, P2WPKH, etc.) can be implemented, for incoming or outgoing transactions.
import { PrimitiveTypeBitcoinAddress } from "@effectstream/sm/builtin";
.addPrimitive(
(syncProtocols) => syncProtocols.parallelBitcoin,
(network, deployments, syncProtocol) => ({
name: "Watch-System-Wallet",
type: PrimitiveTypeBitcoinAddress,
watchAddress: "bcrt1qfv6m6l5s6cgda09yr5nd8rnufkaz59d3aquq03", // Bech32 address
stateMachinePrefix: "bitcoin-tx",
})
)
2. Batcher Adapters (Write)
To submit transactions to Bitcoin (e.g., for settlement or payments), you use the BitcoinAdapter.
Bitcoin Adapter
This adapter manages UTXO selection, transaction building (PSBT), and signing using bitcoinjs-lib.
import { BitcoinAdapter } from "@effectstream/batcher";
const bitcoinAdapter = new BitcoinAdapter({
rpcUrl: "http://127.0.0.1:18443",
rpcUser: "dev",
rpcPass: "devpassword",
seed: "your-wallet-seed-phrase", // Used to derive keys for signing
network: "regtest"
});
3. Orchestration
Use launchBitcoin from @effectstream/orchestrator/start-bitcoin. This spins up a local Bitcoin Core node in regtest mode.
// in start.ts
processesToLaunch: [
...launchBitcoin("@my-project/bitcoin-contracts"),
]
It is also common to include a process to mine blocks automatically in the background to ensure transaction processing during development.
NOTE: To use this launcher you need to implement some
deno taskin your project. A working implementation is provided in thetemplate generator,templatesore2e tests.
{
"name": "@e2e/bitcoin-contracts",
...
"tasks": {
"chain:start": "deno run -A @effectstream/bitcoin-core",
"chain:wait": "wait-on tcp:18443",
"generate:blocks": "deno run -A ./generate-blocks.ts",
"wait-for-block": "deno run -A wait-for-block.ts"
}
}