features/wallet/send_authorization library
The host send-authorization seam (#327 — security review F1).
Some custody models authorize each SPEND individually: the host holds no
standing signing capability and unlocks it per transaction (e.g. an
app-passphrase-gated staged credential, or a biometric-per-send policy).
The package's controllers route EVERY money-committing bridge call through
WalletSendAuthorizer.authorizeSpend, so such a host plugs its
prompt → unlock → sign → re-lock cycle in by overriding
walletSendAuthorizerProvider — no session decorator required. The default
WalletPassthroughSendAuthorizer runs the call unmodified, which is
correct for sealed-keychain custody (the SDK signs whenever asked).
Classes
- WalletPassthroughSendAuthorizer
- The default: no host authorization step — run the signing call directly. Correct for sealed-keychain custody, where the SDK holds the signing capability for the wallet's whole open lifetime.
- WalletSendAuthorizer
- The seam itself. The package invokes authorizeSpend around every money-committing bridge call, exactly once per user-confirmed action:
- WalletSpendIntent
- The display-facts of the spend being authorized — enough for the host's prompt copy, nothing more. §5.4 never-log values: render them in the prompt, never write them to a log.
Enums
- WalletSpendKind
-
What kind of money-committing action is being authorized — drives the
host's prompt copy ("Authorize this payment" vs "Authorize recovering
funds"). Every arm the package can emit; a host
switchstays exhaustive. - WalletSpendOrigin
- Who initiated the spend being authorized — a host POLICY input (#328). automatic marks a spend NO user gesture triggered; the only automatic spend the package emits today is the auto-shield loop's self-transfer (WalletSpendKind.shield — funds stay inside the wallet).
Functions
-
abbreviateWalletAddress(
String address) → String - Elide an address for prompt display (#383 R3): keeps enough of both ends to visually match against a copied address, short enough that a prompt stays one line. Deterministic, display-only — §5.4: never log the result.
Exceptions / Errors
- WalletSpendAuthorizationDenied
- Thrown by a WalletSendAuthorizer when the user (or a host policy) declines the spend. The controllers catch it BEFORE any classification and silently restore the pre-confirm state (review stays reviewable, the one-shot proposal token is unconsumed, ZERO bridge calls were made). The host's own prompt is the user-facing communication channel for a denial — the package deliberately shows no additional fault for it.
- WalletSpendSessionChanged
- Thrown by the SDK from INSIDE an authorized action when the wallet session changed (a host identity switch / wallet re-open) between the prompt opening and the approval landing — the spend is REFUSED: running it would move the DEAD identity's money while every visible surface already shows the new one, so the user could never see what they just approved. Nothing was signed or broadcast.