Minimal TypeScript educational node that models the Bitcoin‑IPC architecture: Proof‑of‑Stake subnets with BTC‑denominated stake, CometBFT‑style weighted quorum gates, cross‑subnet envelopes inspired by SegWit / OP_RETURN batching (SWIFT‑like messaging in the paper), and a local harness with two subnets plus optional hook‑up to Bitcoin Core regtest over JSON‑RPC.
One‑liner: a living reference for researchers and builders reading Bitcoin‑IPC: Scaling Bitcoin with a Network of Proof‑of‑Stake Subnets (HTML) — implemented in TS for clarity instead of production Rust.
This repo does not reproduce the full Bitcoin Scaling Labs stacks (bitcoin‑ipc / ipc / Fendermint). Public reference implementations live in Rust on GitHub — e.g. bitcoinscalinglabs/bitcoin-ipc and bitcoinscalinglabs/ipc (org). subnet-core stays deliberately tiny and dependency‑light in TypeScript for reading, testing, and classroom use.
From public summaries of the whitepaper (v0.3, Dec 2025): subnets are permissionless programmable PoS chains anchored to Bitcoin L1, with critical routing / settlement metadata carried on L1 via SegWit (and OP_RETURN in their design space), aiming for large virtual‑byte savings versus naive L1 usage — figures often cited around ~23× lower vB/tx and effective monetary throughput on the order of ~160+ tps versus raw ~7 tps payment‑style usage on L1, without Bitcoin Core forks.
This codebase does not prove those benchmarks; it implements narrow, test‑backed simulations of stake, quorum math, envelopes, and optional RPC height sync.
| Area | Symbols | Role |
|---|---|---|
| Stake ledger | StakeLedger |
Locks BTC collateral (sats) → voting weight; subnet bootstrap & whitelist hooks. |
| Consensus gate | tryFinalizeWeighted |
Strict > ⅔ stake rule (3·w_commit > 2·w_total). |
| Witness envelope | WitnessEnvelope, envelopeCommitment, encodeWitnessStackItem |
Canonical IPC‑style payloads + hashes (bigint‑safe JSON). |
| OP_RETURN packing | packAnchorPayload, unpackAnchorPayload, IPC_ANCHOR_MAGIC |
Tiny BTCIP1 ‖ sha256 blob ≤ standard relay‑friendly sizes — conceptual cousin to batched witness/OP_RETURN IPC metadata. |
| L1 router (simulated) | L1WitnessRouter |
Ordered anchor log + per‑subnet inbox (stands in for Bitcoin monitor DB). |
| Two‑subnet harness | LocalDevnetHarness |
Deposits + cross‑subnet transfer + rollback unless quorum commits the exact envelope hash. |
| Regtest coordinator | RegtestCoordinatorHarness, BitcoinCoreRpc, bitcoinRpcFromEnv |
Optional live getblockchaininfo block height for anchorHeight when you run bitcoind (regtest/signet/etc.). |
- Node.js ≥ 20
cd subnet-core
npm install
npm test # Vitest (unit + optional integration)
npm run lint # tsc --noEmit
npm run build # emits dist/
npm run clean # remove dist/
# Optional Bitcoin Core regtest via Docker (requires Docker Engine + Compose plugin)
npm run compose:regtest # docker compose up -d (see compose.yaml)
npm run compose:regtest:downWhen BITCOIN_RPC_URL and credentials are set, one integration test talks to your node (describe.skipIf otherwise):
After npm run compose:regtest:
export BITCOIN_RPC_URL=http://127.0.0.1:18443
export BITCOIN_RPC_AUTH=subnetcore:subnetcore # rpcuser:rpcpassword from compose.yaml
npm test # enables test/regtest.integration.test.tsPrefer BITCOIN_RPC_COOKIE_PATH (matches how bitcoind writes auth locally):
export BITCOIN_RPC_URL=http://127.0.0.1:18443
export BITCOIN_RPC_COOKIE_PATH=/path/to/regtest/.cookie
npm testIf BITCOIN_RPC_URL is unset—or credentials cannot be resolved—the integration suite stays skipped (offline‑friendly CI).
Use RegtestCoordinatorHarness.fromEnv() to merge simulated subnets with live blocks height:
import {
RegtestCoordinatorHarness,
envelopeCommitment,
stableStringify,
packAnchorPayload,
} from "./src/index.js";
const harness = RegtestCoordinatorHarness.fromEnv();
const height = await harness.anchorHeightOrFallback();
const intent = { from: "alice", to: "bob", amountSats: 25n, memo: "demo" };
const commitment = envelopeCommitment({
version: 1,
kind: "cross_subnet_transfer",
srcSubnet: "subnet-alpha",
dstSubnet: "subnet-beta",
anchorHeight: height,
nonce: 1n,
payloadUtf8: stableStringify(intent),
});
void packAnchorPayload(commitment); // embed on L1 in real integrations (wallet/RPC wiring out-of-scope here)- TypeScript: your brief mentions Rust subnet‑core; this TS repo targets teaching + fast tests; swap consensus/engine for production crates when moving beyond sketches.
- Safety‑first demo: mismatched quorum commitments rollback the source ledger debit instead of bridging optimistically.
- Out of scope: real Bitcoin Script contracts, mempool fee markets, full CometBFT rounds/evidence, relayer incentives, EVM/FVM execution — add externally if needed.
Telegram: @AuraTerminal