cd /news/ai-agents/an-agent-s-life-on-the-chain-init-to… · home › topics › ai-agents › article
[ARTICLE · art-152407] src=gist.github.com ↗ pub= topic=ai-agents verified=true sentiment=· neutral

An agent's life on the chain: init to exodus (gitmark workflow for LLM agents)

A developer published a step-by-step workflow for running an LLM agent on Bitcoin testnet4 using gitmark, in which the agent is created and funded with 10,000 sats, anchors its commits to Bitcoin via `git mark`, announces its repository on Nostr as a signed NIP-34 kind 30617 event, and finally returns its remaining balance to the operator's voucher. Each step is a single command with a verification check, and the workflow requires explicit operator approval before any irreversible spend or public announcement.

by read6 min views1 publishedOct 18, 2026

A workflow for an LLM agent (or a person driving one). The agent gets a key, gets coins, anchors its commits to Bitcoin, announces the repo on Nostr, and when it is done hands the coin back and closes the trail. Every step is one command; every step has a check. Do the steps in order and stop at the first check that fails.

Tools: npm init agent (create-agent), npx fund-agent, git mark (gitmark ≥ 0.0.82). Chain used here: txbt4, the BLAKE2b testnet4. Nothing below is mainnet.

  1. Never print, log, paste or commit the private key. It lives in git config nostr.privkey and nowhere else.
  2. One command at a time. Read its output before the next one.
  3. A mark is a real Bitcoin spend and cannot be undone. Announcing is public and signed. Exodus sends the whole balance. Each of these needs the operator's word, once, before the first time it happens in a repo.
  4. Never retry a spend blindly. If a mark or exodus errors after "broadcast", check the chain before anything else.
  5. Keep it light: one explorer call per check, no polling loops faster than a minute.
node --version                  # 20 or newer
npm view gitmark version        # 0.0.82 or newer; else: npm install -g gitmark@latest
ls ~/.gitmark/faucet.txt        # the voucher file; if missing, see "No voucher" below

Check: all three print something. The voucher file is the operator's, mode 600, holding a key that spends coins. Never read it aloud; npx fund-agent status is the only way to look at it.

mkdir my-agent && cd my-agent && git init -q
npm init agent

Check: git config --local nostr.privkey | wc -c prints 65. agent.did.json exists. Nothing else to do with the key.

npx fund-agent

What happens: 10,000 sats go from the voucher to the agent's key; the change goes back to the voucher; the coin is written to .well-known/txo/txo.json.

Check: the output ends with === Agent funded successfully! === and a txid. Then:

npx fund-agent balance          # Address: tb1p…, one coin of 10,000 sats (unconfirmed is fine)

If it says the voucher has no coins, stop and tell the operator the address it printed. Do not look for coins elsewhere.

git mark init --chain txbt4

What happens: gitmark finds the coin sitting at the key's base address and adopts it. No spend yet.

Check: git config --local gitmark.txo prints a txo:txbt4:… line, and blocktrails.json exists with "states": [].

git add -A && git commit -qm "what changed"
git mark

What happens: one transaction, 300 sat fee, spending the trail coin to an address derived from this commit. Output: Marked: <commit> → <txid>, the new balance, the new TXO.

Check: git mark info shows Marks: 1, Last commit: is HEAD, Balance: is 300 less than before. Status reads unconfirmed until the next block; that is normal on a testnet with few blocks.

Rules of thumb:

  • Mark commits worth proving, not every commit. 10,000 sats is about thirty marks.
  • git mark on a commit that is already the last mark is refused. That is correct; commit first.
  • An unknown word (git mark anchor ,git mark commit ) prints usage and exits 1. It never marks by accident.
  • Commit blocktrails.json after marking; it is the public trail. Or setgit config gitmark.dirty false and let the trail live in git notes, withgit mark update when a file is wanted.

Repeat 4 for as long as the agent works.

Once, when the repo has a remote worth pointing at:

git remote add origin <url>     # and any mirrors: git remote add forge <url>
git push -u origin HEAD
git mark announce

What happens: a NIP-34 repository announcement (kind 30617), signed with the agent's key, carrying the latest mark as chain, txo and commit tags and every remote as a clone tag. Relays come from git config nostr.relays (comma or space separated), or the defaults.

Check: the output ends Announced: kind 30617 … (n/m relays) with n ≥ 1. The repo then appears at https://play-grounds.github.io/gitmark/ within a minute, agent shown as did:nostr:<hex>.

If n is 0: the relays refused or did not answer. Set git config nostr.relays to relays known to work and run git mark announce again. Nothing was spent.

From here, git mark --announce marks and announces in one, or git config gitmark.announce true makes that the default.

git mark verify                 # every mark against the chain
git mark info                   # balance, marks, closed or not

Anyone with a clone can run these; they need no key.

When the agent is finished, the coin goes back to the funder and the trail is closed.

npx fund-agent status           # Address: tb1p… — the funder's address
git mark exodus <that address> --dry

Read the dry run: Spend: is the current TXO, To: is the funder's address, Send: is the balance less 300. Raw: is the transaction. Nothing was broadcast. Then:

git mark exodus <that address>

Check: output ends Trail closed: git mark will not mark again. Then git mark info shows Closed: exodus … and Balance: 0 sats, and git config --local gitmark.txo prints nothing. The agent's addresses hold no UTXOs. Commit blocktrails.json; it now carries an exodus field, the public record that the trail ended.

After exodus, git mark refuses. That is the point. A new trail means a new repo and a new key.

Symptom Meaning Do
fund-agent : voucher has no coins the operator's voucher is empty stop, report the printed address
git mark init : no coin found funding not yet visible wait one block, run init again
git mark : already the last mark nothing new to mark commit first; --force only on the operator's word
git mark : Trail is closed exodus has run nothing; a new repo if more work is wanted
announce : 0/n relays relay trouble, not a chain problem change nostr.relays , announce again
explorer errors mempool.guide down or rate limited GITMARK_EXPLORER=<another esplora api> and retry, once
anything after "broadcast" the spend may be on the chain look the txid up before retrying

The agent cannot make coins. If ~/.gitmark/faucet.txt is missing, npx fund-agent init creates a key and prints an address; the operator sends testnet coins there (a faucet, a wallet), and npx fund-agent status shows them. Then step 2.

Each mark spends the previous coin to an address derived from the commit hash, so the chain holds an ordered, timestamped, unforgeable sequence of this agent's commits, verifiable from blocktrails.json alone. Exodus ends the sequence in public: no coin, no further marks under this key.

References: gitmark https://github.com/solidpayorg/gitmark (SKILL.md, BURN.md), fund-agent https://github.com/blocktrails/fund-agent, create-agent https://init-agent.com/SKILL.md, the console https://play-grounds.github.io/gitmark/, git-mark.com.

── more in #ai-agents 4 stories · sorted by recency
── more on @gitmark 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/an-agent-s-life-on-t…] indexed:0 read:6min 2026-10-18 · —