Files
smirk-backend-core/openapi.json
T
such-gitea 7592034546 feat(keys): give an encryption subkey its own row
A targeted XMR or WOW tip has to be sealed to a key that is not the spend
key. That scalar is the spend authority and an ed25519 signing oracle the
dapp bridge already exposes, and as a raw reduced scalar it does not pair
with age's SHA512(seed)[0..32] derivation anyway.

Grin got its second row for free, because a slatepack address is bech32 and
a signing key is hex, so the value alone says which row it belongs in. An
encryption subkey has no such tell: it is 32 opaque bytes that look exactly
like the identity key, so it needs an explicit key_type or the upsert on
(user_id, asset, key_type) overwrites the key sign-in verifies against.

So RegisterKeyRequest gains an optional key_type. Omitted, every shipped
wallet keeps the value-based routing it relies on today. Supplied, it must
name one of primary, enc or slatepack; anything else is a 400 rather than a
row nothing will ever read. One invariant outranks the request: a bech32
Grin address is still refused from the primary row, which is the outage
ddbba30 fixed.

The lookup response gains tip_keys alongside public_keys, applying the
per-asset target server-side. For BTC, LTC and Grin the two maps agree. For
XMR and WOW tip_keys carries the enc row or nothing at all, so a wallet too
old to have published one has no tip target, which is the right answer
rather than a fallback to the spend key.
2026-09-17 19:13:39 -04:00

166 KiB