# Titles and what is engraved on a plate


**Draft, not yet verified on hardware.**

Stock firmware v1.4.3 engraves the layouts below on seed and descriptor plates. A wallet's title appears on the screen only, and the fingerprints tell the plates of one wallet apart.

<p class="alert alert-warning">Seed words are typed on the machine only and never pass through a phone, a computer or a chat assistant. A descriptor is not a secret, but it reveals every address of the wallet.</p>

## What you need {#requirements}

- A SeedHammer II on stock firmware v1.4.3.
- To check a plate: the wallet's descriptor or master fingerprints as your wallet app shows them.
- To see a title on the machine: a wallet export that carries the wallet name ([Titles](#titles)).

## On every plate {#common}

- One job engraves one face of one 85 x 85 mm plate, with 3 mm free along every edge.
- No date, plate number, firmware version or wallet name ([Titles](#titles)).
- No plate preview in v1.4.3. The plate itself is the first view of the layout.

## Passphrases and other text {#passphrase}

- No passphrase or free text: "Input Words" takes BIP39 words only. Free text is planned for later firmware.
- Keep a passphrase in a separate backup made another way.

## Seed plate {#seed}

A seed plate has no derivation path or script type; those belong to the descriptor. After the checkmark on "Engrave Seed", the machine plans this layout:

- **Master fingerprint.** 8 capitals, 2.0 mm tall (unverified), centred above the words: `73C5DA0A` for the test seed `abandon` x 11, `about`.
- **Words.** The word number and the whole word in capitals, for example `1 ABANDON`. 2.7 mm tall on a 4.1 mm line (unverified).
- **SeedQR (unverified).** Standard (4 digits per word), not compact, error correction M.

| | 12 words | 24 words |
| --- | --- | --- |
| Left column | words 1 to 12 | words 1 to 16 |
| Right column | the SeedQR, 25 x 25 modules, 22.5 mm wide | words 17 to 20 above the SeedQR (29 x 29 modules, 26.1 mm), words 21 to 24 below |
| Planned engraving time, without homing | 14 min 35 s | 23 min 42 s |

![A 12-word seed plate: fingerprint, words, SeedQR](/static/img/titles-and-plate-layout-01.webp)
<!-- capture: photo, seed plate engraved on v1.4.3 with the Demo A 12-word test vector from lab/TESTWALLET.md, fingerprint 73C5DA0A legible at the top, whole face square to the camera with a ruler beside it, soft side light; no lab shot yet -->

![A 24-word seed plate, words 17 to 24 around the SeedQR](/static/img/titles-and-plate-layout-02.webp)
<!-- capture: photo, seed plate engraved on v1.4.3 with the public BIP39 test vector "abandon" x 23 + "art" (add it to lab/TESTWALLET.md before capture), callouts on words 16, 17, 20 and 21 and on the SeedQR; no lab shot yet -->

## Descriptor plate {#descriptor}

- **Layouts.** "Engrave" lists those that fit: "TEXT + QR", "TEXT ONLY", "QR ONLY" ([fit](/doc/manual/multisig-and-fit#fit)).
- **Text.** The rebuilt descriptor from the top left, wrapped edge to edge, case kept; lines near the top and bottom edges are shortened at the corners. 3.8 mm lines, capitals about 2.2 mm, 2.3 mm per character (unverified).
- **Keys.** Each key keeps its fingerprint and path in brackets, and the text ends in the machine's checksum. A key with the placeholder fingerprint `00000000` is engraved without brackets, so its path is lost too.
- **QR.** The descriptor without checksum, error correction L; centred alone, or top right with the text.
- **Differences.** `h` for `'` and no child path: [Why the plate differs](/doc/manual/multisig-and-fit#differences). No title: [Titles](#titles).
- **Bare keys and shares.** Send a descriptor with key origin, never a bare key ([why](/doc/manual/capability-sheet#formats)). A codex32 share is secret: never send one over NFC ([Shares](/doc/manual/capability-sheet#shares)).

| Example wallet | Layout | Space used | Planned time |
| --- | --- | --- | --- |
| 2-of-3 native segwit, keys with origins, `/<0;1>/*` | TEXT ONLY | top 56 mm of the plate | 10 min 58 s |
| the same 2-of-3 | QR ONLY | 65.7 mm square, centred | 39 min 27 s |
| single-sig native segwit, key with origin, `/0/*` | TEXT + QR | top 54 mm, QR 40.5 mm | 18 min 41 s |

![Two descriptor plates for the same 2-of-3 wallet: TEXT ONLY and QR ONLY](/static/img/titles-and-plate-layout-03.webp)
<!-- capture: photo, two plates engraved on v1.4.3 side by side from lab/fixtures/2of3-multipath.txt: left "TEXT ONLY" (text in the top 56 mm), right "QR ONLY" (65.7 mm QR centred); top view with a ruler, soft side light; no lab shot yet -->

## Titles: shown, not engraved {#titles}

| Export | Title comes from |
| --- | --- |
| JSON with `"label"` and `"descriptor"`: Specter Desktop **Copy Wallet Data** or **Save Wallet File**; Sparrow's **Specter Desktop** export | the `label` field |
| Coldcard-format multisig text: in Sparrow, **Export File...** in the **Coldcard Multisig**, **Keystone Multisig**, **Passport Multisig** or **BlueWallet Vault Multisig** pane (**Show...** gives a QR code, not text); Specter's **Save ColdCard file**; BlueWallet's **Export Coordination Setup** | the `Name:` line |

- A title is the wallet name an export carries, and only these two kinds carry one. A plain descriptor never does, whichever app it comes from.
- Coldcard-format text without a `Name:` line is refused with "Unknown format". Sparrow and Specter shorten the `Name:` to 20 characters in their Coldcard-format exports.
- Sparrow 2.5 and later add `?bh=` or `?gl=` ("Unknown format"): [remove it](/doc/manual/nfc-tools-transfer#prepare). Its Coldcard-format exports have no suffix and no child path ([why](/doc/manual/multisig-and-fit#differences)).
- "Engrave Descriptor" shows the whole title, wrapped, case kept, no 18-character limit (unverified).
- No plate carries the title (unverified). The first SeedHammer engraved a title of up to 18 characters; SeedHammer II firmware from v1.4.1 on engraves none.

![Specter Desktop export starting with "label": "Demo 2of3"](/static/img/titles-and-plate-layout-04.webp)
<!-- capture: lab/specter/shots/specter-26-2of3-wallet-json-selected.png, Specter Desktop v2.1.11, "Export Wallet" overlay, "Wallet JSON Data" text selected, beginning {"label": "Demo 2of3", buttons "Copy Wallet Data" and "Save Wallet File" -->

![Engrave Descriptor with Title "Demo 2of3"](/static/img/titles-and-plate-layout-05.webp)
<!-- capture: II screen, "Engrave Descriptor" after NFC payload lab/fixtures/2of3-specter.json: "Title" "Demo 2of3", "Type" "2-of-3 multisig", "Script" "Segwit (P2WSH)"; Go capture per research/device-screen-map.md 4.2 row 27 -->

## Tell the plates of one wallet apart {#labelling}

- Each seed plate carries its master fingerprint in capitals, for example `73C5DA0A`.
- The descriptor text carries each cosigner's fingerprint in lower case, in brackets before its key: `[73c5da0a/48h/0h/0h/2h]`. A 2-of-3 made from three public test seeds holds `73c5da0a`, `3f635a63` and `28645006`.
- Match each seed plate to one of these; capitals and lower case are the same value. A seed used with a passphrase does not match: its plate shows the fingerprint without the passphrase.
- On a "QR ONLY" plate the fingerprints are in the QR only; a bare or `00000000` key, or an older QR, has none.

## If it does not work {#troubleshooting}

| Symptom | Cause | Fix |
| --- | --- | --- |
| No "Title" line on "Engrave Descriptor" | No name in the export. | Send an export from the [Titles](#titles) table. |
| The wallet name is not on the plate | Titles are shown only. | Keep a note of the name. Tell plates apart by their [fingerprints](#labelling). |
| "Unknown format" with Coldcard-format text | No `Name:` line, or `Format: BIP45` from Specter's **Save ColdCard file** for legacy P2SH. | For legacy P2SH, send **Copy Wallet Data**. [All causes](/doc/manual/troubleshooting#nfc). |
| "Unknown format" with a Sparrow export | A `?bh=` or `?gl=` suffix. | [Remove it](/doc/manual/nfc-tools-transfer#prepare). |
| The seed plate's fingerprint differs from the wallet | The wallet uses a passphrase, or a word differs. | With a passphrase, expected: the plate shows the fingerprint without it ([fingerprints](#labelling)). |
| The checksum or keys on the plate differ from what I sent | The plate carries the rebuilt descriptor ([Text](#descriptor)). | See [why](/doc/manual/multisig-and-fit#differences). |
| No `/0/*` or `/<0;1>/*` on the plate | The export had none. | Send a plain descriptor with `/<0;1>/*` (no title). |
| A QR from older firmware has no fingerprints | v1.4.1 and v1.4.2 left out the master fingerprints and the origin paths before each key. | [Older plates](/doc/manual/recovery-from-plates#old-plates). |

<!--
bench-checks:
  - [ ] lab/fixtures/2of3-specter.json and lab/fixtures/2of3-coldcard.txt on v1.4.3: "Title" "Demo 2of3" shown on "Engrave Descriptor"; engraved "TEXT ONLY" and "QR ONLY" plates carry no title (SYNTHESIS F11). Body: "No plate carries the title (unverified)"
  - [ ] JSON label of 30 characters with lower case and punctuation (for example `my vault (2024)!`): shown whole, wrapped, not upper-cased, not filtered; not shortened to 18 characters; nothing engraved. Body: "(unverified)" on the "Engrave Descriptor" bullet in #titles
  - [ ] Sparrow "Coldcard Multisig" pane, "Export File...", wallet name over 20 characters: Title line shows the 20-character Name; Specter "Save ColdCard file" Name limit; Specter "Save ColdCard file" for a legacy P2SH wallet (`Format: BIP45`): "Unknown format" (desktop-wallets 2.2 F2)
  - [ ] Specter "Copy Wallet Data" for a legacy P2SH multisig: accepted as "Legacy (P2SH)". Host run: the 2of3-specter.json shape with sh() instead of wsh() parses, "TEXT ONLY" and "QR ONLY"
  - [ ] (harmonized 2026-10-10: the page no longer recommends a Coldcard-format export as the `?bh=` workaround; it states that route's cost, no child path, per multisig-and-fit#differences) Sparrow 2.5.x Specter Desktop JSON and plain descriptor after a gap-limit change (`?gl=`) and after a confirmed payment (`?bh=`): "Unknown format"; the plain descriptor trimmed at `?` with no line break: accepted
  - [ ] Demo A 12-word plate: fingerprint 73C5DA0A centred above the words, words 1 to 12 left, SeedQR right; photo; the same seed with a passphrase in a wallet shows a different fingerprint
  - [ ] 24-word plate ("abandon" x 23 + "art"): words 1 to 16 left, 17 to 20 above the SeedQR, 21 to 24 below; add this vector to lab/TESTWALLET.md before capture (host run: 23m42s, QR v3, 26.1 mm); photo
  - [ ] SeedQR form (SYNTHESIS F18): decode both seed plate QRs; expect standard SeedQR digits (4 per word), not CompactSeedQR; 25 x 25 and 29 x 29 modules. Body: "(unverified)" on the SeedQR bullet
  - [ ] Font and character height (unanswered in chat): measure capital height and pitch of seed words (expect about 2.7 mm tall plus stroke, 2.7 mm pitch), fingerprint (about 2.0 mm) and descriptor text (about 2.2 mm, 2.3 mm pitch); figures computed from font/constant and font/sh data at 4.1, 3.0 and 3.8 mm, in no research note. Body: "(unverified)" on the Words and Text bullets
  - [ ] Engrave Plate countdown at start: expect about 14:35 (12 words), 23:42 (24 words), 10:58 ("TEXT ONLY") and 39:27 ("QR ONLY") for lab/fixtures/2of3-multipath.txt, 18:41 ("TEXT + QR") for lab/fixtures/singlesig-wpkh.txt (the two example wallets in the descriptor table); homing is extra
  - [ ] "TEXT + QR" single-sig plate: QR near the top right, text beside and below, corner lines shortened (backup/backup.go EngraveText)
  - [ ] Fit of other 2-of-3 scripts: host runs of 2of3-multipath.txt rewritten as sh(wsh(...)) and sh(...) both give "TEXT ONLY" and "QR ONLY" (QR v14, 65.7 mm); confirm one on the machine before the page names scripts
  - [ ] Engraved text (SYNTHESIS D, F9): a descriptor sent with `'` shows `h` and a different checksum, addresses match in a watch-only wallet (host run: wpkh([73c5da0a/84'/0'/0']xpub.../0/*) engraved as [73c5da0a/84h/0h/0h] with #afwvtk2s); Coldcard-format text ends at the xpubs with no child path; Specter Desktop JSON ends in `/0/*`
  - [ ] Fingerprint 00000000 (bip380/bip380.go:226, origin written only when mfp != 0): host run of wpkh([00000000/84h/0h/0h]xpub6CatWdiZ.../0/*) gives plate text wpkh(xpub6CatWdiZ.../0/*)#kj7aqcx6, no origin on text or QR; confirm on a plate
  - [ ] Bare keys (BRIEF bare xpub hazard, desktop-wallets 1.4 X1 X2, lab/check RESULTS.md notes 2 to 6): lab/fixtures/cosigner-a-xpub.txt (depth 3, child 0h) engraves pkh(xpub6CatWdiZ...PW6V)#pgykunhp, same string; lab/fixtures/cosigner-a-ms-xpub.txt (depth 4) engraves xpub6Bs7JjzNpKcx..., a string not in the payload; a Sparrow "Copy xpub" from a native segwit wallet shows "Legacy (P2PKH)"; confirm on the machine
  - [ ] codex32 share over NFC on v1.4.3 (SYNTHESIS F19), public test vector only, never a real share: layout, identifier engraved under the columns, no fingerprint
  - [ ] All capture comments except the Specter shot: no lab shots of the machine screen or of plates exist yet
  - [ ] Links: /doc/manual/descriptor-desktop-wallets and /doc/manual/descriptor-mobile-wallets were planned in harvest/manual-needs.json; both are now drafted in manuals/ (2026-10-10) and this page links neither; recheck all link targets before publication
notes: condensing pass 2026-10-10 (pre-edit copy manuals/.before/titles-and-plate-layout.md). Moved off the page: the seedhammer.com FAQ (linked before) says the title is engraved, up to 18 characters; the body now states that as the first SeedHammer's behaviour without citing the FAQ. MaxTitleLen/TitleString went unused with the SH II commit 0aaf5e6 "all: implement v2 machine", first in v1.4.1 (device-screen-map 3); the body keeps only "SeedHammer II firmware from v1.4.1 on engraves none". "Free text is planned for later firmware" rests on harvest Q34, Q27 (arbitrary text planned with the UI revamp, no timeline). The troubleshooting row "On a 24-word plate, word 17 is not under word 16" is folded into the seed table cell (17 to 20 above the SeedQR, 21 to 24 below). Verification fixes 2026-10-10: restored #passphrase (heading and anchor), the requirement line, the "keep a note" fix and the 24-word above/below wording; dropped "fixed" from the lead; the 20-character limit is scoped to Coldcard-format exports again (the JSON label is not shortened in the parse path, desktop-wallets 4 C5); title troubleshooting split back into two rows; "(unverified)" moved to cover the whole SeedQR bullet. Five "Check:" sentences became "(unverified)" in the body; each already had a bench item above.
sources: manuals/REVIEW-wave1.md sections 2 to 4 (harmonized: bare keys, codex32, plate differences and `?` removal replaced by links; old-QR wording from the v1.4.3 release note; see manuals/HARMONIZE-wave1.md); research/device-screen-map.md (1.3 C "Engrave Seed"; 1.5 "Engrave Descriptor" Title/Type/Script, "Engrave" / "Choose engraving", "TEXT + QR" "TEXT ONLY" "QR ONLY", SquarePlate 85 x 85 mm and 3 mm margin; 1.6 codex32 only over NFC; 3 what gets engraved, codex32 share identifier, empty-passphrase fingerprint, MaxTitleLen/TitleString unused, 0aaf5e6 "all: implement v2 machine" first in v1.4.1; 5 items 2 and 3), research/BRIEF.md (corrections: titles shown not engraved, FAQ title claim from the first machine, no passphrase screen, one face per job; SETTLED BY CODE fit; Coldcard text needs Name:; ?bh= and ?gl= annotations, trimmed at ?; bare xpub hazard; xpub read as P2PKH; sortedmulti P2SH supported), research/desktop-wallets.md (key finding 1; 1.1 pane table, Show... is BBQr or UR for Coldcard, Keystone, Passport; 1.2 Name shortened to 20; 1.3 annotation trap; 1.4 X1 X2; 2.1 and 2.2 Specter labels, ColdCard file F1 F2 BIP45; 4 titles), research/mobile-wallets.md (1 parser run, 4 BlueWallet "Export Coordination Setup", P2SH-P2WSH refused), lab/check (shcheck check -v on lab/fixtures/2of3-multipath.txt, 2of3-specter.json, singlesig-wpkh.txt, cosigner-a-xpub.txt, cosigner-a-ms-xpub.txt, on the Demo A 12-word and "abandon" x 23 + "art" 24-word public vectors, and on scratch payloads for 00000000, apostrophe, legacy JSON, nested and legacy 2-of-3; RESULTS.md notes 1 to 6; firmware ea4b65b backup/backup.go frontSideSeed, EngraveText, engraveSeedString; gui/gui.go engraveSeed, validateDescriptor, DescriptorScreen.Draw, engraveObjectFlow; bip32 Path.Encode writes h; bip380/bip380.go:226; seedqr.QR; glyph heights computed from font/constant and font/sh data), lab/TESTWALLET.md (Demo A fingerprint, demo 2-of-3 fingerprints), lab/specter/shots/specter-26-2of3-wallet-json-selected.png (Specter v2.1.11; lab/specter has no README or NOTES yet, labels from research/desktop-wallets.md 2.1), manuals/seed-entry.md #limits (share rule wording), manuals/recovery-from-plates.md #old-plates, harvest Q33 Q34 Q27 (also Q40, Q46), SYNTHESIS D (checksum differs, engraved text differs, stripped QR on v1.4.1 and v1.4.2, Sparrow stripped import with 00000000), SYNTHESIS F 6 7 9 11 14 18 19
-->
