feat(platform-wallet): parse a state transition's kind and token-purchase intent - #4584
feat(platform-wallet): parse a state transition's kind and token-purchase intent#4584romchornyi wants to merge 1 commit into
Conversation
…hase intent DashConnect's `dash-st:` link hands a wallet a serialized state transition. The only parser exposed was `platform_wallet_parse_identity_update_transition`, which accepts an `IdentityUpdateTransition` and nothing else — the DashConnect key-registration step. A dApp asking a wallet to authorize a token purchase was rejected with "Expected IdentityUpdateTransition, got Batch(...)". Adds `platform_wallet_parse_state_transition`, which deserializes once and reports which kind it found alongside the matching payload, so a caller branches on a discriminant rather than on a thrown error. Two kinds are recognised: identity update (projected exactly as before) and a batch carrying a single token direct purchase, projected to the fields a purchase needs and a user must see — owner, data contract, token id and position, count, and total agreed price. Deliberately a parser, not a signer. There is no entry point that signs caller-supplied bytes: a wallet reads the intent, shows it, and rebuilds the purchase through the existing `platform_wallet_token_purchase`, so it only ever signs a transition it constructed itself. Rejected rather than projected, because a user cannot meaningfully approve them and the rebuild path could not reproduce them faithfully: a batch that is not exactly one token purchase (empty, several, or another transition kind), and a purchase carrying `using_group_info`, which the rebuild submits without. `identity_update.rs` keeps its narrow public contract; its tagged/tagless framing fallback is generalized to several candidate variant tags and shared. Swift: `ParsedStateTransition` / `ParsedTokenPurchaseTransition` and `ManagedPlatformWallet.parseStateTransition(_:)` beside the existing identity-update pair.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (4)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthroughThe Rust FFI adds flexible parsing for identity updates and token direct purchases. The Swift SDK exposes parsed state-transition types and maps FFI results to Swift values. ChangesState Transition Parsing
Estimated code review effort: 4 (Complex) | ~45 minutes Merge Risk: 🔵 Low · up to This change lets wallets parse and display token-purchase intents, but ambiguous framing and the lack of a built-in binding between displayed purchase details and later signing inputs could allow an incorrect intent to be approved if a consumer mishandles the values. The change is mergeable with explicit security-owner awareness and follow-up on canonical framing and approval binding. Sequence Diagram(s)sequenceDiagram
participant ManagedPlatformWallet
participant RustFFI
participant StateTransitionParser
ManagedPlatformWallet->>RustFFI: Call platform_wallet_parse_state_transition
RustFFI->>StateTransitionParser: Parse tagged or tagless bytes
StateTransitionParser-->>RustFFI: Return parsed kind and fields
RustFFI-->>ManagedPlatformWallet: Return ParsedStateTransitionFFI
ManagedPlatformWallet->>RustFFI: Free FFI output
ManagedPlatformWallet-->>ManagedPlatformWallet: Build ParsedStateTransition
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
🕓 Ready for review — 46 ahead in queue (commit a77c557) |
Issue being fixed or feature implemented
DashConnect's
dash-st:link hands a wallet a serialized state transition. The only parser exposed wasplatform_wallet_parse_identity_update_transition, which accepts anIdentityUpdateTransitionand nothing else — the DashConnect key-registration step.A dApp asking a wallet to authorize a token purchase was therefore rejected outright:
Observed against a real dApp (Yappr on a devnet). Its fallback without this was to ask the user to paste a CRITICAL private key into a web page, which is what DashConnect exists to avoid.
What was done?
packages/rs-platform-wallet-ffi/src/parse_state_transition.rsexposingplatform_wallet_parse_state_transition/..._free. It deserializes once and reports which kind it found alongside the matching payload, so a caller branches on a discriminant instead of on a thrown "expected X, got Y" error.ParsedStateTransitionFFIcarrieskind(NONE/IDENTITY_UPDATE/TOKEN_DIRECT_PURCHASE, exported as#defines) plus both payloads by value; exactly one is populated.ParsedTokenDirectPurchaseFFIis a POD struct withowner_id,data_contract_id,token_id,token_contract_position,token_countandtotal_agreed_price— whatplatform_wallet_token_purchaseneeds, plus what a user must see before approving.identity_update.rskeeps its existing public contract untouched, so current callers keep working; its tagged/tagless framing fallback is generalized to several candidate variant tags and shared throughdeserialize_transition_with_flexible_framing.ParsedStateTransition/ParsedTokenPurchaseTransitionandManagedPlatformWallet.parseStateTransition(_:)beside the existing identity-update pair.Deliberately a parser, not a signer. There is no entry point that signs caller-supplied bytes. The intended flow is parse → show the intent to the user → rebuild the purchase through the existing
platform_wallet_token_purchase, so a wallet only ever signs a transition it constructed itself.Rejected rather than projected, because a user cannot meaningfully approve them and the rebuild path could not reproduce them faithfully: a batch that is not exactly one token purchase (empty, several, or another transition kind), and a purchase carrying
using_group_info, which the rebuild submits without.How Has This Been Tested?
cargo test -p platform-wallet-ffi --lib— 307 passed, including 10 new tests inparse_state_transition::tests: tagged and tagless purchase, identity update through the umbrella parser, and rejection of multi-transition, empty, non-purchase, group-gated and malformed input, plus a free-is-safe case. The 7 existingidentity_updatetests guard the framing refactor and still pass, including the real captured fixture.cargo check -p platform-wallet-ffiandcargo clippy -p platform-wallet-ffi --libclean.packages/swift-sdk/build_ios.sh --target ios --target sim— xcframework rebuilt for both slices; the generated header carries the new symbols and kind constants, and the script's SwiftExampleApp build (-warnings-as-errors) compiles the modifiedManagedPlatformWallet.swift.dash-st:purchase link, renders 100 tokens for 0.001 DASH, and completes the purchase.Breaking Changes
None. Everything added is new surface;
platform_wallet_parse_identity_update_transitionis unchanged.Checklist:
Summary by CodeRabbit