bindingToken property
FR-17 (#396): the SDK-minted spend-binding nonce for the EXACT proposal/quote this authorization covers. A host with a native seed port records it at stage time, and its supplier fail-closes a native seed pull presenting anything else — the review↔sign confusion defense. Null for the operations that pull unbound (the shield-to-self sweep / reclaim) and for offline QUEUE-time authorization (the binding is minted at enqueue and surfaced on the parked-send row for a re-stage). NOT key material — but do not log it (it correlates a proposal with its sign moment; §5.4 like every field here).
ENFORCEMENT PREREQUISITE (else recording this is a silent no-op): FR-17
only bites when the host registered the BOUND native seed supplier
(zec_wallet_register_seed_port_bound) AND its supply callback compares
this token (strict equality; unbound stage ⇔ null pull) and returns
unavailable on mismatch. A default passthrough authorizer or a
sealed-keychain custody wallet has no native pull to bind — the token is
inert there, which is fine.
QUEUE handoff (both moments — see WalletSpendKind.queuedSend). At
QUEUE-TIME this is null: the intent is only being committed, and signing is
deferred, so a stage recorded here can never serve the later bound drain
pull (the send would park unsigned — funds safe). At AUTHORIZE-NOW time
(FR-23-b authorizeParkedSend) it is the PARKED ROW's own binding, copied
straight from ParkedSend.binding — stage for exactly this value and the
sign inside your bracket succeeds; stage for any other row and it is
refused, leaving the send parked rather than wrongly signed.
Implementation
final Uint8List? bindingToken;