Repository navigation
feat(sdk): multiple choice decision proposals in the Swift and Kotlin SDKs - #5919
QuantumExplorer wants to merge 2 commits into
Conversation
… SDKs Multiple choice proposals had helpers in rs-sdk, wasm-sdk and js-evo-sdk but nothing on mobile, where yes/no proposals have a full stack. This adds the same stack for multiple choice. rs-platform-wallet and its FFI: create a multiple choice proposal, edit it (read once, put at the next revision, so Platform refuses an edit another one overtook) and enter a choice. A choice goes through the ordinary document put, which already reads and states the contest fund. rs-sdk-ffi: the proposal, the listings by owner and by creation time, the vote among the choices, the kept choice, a masternode's answer, the processing fee, the fund to enter a choice, and the masternode vote (for a choice by its document id, for none of the choices, or abstain) through the shared MasternodeVoter. Swift and Kotlin (through rs-unified-sdk-jni): models, reads, the vote and the wallet writes over those functions, with example app screens beside the yes/no ones: a list, a detail screen with the tallies, the result and the vote, and forms to create, edit and enter a choice. The wrappers marshal only: what a proposal or a choice may hold, who may enter a choice and how long a proposal may be edited stay with Platform. Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 1 minute. View limit details
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. |
|
Waiting for bot review — thepastaclaw not yet. Wait for the missing reviews, or a writer can post |
|
🔍 Review in progress — actively reviewing now (commit c07a7e6) · triage: normal |
Basic explanation
What this does: A multiple choice proposal is a question put to the masternodes whose answers ("choices") anyone, or only its author, can enter; the masternodes vote and the choice with the most votes is kept. The Rust and JavaScript SDKs got helpers for it in #5903. This adds the same to the Swift and Kotlin SDKs: create a proposal, edit it, enter a choice, list proposals, read the vote and the kept choice, and cast a masternode's vote, with screens for all of it in both example apps.
Value: Yes/no proposals already work end to end on mobile; multiple choice proposals had nothing there. A mobile app can now show the cost before signing (0.2 Dash for a proposal, the contest fund for a choice) and vote for a choice by its document id without assembling the contest by hand.
Risks: Low. No consensus code changes: this is client code in the wallet, the two FFI crates, the JNI bridge and the two SDKs. The existing yes/no code is touched only to share helpers (visibility changes, one helper that now takes the document type name). Not exercised against a live network, because no protocol version 15 network exists yet, and the Kotlin instrumented test was not run (no emulator).
Issue being fixed or feature implemented
Part of #5679 (decision proposals). Follows #5903 (Rust and JavaScript helpers) and mirrors #5704 (yes/no proposals on mobile).
docs/protocol/decision-proposals.mdsaid "The mobile SDKs have no multiple choice helpers yet."What was done?
Before and after
Before, the only route to a vote among a proposal's choices from Kotlin was the generic contested vote call, written for DPNS labels: the caller named the contract, the document type, the index and its values, and passed the choice's document id where the call expects a contender's identity id.
walletManager.voteCasting.castVote( sdk, dataContractId = "3iNyoNwjCTkb7XS3RHyWUtLx7pgC6AFAEQNNDHzxqngF", documentTypeName = "choice", indexName = "byProposal", indexValues = listOf(proposalIdAsIndexValue), choice = VoteChoice.TowardsIdentity(choiceDocumentId), proTxHash, votingPrivateKey, networkOrd, )After:
sdk.multipleChoiceProposals.castVote( proposalId, MultipleChoiceVoteChoice.Choice(choiceId), // or NoneOfTheChoices, or Abstain proTxHash, votingPrivateKey, )rs-platform-walletandrs-platform-wallet-ffiIdentityWallet::create_multiple_choice_proposal_with_signer,edit_multiple_choice_proposal_with_signer,enter_choice_with_signer.rs-sdkbuilds the documents; the wallet selects the signing key, puts the document and keeps the owner's proven balance, as the yes/no create does.platform_wallet_multiple_choice_proposal_create,_edit,_enter_choice, withDescriptionDocumentFFI,MultipleChoiceProposalParamsFFI,MultipleChoiceProposalEditFFI(keep, set or remove for both the url and the description document) andChoiceParamsFFI.rs-sdk-ffidash_sdk_multiple_choice_proposal_fetch,_list_by_owner,_list_by_created_at,_get_vote,_get_kept_choice,_get_masternode_vote,_get_processing_fee,_get_choice_fund_to_join,_cast_vote. Reads return JSON; the two amounts return credits as a decimal string, as the identity balance does._cast_votetakes a byte (0 for a choice with its id, 1 for none of the choices, 2 for abstain), refuses any other combination before a network call, and votes through theMasternodeVoterthe contested and yes/no votes share.Swift SDK and SwiftExampleApp
MultipleChoiceProposal,ProposalChoice,MultipleChoiceProposalVote,MultipleChoiceVoteChoice, and the params and edit types.SDK:multipleChoiceProposal(id:),multipleChoiceProposalsByOwner,multipleChoiceProposalsByCreatedAt,multipleChoiceProposalVote,multipleChoiceProposalKeptChoice,multipleChoiceProposalMasternodeVote,multipleChoiceProposalProcessingFee,multipleChoiceProposalChoiceFundToJoin,castMultipleChoiceProposalVote.ManagedPlatformWallet:createMultipleChoiceProposal,editMultipleChoiceProposal,enterMultipleChoiceProposalChoice.Kotlin SDK,
rs-unified-sdk-jniand KotlinExampleAppmultiple_choice_proposals.rs, sharing the yes/no bridge's helpers.Sdk.multipleChoiceProposals(fetch,listByOwner,listByCreatedAt,vote,keptChoice,masternodeVote,processingFee,choiceFundToJoin,castVote) andPlatformWalletManager.multipleChoiceProposals(create,edit,enterChoice).QueryRegistryrows,PARITY.mdandTEST_PLAN.mdentries.What the wrappers leave to Platform
They marshal only. What a proposal or a choice may hold, who may enter a choice and how long a proposal may be edited are checked on chain: both apps show Edit to the proposal's owner at any time and let Platform refuse it after the window, as the yes/no screens do.
Once a vote ends, the vote read no longer carries the choices' text, so the detail screens make a second read for the kept choice.
How Has This Been Tested?
cargo test -p platform-wallet --lib -- multiple_choice_proposal decision_proposal: 16 passed (8 new).cargo test -p platform-wallet-ffi --lib -- multiple_choice_proposal decision_proposal: 14 passed (7 new).cargo test -p rs-sdk-ffi --lib -- decision_proposal: 27 passed (12 new).cargo test -p rs-unified-sdk-jni --lib -- multiple_choice decision_proposal: 5 passed (4 new).cargo fmt --all -- --checkclean;cargo clippy --all-targetson the four crates shows nothing in the touched files.:sdk:compileDebugKotlin :app:compileDebugKotlin :sdk:compileDebugAndroidTestKotlinbuild;MultipleChoiceProposalModelsTest16,MultipleChoiceProposalFormTest10,MultipleChoiceDocumentCreateViewModelTest5, with the yes/noDecisionProposalModelsTest14 andCreateDecisionProposalViewModelTest3 still passing../build_ios.sh --target sim --profile dev, the SwiftExampleApp simulator build, andswift teston the four decision proposal test classes: 46 passed (26 new).python3 scripts/check_sdk_parity_manifest.py: OK.Not run: the Kotlin instrumented
MultipleChoiceProposalsFfiTest(compiled only), either app on a device or simulator, and anything against a live network.Breaking Changes
None.
Checklist:
structure.rs, regeneratedgrovedb-structure.json, and checked the structure viewer link posted on this pull requestFor repository code-owners and collaborators only
🤖 Generated with Claude Code
PR Hygiene ·
c07a7e6/skip-botsproceeds without the ones not yet reported/self-reviewedkotlin-sdk(packages/kotlin-sdk/KotlinExampleApp/TEST_PLAN.md,packages/kotlin-sdk/KotlinExampleApp/app/src/main/java/org/dashfoundation/example/navigation/AppNavHost.kt,packages/kotlin-sdk/KotlinExampleApp/app/src/main/java/org/dashfoundation/example/navigation/Routes.ktand 16 more) — HashEngineeringrs-platform-wallet-ffi(packages/rs-platform-wallet-ffi/src/decision_proposal.rs,packages/rs-platform-wallet-ffi/src/lib.rs,packages/rs-platform-wallet-ffi/src/multiple_choice_proposal.rs) — HashEngineering or ZocoLini or llbartekll or romchornyirs-platform-wallet(packages/rs-platform-wallet/src/wallet/identity/network/decision_proposal.rs,packages/rs-platform-wallet/src/wallet/identity/network/mod.rs,packages/rs-platform-wallet/src/wallet/identity/network/multiple_choice_proposal.rs) — HashEngineering or ZocoLini or llbartekll or romchornyirust-sdk-ffi(packages/rs-sdk-ffi/src/decision_proposal/json.rs,packages/rs-sdk-ffi/src/decision_proposal/mod.rs,packages/rs-sdk-ffi/src/decision_proposal/multiple_choice/json.rsand 2 more) — lklimek or shumkovswift-sdk(packages/swift-sdk/Sources/SwiftDashSDK/PlatformWallet/ManagedPlatformWalletMultipleChoiceProposals.swift,packages/swift-sdk/Sources/SwiftDashSDK/Voting/MultipleChoiceProposal.swift,packages/swift-sdk/Sources/SwiftDashSDK/Voting/SDK+DecisionProposals.swiftand 7 more) — llbartekll or romchornyiWhen every merge requirement is met, the
PR Hygienecheck passes. Reviewer limits do not block merging; other required GitHub checks and protections still apply.