Names you can check. Even against us.
Your bWalletX name is signed by your own wallet. Every wallet checks that signature before it pays. And every change to who a name points to goes in a public log that anyone can read, including changes we make ourselves.
What a name is
A bWalletX name is alice@bwalletx.com, or $alice for short. It points to one wallet’s identity key. When someone pays $alice, their wallet asks our name server which key the name points to, then pays that key directly.
We never hold your keys or your coins. Payments go wallet to wallet. But the name itself is a row in our database.
The risk, plainly
Whoever controls the name directory could point a name at a different key. Payments already made are safe. But future payments to that name would go to the new key. That is a real power, and we hold it. On 17 October 2026 we used it: at the owner’s request we moved two of his own names between his own two wallets by editing the database directly. Nobody lost anything. But it showed how easy it was, and that nobody else could have seen it. So we built limits, and we made every use of the power public. The story is in blog 058.
Three layers
1. Signed bindings
The wallet that owns a name signs a short statement: “this name points to my key, version N”. Our name server hands that signature out with the key. We can’t make that signature for a key we don’t hold. Before every payment to a bWalletX name, the paying wallet checks it and shows one of three things:
- Signed by its owner. The key’s holder put this name on this key.
- Not signed by its owner yet. A grey note. The payment still works. Wallets sign their names when they next open, so this fades out.
- Bad signature. The signature doesn’t match. The payment is blocked.
2. A public name log
Every change of who a name points to is written to a log. Each entry includes the hash of the one before, so entries can’t be quietly changed or removed. A database trigger writes the entries, so a direct database edit by us is logged too, marked admin. The first three entries are exactly that: our own edits on 17 October.
Each entry says who made the change: owner (the name’s owner signed it), server (our server made it for a request the owner signed) or admin (anything else, which means us).
3. On chain (coming)
Next, the log’s latest hash goes into a Bitcoin transaction once a day, so the log can’t be rewritten after the fact. And for names that must never depend on us at all, there are OpNS names: names held on chain, in your own wallet.
Standing on others’ work
We did not invent signed names. Others got there first, and we are building toward their work:
- BRC-169 binds a handle to a key with a certificate signed by the host, and tells wallets to warn before paying when a name’s key changes. Ours is signed by the owner instead, and fits inside ordinary paymail. Our wallet now has that key-change warning too.
- BRC-174 is the formal spec for on-chain names (OpNS) bound to a key. That is where bWalletX names are headed.
- The paymail standard already names this risk: “Alias Reassignment (server & database access)”.
- Certificate Transparency showed how public, append-only logs keep operators honest. Our log is a simple version of that idea.
What we add is small: the owner’s signature inside the paymail answer that wallets already fetch, and a log that records our own database edits.
Check a name yourself
You don’t need our app. Ask the name server for a name’s key and binding:
curl https://pay.bwallet.space/api/paymail/id/npg@bwalletx.com
The answer has pubkey and, once the owner’s wallet has signed, a binding with alias, seq, timestamp and signature. Read the log, whole or for one name:
curl https://pay.bwallet.space/api/paymail/name-log
curl "https://pay.bwallet.space/api/paymail/name-log?alias=npg"
Then check the signature with @bsv/sdk. The signed message is these fields, in this order:
bwallet-paymail|v1|bind|alias=<alias>|identityKey=<key>|seq=<n>|timestamp=<ms>
import { ProtoWallet, Utils } from '@bsv/sdk';
const r = await fetch('https://pay.bwallet.space/api/paymail/id/npg@bwalletx.com').then((x) => x.json());
const b = r.binding; // undefined = not signed by its owner yet
const msg = `bwallet-paymail|v1|bind|alias=${b.alias}|identityKey=${r.pubkey}|seq=${b.seq}|timestamp=${b.timestamp}`;
const { valid } = await new ProtoWallet('anyone').verifySignature({
data: Utils.toArray(msg, 'utf8'),
signature: Utils.toArray(b.signature, 'hex'),
protocolID: [2, 'bwallet paymail'],
keyID: '1',
counterparty: r.pubkey,
});
console.log(valid ? 'Signed by its owner' : 'Bad signature');
The log’s hash rule: entry_hash = sha256(prev_hash|alias|identity_key|prev_identity_key|action|actor|seq|signature|note|created_at), with empty strings for missing fields and created_at in UTC as YYYY-MM-DDTHH:MM:SS.ffffffZ. The first entry’s prev_hash is 64 zeros. The full write-up is in our draft standard.
The limits
- We still serve the bindings and the log. We could hold back a binding. The name would then show “not signed”, which you can see.
- We could serve an older genuine binding. Its version number would be lower than the one in the log, which you can see.
- The log is in our database until it is anchored on chain. The hash chain shows edits to past entries, but only once someone has kept a copy to compare. Keep one if you like.
- A name with no binding yet can’t be checked by signature, only by the log.
Only layer 3 takes us out of the picture. We will say so on this page until it ships.
Status, 17 Oct 2026
- ✓ LiveSigned bindings. Wallets sign their own names and check names before paying.
- ✓ LiveBad signatures block payment.
- ✓ LivePublic name log. Hash-chained, append-only, every change logged by the database itself, including ours.
- ✓ LiveOur 17 Oct edits in the log as its first three entries, marked
admin. - ✓ LiveHandovers need both wallets. A name moves only when its owner releases it and the new wallet accepts. No one, us included, can move it any other way.
- ✓ LiveNo back door for lost keys. A name stays with its key. Recovery is yours, set up in advance.
- ✓ LiveKey-change warning. If a name you’ve paid before points somewhere new without a handover, Send stops.
- ✓ LiveProposed to the BRC authors in BRCs issue #329.
- ◻ ComingDaily on-chain anchor of the log’s latest hash.
- ◻ ComingOpNS names in the wallet as the name that never depends on us.
Questions
Are you custodial?
No. Your keys are made on your device and never reach us. We can’t spend your coins or sign for you. The name directory is the one thing we control, and this page is about limiting it.
Can you change my name?
Technically, yes. Anyone who runs a name directory can. What we can’t do is make your wallet’s signature for a different key, or change past log entries without it showing to anyone who kept a copy. Once the daily anchor ships, it will show to everyone.
What happens if you do?
Payers’ wallets stop showing “Signed by its owner” for that name, because the new key has no signature from you. A forged signature blocks payment. And the change appears in the public log, with who made it.
How does a name move to a new wallet properly?
The old owner releases it, then the new wallet signs its own binding for the name. Both steps are in the log.
Why not just use OpNS?
We will, for names that matter most. OpNS names are held on chain in your wallet, so they don’t depend on us at all. But a paymail like alice@bwalletx.com works with every paymail wallet today, and it’s free and instant to claim. Signed bindings make that kind of name checkable while OpNS grows.
bWalletX is in beta: test with small amounts. Questions: support@bwalletx.com