Paying a .cell name over Fiber on testnet: what it took

In early September we checked whether a .cell name can work as a Fiber payment endpoint: a payer reads the name, finds the node, and pays it without asking the payee for anything. On testnet it did, including a payment routed through a public hub. Two things had to be fixed on the payee’s side first, and they are the useful part of this post.

The records

A name publishes two records:

  • fiber.node: the node’s public key, 33 raw bytes. Fiber’s RPC takes it as bare hex in target_pubkey, so strip any 0x prefix at that boundary.
  • fiber.addr: a multiaddr, as text.

There is no invoice record. An invoice is made for one payment, so the payer keysends to the published key, or asks for an invoice out of band. A wrong or stale key is a denial of payment, not a theft: payments settle against the node key, so publishing someone else’s key sends the money to them.

The records for telmo.cell went on chain in 0xba70f36da3101ef7439fbc417351f714ca04bcc629d37d481808764446a713a1, Pudge block 22301240, 2026-09-03 22:27 UTC. Like every record, they sit in the witness and the cell commits to their hash.

What we measured

In every step the payee was addressed only by the key read back from the name.

Step Result
Dial A node with no bootnodes dialled the published multiaddr and completed the handshake in about 3 s. The payee logged the inbound peer from a public IP.
Direct keysend, 1.23 CKB Success, fee 0, no invoice. Payee +123,000,000 shannons, payer -123,000,000.
Routed keysend, 2.34 CKB To a node the payer had no channel with: Success, fee 234,000 shannons (0.1%).
Pay by name, 4.56 CKB An independent node, with its own identity and network, one channel to a public hub and no channel to the payee, resolved telmo.cell and paid it: Success, fee 456,000 shannons (0.1%), payee +456,000,000 exactly.

The fee is how we know the payments were forwarded. A direct channel costs 0, and each routed payment cost exactly the hub’s advertised tlc_fee_proportional_millionths, 1000.

The payments themselves are off chain. The evidence is each node’s payment status and channel balances, which we logged. The only on-chain part is the records’ transaction above.

What had to be true first

  1. A private channel makes the node invisible. The payee’s only channel was private, so it did not appear in graph_nodes and no other node could compute a route to it. The name resolved perfectly to a node the network could not see.
  2. A new channel is outbound only. A public 2000 CKB channel to a hub still could not receive, because the other side held nothing pointing back. The payee had to spend 200 CKB out through it first. After that it held an announced 1901 CKB channel with about 200 CKB of inbound liquidity, which was the most a single routed payment into the name could carry.

So being payable is something the node operator arranges, not something a name declares.

Limits

  • This was testnet, between 3 and 4 September. The namespace it ran on was replaced by a new deployment on 4 September, and the payee node is no longer running, so the exact setup cannot be re-run. The record format is unchanged.
  • Today no name publishes a Fiber node: 0 of 62 on mainnet and 0 of 43 on testnet, checked on 2026-09-27.
  • Paying over Fiber needs a running fnn node. We know of no end-user wallet that pays Fiber today, so this is for node operators and services, not for a person with a phone.

Trying it

A name’s records come back from GET https://cellula.id/api/resolve/<name> (or testnet.cellula.id) with a fiber field, null when the name publishes none. From there it is a send_payment on your own node, with target_pubkey set to the key without 0x, and keysend: true.

If you run a Fiber node and want to try paying a name, or see a better endpoint to publish than a key and a multiaddr, say so here.

6 Likes