Anchor git commits to Bitcoin via blocktrails key chaining.
npm install -g gitmarkThis gives you git mark as a native git subcommand.
# Initialize in a git repo (tbtc4 = Bitcoin testnet4)
git mark init --chain tbtc4 --voucher txo:tbtc4:txid:vout?amount=X&key=Y
# Or read vouchers from a file (uses last line, removes on success)
git mark init --voucher ~/faucet/vouchers.txt
# Make commits, then mark them
git commit -m "my change"
git mark
# Verify the trail against Bitcoin
git mark verify
# Show trail state
git mark infoPick one with --chain at git mark init. It's recorded in blocktrails.json and used for every later mark.
| Chain | Network | Addresses | Explorer API |
|---|---|---|---|
tbtc4 (default) |
Bitcoin testnet4 | tb1p… |
mempool.space/testnet4 |
tbtc3 |
Bitcoin testnet3 | tb1p… |
mempool.space/testnet |
signet |
Bitcoin signet | tb1p… |
mempool.space/signet |
btc |
Bitcoin | bc1p… |
mempool.space |
xbt |
BLAKE2b fork of Bitcoin, from block 961,640 | bc1p… |
mempool.kilombino.com |
txbt4 |
BLAKE2b fork of testnet4, from block 150,308 | tb1p… |
mempool.guide/testnet4 |
On xbt and txbt4, marks are signed with SIGHASH_UNIFIED (spec): a 65-byte signature ending 0x21 that Knots accepts on the BLAKE2b chains and SHA256d nodes reject. Coins from before the fork exist on both chains, so without this a mark could be replayed onto the original chain. lib/unified-sighash.js implements it and passes Knots's 166 test vectors (test/unified_sighash.json).
Each git mark creates a real Bitcoin transaction. The address is derived from your key + the commit hash using BIP-341 taproot key chaining:
baseKey + tweak(commit₁) → Address₁ → TXO₁
baseKey + tweak(commit₁, commit₂) → Address₂ → TXO₂
The chain of addresses on Bitcoin mirrors the chain of commits in git. Anyone can verify by re-deriving the addresses from the public key + commit hashes.
| Command | Description |
|---|---|
git mark init |
Initialize trail. Options: --chain, --voucher, --force |
git mark |
Anchor HEAD commit to Bitcoin |
git mark info |
Show trail state, balance, addresses |
git mark verify |
Verify all marks against Bitcoin |
git mark update |
Update blocktrails.json from git notes |
git mark badge |
Print README badge markdown. Option: --branch |
git mark --version |
Show version |
git mark badge prints markdown for a README badge, built from the origin remote, the current branch (or --branch) and blocktrails.json. For example, this is the badge for melvincarvalho/delivery-day, whose trail is on txbt4:
It's a shields.io dynamic JSON badge that counts states in the pushed trail file, and links to the latest mark on the chain's explorer. The count updates whenever blocktrails.json is pushed, so it shows what the repo records. git mark verify checks it against the chain. For remotes not on GitHub, it prints RAW_TRAIL_URL and TRAIL_LINK placeholders to fill in.
blocktrails.json in your repo root — committed, visible, verifiable:
{
"version": "0.0.3",
"profile": "gitmark",
"pubkeyBase": "02abc...",
"chain": "tbtc4",
"states": ["a1b2c3", "e5f6a7"],
"txo": [
"txo:tbtc4:abc:0?commit=a1b2c3",
"txo:tbtc4:def:0?commit=e5f6a7"
]
}- pubkeyBase — compressed pubkey (02/03 prefix), base for BIP-341 key chaining
- states — commit hashes (input to key derivation)
- txo — Bitcoin anchors (TXO URIs, self-contained and verifiable)
Private spending state stored in gitmark.txo git config (never committed).
# Private key (auto-generated by init)
git config --local nostr.privkey <64-char-hex>
# Current UTXO (updated on each mark)
git config --local gitmark.txo txo:tbtc4:txid:vout?amount=X&commit=Y
# Dirty flag — set to false to keep working tree clean after marking
git config --local gitmark.dirty falseWhen gitmark.dirty=false, git mark only writes git notes + git config. Run git mark update to sync blocktrails.json when ready.
Same secp256k1 key used for Nostr, Bitcoin, and Solid pod authentication.
Two: @noble/curves and @noble/hashes. No bitcoinjs-lib, no external transaction builders.
- blocktrails.org — state anchoring on Bitcoin
- git-mark.com — project homepage
- BIP-341 — Taproot key tweaking
AGPL-3.0 © Melvin Carvalho