diff --git a/CHANGELOG.md b/CHANGELOG.md index 374242d896..e1e3370903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,22 @@ ### fix: Only kill main process on `dfx stop` Removes misleading panics when running `dfx stop`. +### feat: Initialise the nns with an account controlled by a secp256k1 key + +This enables easy access to toy ICP using command line tools and this key: +``` +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEICJxApEbuZznKFpV+VKACRK30i6+7u5Z13/DOl18cIC+oAcGBSuBBAAK +oUQDQgAEPas6Iag4TUx+Uop+3NhE6s3FlayFtbwdhRVjvOar0kPTfE/N8N6btRnd +74ly5xXEBNSXiENyxhEuzOZrIWMCNQ== +-----END EC PRIVATE KEY----- +``` +For example, you can create an identity in dfx by putting this key in the file `ident-1.pem` and importing it: +``` +dfx identity import ident-1 ident-1.pem +dfx --identity ident-1 ledger balance +``` + ### feat: default to run ic-wasm shrink when build canisters This behavior applies to Motoko, Rust and Custom canisters. If you want to disable this behavior, you can config it in dfx.json: diff --git a/e2e/assets/nns/ident-1/identity.pem b/e2e/assets/nns/ident-1/identity.pem new file mode 100644 index 0000000000..0b3a1f3bc5 --- /dev/null +++ b/e2e/assets/nns/ident-1/identity.pem @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MHQCAQEEICJxApEbuZznKFpV+VKACRK30i6+7u5Z13/DOl18cIC+oAcGBSuBBAAK +oUQDQgAEPas6Iag4TUx+Uop+3NhE6s3FlayFtbwdhRVjvOar0kPTfE/N8N6btRnd +74ly5xXEBNSXiENyxhEuzOZrIWMCNQ== +-----END EC PRIVATE KEY----- diff --git a/e2e/tests-dfx/nns.bash b/e2e/tests-dfx/nns.bash index a1ed598d35..19cd597be5 100755 --- a/e2e/tests-dfx/nns.bash +++ b/e2e/tests-dfx/nns.bash @@ -116,7 +116,8 @@ assert_nns_canister_id_matches() { dfx_start_for_nns_install dfx nns install - echo Checking that the install worked... + echo "Checking that the install worked..." + echo " The expected wasms should be installed..." # Note: The installation is quite expensive, so we test extensively on one installation # rather than doing a separate installation for every test. The tests are read-only # so no test should affect the output of another. @@ -145,6 +146,22 @@ assert_nns_canister_id_matches() { wasm_matches internet_identity internet_identity_dev.wasm wasm_matches nns-dapp nns-dapp_local.wasm + echo " Accounts should have funds..." + account_has_funds() { + assert_command dfx ledger balance "$1" + assert_eq "1000000000.00000000 ICP" + } + SECP256K1_ACCOUNT_ID="2b8fbde99de881f695f279d2a892b1137bfe81a42d7694e064b1be58701e1138" + ED25519_ACCOUNT_ID="5b315d2f6702cb3a27d826161797d7b2c2e131cd312aece51d4d5574d1247087" + account_has_funds "$SECP256K1_ACCOUNT_ID" + account_has_funds "$ED25519_ACCOUNT_ID" + + echo " The secp256k1 account can be controlled from the command line" + install_asset nns + dfx identity import --force --disable-encryption ident-1 ident-1/identity.pem + assert_command dfx ledger account-id --identity ident-1 + assert_eq "$SECP256K1_ACCOUNT_ID" + echo Stopping dfx... dfx stop } diff --git a/src/dfx/src/lib/nns/install_nns.rs b/src/dfx/src/lib/nns/install_nns.rs index 5e05bf5189..fbbb11c6ac 100644 --- a/src/dfx/src/lib/nns/install_nns.rs +++ b/src/dfx/src/lib/nns/install_nns.rs @@ -26,6 +26,7 @@ use ic_agent::Agent; use ic_utils::interfaces::management_canister::builders::InstallMode; use ic_utils::interfaces::ManagementCanister; use reqwest::Url; +use std::ffi::OsStr; use std::fs; use std::io::Write; use std::path::Component; @@ -75,7 +76,10 @@ pub async fn install_nns( let ic_nns_init_opts = IcNnsInitOpts { wasm_dir: nns_wasm_dir(env), nns_url: nns_url.to_string(), - test_accounts: Some(canisters::TEST_ACCOUNT.to_string()), + test_accounts: vec![ + canisters::ED25519_TEST_ACCOUNT.to_string(), + canisters::SECP256K1_TEST_ACCOUNT.to_string(), + ], sns_subnets: Some(subnet_id.to_string()), }; ic_nns_init(ic_nns_init_path, &ic_nns_init_opts).await?; @@ -450,7 +454,7 @@ pub struct IcNnsInitOpts { wasm_dir: PathBuf, /// The ID of a test account that ic-nns-init will create and to initialise with tokens. /// Note: At present only one test account is supported. - test_accounts: Option, + test_accounts: Vec, /// A subnet for SNS canisters. /// Note: In this context we support at most one subnet. sns_subnets: Option, @@ -477,6 +481,12 @@ pub async fn ic_nns_init(ic_nns_init_path: &Path, opts: &IcNnsInitOpts) -> anyho cmd.arg("--sns-subnet"); cmd.arg(subnet); }); + let args: Vec<_> = cmd + .get_args() + .into_iter() + .map(OsStr::to_string_lossy) + .collect(); + println!("ic-nns-init {}", args.join(" ")); cmd.stdout(std::process::Stdio::inherit()); cmd.stderr(std::process::Stdio::inherit()); let output = cmd diff --git a/src/dfx/src/lib/nns/install_nns/canisters.rs b/src/dfx/src/lib/nns/install_nns/canisters.rs index a28300b8f4..14115eb6db 100644 --- a/src/dfx/src/lib/nns/install_nns/canisters.rs +++ b/src/dfx/src/lib/nns/install_nns/canisters.rs @@ -189,4 +189,33 @@ pub const SNS_CANISTERS: [&SnsCanisterInstallation; 5] = [ ]; /// Test account with well known public & private keys, used in NNS_LEDGER, NNS_DAPP and third party projects. -pub const TEST_ACCOUNT: &str = "5b315d2f6702cb3a27d826161797d7b2c2e131cd312aece51d4d5574d1247087"; +/// The keys use the ED25519 curve, used for BasicIdentity on th eInternet Computer. +/// The keys are as follows, in the tweetnacl format used by agent-js: +/// ``` +/// const publicKey = "Uu8wv55BKmk9ZErr6OIt5XR1kpEGXcOSOC1OYzrAwuk="; +/// const privateKey = +/// "N3HB8Hh2PrWqhWH2Qqgr1vbU9T3gb1zgdBD8ZOdlQnVS7zC/nkEqaT1kSuvo4i3ldHWSkQZdw5I4LU5jOsDC6Q=="; +/// const identity = Ed25519KeyIdentity.fromKeyPair( +/// base64ToUInt8Array(publicKey), +/// base64ToUInt8Array(privateKey) +/// ); +/// ``` +pub const ED25519_TEST_ACCOUNT: &str = + "5b315d2f6702cb3a27d826161797d7b2c2e131cd312aece51d4d5574d1247087"; + +/// Test account for command line usage. The test account is typically called ident-1 +/// The keys use the secp256k1 curve. To use: +/// ``` +/// $ cat ~/.config/dfx/identity/ident-1/identity.pem +/// -----BEGIN EC PRIVATE KEY----- +/// MHQCAQEEICJxApEbuZznKFpV+VKACRK30i6+7u5Z13/DOl18cIC+oAcGBSuBBAAK +/// oUQDQgAEPas6Iag4TUx+Uop+3NhE6s3FlayFtbwdhRVjvOar0kPTfE/N8N6btRnd +/// 74ly5xXEBNSXiENyxhEuzOZrIWMCNQ== +/// -----END EC PRIVATE KEY----- +/// ``` +/// The test account should match the output of: +/// ``` +/// $ dfx --identity ident-1 ledger account-id +/// ``` +pub const SECP256K1_TEST_ACCOUNT: &str = + "2b8fbde99de881f695f279d2a892b1137bfe81a42d7694e064b1be58701e1138";