Skip to content

Commit

Permalink
feat: support the new sns sale payment flow for the ticketing system (#…
Browse files Browse the repository at this point in the history
…156)

* update deps

* sns new_sale_ticket

* test

* rename to pay

* more args in pay

* doc sns pay

* doc new-sale-ticket

* changelog

* fmt

* remove --ticket-creation-time

* fix test

* fix typos
  • Loading branch information
lwshang authored Feb 9, 2023
1 parent 1356154 commit 6c2b6ee
Show file tree
Hide file tree
Showing 17 changed files with 331 additions and 166 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- ckBTC commands and support. (#153)
- SNS commands and support (replaces sns-quill). (#154)
- Support the new sns sale payment flow for the ticketing system. (#156)

## [0.3.2] - 2023-01-13

Expand Down
160 changes: 76 additions & 84 deletions Cargo.lock

Large diffs are not rendered by default.

26 changes: 13 additions & 13 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@ flate2 = "1.0.22"
hex = {version = "0.4.2", features = ["serde"] }
ic-agent = "0.21.0"
ic-identity-hsm = "0.21.0"
ic-base-types = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-ckbtc-minter = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-icrc1 = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-nervous-system-common = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-nns-common = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-nns-constants = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-nns-governance = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-sns-governance = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-sns-root = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-sns-swap = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-sns-wasm = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ic-base-types = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-ckbtc-minter = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-icrc1 = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-nervous-system-common = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-nns-common = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-nns-constants = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-nns-governance = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-sns-governance = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-sns-root = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-sns-swap = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-sns-wasm = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ic-types = "0.4.1"
icp-ledger = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
ledger-canister = { git = "https://github.com/dfinity/ic", rev = "0fc243cb16fbe9d45fd39b0bc6bd7a30dfc0aa77" }
icp-ledger = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
ledger-canister = { git = "https://github.com/dfinity/ic", rev = "1ce7e5b0bd68760382eb2b3b810a11bd600770be" }
num-bigint = "0.4.3"
openssl = "0.10.45"
pem = "1.0.1"
Expand Down
100 changes: 87 additions & 13 deletions candid/sns-swap.did
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,26 @@ 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;
existing_ticket : opt Ticket;
error_type : int32;
};
type ErrorRefundIcpRequest = record { source_principal_id : opt principal };
type ErrorRefundIcpResponse = record { result : opt Result };
type FailedUpdate = record {
err : opt CanisterCallError;
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 };
Expand All @@ -54,9 +60,15 @@ type GetDerivedStateResponse = record {
buyer_total_icp_e8s : opt nat64;
};
type GetInitResponse = record { init : opt Init };
type GetLifecycleResponse = record { lifecycle : opt int32 };
type GetLifecycleResponse = record {
decentralization_sale_open_timestamp_seconds : opt nat64;
lifecycle : opt int32;
};
type GetOpenTicketResponse = record { result : opt Result_1 };
type GetSaleParametersResponse = record { params : opt Params };
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;
Expand All @@ -67,16 +79,45 @@ 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;
};
type ListCommunityFundParticipantsRequest = record {
offset : opt nat64;
limit : opt nat32;
};
type ListCommunityFundParticipantsResponse = record {
cf_participants : vec CfParticipant;
};
type ListDirectParticipantsRequest = record {
offset : opt nat32;
limit : opt nat32;
};
type ListDirectParticipantsResponse = record { participants : vec Participant };
type ListSnsNeuronRecipesRequest = record {
offset : opt nat64;
limit : opt nat32;
};
type ListSnsNeuronRecipesResponse = record {
sns_neuron_recipes : vec SnsNeuronRecipe;
};
type NeuronAttributes = record { dissolve_delay_seconds : nat64; memo : nat64 };
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 OpenRequest = record {
cf_participants : vec CfParticipant;
params : opt Params;
Expand All @@ -89,35 +130,44 @@ type Params = record {
swap_due_timestamp_seconds : nat64;
min_participants : nat32;
sns_token_e8s : nat64;
sale_delay_seconds : opt nat64;
max_participant_icp_e8s : nat64;
min_icp_e8s : nat64;
};
type Possibility = variant { Ok : Response; Err : CanisterCallError };
type Possibility_1 = variant {
type Participant = record {
participation : opt BuyerState;
participant_id : opt principal;
};
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;
icp_ledger_account_balance_e8s : nat64;
};
type Response = record { governance_error : opt GovernanceError };
type Result = variant { Ok : Ok; Err : Err };
type SetDappControllersCallResult = record { possibility : opt Possibility_1 };
type Result_1 = variant { Ok : Ok_1; Err : Err_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;
};
type Swap = record {
neuron_recipes : vec SnsNeuronRecipe;
decentralization_sale_open_timestamp_seconds : opt nat64;
finalize_swap_in_progress : opt bool;
cf_participants : vec CfParticipant;
init : opt Init;
Expand All @@ -126,7 +176,19 @@ 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;
account : opt Icrc1Account;
amount_icp_e8s : nat64;
};
type TransferableAmount = record {
transfer_start_timestamp_seconds : nat64;
amount_e8s : nat64;
Expand All @@ -141,10 +203,22 @@ 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_sale_parameters : (record {}) -> (GetSaleParametersResponse) query;
get_state : (record {}) -> (GetStateResponse) query;
list_community_fund_participants : (ListCommunityFundParticipantsRequest) -> (
ListCommunityFundParticipantsResponse,
) query;
list_direct_participants : (ListDirectParticipantsRequest) -> (
ListDirectParticipantsResponse,
) query;
list_sns_neuron_recipes : (ListSnsNeuronRecipesRequest) -> (
ListSnsNeuronRecipesResponse,
) query;
new_sale_ticket : (NewSaleTicketRequest) -> (NewSaleTicketResponse);
open : (OpenRequest) -> (record {});
refresh_buyer_tokens : (RefreshBuyerTokensRequest) -> (
RefreshBuyerTokensResponse,
);
restore_dapp_controllers : (record {}) -> (SetDappControllersCallResult);
}
}
3 changes: 2 additions & 1 deletion docs/cli-reference/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ When you have quill installed, you can use the following commands to specify the
- [quill sns make-proposal](./sns/quill-sns-make-proposal.md)
- [quill sns make-upgrade-canister-proposal](./sns/quill-sns-make-upgrade-canister-proposal.md)
- [quill sns neuron-permission](./sns/quill-sns-neuron-permission.md)
- [quill sns new-sale-ticket](./sns/quill-sns-new-sale-ticket.md)
- [quill sns pay](./sns/quill-sns-pay.md)
- [quill sns register-vote](./sns/quill-sns-register-vote.md)
- [quill sns stake-maturity](./sns/quill-sns-stake-maturity.md)
- [quill sns stake-neuron](./sns/quill-sns-stake-neuron.md)
- [quill sns status](./sns/quill-sns-status.md)
- [quill sns swap](./sns/quill-sns-swap.md)
- [quill sns transfer](./sns/quill-sns-transfer.md)
- [quill transfer](./quill-transfer.md)
- [quill update-node-provider](./quill-update-node-provider.md)
25 changes: 25 additions & 0 deletions docs/cli-reference/sns/quill-sns-new-sale-ticket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# quill sns new-sale-ticket

Attempt to create a new sale ticket. If there is already an open ticket, it will return the details of the existing ticket.


## Basic usage

The basic syntax for running `quill sns new-sale-ticket` commands is:

```bash
quill sns new-sale-ticket --amount-icp-e8s <AMOUNT_ICP_E8S> [option]
```

## Flags

| Flag | Description |
|-----------------|-----------------------------|
| `-h`, `--help` | Displays usage information. |

## Options

| Option | Description |
|-----------------------------|-----------------------------------------------------------|
| `--amount-icp-e8s <AMOUNT>` | The amount of ICP tokens to participate in this sns sale. |
| `--subaccount <SUBACCOUNT>` | The subaccount you will use to pay for this ticket. |
38 changes: 38 additions & 0 deletions docs/cli-reference/sns/quill-sns-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# quill sns pay

Signs messages to pay for an open sale ticket that you can create using `quill sns new-sale-ticket`.

This operation consists of two messages:

First, transfer ICP to the sale canister on the NNS ledger, under the subaccount for your principal.

Second, the sale canister is notified that the transfer has been made.

## Basic usage

The basic syntax for running `quill sns pay` commands is:

```bash
quill sns pay --amount-icp-e8s <AMOUNT_ICP_E8S> --ticket-id <TICKET_ID> [option]
```

## Flags

| Flag | Description |
|-----------------|-----------------------------|
| `-h`, `--help` | Displays usage information. |
| `--notify-only` | No transfer will be made. |

## Options

| Option | Description |
|-------------------------------------------------|---------------------------------------|
| `--amount-icp-e8s <AMOUNT>` | The amount of ICP to transfer. |
| `--subaccount <SUBACCOUNT>` | Pay from this subaccount. |
| `--ticket-id` | The ticket_id of the sale ticket. |

## Remarks

Once the pay has been finalized, if it was successful, you will receive your neurons automatically. Your neuron's share of the governance tokens at sale finalization will be proportional to your share of the contributed ICP.

If `--notify-only` is specified, only the notification message will be generated. This is useful if there was an error previously submitting the notification which you have since rectified, or if you have made the transfer with another tool.
31 changes: 0 additions & 31 deletions docs/cli-reference/sns/quill-sns-swap.md

This file was deleted.

14 changes: 10 additions & 4 deletions src/commands/sns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ mod list_deployed_snses;
mod make_proposal;
mod make_upgrade_canister_proposal;
mod neuron_permission;
mod new_sale_ticket;
mod pay;
mod register_vote;
mod stake_maturity;
mod stake_neuron;
mod status;
mod swap;
mod transfer;

/// Commands for interacting with a Service Nervous System's Ledger & Governance canisters.
Expand Down Expand Up @@ -58,11 +59,12 @@ pub enum SnsCommand {
MakeProposal(make_proposal::MakeProposalOpts),
MakeUpgradeCanisterProposal(make_upgrade_canister_proposal::MakeUpgradeCanisterProposalOpts),
NeuronPermission(neuron_permission::NeuronPermissionOpts),
NewSaleTicket(new_sale_ticket::NewSaleTicketOpts),
RegisterVote(register_vote::RegisterVoteOpts),
StakeMaturity(stake_maturity::StakeMaturityOpts),
StakeNeuron(stake_neuron::StakeNeuronOpts),
Status(status::StatusOpts),
Swap(swap::SwapOpts),
Pay(pay::PayOpts),
Transfer(transfer::TransferOpts),
}

Expand Down Expand Up @@ -95,6 +97,10 @@ pub fn dispatch(auth: &AuthInfo, opts: SnsOpts, qr: bool, fetch_root_key: bool)
let out = neuron_permission::exec(auth, &canister_ids?, opts)?;
print_vec(qr, &out)?;
}
SnsCommand::NewSaleTicket(opts) => {
let out = new_sale_ticket::exec(auth, &canister_ids?, opts)?;
print_vec(qr, &out)?;
}
SnsCommand::RegisterVote(opts) => {
let out = register_vote::exec(auth, &canister_ids?, opts)?;
print_vec(qr, &out)?;
Expand All @@ -108,8 +114,8 @@ pub fn dispatch(auth: &AuthInfo, opts: SnsOpts, qr: bool, fetch_root_key: bool)
print_vec(qr, &out)?;
}
SnsCommand::Status(opts) => status::exec(&canister_ids?, opts, fetch_root_key)?,
SnsCommand::Swap(opts) => {
let out = swap::exec(auth, &canister_ids?, opts)?;
SnsCommand::Pay(opts) => {
let out = pay::exec(auth, &canister_ids?, opts)?;
print_vec(qr, &out)?;
}
SnsCommand::Transfer(opts) => {
Expand Down
Loading

0 comments on commit 6c2b6ee

Please sign in to comment.