bitcoin.mineracks.com /Build /Storage and oracles ·VSS · versioned storage ← Monero remote node DLC oracle → The directory
mineracksmineracks VSS/wallet labels

Wallet labels over VSS

A profile · draft 2 · 21 September 2026 · source

How a Bitcoin wallet keeps its BIP-329 labels — and the notes and files that belong with them — on a storage host it does not trust, so that they come back with the wallet from the same material that restores the wallet. First implementation: Any Two Keys (labels.rs), against https://vss.mineracks.com/vss. Any VSS host works; nothing here is specific to ours.

Why VSS

LDK's Versioned Storage Service is a small authenticated key-value store with per-object versions. Clients encrypt before upload. The operator sees an authentication public key, a store id and ciphertext, and nothing that ties them to an address or a transaction. That is the right shape for labels, which say who paid you and why, and there was no need for a new server.

The root secret

Everything derives from one 32-byte root that the wallet can rebuild from its own recovery material and nobody else can.

From the root, HKDF-Expand with the root as PRK:

Output Info Use
content key, 32 bytes "content" XChaCha20-Poly1305 for the record object and every file chunk
auth key, 32 bytes "auth" ‖ counter (counter from 0 until a valid secp256k1 scalar) signs the VSS requests (LDK signature auth)
store id, 16 bytes → 32 hex "store" VSS store_id
attachment-naming key, 32 bytes "att-name" names file objects without revealing their hash

The record object

One VSS object per wallet, key labels:

"A2KL" 0x01 ‖ nonce[24] ‖ XChaCha20-Poly1305(content key, nonce, aad = store id, plaintext)

Plaintext is JSON: {"v":1,"records":{"<type>:<ref>": <record>}}. Keys are BIP-329 type:ref — addr:, tx:, out: for outputs. A record is:

Field Meaning
label the BIP-329 label. Empty means deleted: a tombstone, so the deletion travels too
t when the record last changed, unix seconds
note longer text belonging to the same subject (the reference implementation allows 20,000 characters)
files attachments, each {name, mime, size, sha256, t} — see below
anything else carried through untouched

A record is alive if it has a label, a note or files. A record that is only extras is alive too.

Every implementation must preserve fields it does not understand. A build that drops unknown fields erases them for every other device on its next write. The reference implementation flattens them into the record and writes them back verbatim. This is what lets the format grow without a version negotiation: Any Two Keys puts a ctx object there, written once per transaction, recording which computer made or first saw the payment and — only with the owner's consent — roughly where.

Sync and merge

Get, merge, put with the version just read; on a version conflict, get and merge again. Merge is per record:

Two devices editing the same wallet converge without a coordinator, and the host never has to understand the content.

Attachments

A file's bytes are their own objects: att/<name>/<n>, one 256 KiB chunk of plaintext each.

"A2KA" 0x01 ‖ nonce[24] ‖ XChaCha20-Poly1305(content key, nonce, aad = "att/<name>/<n>", chunk)

What the host learns

An authentication public key and a store id, both random-looking and unrelated to the wallet's keys. Object sizes and write times. The number of chunks a file has, which bounds its size. It cannot read a label, a note or a file, cannot tell which wallet a store belongs to, cannot test whether you hold a file it has seen elsewhere, and cannot alter anything without the client noticing. Rate limits and body caps are the only abuse brakes, as for any VSS tenant.

Status

Implemented and in use: labels, notes, extra fields, attachments, and the merge rules above, exercised by a live round trip against vss.mineracks.com on every release — two simulated computers converge, a deletion travels, a wrong key opens nothing, and a file goes up, comes back proved and is deleted again.

← mineracks VSS · the catalog entry · Terms