From b498166796c50ebbba8849bb708192b735071d1f Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Tue, 24 Jan 2023 09:57:03 -0500 Subject: [PATCH 01/11] Update swap.did --- candid/swap.did | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/candid/swap.did b/candid/swap.did index d772cb8..9875640 100644 --- a/candid/swap.did +++ b/candid/swap.did @@ -31,6 +31,7 @@ type DerivedState = record { }; type DirectInvestment = record { buyer_principal : text }; type Err = record { description : opt text; error_type : opt int32 }; +type Err_1 = record { error_type : opt int32 }; type ErrorRefundIcpRequest = record { source_principal_id : opt principal }; type ErrorRefundIcpResponse = record { result : opt Result }; type FailedUpdate = record { @@ -55,8 +56,10 @@ type GetDerivedStateResponse = record { }; type GetInitResponse = record { init : opt Init }; type GetLifecycleResponse = record { lifecycle : opt int32 }; +type GetOpenTicketResponse = record { result : opt Result_1 }; type GetStateResponse = record { swap : opt Swap; derived : opt DerivedState }; type GovernanceError = record { error_message : text; error_type : int32 }; +type Icrc1Account = record { owner : opt principal; subaccount : opt vec nat8 }; type Init = record { sns_root_canister_id : text; fallback_controller_principal_ids : vec text; @@ -77,6 +80,7 @@ type NeuronBasketConstructionParameters = record { count : nat64; }; type Ok = record { block_height : opt nat64 }; +type Ok_1 = record { ticket : opt Ticket }; type OpenRequest = record { cf_participants : vec CfParticipant; params : opt Params; @@ -105,6 +109,7 @@ type RefreshBuyerTokensResponse = record { }; type Response = record { governance_error : opt GovernanceError }; type Result = variant { Ok : Ok; Err : Err }; +type Result_1 = variant { Ok : Ok_1; Err : Err_1 }; type SetDappControllersCallResult = record { possibility : opt Possibility_1 }; type SetDappControllersResponse = record { failed_updates : vec FailedUpdate }; type SetModeCallResult = record { possibility : opt Possibility_2 }; @@ -127,6 +132,12 @@ type Swap = record { open_sns_token_swap_proposal_id : opt nat64; }; type SweepResult = record { failure : nat32; skipped : nat32; success : nat32 }; +type Ticket = record { + creation_time : nat64; + ticket_id : nat64; + account : opt Icrc1Account; + amount_icp_e8s : nat64; +}; type TransferableAmount = record { transfer_start_timestamp_seconds : nat64; amount_e8s : nat64; @@ -141,6 +152,7 @@ service : (Init) -> { get_derived_state : (record {}) -> (GetDerivedStateResponse) query; get_init : (record {}) -> (GetInitResponse) query; get_lifecycle : (record {}) -> (GetLifecycleResponse) query; + get_open_ticket : (record {}) -> (GetOpenTicketResponse) query; get_state : (record {}) -> (GetStateResponse) query; open : (OpenRequest) -> (record {}); refresh_buyer_tokens : (RefreshBuyerTokensRequest) -> ( From 96d3b2205d1038f317234c307ed87f367ca2f59f Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Tue, 24 Jan 2023 12:53:42 -0500 Subject: [PATCH 02/11] send get_open_ticket --- src/commands/get_open_ticket.rs | 24 ++++++++++++++++++++++++ src/commands/mod.rs | 8 ++++++++ tests/commands/get-open-tocket.sh | 1 + tests/outputs/get-open-tocket.txt | 7 +++++++ 4 files changed, 40 insertions(+) create mode 100644 src/commands/get_open_ticket.rs create mode 100644 tests/commands/get-open-tocket.sh create mode 100644 tests/outputs/get-open-tocket.txt diff --git a/src/commands/get_open_ticket.rs b/src/commands/get_open_ticket.rs new file mode 100644 index 0000000..ecc15ff --- /dev/null +++ b/src/commands/get_open_ticket.rs @@ -0,0 +1,24 @@ +use crate::{ + lib::{ + signing::{sign_ingress_with_request_status_query, IngressWithRequestId}, + AnyhowResult, TargetCanister, + }, + SnsCanisterIds, +}; +use candid::Encode; + +#[derive(candid::CandidType, candid::Deserialize)] +struct GetOpenTicketArg {} + +pub fn exec( + pem: &str, + sns_canister_ids: &SnsCanisterIds, +) -> AnyhowResult> { + let req = sign_ingress_with_request_status_query( + pem, + "get_open_ticket", + Encode!(&GetOpenTicketArg {})?, + TargetCanister::Swap(sns_canister_ids.swap_canister_id.get().0), + )?; + Ok(vec![req]) +} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 346d260..59c57da 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -9,6 +9,7 @@ use tokio::runtime::Runtime; mod account_balance; mod configure_dissolve_delay; mod generate; +mod get_open_ticket; mod get_swap_refund; mod list_deployed_snses; mod make_proposal; @@ -48,6 +49,8 @@ pub enum Command { /// can submit proposals (such as a Motion Proposal) to be voted on by other neuron /// holders. MakeProposal(make_proposal::MakeProposalOpts), + /// Get the open sale ticket for the caller if exist. + GetOpenTicket, GetSwapRefund(get_swap_refund::GetSwapRefundOpts), ListDeployedSnses(list_deployed_snses::ListDeployedSnsesOpts), /// Signs a ManageNeuron message to register a vote for a proposal. Registering a vote will @@ -106,6 +109,11 @@ pub fn exec( let canister_ids = require_canister_ids(sns_canister_ids)?; make_proposal::exec(&pem, &canister_ids, opts).and_then(|out| print_vec(qr, &out)) } + Command::GetOpenTicket => { + let pem = require_pem(private_key_pem)?; + let canister_ids = require_canister_ids(sns_canister_ids)?; + get_open_ticket::exec(&pem, &canister_ids).and_then(|out| print_vec(qr, &out)) + } Command::GetSwapRefund(opts) => { let pem = require_pem(private_key_pem)?; let canister_ids = require_canister_ids(sns_canister_ids)?; diff --git a/tests/commands/get-open-tocket.sh b/tests/commands/get-open-tocket.sh new file mode 100644 index 0000000..c597d03 --- /dev/null +++ b/tests/commands/get-open-tocket.sh @@ -0,0 +1 @@ +${CARGO_TARGET_DIR:-../target}/debug/sns-quill --canister-ids-file ./canister_ids.json --pem-file - get-open-ticket | ${CARGO_TARGET_DIR:-../target}/debug/sns-quill send --dry-run - diff --git a/tests/outputs/get-open-tocket.txt b/tests/outputs/get-open-tocket.txt new file mode 100644 index 0000000..fc66fed --- /dev/null +++ b/tests/outputs/get-open-tocket.txt @@ -0,0 +1,7 @@ +Sending message with + + Call type: update + Sender: fdsgv-62ihb-nbiqv-xgic5-iefsv-3cscz-tmbzv-63qd5-vh43v-dqfrt-pae + Canister id: rkp4c-7iaaa-aaaaa-aaaca-cai + Method name: get_open_ticket + Arguments: (record {}) From eab8d788943bbfa575d9858d391137fe7d54bcb5 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Tue, 24 Jan 2023 13:03:26 -0500 Subject: [PATCH 03/11] handle response after send --- src/commands/send.rs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/commands/send.rs b/src/commands/send.rs index 189d2b7..5b65762 100644 --- a/src/commands/send.rs +++ b/src/commands/send.rs @@ -146,6 +146,7 @@ enum SupportedResponse { IcpTransfer, RefreshBuyerTokens, GetSnsCanistersSummary, + GetOpenTicket, } impl FromStr for SupportedResponse { @@ -160,6 +161,7 @@ impl FromStr for SupportedResponse { "send_dfx" => Ok(SupportedResponse::IcpTransfer), "refresh_buyer_tokens" => Ok(SupportedResponse::RefreshBuyerTokens), "get_sns_canisters_summary" => Ok(SupportedResponse::GetSnsCanistersSummary), + "get_open_ticket" => Ok(SupportedResponse::GetOpenTicket), unsupported_response => Err(anyhow!( "{} is not a supported response", unsupported_response @@ -200,7 +202,15 @@ fn print_response(blob: Vec, method_name: String) -> AnyhowResult { let response = Decode!(blob.as_slice(), GetSnsCanistersSummaryResponse)?; println!("Response: {:#?\n}", response); } + SupportedResponse::GetOpenTicket => { + let response = Decode!(blob.as_slice(), GetOpenTicketResponse)?; + println!("Response: {:#?\n}", response); + } } Ok(()) } + +// FIXME: use ic_sns_swap when it is available +#[derive(Debug, candid::CandidType, candid::Deserialize)] +struct GetOpenTicketResponse {} From cbd7b818512b8d21205eeed5c52d5a7be1ac4064 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Tue, 24 Jan 2023 16:28:46 -0500 Subject: [PATCH 04/11] send new-sale-ticket --- candid/swap.did | 17 +++++++++++ src/commands/mod.rs | 7 +++++ src/commands/new_sale_ticket.rs | 48 +++++++++++++++++++++++++++++++ tests/commands/new-sale-ticket.sh | 1 + tests/outputs/new-sale-ticket.txt | 12 ++++++++ 5 files changed, 85 insertions(+) create mode 100644 src/commands/new_sale_ticket.rs create mode 100644 tests/commands/new-sale-ticket.sh create mode 100644 tests/outputs/new-sale-ticket.txt diff --git a/candid/swap.did b/candid/swap.did index 9875640..b6a9b29 100644 --- a/candid/swap.did +++ b/candid/swap.did @@ -32,6 +32,11 @@ type DerivedState = record { type DirectInvestment = record { buyer_principal : text }; type Err = record { description : opt text; error_type : opt int32 }; type Err_1 = record { error_type : opt int32 }; +type Err_2 = record { + invalid_user_amount : opt InvalidUserAmount; + allowance_icp_e8s : opt nat64; + error_type : opt int32; +}; type ErrorRefundIcpRequest = record { source_principal_id : opt principal }; type ErrorRefundIcpResponse = record { result : opt Result }; type FailedUpdate = record { @@ -70,6 +75,10 @@ type Init = record { sns_ledger_canister_id : text; sns_governance_canister_id : text; }; +type InvalidUserAmount = record { + min_amount_icp_e8s_included : nat64; + max_amount_icp_e8s_included : nat64; +}; type Investor = variant { CommunityFund : CfInvestment; Direct : DirectInvestment; @@ -79,8 +88,14 @@ type NeuronBasketConstructionParameters = record { dissolve_delay_interval_seconds : nat64; count : nat64; }; +type NewSaleTicketRequest = record { + subaccount : opt vec nat8; + amount_icp_e8s : nat64; +}; +type NewSaleTicketResponse = record { result : opt Result_2 }; type Ok = record { block_height : opt nat64 }; type Ok_1 = record { ticket : opt Ticket }; +type Ok_2 = record { creation_time : nat64; ticket_id : nat64 }; type OpenRequest = record { cf_participants : vec CfParticipant; params : opt Params; @@ -110,6 +125,7 @@ type RefreshBuyerTokensResponse = record { type Response = record { governance_error : opt GovernanceError }; type Result = variant { Ok : Ok; Err : Err }; type Result_1 = variant { Ok : Ok_1; Err : Err_1 }; +type Result_2 = variant { Ok : Ok_2; Err : Err_2 }; type SetDappControllersCallResult = record { possibility : opt Possibility_1 }; type SetDappControllersResponse = record { failed_updates : vec FailedUpdate }; type SetModeCallResult = record { possibility : opt Possibility_2 }; @@ -154,6 +170,7 @@ service : (Init) -> { get_lifecycle : (record {}) -> (GetLifecycleResponse) query; get_open_ticket : (record {}) -> (GetOpenTicketResponse) query; get_state : (record {}) -> (GetStateResponse) query; + new_sale_ticket : (NewSaleTicketRequest) -> (NewSaleTicketResponse); open : (OpenRequest) -> (record {}); refresh_buyer_tokens : (RefreshBuyerTokensRequest) -> ( RefreshBuyerTokensResponse, diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 59c57da..83fc784 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -15,6 +15,7 @@ mod list_deployed_snses; mod make_proposal; mod make_upgrade_canister_proposal; mod neuron_permission; +mod new_sale_ticket; mod public; mod qrcode; mod register_vote; @@ -52,6 +53,7 @@ pub enum Command { /// Get the open sale ticket for the caller if exist. GetOpenTicket, GetSwapRefund(get_swap_refund::GetSwapRefundOpts), + NewSaleTicket(new_sale_ticket::NewSaleTicketOpts), ListDeployedSnses(list_deployed_snses::ListDeployedSnsesOpts), /// Signs a ManageNeuron message to register a vote for a proposal. Registering a vote will /// update the ballot of the given proposal and could trigger followees to vote. When @@ -119,6 +121,11 @@ pub fn exec( let canister_ids = require_canister_ids(sns_canister_ids)?; get_swap_refund::exec(&pem, &canister_ids, opts).and_then(|out| print_vec(qr, &out)) } + Command::NewSaleTicket(opts) => { + let pem = require_pem(private_key_pem)?; + let canister_ids = require_canister_ids(sns_canister_ids)?; + new_sale_ticket::exec(&pem, &canister_ids, opts).and_then(|out| print_vec(qr, &out)) + } Command::ListDeployedSnses(opts) => { runtime.block_on(async { list_deployed_snses::exec(opts).await }) } diff --git a/src/commands/new_sale_ticket.rs b/src/commands/new_sale_ticket.rs new file mode 100644 index 0000000..723fdb6 --- /dev/null +++ b/src/commands/new_sale_ticket.rs @@ -0,0 +1,48 @@ +use candid::Encode; +use clap::Parser; + +use crate::{ + commands::transfer::HexSubaccount, + lib::{ + signing::{sign_ingress_with_request_status_query, IngressWithRequestId}, + AnyhowResult, TargetCanister, + }, + SnsCanisterIds, +}; + +/// Attempts to create a new Ticket for the caller. +#[derive(Parser)] +pub struct NewSaleTicketOpts { + // TODO: check this description + /// The amount of ICP tokens in e8s. + #[clap(long)] + amount_icp_e8s: u64, + + /// The subaccount of the account to create sale ticket. For example: e000d80101 + #[clap(long)] + subaccount: Option, +} + +#[derive(candid::CandidType, candid::Deserialize)] +struct NewSaleTicketRequest { + amount_icp_e8s: u64, + subaccount: Option<[u8; 32]>, +} + +pub fn exec( + pem: &str, + sns_canister_ids: &SnsCanisterIds, + opts: NewSaleTicketOpts, +) -> AnyhowResult> { + let message = NewSaleTicketRequest { + amount_icp_e8s: opts.amount_icp_e8s, + subaccount: opts.subaccount.map(|sub| sub.0), + }; + let req = sign_ingress_with_request_status_query( + pem, + "new_sale_ticket", + Encode!(&message)?, + TargetCanister::Swap(sns_canister_ids.swap_canister_id.get().0), + )?; + Ok(vec![req]) +} diff --git a/tests/commands/new-sale-ticket.sh b/tests/commands/new-sale-ticket.sh new file mode 100644 index 0000000..243bdb9 --- /dev/null +++ b/tests/commands/new-sale-ticket.sh @@ -0,0 +1 @@ +${CARGO_TARGET_DIR:-../target}/debug/sns-quill --canister-ids-file ./canister_ids.json --pem-file - new-sale-ticket --amount-icp-e8s 100000 --subaccount e000d80101 | ${CARGO_TARGET_DIR:-../target}/debug/sns-quill send --dry-run - diff --git a/tests/outputs/new-sale-ticket.txt b/tests/outputs/new-sale-ticket.txt new file mode 100644 index 0000000..ed5e0c5 --- /dev/null +++ b/tests/outputs/new-sale-ticket.txt @@ -0,0 +1,12 @@ +Sending message with + + Call type: update + Sender: fdsgv-62ihb-nbiqv-xgic5-iefsv-3cscz-tmbzv-63qd5-vh43v-dqfrt-pae + Canister id: rkp4c-7iaaa-aaaaa-aaaca-cai + Method name: new_sale_ticket + Arguments: ( + record { + subaccount = opt blob "\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\e0\00\d8\01\01"; + amount_icp_e8s = 100_000 : nat64; + }, +) From 126183d2237c56bc7f52020aa199a300fac1a8f1 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Tue, 24 Jan 2023 16:32:23 -0500 Subject: [PATCH 05/11] handle new-ssale-ticket response --- src/commands/new_sale_ticket.rs | 1 + src/commands/send.rs | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/src/commands/new_sale_ticket.rs b/src/commands/new_sale_ticket.rs index 723fdb6..a161d07 100644 --- a/src/commands/new_sale_ticket.rs +++ b/src/commands/new_sale_ticket.rs @@ -23,6 +23,7 @@ pub struct NewSaleTicketOpts { subaccount: Option, } +// FIXME: use ic_sns_swap when it is available #[derive(candid::CandidType, candid::Deserialize)] struct NewSaleTicketRequest { amount_icp_e8s: u64, diff --git a/src/commands/send.rs b/src/commands/send.rs index 5b65762..6e09b10 100644 --- a/src/commands/send.rs +++ b/src/commands/send.rs @@ -147,6 +147,7 @@ enum SupportedResponse { RefreshBuyerTokens, GetSnsCanistersSummary, GetOpenTicket, + NewSaleTicket, } impl FromStr for SupportedResponse { @@ -162,6 +163,7 @@ impl FromStr for SupportedResponse { "refresh_buyer_tokens" => Ok(SupportedResponse::RefreshBuyerTokens), "get_sns_canisters_summary" => Ok(SupportedResponse::GetSnsCanistersSummary), "get_open_ticket" => Ok(SupportedResponse::GetOpenTicket), + "new-sale-ticket" => Ok(SupportedResponse::NewSaleTicket), unsupported_response => Err(anyhow!( "{} is not a supported response", unsupported_response @@ -206,6 +208,10 @@ fn print_response(blob: Vec, method_name: String) -> AnyhowResult { let response = Decode!(blob.as_slice(), GetOpenTicketResponse)?; println!("Response: {:#?\n}", response); } + SupportedResponse::NewSaleTicket => { + let response = Decode!(blob.as_slice(), NewSaleTicketResponse)?; + println!("Response: {:#?\n}", response); + } } Ok(()) @@ -214,3 +220,7 @@ fn print_response(blob: Vec, method_name: String) -> AnyhowResult { // FIXME: use ic_sns_swap when it is available #[derive(Debug, candid::CandidType, candid::Deserialize)] struct GetOpenTicketResponse {} + +// FIXME: use ic_sns_swap when it is available +#[derive(Debug, candid::CandidType, candid::Deserialize)] +struct NewSaleTicketResponse {} From 05fe9716adf2a5c6e3e6916e7a358549adcd4570 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Wed, 1 Feb 2023 19:24:01 -0500 Subject: [PATCH 06/11] typo --- src/commands/send.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/send.rs b/src/commands/send.rs index 6e09b10..ebec63a 100644 --- a/src/commands/send.rs +++ b/src/commands/send.rs @@ -163,7 +163,7 @@ impl FromStr for SupportedResponse { "refresh_buyer_tokens" => Ok(SupportedResponse::RefreshBuyerTokens), "get_sns_canisters_summary" => Ok(SupportedResponse::GetSnsCanistersSummary), "get_open_ticket" => Ok(SupportedResponse::GetOpenTicket), - "new-sale-ticket" => Ok(SupportedResponse::NewSaleTicket), + "new_sale_ticket" => Ok(SupportedResponse::NewSaleTicket), unsupported_response => Err(anyhow!( "{} is not a supported response", unsupported_response From 9adc993ebbb45fc75d02a946eee2b8ce519fbc6e Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Wed, 1 Feb 2023 19:24:10 -0500 Subject: [PATCH 07/11] update swap.did --- candid/swap.did | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/candid/swap.did b/candid/swap.did index b6a9b29..01f88ee 100644 --- a/candid/swap.did +++ b/candid/swap.did @@ -34,8 +34,8 @@ type Err = record { description : opt text; error_type : opt int32 }; type Err_1 = record { error_type : opt int32 }; type Err_2 = record { invalid_user_amount : opt InvalidUserAmount; - allowance_icp_e8s : opt nat64; - error_type : opt int32; + existing_ticket : opt Ticket; + error_type : int32; }; type ErrorRefundIcpRequest = record { source_principal_id : opt principal }; type ErrorRefundIcpResponse = record { result : opt Result }; @@ -44,13 +44,13 @@ type FailedUpdate = record { dapp_canister_id : opt principal; }; type FinalizeSwapResponse = record { + set_dapp_controllers_call_result : opt SetDappControllersCallResult; settle_community_fund_participation_result : opt SettleCommunityFundParticipationResult; error_message : opt text; - set_dapp_controllers_result : opt SetDappControllersCallResult; - sns_governance_normal_mode_enabled : opt SetModeCallResult; - sweep_icp : opt SweepResult; - sweep_sns : opt SweepResult; - create_neuron : opt SweepResult; + set_mode_call_result : opt SetModeCallResult; + sweep_icp_result : opt SweepResult; + claim_neuron_result : opt SweepResult; + sweep_sns_result : opt SweepResult; }; type GetBuyerStateRequest = record { principal_id : opt principal }; type GetBuyerStateResponse = record { buyer_state : opt BuyerState }; @@ -95,7 +95,6 @@ type NewSaleTicketRequest = record { type NewSaleTicketResponse = record { result : opt Result_2 }; type Ok = record { block_height : opt nat64 }; type Ok_1 = record { ticket : opt Ticket }; -type Ok_2 = record { creation_time : nat64; ticket_id : nat64 }; type OpenRequest = record { cf_participants : vec CfParticipant; params : opt Params; @@ -111,12 +110,12 @@ type Params = record { max_participant_icp_e8s : nat64; min_icp_e8s : nat64; }; -type Possibility = variant { Ok : Response; Err : CanisterCallError }; -type Possibility_1 = variant { +type Possibility = variant { Ok : SetDappControllersResponse; Err : CanisterCallError; }; -type Possibility_2 = variant { Err : CanisterCallError }; +type Possibility_1 = variant { Ok : Response; Err : CanisterCallError }; +type Possibility_2 = variant { Ok : record {}; Err : CanisterCallError }; type RefreshBuyerTokensRequest = record { buyer : text }; type RefreshBuyerTokensResponse = record { icp_accepted_participation_e8s : nat64; @@ -125,15 +124,16 @@ type RefreshBuyerTokensResponse = record { type Response = record { governance_error : opt GovernanceError }; type Result = variant { Ok : Ok; Err : Err }; type Result_1 = variant { Ok : Ok_1; Err : Err_1 }; -type Result_2 = variant { Ok : Ok_2; Err : Err_2 }; -type SetDappControllersCallResult = record { possibility : opt Possibility_1 }; +type Result_2 = variant { Ok : Ok_1; Err : Err_2 }; +type SetDappControllersCallResult = record { possibility : opt Possibility }; type SetDappControllersResponse = record { failed_updates : vec FailedUpdate }; type SetModeCallResult = record { possibility : opt Possibility_2 }; type SettleCommunityFundParticipationResult = record { - possibility : opt Possibility; + possibility : opt Possibility_1; }; type SnsNeuronRecipe = record { sns : opt TransferableAmount; + claimed_status : opt int32; neuron_attributes : opt NeuronAttributes; investor : opt Investor; }; @@ -147,7 +147,13 @@ type Swap = record { params : opt Params; open_sns_token_swap_proposal_id : opt nat64; }; -type SweepResult = record { failure : nat32; skipped : nat32; success : nat32 }; +type SweepResult = record { + failure : nat32; + skipped : nat32; + invalid : nat32; + success : nat32; + global_failures : nat32; +}; type Ticket = record { creation_time : nat64; ticket_id : nat64; From eced27eec9577f799f312b9f2e3bc47ff6bab6cc Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Wed, 1 Feb 2023 19:38:14 -0500 Subject: [PATCH 08/11] combine into get-sale-ticket --- src/commands/get_open_ticket.rs | 24 ------------------- ...{new_sale_ticket.rs => get_sale_ticket.rs} | 21 +++++++++++----- src/commands/mod.rs | 16 ++++--------- tests/commands/get-open-tocket.sh | 1 - ...{new-sale-ticket.sh => get-sale-ticket.sh} | 2 +- tests/outputs/get-open-tocket.txt | 7 ------ ...ew-sale-ticket.txt => get-sale-ticket.txt} | 7 ++++++ tests/outputs/refund.txt | 2 +- tests/outputs/status.txt | 2 +- 9 files changed, 29 insertions(+), 53 deletions(-) delete mode 100644 src/commands/get_open_ticket.rs rename src/commands/{new_sale_ticket.rs => get_sale_ticket.rs} (66%) delete mode 100644 tests/commands/get-open-tocket.sh rename tests/commands/{new-sale-ticket.sh => get-sale-ticket.sh} (72%) delete mode 100644 tests/outputs/get-open-tocket.txt rename tests/outputs/{new-sale-ticket.txt => get-sale-ticket.txt} (63%) diff --git a/src/commands/get_open_ticket.rs b/src/commands/get_open_ticket.rs deleted file mode 100644 index ecc15ff..0000000 --- a/src/commands/get_open_ticket.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::{ - lib::{ - signing::{sign_ingress_with_request_status_query, IngressWithRequestId}, - AnyhowResult, TargetCanister, - }, - SnsCanisterIds, -}; -use candid::Encode; - -#[derive(candid::CandidType, candid::Deserialize)] -struct GetOpenTicketArg {} - -pub fn exec( - pem: &str, - sns_canister_ids: &SnsCanisterIds, -) -> AnyhowResult> { - let req = sign_ingress_with_request_status_query( - pem, - "get_open_ticket", - Encode!(&GetOpenTicketArg {})?, - TargetCanister::Swap(sns_canister_ids.swap_canister_id.get().0), - )?; - Ok(vec![req]) -} diff --git a/src/commands/new_sale_ticket.rs b/src/commands/get_sale_ticket.rs similarity index 66% rename from src/commands/new_sale_ticket.rs rename to src/commands/get_sale_ticket.rs index a161d07..1430876 100644 --- a/src/commands/new_sale_ticket.rs +++ b/src/commands/get_sale_ticket.rs @@ -10,10 +10,9 @@ use crate::{ SnsCanisterIds, }; -/// Attempts to create a new Ticket for the caller. +/// Get the sale ticket of the caller. If there is no open ticket yet, create a new ticket with specified arguments. #[derive(Parser)] -pub struct NewSaleTicketOpts { - // TODO: check this description +pub struct GetSaleTicketOpts { /// The amount of ICP tokens in e8s. #[clap(long)] amount_icp_e8s: u64, @@ -30,20 +29,30 @@ struct NewSaleTicketRequest { subaccount: Option<[u8; 32]>, } +#[derive(candid::CandidType, candid::Deserialize)] +struct GetOpenTicketArg {} + pub fn exec( pem: &str, sns_canister_ids: &SnsCanisterIds, - opts: NewSaleTicketOpts, + opts: GetSaleTicketOpts, ) -> AnyhowResult> { + let req1 = sign_ingress_with_request_status_query( + pem, + "get_open_ticket", + Encode!(&GetOpenTicketArg {})?, + TargetCanister::Swap(sns_canister_ids.swap_canister_id.get().0), + )?; + let message = NewSaleTicketRequest { amount_icp_e8s: opts.amount_icp_e8s, subaccount: opts.subaccount.map(|sub| sub.0), }; - let req = sign_ingress_with_request_status_query( + let req2 = sign_ingress_with_request_status_query( pem, "new_sale_ticket", Encode!(&message)?, TargetCanister::Swap(sns_canister_ids.swap_canister_id.get().0), )?; - Ok(vec![req]) + Ok(vec![req1, req2]) } diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 83fc784..5f430f0 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -9,13 +9,12 @@ use tokio::runtime::Runtime; mod account_balance; mod configure_dissolve_delay; mod generate; -mod get_open_ticket; mod get_swap_refund; mod list_deployed_snses; mod make_proposal; mod make_upgrade_canister_proposal; mod neuron_permission; -mod new_sale_ticket; +mod get_sale_ticket; mod public; mod qrcode; mod register_vote; @@ -50,10 +49,8 @@ pub enum Command { /// can submit proposals (such as a Motion Proposal) to be voted on by other neuron /// holders. MakeProposal(make_proposal::MakeProposalOpts), - /// Get the open sale ticket for the caller if exist. - GetOpenTicket, GetSwapRefund(get_swap_refund::GetSwapRefundOpts), - NewSaleTicket(new_sale_ticket::NewSaleTicketOpts), + GetSaleTicket(get_sale_ticket::GetSaleTicketOpts), ListDeployedSnses(list_deployed_snses::ListDeployedSnsesOpts), /// Signs a ManageNeuron message to register a vote for a proposal. Registering a vote will /// update the ballot of the given proposal and could trigger followees to vote. When @@ -111,20 +108,15 @@ pub fn exec( let canister_ids = require_canister_ids(sns_canister_ids)?; make_proposal::exec(&pem, &canister_ids, opts).and_then(|out| print_vec(qr, &out)) } - Command::GetOpenTicket => { - let pem = require_pem(private_key_pem)?; - let canister_ids = require_canister_ids(sns_canister_ids)?; - get_open_ticket::exec(&pem, &canister_ids).and_then(|out| print_vec(qr, &out)) - } Command::GetSwapRefund(opts) => { let pem = require_pem(private_key_pem)?; let canister_ids = require_canister_ids(sns_canister_ids)?; get_swap_refund::exec(&pem, &canister_ids, opts).and_then(|out| print_vec(qr, &out)) } - Command::NewSaleTicket(opts) => { + Command::GetSaleTicket(opts) => { let pem = require_pem(private_key_pem)?; let canister_ids = require_canister_ids(sns_canister_ids)?; - new_sale_ticket::exec(&pem, &canister_ids, opts).and_then(|out| print_vec(qr, &out)) + get_sale_ticket::exec(&pem, &canister_ids, opts).and_then(|out| print_vec(qr, &out)) } Command::ListDeployedSnses(opts) => { runtime.block_on(async { list_deployed_snses::exec(opts).await }) diff --git a/tests/commands/get-open-tocket.sh b/tests/commands/get-open-tocket.sh deleted file mode 100644 index c597d03..0000000 --- a/tests/commands/get-open-tocket.sh +++ /dev/null @@ -1 +0,0 @@ -${CARGO_TARGET_DIR:-../target}/debug/sns-quill --canister-ids-file ./canister_ids.json --pem-file - get-open-ticket | ${CARGO_TARGET_DIR:-../target}/debug/sns-quill send --dry-run - diff --git a/tests/commands/new-sale-ticket.sh b/tests/commands/get-sale-ticket.sh similarity index 72% rename from tests/commands/new-sale-ticket.sh rename to tests/commands/get-sale-ticket.sh index 243bdb9..5f5a238 100644 --- a/tests/commands/new-sale-ticket.sh +++ b/tests/commands/get-sale-ticket.sh @@ -1 +1 @@ -${CARGO_TARGET_DIR:-../target}/debug/sns-quill --canister-ids-file ./canister_ids.json --pem-file - new-sale-ticket --amount-icp-e8s 100000 --subaccount e000d80101 | ${CARGO_TARGET_DIR:-../target}/debug/sns-quill send --dry-run - +${CARGO_TARGET_DIR:-../target}/debug/sns-quill --canister-ids-file ./canister_ids.json --pem-file - get-sale-ticket --amount-icp-e8s 100000 --subaccount e000d80101 | ${CARGO_TARGET_DIR:-../target}/debug/sns-quill send --dry-run - diff --git a/tests/outputs/get-open-tocket.txt b/tests/outputs/get-open-tocket.txt deleted file mode 100644 index fc66fed..0000000 --- a/tests/outputs/get-open-tocket.txt +++ /dev/null @@ -1,7 +0,0 @@ -Sending message with - - Call type: update - Sender: fdsgv-62ihb-nbiqv-xgic5-iefsv-3cscz-tmbzv-63qd5-vh43v-dqfrt-pae - Canister id: rkp4c-7iaaa-aaaaa-aaaca-cai - Method name: get_open_ticket - Arguments: (record {}) diff --git a/tests/outputs/new-sale-ticket.txt b/tests/outputs/get-sale-ticket.txt similarity index 63% rename from tests/outputs/new-sale-ticket.txt rename to tests/outputs/get-sale-ticket.txt index ed5e0c5..5b8d7e7 100644 --- a/tests/outputs/new-sale-ticket.txt +++ b/tests/outputs/get-sale-ticket.txt @@ -1,5 +1,12 @@ Sending message with + Call type: update + Sender: fdsgv-62ihb-nbiqv-xgic5-iefsv-3cscz-tmbzv-63qd5-vh43v-dqfrt-pae + Canister id: rkp4c-7iaaa-aaaaa-aaaca-cai + Method name: get_open_ticket + Arguments: (record {}) +Sending message with + Call type: update Sender: fdsgv-62ihb-nbiqv-xgic5-iefsv-3cscz-tmbzv-63qd5-vh43v-dqfrt-pae Canister id: rkp4c-7iaaa-aaaaa-aaaca-cai diff --git a/tests/outputs/refund.txt b/tests/outputs/refund.txt index 173b687..eb7d64d 100644 --- a/tests/outputs/refund.txt +++ b/tests/outputs/refund.txt @@ -8,4 +8,4 @@ Sending message with record { source_principal_id = opt principal "fdsgv-62ihb-nbiqv-xgic5-iefsv-3cscz-tmbzv-63qd5-vh43v-dqfrt-pae"; }, -) \ No newline at end of file +) diff --git a/tests/outputs/status.txt b/tests/outputs/status.txt index b784c38..822fdd5 100644 --- a/tests/outputs/status.txt +++ b/tests/outputs/status.txt @@ -4,4 +4,4 @@ Sending message with Sender: 2vxsx-fae Canister id: r7inp-6aaaa-aaaaa-aaabq-cai Method name: get_sns_canisters_summary - Arguments: (record { update_canister_list = null }) \ No newline at end of file + Arguments: (record { update_canister_list = null }) From 3acd073a10488a79fceaf9e9931f0386dc5da103 Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Wed, 1 Feb 2023 19:41:00 -0500 Subject: [PATCH 09/11] fmt --- src/commands/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 5f430f0..96f96e7 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -9,12 +9,12 @@ use tokio::runtime::Runtime; mod account_balance; mod configure_dissolve_delay; mod generate; +mod get_sale_ticket; mod get_swap_refund; mod list_deployed_snses; mod make_proposal; mod make_upgrade_canister_proposal; mod neuron_permission; -mod get_sale_ticket; mod public; mod qrcode; mod register_vote; From 7d7f9b838bd0d60d606ea99d8f9b66e483d4456b Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Wed, 1 Feb 2023 19:51:18 -0500 Subject: [PATCH 10/11] mark todo with jira ticket --- src/commands/get_sale_ticket.rs | 2 +- src/commands/send.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/commands/get_sale_ticket.rs b/src/commands/get_sale_ticket.rs index 1430876..2d54eb1 100644 --- a/src/commands/get_sale_ticket.rs +++ b/src/commands/get_sale_ticket.rs @@ -22,7 +22,7 @@ pub struct GetSaleTicketOpts { subaccount: Option, } -// FIXME: use ic_sns_swap when it is available +// TODO: SDK-954 - use ic_sns_swap when it is available #[derive(candid::CandidType, candid::Deserialize)] struct NewSaleTicketRequest { amount_icp_e8s: u64, diff --git a/src/commands/send.rs b/src/commands/send.rs index ebec63a..57e7808 100644 --- a/src/commands/send.rs +++ b/src/commands/send.rs @@ -217,10 +217,10 @@ fn print_response(blob: Vec, method_name: String) -> AnyhowResult { Ok(()) } -// FIXME: use ic_sns_swap when it is available +// TODO: SDK-954 - use ic_sns_swap when it is available #[derive(Debug, candid::CandidType, candid::Deserialize)] struct GetOpenTicketResponse {} -// FIXME: use ic_sns_swap when it is available +// TODO: SDK-954 - use ic_sns_swap when it is available #[derive(Debug, candid::CandidType, candid::Deserialize)] struct NewSaleTicketResponse {} From 87f6c0c9f9d6dc8bb678b96e82c4cce43d6f181e Mon Sep 17 00:00:00 2001 From: Linwei Shang Date: Wed, 1 Feb 2023 19:59:47 -0500 Subject: [PATCH 11/11] doc help --- src/commands/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 96f96e7..a17e28b 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -50,6 +50,7 @@ pub enum Command { /// holders. MakeProposal(make_proposal::MakeProposalOpts), GetSwapRefund(get_swap_refund::GetSwapRefundOpts), + /// Get the sale ticket of the caller. If there is no open ticket yet, create a new ticket with specified arguments. GetSaleTicket(get_sale_ticket::GetSaleTicketOpts), ListDeployedSnses(list_deployed_snses::ListDeployedSnsesOpts), /// Signs a ManageNeuron message to register a vote for a proposal. Registering a vote will