Skip to content

Commit f7577ba

Browse files
committed
docs(swaps): preimage scheme hashes the x-only pubkey, not the descriptor string
1 parent fb6195a commit f7577ba

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

docs/articles/swaps.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,18 +110,18 @@ Typical states recorded against each `ArkSwap`:
110110
The preimages we generate for reverse and chain swaps are derived deterministically from the wallet's signing material so that a restored wallet can re-derive them and claim outstanding VHTLCs. The scheme:
111111

112112
```
113-
message = SHA-256( "Arkade-Boltz-Preimage-v1" || descriptor.ToString() || u32_le(index) )
113+
message = SHA-256( "Arkade-Boltz-Preimage-v1" || xonly_pubkey(32) || u32_le(index) )
114114
sig = BIP-340-Schnorr( descriptor_key, message, aux_rand=null )
115115
preimage = SHA-256( sig )
116116
```
117117

118118
The signed input bundles three things:
119119

120120
- **Tag** — domain-separates this signature from any other use of the descriptor's key. The string is intentionally protocol+provider scoped (`Arkade`+`Boltz`) rather than SDK-scoped, so an Arkade wallet implemented on top of any Arkade SDK (TypeScript, Go, Rust, .NET) can produce the same preimage from the same wallet material and recover swaps the .NET SDK created. Versioned (`-v1`) so a future scheme bump can ship as `-v2` while recovery still tries v1 for older swaps.
121-
- **Descriptor**scopes the preimage to the specific swap descriptor.
122-
- **Index** — lets a caller derive multiple preimages from the same descriptor. Always `0` today; baked into v1 so recovery iteration is forward-compatible without a scheme bump.
121+
- **Public key**the descriptor's x-only public key, *not* its string form. A descriptor stringifies differently for the same key (a signing descriptor carries key origin + derivation path + checksum; the bare receiver descriptor a restore reconstructs does not), so anchoring on the canonical pubkey keeps create-time and restore-time derivation identical — and lets any Arkade SDK reproduce it.
122+
- **Index** — lets a caller derive multiple preimages from the same key. Always `0` today; baked into v1 so recovery iteration is forward-compatible without a scheme bump.
123123

124-
BIP-340 with `aux_rand=null` is deterministic per `(key, message)`, so same `(wallet, descriptor, index)` always yields the same preimage. Recovery: when `RestoreSwaps` rediscovers a reverse swap, it re-derives the candidate preimage with `index=0`, verifies `SHA-256(candidate) == restored.PreimageHash`, and attaches it to the swap's metadata for the sweeper to claim. Hash mismatch (legacy random preimage, or wrong descriptor) leaves the preimage out; `EnrichReverseSwapPreimage` remains the manual fallback.
124+
BIP-340 with `aux_rand=null` is deterministic per `(key, message)`, so same `(wallet, pubkey, index)` always yields the same preimage. Recovery: when `RestoreSwaps` rediscovers a reverse swap, it re-derives the candidate preimage with `index=0`, verifies `SHA-256(candidate) == restored.PreimageHash`, and attaches it to the swap's metadata for the sweeper to claim. Hash mismatch (legacy random preimage, or wrong key) leaves the preimage out; `EnrichReverseSwapPreimage` remains the manual fallback.
125125

126126
Watch-only wallets (no signer) fall back to a random preimage on create — they don't get the recovery story but they can still execute swaps until they pair a signer.
127127

0 commit comments

Comments
 (0)