From d34d6254362d006d395022f88729b691ef076768 Mon Sep 17 00:00:00 2001 From: Hamish Peebles Date: Mon, 16 Oct 2023 14:20:09 +0100 Subject: [PATCH] Support submitting proposals to any governance canister (#4579) --- .../impl/src/jobs/send_prizes.rs | 1 + backend/canisters/proposals_bot/CHANGELOG.md | 4 +++ .../api/src/updates/c2c_submit_proposal.rs | 4 ++- .../impl/src/model/nervous_systems.rs | 30 +++++++++++++++-- .../impl/src/updates/c2c_submit_proposal.rs | 26 +++++++++------ backend/canisters/user/CHANGELOG.md | 1 + backend/canisters/user/api/can.did | 6 +++- .../user/api/src/updates/submit_proposal.rs | 8 +++-- .../user/impl/src/updates/submit_proposal.rs | 22 ++++++------- backend/libraries/ledger_utils/src/icrc1.rs | 33 ++++++++++--------- backend/libraries/ledger_utils/src/lib.rs | 5 ++- backend/libraries/types/src/cryptocurrency.rs | 12 +++++++ .../components/home/MakeProposalModal.svelte | 2 +- .../src/services/openchatAgent.ts | 13 +++++++- .../src/services/user/candid/idl.js | 4 +++ .../src/services/user/candid/types.d.ts | 4 +++ .../src/services/user/user.client.ts | 19 ++++++++--- frontend/openchat-client/src/openchat.ts | 6 ++++ frontend/openchat-shared/src/domain/worker.ts | 4 +++ frontend/openchat-worker/src/worker.ts | 9 ++++- 20 files changed, 162 insertions(+), 51 deletions(-) diff --git a/backend/bots/examples/group_prize_bot/impl/src/jobs/send_prizes.rs b/backend/bots/examples/group_prize_bot/impl/src/jobs/send_prizes.rs index 518e779a6e..ad111725e7 100644 --- a/backend/bots/examples/group_prize_bot/impl/src/jobs/send_prizes.rs +++ b/backend/bots/examples/group_prize_bot/impl/src/jobs/send_prizes.rs @@ -159,6 +159,7 @@ async fn transfer_prize_funds_to_group( match icrc1::process_transaction(pending_transaction, group).await { Ok(completed_transaction) => mutate_state(|state| { + let completed_transaction = CompletedCryptoTransaction::from(completed_transaction); state.data.prizes_sent.push(Prize { group, transaction: completed_transaction.clone(), diff --git a/backend/canisters/proposals_bot/CHANGELOG.md b/backend/canisters/proposals_bot/CHANGELOG.md index 9669c78492..4023d15fee 100644 --- a/backend/canisters/proposals_bot/CHANGELOG.md +++ b/backend/canisters/proposals_bot/CHANGELOG.md @@ -5,6 +5,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [unreleased] +### Added + +- Support submitting proposals to any governance canister ([#4579](https://github.com/open-chat-labs/open-chat/pull/4579)) + ## [[2.0.884](https://github.com/open-chat-labs/open-chat/releases/tag/v2.0.884-proposals_bot)] - 2023-10-12 ### Added diff --git a/backend/canisters/proposals_bot/api/src/updates/c2c_submit_proposal.rs b/backend/canisters/proposals_bot/api/src/updates/c2c_submit_proposal.rs index fa797ff486..dbd7b7296f 100644 --- a/backend/canisters/proposals_bot/api/src/updates/c2c_submit_proposal.rs +++ b/backend/canisters/proposals_bot/api/src/updates/c2c_submit_proposal.rs @@ -1,18 +1,20 @@ use crate::ProposalToSubmit; use candid::CandidType; use serde::{Deserialize, Serialize}; -use types::CanisterId; +use types::{icrc1, CanisterId}; #[derive(CandidType, Serialize, Deserialize, Debug)] pub struct Args { pub governance_canister_id: CanisterId, pub proposal: ProposalToSubmit, + pub transaction: icrc1::CompletedCryptoTransaction, } #[derive(CandidType, Serialize, Deserialize, Debug)] pub enum Response { Success, GovernanceCanisterNotSupported, + InsufficientPayment(u128), Retrying(String), InternalError(String), } diff --git a/backend/canisters/proposals_bot/impl/src/model/nervous_systems.rs b/backend/canisters/proposals_bot/impl/src/model/nervous_systems.rs index d176d38a08..2719ee620f 100644 --- a/backend/canisters/proposals_bot/impl/src/model/nervous_systems.rs +++ b/backend/canisters/proposals_bot/impl/src/model/nervous_systems.rs @@ -6,8 +6,8 @@ use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::{BTreeMap, HashMap}; use std::mem; use types::{ - CanisterId, MessageId, Milliseconds, MultiUserChat, Proposal, ProposalDecisionStatus, ProposalId, ProposalRewardStatus, - ProposalUpdate, SnsNeuronId, TimestampMillis, UserId, + icrc1, CanisterId, MessageId, Milliseconds, MultiUserChat, Proposal, ProposalDecisionStatus, ProposalId, + ProposalRewardStatus, ProposalUpdate, SnsNeuronId, TimestampMillis, UserId, }; #[derive(Serialize, Deserialize, Default)] @@ -46,6 +46,26 @@ impl NervousSystems { .and_then(|ns| ns.neuron_id_for_submitting_proposals) } + pub fn validate_submit_proposal_payment( + &self, + governance_canister_id: &CanisterId, + payment: icrc1::CompletedCryptoTransaction, + ) -> Result { + use ValidateSubmitProposalPaymentError::*; + if let Some(ns) = self.nervous_systems.get(governance_canister_id) { + if let Some(neuron_id) = ns.neuron_id_for_submitting_proposals { + return if payment.ledger != ns.ledger_canister_id { + Err(IncorrectLedger) + } else if u64::try_from(payment.amount).unwrap() < ns.proposal_rejection_fee { + Err(InsufficientPayment(ns.proposal_rejection_fee + ns.transaction_fee)) + } else { + Ok(neuron_id) + }; + } + } + Err(GovernanceCanisterNotSupported) + } + pub fn set_neuron_id_for_submitting_proposals( &mut self, governance_canister_id: &CanisterId, @@ -429,3 +449,9 @@ pub struct UserSubmittedProposalResult { pub user_id: UserId, pub adopted: bool, } + +pub enum ValidateSubmitProposalPaymentError { + GovernanceCanisterNotSupported, + IncorrectLedger, + InsufficientPayment(u64), +} diff --git a/backend/canisters/proposals_bot/impl/src/updates/c2c_submit_proposal.rs b/backend/canisters/proposals_bot/impl/src/updates/c2c_submit_proposal.rs index 633b274522..dc3d4496d7 100644 --- a/backend/canisters/proposals_bot/impl/src/updates/c2c_submit_proposal.rs +++ b/backend/canisters/proposals_bot/impl/src/updates/c2c_submit_proposal.rs @@ -1,3 +1,4 @@ +use crate::model::nervous_systems::ValidateSubmitProposalPaymentError; use crate::timer_job_types::{LookupUserThenSubmitProposalJob, SubmitProposalJob, TimerJob}; use crate::{mutate_state, read_state, RuntimeState}; use candid::Principal; @@ -9,7 +10,7 @@ use sns_governance_canister::types::manage_neuron::Command; use sns_governance_canister::types::proposal::Action; use sns_governance_canister::types::{manage_neuron_response, Motion, Proposal, Subaccount, TransferSnsTreasuryFunds}; use tracing::{error, info}; -use types::{CanisterId, MultiUserChat, SnsNeuronId, UserDetails, UserId}; +use types::{icrc1, CanisterId, MultiUserChat, SnsNeuronId, UserDetails, UserId}; use user_index_canister_c2c_client::{lookup_user, LookupUserError}; use utils::time::SECOND_IN_MS; @@ -23,7 +24,7 @@ async fn c2c_submit_proposal(args: Args) -> Response { user_index_canister_id, neuron_id, chat, - } = match read_state(|state| prepare(&args, state)) { + } = match read_state(|state| prepare(args.governance_canister_id, args.transaction, state)) { Ok(ok) => ok, Err(response) => return response, }; @@ -46,20 +47,25 @@ struct PrepareResult { chat: MultiUserChat, } -fn prepare(args: &Args, state: &RuntimeState) -> Result { - if let Some(neuron_id) = state +fn prepare( + governance_canister_id: CanisterId, + transaction: icrc1::CompletedCryptoTransaction, + state: &RuntimeState, +) -> Result { + use ValidateSubmitProposalPaymentError as E; + match state .data .nervous_systems - .get_neuron_id_for_submitting_proposals(&args.governance_canister_id) + .validate_submit_proposal_payment(&governance_canister_id, transaction) { - Ok(PrepareResult { + Ok(neuron_id) => Ok(PrepareResult { caller: state.env.caller(), user_index_canister_id: state.data.user_index_canister_id, neuron_id, - chat: state.data.nervous_systems.get_chat_id(&args.governance_canister_id).unwrap(), - }) - } else { - Err(GovernanceCanisterNotSupported) + chat: state.data.nervous_systems.get_chat_id(&governance_canister_id).unwrap(), + }), + Err(E::GovernanceCanisterNotSupported | E::IncorrectLedger) => Err(GovernanceCanisterNotSupported), + Err(E::InsufficientPayment(min)) => Err(InsufficientPayment(min.into())), } } diff --git a/backend/canisters/user/CHANGELOG.md b/backend/canisters/user/CHANGELOG.md index 531d08f708..18d0da9d7f 100644 --- a/backend/canisters/user/CHANGELOG.md +++ b/backend/canisters/user/CHANGELOG.md @@ -7,6 +7,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added +- Support submitting proposals to any governance canister ([#4579](https://github.com/open-chat-labs/open-chat/pull/4579)) - Support sending ICP to ICRC1 accounts ([#4583](https://github.com/open-chat-labs/open-chat/pull/4583)) ### Removed diff --git a/backend/canisters/user/api/can.did b/backend/canisters/user/api/can.did index 2937038a3a..0c9bab4eb0 100644 --- a/backend/canisters/user/api/can.did +++ b/backend/canisters/user/api/can.did @@ -568,6 +568,10 @@ type SavedCryptoAccountsResponse = variant { type SubmitProposalArgs = record { governance_canister_id : CanisterId; proposal : ProposalToSubmit; + ledger : CanisterId; + token : Cryptocurrency; + proposal_rejection_fee : nat; + transaction_fee : nat; }; type ProposalToSubmit = record { @@ -593,7 +597,7 @@ type ProposalToSubmitAction = variant { type SubmitProposalResponse = variant { Success; GovernanceCanisterNotSupported; - Unauthorized; + InsufficientPayment : nat; UserSuspended; TransferFailed : text; Retrying : text; diff --git a/backend/canisters/user/api/src/updates/submit_proposal.rs b/backend/canisters/user/api/src/updates/submit_proposal.rs index a1d2349929..25e81ff47a 100644 --- a/backend/canisters/user/api/src/updates/submit_proposal.rs +++ b/backend/canisters/user/api/src/updates/submit_proposal.rs @@ -2,19 +2,23 @@ use candid::CandidType; use proposals_bot_canister::ProposalToSubmit; use serde::{Deserialize, Serialize}; use std::fmt::Debug; -use types::CanisterId; +use types::{CanisterId, Cryptocurrency}; #[derive(CandidType, Serialize, Deserialize, Debug)] pub struct Args { pub governance_canister_id: CanisterId, pub proposal: ProposalToSubmit, + pub ledger: CanisterId, + pub token: Cryptocurrency, + pub proposal_rejection_fee: u128, + pub transaction_fee: u128, } #[derive(CandidType, Serialize, Deserialize, Debug)] pub enum Response { Success, GovernanceCanisterNotSupported, - Unauthorized, + InsufficientPayment(u128), UserSuspended, TransferFailed(String), Retrying(String), diff --git a/backend/canisters/user/impl/src/updates/submit_proposal.rs b/backend/canisters/user/impl/src/updates/submit_proposal.rs index 12b7989210..bcdeebf22e 100644 --- a/backend/canisters/user/impl/src/updates/submit_proposal.rs +++ b/backend/canisters/user/impl/src/updates/submit_proposal.rs @@ -4,9 +4,8 @@ use canister_tracing_macros::trace; use ic_cdk_macros::update; use ledger_utils::icrc1::process_transaction; use types::icrc1::{Account, PendingCryptoTransaction}; -use types::{CanisterId, Cryptocurrency, UserId}; +use types::{CanisterId, UserId}; use user_canister::submit_proposal::{Response::*, *}; -use utils::consts::{SNS_GOVERNANCE_CANISTER_ID, SNS_LEDGER_CANISTER_ID}; #[update(guard = "caller_is_owner")] #[trace] @@ -23,19 +22,22 @@ async fn submit_proposal(args: Args) -> Response { }; // Make the crypto transfer - if let Err(failed) = process_transaction(transaction, my_user_id.into()).await { - return TransferFailed(failed.error_message().to_string()); - } + let completed_transaction = match process_transaction(transaction, my_user_id.into()).await { + Ok(completed) => completed, + Err(failed) => return TransferFailed(failed.error_message), + }; let c2c_args = proposals_bot_canister::c2c_submit_proposal::Args { governance_canister_id: args.governance_canister_id, proposal: args.proposal, + transaction: completed_transaction, }; match proposals_bot_canister_c2c_client::c2c_submit_proposal(proposals_bot_canister_id, &c2c_args).await { Ok(proposals_bot_canister::c2c_submit_proposal::Response::Success) => Success, Ok(proposals_bot_canister::c2c_submit_proposal::Response::GovernanceCanisterNotSupported) => { GovernanceCanisterNotSupported } + Ok(proposals_bot_canister::c2c_submit_proposal::Response::InsufficientPayment(min)) => InsufficientPayment(min), Ok(proposals_bot_canister::c2c_submit_proposal::Response::Retrying(error)) => Retrying(error), Ok(proposals_bot_canister::c2c_submit_proposal::Response::InternalError(error)) => InternalError(error), Err(error) => { @@ -60,18 +62,16 @@ struct PrepareResult { fn prepare(args: &Args, state: &RuntimeState) -> Result { if state.data.suspended.value { Err(UserSuspended) - } else if args.governance_canister_id != SNS_GOVERNANCE_CANISTER_ID { - Err(GovernanceCanisterNotSupported) } else { Ok(PrepareResult { my_user_id: state.env.canister_id().into(), proposals_bot_canister_id: state.data.proposals_bot_canister_id, transaction: PendingCryptoTransaction { - ledger: SNS_LEDGER_CANISTER_ID, - token: Cryptocurrency::CHAT, - amount: 4_0000_0000, // 4 CHAT + ledger: args.ledger, + token: args.token.clone(), + amount: args.proposal_rejection_fee + args.transaction_fee, to: Account::from(state.data.proposals_bot_canister_id), - fee: Cryptocurrency::CHAT.fee().unwrap(), + fee: args.transaction_fee, memo: None, created: state.env.now_nanos(), }, diff --git a/backend/libraries/ledger_utils/src/icrc1.rs b/backend/libraries/ledger_utils/src/icrc1.rs index 3cafa335d4..857f672818 100644 --- a/backend/libraries/ledger_utils/src/icrc1.rs +++ b/backend/libraries/ledger_utils/src/icrc1.rs @@ -1,8 +1,11 @@ use types::icrc1::{Account, TransferArg}; -use types::{CanisterId, CompletedCryptoTransaction, FailedCryptoTransaction}; +use types::{ + icrc1::{CompletedCryptoTransaction, FailedCryptoTransaction, PendingCryptoTransaction}, + CanisterId, +}; pub async fn process_transaction( - transaction: types::icrc1::PendingCryptoTransaction, + transaction: PendingCryptoTransaction, sender: CanisterId, ) -> Result { let from = Account::from(sender); @@ -17,7 +20,7 @@ pub async fn process_transaction( }; match icrc1_ledger_canister_c2c_client::icrc1_transfer(transaction.ledger, &args).await { - Ok(Ok(block_index)) => Ok(CompletedCryptoTransaction::ICRC1(types::icrc1::CompletedCryptoTransaction { + Ok(Ok(block_index)) => Ok(CompletedCryptoTransaction { ledger: transaction.ledger, token: transaction.token.clone(), amount: transaction.amount, @@ -27,7 +30,7 @@ pub async fn process_transaction( memo: transaction.memo.clone(), created: transaction.created, block_index: block_index.0.try_into().unwrap(), - })), + }), Ok(Err(transfer_error)) => { let error_message = format!("Transfer failed. {transfer_error:?}"); Err(error_message) @@ -37,17 +40,15 @@ pub async fn process_transaction( Err(error_message) } } - .map_err(|error| { - FailedCryptoTransaction::ICRC1(types::icrc1::FailedCryptoTransaction { - ledger: transaction.ledger, - token: transaction.token, - amount: transaction.amount, - fee: transaction.fee, - from: types::icrc1::CryptoAccount::Account(from), - to: types::icrc1::CryptoAccount::Account(transaction.to), - memo: transaction.memo, - created: transaction.created, - error_message: error, - }) + .map_err(|error| FailedCryptoTransaction { + ledger: transaction.ledger, + token: transaction.token, + amount: transaction.amount, + fee: transaction.fee, + from: types::icrc1::CryptoAccount::Account(from), + to: types::icrc1::CryptoAccount::Account(transaction.to), + memo: transaction.memo, + created: transaction.created, + error_message: error, }) } diff --git a/backend/libraries/ledger_utils/src/lib.rs b/backend/libraries/ledger_utils/src/lib.rs index 44bf013070..0ed78347c5 100644 --- a/backend/libraries/ledger_utils/src/lib.rs +++ b/backend/libraries/ledger_utils/src/lib.rs @@ -51,7 +51,10 @@ pub async fn process_transaction( if t.token == Cryptocurrency::InternetComputer { nns::process_transaction(t.into(), sender).await } else { - icrc1::process_transaction(t, sender).await + match icrc1::process_transaction(t, sender).await { + Ok(c) => Ok(c.into()), + Err(f) => Err(f.into()), + } } } } diff --git a/backend/libraries/types/src/cryptocurrency.rs b/backend/libraries/types/src/cryptocurrency.rs index acbfda8c45..e7cefe937f 100644 --- a/backend/libraries/types/src/cryptocurrency.rs +++ b/backend/libraries/types/src/cryptocurrency.rs @@ -451,6 +451,18 @@ pub mod icrc1 { pub created: TimestampNanos, pub error_message: String, } + + impl From for super::CompletedCryptoTransaction { + fn from(value: CompletedCryptoTransaction) -> Self { + super::CompletedCryptoTransaction::ICRC1(value) + } + } + + impl From for super::FailedCryptoTransaction { + fn from(value: FailedCryptoTransaction) -> Self { + super::FailedCryptoTransaction::ICRC1(value) + } + } } impl From for nns::PendingCryptoTransaction { diff --git a/frontend/app/src/components/home/MakeProposalModal.svelte b/frontend/app/src/components/home/MakeProposalModal.svelte index 40d24c4183..be73cb2365 100644 --- a/frontend/app/src/components/home/MakeProposalModal.svelte +++ b/frontend/app/src/components/home/MakeProposalModal.svelte @@ -32,7 +32,6 @@ const client = getContext("client"); const dispatch = createEventDispatcher(); const user = client.user; - const proposalCost = BigInt(400000000); export let selectedMultiUserChat: MultiUserChat; export let governanceCanisterId: string; @@ -63,6 +62,7 @@ $: symbol = tokenDetails.symbol; $: howToBuyUrl = tokenDetails.howToBuyUrl; $: transferFee = tokenDetails.transferFee; + $: proposalCost = tokenDetails.nervousSystem?.proposalRejectionFee ?? BigInt(0); $: requiredFunds = proposalCost + transferFee + transferFee; $: insufficientFunds = cryptoBalance < requiredFunds; $: padding = $mobileWidth ? 16 : 24; // yes this is horrible diff --git a/frontend/openchat-agent/src/services/openchatAgent.ts b/frontend/openchat-agent/src/services/openchatAgent.ts index 8aed2f9c24..6d0ced6f44 100644 --- a/frontend/openchat-agent/src/services/openchatAgent.ts +++ b/frontend/openchat-agent/src/services/openchatAgent.ts @@ -2572,7 +2572,18 @@ export class OpenChatAgent extends EventTarget { submitProposal( governanceCanisterId: string, proposal: CandidateProposal, + ledger: string, + token: string, + proposalRejectionFee: bigint, + transactionFee: bigint, ): Promise { - return this.userClient.submitProposal(governanceCanisterId, proposal); + return this.userClient.submitProposal( + governanceCanisterId, + proposal, + ledger, + token, + proposalRejectionFee, + transactionFee, + ); } } diff --git a/frontend/openchat-agent/src/services/user/candid/idl.js b/frontend/openchat-agent/src/services/user/candid/idl.js index f0080f445f..65b6224410 100644 --- a/frontend/openchat-agent/src/services/user/candid/idl.js +++ b/frontend/openchat-agent/src/services/user/candid/idl.js @@ -1278,8 +1278,12 @@ export const idlFactory = ({ IDL }) => { 'summary' : IDL.Text, }); const SubmitProposalArgs = IDL.Record({ + 'token' : Cryptocurrency, + 'transaction_fee' : IDL.Nat, + 'ledger' : CanisterId, 'governance_canister_id' : CanisterId, 'proposal' : ProposalToSubmit, + 'proposal_rejection_fee' : IDL.Nat, }); const SubmitProposalResponse = IDL.Variant({ 'Retrying' : IDL.Text, diff --git a/frontend/openchat-agent/src/services/user/candid/types.d.ts b/frontend/openchat-agent/src/services/user/candid/types.d.ts index 345c1d0d36..59df2b28f9 100644 --- a/frontend/openchat-agent/src/services/user/candid/types.d.ts +++ b/frontend/openchat-agent/src/services/user/candid/types.d.ts @@ -1637,8 +1637,12 @@ export interface SnsProposal { 'proposer' : SnsNeuronId, } export interface SubmitProposalArgs { + 'token' : Cryptocurrency, + 'transaction_fee' : bigint, + 'ledger' : CanisterId, 'governance_canister_id' : CanisterId, 'proposal' : ProposalToSubmit, + 'proposal_rejection_fee' : bigint, } export type SubmitProposalResponse = { 'Retrying' : string } | { 'Success' : null } | diff --git a/frontend/openchat-agent/src/services/user/user.client.ts b/frontend/openchat-agent/src/services/user/user.client.ts index cd8fb5d4cb..550c15cf22 100644 --- a/frontend/openchat-agent/src/services/user/user.client.ts +++ b/frontend/openchat-agent/src/services/user/user.client.ts @@ -65,7 +65,7 @@ import type { NamedAccount, SaveCryptoAccountResponse, CandidateProposal, - SubmitProposalResponse + SubmitProposalResponse, } from "openchat-shared"; import { CandidService } from "../candidService"; import { @@ -1121,11 +1121,22 @@ export class UserClient extends CandidService { ); } - submitProposal(governanceCanisterId: string, proposal: CandidateProposal): Promise { + submitProposal( + governanceCanisterId: string, + proposal: CandidateProposal, + ledger: string, + token: string, + proposalRejectionFee: bigint, + transactionFee: bigint, + ): Promise { return this.handleResponse( this.userService.submit_proposal({ - governance_canister_id : Principal.fromText(governanceCanisterId), - proposal : proposalToSubmit(proposal), + governance_canister_id: Principal.fromText(governanceCanisterId), + proposal: proposalToSubmit(proposal), + ledger: Principal.fromText(ledger), + token: apiToken(token), + proposal_rejection_fee: proposalRejectionFee, + transaction_fee: transactionFee, }), submitProposalResponse, ); diff --git a/frontend/openchat-client/src/openchat.ts b/frontend/openchat-client/src/openchat.ts index da430abc1f..255e7d9f9c 100644 --- a/frontend/openchat-client/src/openchat.ts +++ b/frontend/openchat-client/src/openchat.ts @@ -5009,10 +5009,16 @@ export class OpenChat extends OpenChatAgentWorker { } submitProposal(governanceCanisterId: string, proposal: CandidateProposal): Promise { + const token = this.getTokenByGovernanceCanister(governanceCanisterId); + return this.sendRequest({ kind: "submitProposal", governanceCanisterId, proposal, + ledger: token.ledger, + token: token.symbol, + proposalRejectionFee: token.nervousSystem?.proposalRejectionFee ?? BigInt(0), + transactionFee: token.transferFee, }) .then((resp) => { if (resp.kind === "success" || resp.kind === "retrying") { diff --git a/frontend/openchat-shared/src/domain/worker.ts b/frontend/openchat-shared/src/domain/worker.ts index 1978ade8f4..f8c4927bdc 100644 --- a/frontend/openchat-shared/src/domain/worker.ts +++ b/frontend/openchat-shared/src/domain/worker.ts @@ -1329,6 +1329,10 @@ type FollowThread = { type SubmitProposal = { governanceCanisterId: string; proposal: CandidateProposal; + ledger: string; + token: string; + proposalRejectionFee: bigint; + transactionFee: bigint; kind: "submitProposal"; }; diff --git a/frontend/openchat-worker/src/worker.ts b/frontend/openchat-worker/src/worker.ts index 0dfddae05d..9b03d7b944 100644 --- a/frontend/openchat-worker/src/worker.ts +++ b/frontend/openchat-worker/src/worker.ts @@ -1272,7 +1272,14 @@ self.addEventListener("message", (msg: MessageEvent) => executeThenReply( payload, correlationId, - agent.submitProposal(payload.governanceCanisterId, payload.proposal), + agent.submitProposal( + payload.governanceCanisterId, + payload.proposal, + payload.ledger, + payload.token, + payload.proposalRejectionFee, + payload.transactionFee, + ), ); break;