Your Pod Is Your Bank

The webledger, TXO URIs, and where your sats actually live
April 2026 · melvin.me · Part 5 of Solid Articles

1. Check Your Balance

If you followed Parts 3 and 4, you deposited testnet sats and spent some reading a paywalled article. Where did the money go?

curl -H "Authorization: Nostr $NIP98_TOKEN" \
  http://localhost:4443/pay/.balance
200 OK
{
  "did": "did:nostr:5e7617...45af",
  "balance": 40,
  "unit": "sat"
}

Forty sats. You deposited 50, spent 10 reading an article. Your balance is on your server. Not Stripe's server. Not PayPal's server. A file on your machine.

2. Where It Lives

The balance is stored in a webledger — a JSON file at a well-known path on your pod:

cat data/.well-known/webledgers/webledgers.json
{
  "entries": [
    {
      "url": "did:nostr:5e7617...45af",
      "amount": "40"
    }
  ]
}

That's it. A JSON file with entries. Each entry has an identity (url) and a balance (amount). No database. No encrypted blob. Just a file you can read, back up, rsync, or version with git.

Your money is a file

Traditional payment systems store your balance in their database, behind their API, under their terms of service. A webledger stores it in your filesystem, under your control, in a format anyone can read. The webledgers.org spec defines the format so different implementations can interoperate.

3. Where the Money Came From

In Part 3, you deposited testnet sats by posting a TXO URI. Let's unpack what that means.

A TXO (Transaction Output) is a pointer to sats on the Bitcoin blockchain. Every Bitcoin transaction creates outputs — specific amounts at specific locations. A TXO URI identifies one:

txo:tbtc4:a1b2c3d4e5f6...789:0
PartMeaning
txo:It's a TXO URI
tbtc4:Chain — testnet4 (free sats for development)
a1b2c3...789Transaction ID (the hash of the transaction)
:0Output index (first output in this transaction)

When you POST this to /pay/.deposit, the server:

TXO URI Mempool API Verify on chain Credit webledger
You send proof → Server checks Bitcoin → Confirmed? → Balance updated

The server verifies that a transaction output exists on the blockchain and credits the equivalent amount in the webledger. You can also send sats directly to your personal deposit address (GET /pay/.address?user=did:nostr:YOUR_KEY) — the pod detects the deposit automatically when you check your balance.

4. One Key, Full Circle

Remember the Nostr key from Part 2? The same secp256k1 key that signs your NIP-98 auth events is also a valid Bitcoin taproot key. So the full flow uses one key for everything:

StepWhat HappensKey Used
Get satsFaucet sends to your taproot addressYour pubkey
DepositPOST TXO URI + NIP-98 signatureYour privkey signs
VerifyServer checks chain, credits did:nostrYour pubkey = identity
AccessNIP-98 signature + balance checkYour privkey signs
SpendServer deducts from webledgerYour did:nostr = account

One keypair. Authentication, payment address, identity, and account — all the same 32 bytes.

5. No Custodian

Here's what's not involved:

TraditionalHTTP 402 + Webledger
Bank holds your moneyBalance is a file on your pod
Payment processor takes a cutNo intermediary
KYC / identity verificationNostr key (pseudonymous)
Chargebacks, disputes, freezesSats verified on chain are final
API keys, webhooks, SDKsOne curl command
Terms of serviceYour server, your rules

The webledger is a local accounting system. It records what was proven (via TXO) and what was spent (via PaymentCondition). The source of truth is the blockchain for deposits and the file for balances. Both are verifiable. Neither requires trust.