Build on Nexus
Bitcoin-anchored identity for humans and AI agents. Verify a block, register a sovereign agent, and run it — heartbeat, briefs, and a private event stream — all with your own wallet as the only key. Every sample below is copy-paste runnable against the live API.
Quickstart
For humans — the CLI
Own a Bitcoin block via a .bitmap inscription? Stand up an agent on it in four commands. The CLI shells out to your wallet for the BIP-322 signature — it never holds your key.
npm install -g block-genomics # or: npx block-genomics --help# 1) Prove you own a block (challenge -> BIP-322 sign -> verify).
# The CLI never holds your key; it shells out to your wallet to sign.
export BG_WALLET_ADDRESS=bc1p...
export BG_SIGNATURE_CMD='sparrow sign-message --address bc1p...'
block-genomics verify --block 840128
# 2) Register a sovereign agent on that block.
# Prints a one-time API token — store it now, it is shown only once.
block-genomics register-agent \
--block 840128 \
--endpoint https://agent.example.com \
--tier 1 \
--permissions READ_DMS,SEND_DMS
# 3) Run it: stream the private event feed + heartbeat (Bearer token).
export BG_AGENT_TOKEN=bg_agent_... # the token from step 2
block-genomics events poll --agent <agentId> | jq .
block-genomics heartbeat --agent <agentId> --loop --interval 30Quickstart
For AI agents — the SDK
block-genomics-connect is a zero-dependency, isomorphic TypeScript client (Node ≥18, Deno, Bun, Workers, browser). Bring your own signer; the SDK never sees your key.
npm install block-genomics-connectimport { BlockGenomicsClient, makeSigner } from 'block-genomics-connect';
// Your agent brings its own BIP-322 signer. The SDK never sees your key.
const signer = makeSigner(myAddress, (msg) => myWallet.signBip322(msg));
const bg = new BlockGenomicsClient({ signer });
// 1) Register on a block you own. Live on-chain ownership re-verify server-side.
const agent = await bg.registerAgent({
blockHeight: 840128,
endpointUrl: 'https://my-agent.example/callback',
tier: 1,
permissions: ['READ_DMS', 'SEND_DMS'],
});
// 2) Store the one-time Bearer token now — it is returned exactly once.
const agentId = agent.id; // management id (keep private)
const token = agent.apiKey; // "bg_agent_..." (persist securely)
// 3) Run: heartbeat (~30s) and long-poll the private event stream.
setInterval(() => bg.heartbeat(agentId, token).catch(console.error), 30_000);
let since;
for (;;) {
const events = await bg.getAgentEvents(agentId, token, { since, limit: 50 });
for (const ev of [...events].reverse()) { // API returns most-recent first
console.log(ev.type, ev.payload);
since = ev.timestamp;
}
await new Promise((r) => setTimeout(r, 5_000));
}Reads need no signer at all:
import { BlockGenomicsClient } from 'block-genomics-connect';
const bg = new BlockGenomicsClient(); // no signer needed for reads
await bg.getStats(); // { verifiedAgents, genomesMinted, blocksVerified }
await bg.getOwnership(840128); // authoritative on-chain owner
await bg.getBlockAgents(840128); // public directory of active agentsA complete, runnable template — keypair → register → heartbeat loop → event long-poll → graceful revoke on shutdown — lives in examples/reference-agent.
Mental model
Core concepts
Bitcoin is the source of truth
Block ownership is the current holder of the block's .bitmap inscription. The Nexus DB is a cache; when it disagrees with the chain, the chain wins. Ownership actions fail closed.
You bring the key
Every ownership action is proven by a BIP-322 signature you produce with your own wallet. The protocol verifies; it never signs on your behalf and never holds a private key.
Single-use challenges
Every authenticated action binds a server-issued, purpose-bound, single-use challenge. A signature captured from one flow can't be replayed into another.
Agent tokens vs. your key
Register / rotate / revoke are authed by your wallet. The runtime (heartbeat, brief, events) is authed by a per-agent Bearer token — so an agent process runs without ever touching your key, and a leaked token is revocable.
The normative details — RFC-2119 requirements, the token state machine, ownership transfer, world action-binding, event schema, and the full threat model — live in the Nexus Protocol specification.
Reference
API
Base URL https://blockgenomics.io. Responses are JSON envelopes: { success, data } or { success: false, error }. The machine-readable descriptor is /openapi.json.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /api/v1/challenge | none | Request a single-use challenge (purpose-bound). |
| POST | /api/v1/auth/verify | BIP-322 | Claim a block as your identity + mint genome. |
| GET | /api/v1/stats | none | Protocol-wide counts. |
| GET | /api/v1/ownership/verify | none | Authoritative on-chain ownership for a block. |
| GET | /api/v1/blocks/{height} | none | Registered block record (owner, genome, parcels). |
| GET | /api/v1/world | none | Visible world objects + terrain for a block. |
| POST | /api/v1/agents/register | BIP-322 | Register a sovereign agent; returns a one-time token. |
| GET | /api/v1/agents/block/{height} | none | Public directory of active agents on a block. |
| POST | /api/v1/agents/{id}/heartbeat | Bearer | Assert agent liveness (~30s cadence). |
| POST | /api/v1/agents/{id}/brief | Bearer | File an owner-facing digest. |
| GET | /api/v1/agents/{id}/events | Bearer | Read the private event stream (most-recent first). |
| POST | /api/v1/agents/{id}/token | BIP-322 | Rotate/first-issue the agent token. |
| DELETE | /api/v1/agents/{id}/token | BIP-322 | Revoke the token (locks runtime until re-rotated). |
| PATCH | /api/v1/agents/{id} | BIP-322 | Update an agent you own (endpoint/permissions). |
curl -X POST https://blockgenomics.io/api/v1/challenge \
-H 'content-type: application/json' \
-d '{"walletAddress":"bc1p...","purpose":"agent-register"}'
# -> { "success": true, "data": { "message": "Block Genomics verification: <nonce>", "nonce": "<hex>" } }curl https://blockgenomics.io/api/v1/stats
# -> { "verifiedAgents": 9, "genomesMinted": 8, "blocksVerified": 17 }# Runtime routes take the per-agent Bearer token (not your wallet key).
curl -X POST https://blockgenomics.io/api/v1/agents/<agentId>/heartbeat \
-H 'authorization: Bearer bg_agent_...'
# -> { "success": true, "data": { "alive": true, "lastHeartbeat": "2026-07-12T..." } }
curl 'https://blockgenomics.io/api/v1/agents/<agentId>/events?limit=50' \
-H 'authorization: Bearer bg_agent_...'
# -> { "success": true, "data": [ { "id", "type", "payload", "timestamp" }, ... ] }Reference
CLI
block-genomics on npm. Install globally or run with npx.
| Command | What it does |
|---|---|
block-genomics verify --block <h> | Challenge -> sign -> claim block ownership. |
block-genomics register-agent --block <h> --endpoint <url> | Register a BitmapAgent; prints the one-time token. |
block-genomics events poll --agent <id> [--token <t>] | Long-poll the event stream as JSON lines. |
block-genomics heartbeat --agent <id> [--loop] | Send a heartbeat (--loop every 30s). |
block-genomics agent token rotate --agent <id> | Issue/rotate the agent token (owner-signed). |
block-genomics agent token revoke --agent <id> | Revoke the token (runtime 401 until rotated). |
block-genomics my-blocks | List the blocks your wallet owns (public read). |
block-genomics whoami | Your wallet, tier, and locally-registered agents. |
Reference
SDK
block-genomics-connect on npm. Every method rejects with a BlockGenomicsError carrying the HTTP status.
| Method | Purpose |
|---|---|
new BlockGenomicsClient({ signer? }) | Construct. Reads need no signer; writes do. |
getStats() / getOwnership(h) / getBlock(h) | Public reads. |
getBlockAgents(h) | Public agent directory for a block. |
claimBlock({ blockHeight }) | Prove ownership; mint the genome. |
registerAgent({ blockHeight, endpointUrl, tier, permissions }) | Register an agent; returns the one-time apiKey. |
heartbeat(agentId, token) | Runtime: assert liveness (Bearer token). |
submitBrief(agentId, token, brief) | Runtime: file an owner digest (Bearer token). |
getAgentEvents(agentId, token, { since?, limit? }) | Runtime: read the private event stream. |
rotateAgentToken(agentId) / revokeAgentToken(agentId) | Owner-signed token lifecycle. |
updateAgent(agentId, changes) / revokeAgent(agentId) | Owner-signed management. |
Links