Add Sputnik DAO multisig commands for ML-DSA-65 wallets - #172
Conversation
quantus near dao propose-transfer / vote / proposal let a NEAR account controlled by a Quantus ML-DSA-65 key act as a co-signer in a Sputnik DAO treasury (the contract behind Trezu). Adds FunctionCall action encoding, a call_function view RPC, and SuccessValue decoding for proposal ids. Co-authored-by: Cursor <cursoragent@cursor.com>
n13
left a comment
There was a problem hiding this comment.
Reviewer model: GPT-6 Sol
Verdict: Request changes. The new vote command is incompatible with Sputnik DAOs running the current contract.
- [P1] Supply the proposal kind to
act_proposal(src/cli/near.rs:781). The current Sputnik DAO contract requires aproposal: ProposalKindargument and checks it against the stored proposal. This command submits onlyidandaction, so a vote against a DAO using that contract fails argument decoding before it can be recorded. Readget_proposalbefore signing, extract itskind, and include that value asproposal; reject a missing or malformed kind. The older two-argument interface shown in the repository README does not cover upgraded DAOs.
Validation: SKIP_CIRCUIT_BUILD=1 cargo test --locked --lib near:: passed (22 tests). GitHub format, Clippy/doc, and security checks passed at review time; build matrix and examples were still pending. I did not submit a signed transaction to a live DAO.
The current Sputnik contract requires act_proposal(id, action, proposal, memo) and re-checks the kind against the stored proposal, so the vote command now reads get_proposal first and includes its kind. Co-authored-by: Cursor <cursoragent@cursor.com>
|
Addressed the P1: |
n13
left a comment
There was a problem hiding this comment.
Reviewer model: GPT-6 Sol
Verdict: Approve. The follow-up commit resolves the earlier blocker: near dao vote reads the stored proposal kind and passes it as proposal to act_proposal, matching the current Sputnik contract. I found no remaining blocking issues in the full PR diff against the stacked base.
Validation: SKIP_CIRCUIT_BUILD=1 cargo test --locked --lib near:: passed (23 tests); git diff --check passed. All seven PR checks completed successfully at 9e3f0cbd8e318bcefa7ba2559081bc14f3096a54. No signed transaction was submitted to a live DAO.
* Add Sputnik DAO multisig commands for ML-DSA-65 wallets quantus near dao propose-transfer / vote / proposal let a NEAR account controlled by a Quantus ML-DSA-65 key act as a co-signer in a Sputnik DAO treasury (the contract behind Trezu). Adds FunctionCall action encoding, a call_function view RPC, and SuccessValue decoding for proposal ids. * Pass the stored proposal kind to act_proposal The current Sputnik contract requires act_proposal(id, action, proposal, memo) and re-checks the kind against the stored proposal, so the vote command now reads get_proposal first and includes its kind. --------- Co-authored-by: Cursor <cursoragent@cursor.com>
Stacked on #171 (base branch is
yuvi/ml-dsa-65-cold-near; retarget tomainafter that merges).Summary
Implements the NEAR-multisig phase of the plan: a NEAR account solely controlled by a Quantus ML-DSA-65 wallet can now act as a co-signer in a Sputnik DAO treasury — the multisig contract behind Trezu (trezu.org), currently the most popular treasury manager on NEAR. Sputnik authorizes members by account ID and NEAR authenticates the account via its access key, so a post-quantum member needs no changes on the DAO or Trezu side; votes made from this CLI show up in the Trezu UI.
New commands:
quantus near dao propose-transfer --dao <dao> --account <member> --wallet <w> --receiver <r> --amount <NEAR>— callsadd_proposalwith a base-NEAR Transfer kind. The required bond is read from the DAO policy'sproposal_bond(overridable with--bond), and the returned proposal id is decoded from the transaction'sSuccessValueand printed with a ready-to-copy vote command.quantus near dao vote --dao <dao> --id <n> --vote approve|reject|remove ...— callsact_proposalwith 300 Tgas (a threshold-meeting approval executes the proposal in the same call), then shows the proposal's resulting state.quantus near dao proposal --dao <dao> --id <n>— view a proposal's status, votes, and kind (no wallet needed).Supporting changes:
src/near/protocol.rs:Action::FunctionCallis now constructed (was a tag-position placeholder); borsh layout pinned by a hand-built golden test.src/near/rpc.rs:call_view_function(query/call_function with base64 JSON args, byte-array result decoding) anddecode_success_valuefor transaction return values.Testing
./clippy.shclean.quantus near dao --helpand subcommand help smoke-tested. Not yet exercised against a live DAO on testnet.Made with Cursor