Skip to content

Commit 2be4264

Browse files
feat: Support more operations with Ledger (#266)
1 parent 7b80e89 commit 2be4264

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

75 files changed

+634
-88
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## Unreleased
99

10+
- Ledger support has been updated. Ledger devices can now be used to vote and follow, disburse neurons (but not neuron maturity), add hotkeys, and set neuron visibility; as well as stake new neurons or claim them from Genesis, and transfer to all types of NNS accounts.
1011
- Added command for disbursing maturity from neurons, `quill neuron-manage --disburse-maturity`, with optional parameters `--disburse-maturity-percentage` and `--disburse-maturity-to`.
1112
- Updated to rev c7993fa049275b6700df8dfcc02f90d0fca82f24, adding support for the `FulfillSubnetRentalRequest` proposal.
1213
- `--refresh-followers` has been renamed to the more accurate `--refresh-following`.

e2e/assets/sns_canister_ids.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
2-
"governance_canister_id": "rrkah-fqaaa-aaaaa-aaaaq-cai",
3-
"ledger_canister_id": "ryjl3-tyaaa-aaaaa-aaaba-cai",
4-
"root_canister_id": "r7inp-6aaaa-aaaaa-aaabq-cai",
5-
"swap_canister_id": "rkp4c-7iaaa-aaaaa-aaaca-cai"
2+
"governance_canister_id": "zqfso-syaaa-aaaaq-aaafq-cai",
3+
"ledger_canister_id": "zfcdd-tqaaa-aaaaq-aaaga-cai",
4+
"root_canister_id": "zxeu2-7aaaa-aaaaq-aaafa-cai",
5+
"swap_canister_id": "zcdfx-6iaaa-aaaaq-aaagq-cai"
66
}

src/commands/claim_neurons.rs

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,37 @@ use k256::elliptic_curve::sec1::ToEncodedPoint;
1313
pub struct ClaimNeuronOpts;
1414

1515
pub fn exec(auth: &AuthInfo) -> AnyhowResult<Vec<IngressWithRequestId>> {
16-
if let AuthInfo::K256Key(pk) = auth {
17-
let point = pk.public_key().to_encoded_point(false);
18-
let sig = Encode!(&hex::encode(point.as_bytes()))?;
16+
match auth {
17+
AuthInfo::K256Key(pk) => {
18+
let point = pk.public_key().to_encoded_point(false);
19+
let sig = Encode!(&hex::encode(point.as_bytes()))?;
20+
Ok(vec![sign_ingress_with_request_status_query(
21+
auth,
22+
genesis_token_canister_id(),
23+
ROLE_NNS_GTC,
24+
"claim_neurons",
25+
sig,
26+
)?])
27+
}
28+
#[cfg(feature = "ledger")]
29+
AuthInfo::Ledger => {
30+
use crate::lib::ledger::LedgerIdentity;
31+
use k256::PublicKey;
32+
use pkcs8::DecodePublicKey;
1933

20-
Ok(vec![sign_ingress_with_request_status_query(
21-
auth,
22-
genesis_token_canister_id(),
23-
ROLE_NNS_GTC,
24-
"claim_neurons",
25-
sig,
26-
)?])
27-
} else {
28-
Err(anyhow!(
34+
let point = PublicKey::from_public_key_der(&LedgerIdentity::new()?.public_key()?.1)?
35+
.to_encoded_point(false);
36+
let sig = Encode!(&hex::encode(point.as_bytes()))?;
37+
Ok(vec![sign_ingress_with_request_status_query(
38+
auth,
39+
genesis_token_canister_id(),
40+
ROLE_NNS_GTC,
41+
"claim_neurons",
42+
sig,
43+
)?])
44+
}
45+
_ => Err(anyhow!(
2946
"claim-neurons command requires --pem-file to be specified"
30-
))
47+
)),
3148
}
3249
}

src/commands/neuron_manage.rs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,13 +167,11 @@ enum NativeVisibility {
167167
pub fn exec(auth: &AuthInfo, opts: ManageOpts) -> AnyhowResult<Vec<IngressWithRequestId>> {
168168
if opts.ledger {
169169
ensure!(
170-
opts.add_hot_key.is_none() && opts.remove_hot_key.is_none() && !opts.disburse && opts.disburse_amount.is_none() && opts.disburse_to.is_none()
171-
&& !opts.clear_manage_neuron_followees && !opts.join_community_fund && !opts.leave_community_fund
172-
&& opts.follow_topic.is_none() && opts.follow_neurons.is_none() && opts.register_vote.is_none() && !opts.reject
173-
&& opts.set_visibility.is_none() && !opts.refresh_following,
170+
!opts.disburse_maturity && opts.disburse_maturity_to.is_none()
171+
&& opts.disburse_maturity_percentage.is_none(),
174172
"\
175-
Cannot use --ledger with these flags. This version of quill only supports the following neuron-manage operations with a Ledger device:
176-
--additional-dissolve-delay-seconds, --start-dissolving, --stop-dissolving, --split, --merge-from-neuron, --spawn, --stake-maturity, --auto-stake-maturity"
173+
Cannot use --ledger with these flags. This version of quill does not support the --disburse-maturity, --disburse-maturity-to, \
174+
or --disburse-maturity-percentage flags with a Ledger device"
177175
);
178176
}
179177
let mut msgs = Vec::new();

src/commands/neuron_stake.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::{
66
AnyhowResult, AuthInfo, ParsedNnsAccount, ParsedSubaccount, ROLE_NNS_GOVERNANCE,
77
},
88
};
9-
use anyhow::{anyhow, ensure};
9+
use anyhow::anyhow;
1010
use candid::{Encode, Principal};
1111
use clap::Parser;
1212
use ic_nns_constants::GOVERNANCE_CANISTER_ID;
@@ -57,10 +57,6 @@ pub struct StakeOpts {
5757
}
5858

5959
pub fn exec(auth: &AuthInfo, opts: StakeOpts) -> AnyhowResult<Vec<IngressWithRequestId>> {
60-
ensure!(
61-
!opts.ledger,
62-
"Cannot use `--ledger` with this command. This version of Quill does not support staking new neurons with a Ledger device"
63-
);
6460
let controller = crate::lib::get_principal(auth)?;
6561
let nonce = match (&opts.nonce, &opts.name) {
6662
(Some(nonce), _) => *nonce,

src/lib/ledger.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ pub fn supported_transaction(canister_id: &Principal, method_name: &str) -> bool
266266
|| method_name == "list_neurons_pb"
267267
|| method_name == "update_node_provider"
268268
} else if *canister_id == ledger_canister_id() {
269-
method_name == "send_pb" || method_name == "icrc1_transfer"
269+
method_name == "send_pb" || method_name == "icrc1_transfer" || method_name == "transfer"
270270
} else {
271271
method_name == "icrc1_transfer"
272272
|| method_name == "manage_neuron"

tests/output/ckbtc.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ use crate::{
33
PRINCIPAL,
44
};
55

6-
ledger_compatible![balance, withdrawal_address, transfer];
6+
ledger_compatible![
7+
balance,
8+
withdrawal_address,
9+
transfer,
10+
// update_balance,
11+
// retrieve_btc
12+
];
713

814
#[test]
915
fn balance() {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Error: Cannot use `--ledger` with this command. This version of Quill does not support staking new neurons with a Ledger device
1+
Error: Cannot use --ledger with this command. This version of Quill only supports transfers and certain neuron management operations with a Ledger device
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
Error: Cannot use --ledger with these flags. This version of quill only supports the following neuron-manage operations with a Ledger device:
2-
--additional-dissolve-delay-seconds, --start-dissolving, --stop-dissolving, --split, --merge-from-neuron, --spawn, --stake-maturity, --auto-stake-maturity
1+
Error: Cannot use --ledger with these flags. This version of quill does not support the --disburse-maturity, --disburse-maturity-to, or --disburse-maturity-percentage flags with a Ledger device

tests/output/default/sns/balance/simple.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Sending message with
22

33
Call type: update
44
Sender: 2vxsx-fae
5-
Canister id: ryjl3-tyaaa-aaaaa-aaaba-cai
5+
Canister id: zfcdd-tqaaa-aaaaq-aaaga-cai
66
Method name: icrc1_balance_of
77
Arguments: (
88
record {

0 commit comments

Comments
 (0)