diff --git a/CHANGELOG.md b/CHANGELOG.md index 06b8c074..5979cb23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +- Added option to print DFN address for Genesis investors. (#184) + ## [0.4.1] - 2023-03-23 - Added release binaries for linux-gnu in addition to linux-musl on amd64. diff --git a/Cargo.lock b/Cargo.lock index a219d2c6..4457f39d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -977,9 +977,9 @@ dependencies = [ [[package]] name = "digest" -version = "0.10.3" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2fb860ca6fafa5552fb6d0e816a69c8e49f0908bf524e30a90d97c85892d506" +checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.2", "crypto-common", @@ -1049,7 +1049,7 @@ dependencies = [ "base16ct", "crypto-bigint", "der", - "digest 0.10.3", + "digest 0.10.6", "ff", "generic-array", "group", @@ -1447,7 +1447,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", ] [[package]] @@ -3432,7 +3432,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", ] [[package]] @@ -3739,6 +3739,7 @@ dependencies = [ "serde_bytes", "serde_cbor", "serde_json", + "sha3", "simple_asn1", "tempfile", "tiny-bip39", @@ -3956,7 +3957,7 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1facec54cb5e0dc08553501fa740091086d0259ad0067e0d4103448e4cb22ed3" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", ] [[package]] @@ -4299,16 +4300,16 @@ checksum = "cf9db03534dff993187064c4e0c05a5708d2a9728ace9a8959b77bedf415dac5" dependencies = [ "cfg-if 1.0.0", "cpufeatures", - "digest 0.10.3", + "digest 0.10.6", ] [[package]] name = "sha3" -version = "0.10.2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a31480366ec990f395a61b7c08122d99bd40544fdb5abcfc1b06bb29994312c" +checksum = "bdf0c33fae925bdc080598b84bc15c55e7b9a4a43b3c704da051f977469691c9" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", "keccak", ] @@ -4327,7 +4328,7 @@ version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" dependencies = [ - "digest 0.10.3", + "digest 0.10.6", "rand_core 0.6.3", ] diff --git a/Cargo.toml b/Cargo.toml index 55885b10..863dc969 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,6 +54,7 @@ crc32fast = "1.3.2" data-encoding = "2.3.3" itertools = "0.10.5" atty = "0.2.14" +sha3 = "0.10.6" [dev-dependencies] tempfile = "3.3.0" diff --git a/docs/cli-reference/quill-public-ids.md b/docs/cli-reference/quill-public-ids.md index e009b4cb..6d91ed8d 100644 --- a/docs/cli-reference/quill-public-ids.md +++ b/docs/cli-reference/quill-public-ids.md @@ -12,9 +12,10 @@ quill public-ids [option] ## Flags -| Flag | Description | -|----------------|-----------------------------| -| `-h`, `--help` | Displays usage information. | +| Flag | Description | +|-----------------|----------------------------------------------------------------| +| `-h`, `--help` | Displays usage information. | +| `--genesis-dfn` | Additionally prints the legacy DFN address for Genesis claims. | ## Options diff --git a/src/commands/public.rs b/src/commands/public.rs index 14c6796d..82545429 100644 --- a/src/commands/public.rs +++ b/src/commands/public.rs @@ -1,8 +1,10 @@ use crate::lib::{get_account_id, get_identity, AnyhowResult, AuthInfo}; -use anyhow::anyhow; +use anyhow::{anyhow, bail, Context}; use candid::Principal; use clap::Parser; use icp_ledger::AccountIdentifier; +use k256::{elliptic_curve::sec1::ToEncodedPoint, SecretKey}; +use sha3::{Digest, Keccak256}; #[derive(Parser)] /// Prints the principal id and the account id. @@ -10,22 +12,31 @@ pub struct PublicOpts { /// Principal for which to get the account_id. #[clap(long)] principal_id: Option, + /// Additionally prints the legacy DFN address for Genesis claims. + #[clap(long, conflicts_with = "principal-id")] + genesis_dfn: bool, } /// Prints the account and the principal ids. pub fn exec(auth: &AuthInfo, opts: PublicOpts) -> AnyhowResult { - let (principal_id, account_id) = get_public_ids(auth, opts)?; + let (principal_id, account_id) = get_public_ids(auth, &opts)?; println!("Principal id: {}", principal_id.to_text()); println!("Account id: {}", account_id); + if opts.genesis_dfn { + let AuthInfo::PemFile(pem) = auth else { + bail!("Must supply a pem or seed file for the DFN address"); + }; + println!("DFN address: {}", get_dfn(pem)?) + } Ok(()) } /// Returns the account id and the principal id if the private key was provided. fn get_public_ids( auth: &AuthInfo, - opts: PublicOpts, + opts: &PublicOpts, ) -> AnyhowResult<(Principal, AccountIdentifier)> { - match opts.principal_id { + match &opts.principal_id { Some(principal_id) => { let principal_id = Principal::from_text(principal_id)?; Ok((principal_id, get_account_id(principal_id)?)) @@ -42,6 +53,14 @@ fn get_public_ids( } } +fn get_dfn(pem: &str) -> AnyhowResult { + let pk = SecretKey::from_sec1_pem(pem).context("DFN addresses need a secp256k1 key")?; + let pubk = pk.public_key(); + let uncompressed = pubk.to_encoded_point(false); + let hash = Keccak256::digest(&uncompressed.as_bytes()[1..]); + Ok(hex::encode(&hash[12..])) +} + /// Returns the account id and the principal id if the private key was provided. pub fn get_ids(auth: &AuthInfo) -> AnyhowResult<(Principal, AccountIdentifier)> { let principal_id = get_identity(auth)?.sender().map_err(|e| anyhow!(e))?; diff --git a/tests/commands/public-ids-dfn.sh b/tests/commands/public-ids-dfn.sh new file mode 100755 index 00000000..491fac2d --- /dev/null +++ b/tests/commands/public-ids-dfn.sh @@ -0,0 +1 @@ +"$QUILL" public-ids --genesis-dfn --seed-file - <<<"fee tube anger harsh pipe pull since path erase hire ordinary display" diff --git a/tests/outputs/public-ids-dfn.txt b/tests/outputs/public-ids-dfn.txt new file mode 100644 index 00000000..f0002f57 --- /dev/null +++ b/tests/outputs/public-ids-dfn.txt @@ -0,0 +1,3 @@ +Principal id: ed6vu-jnldn-5wync-3xnlm-jzlg2-5kjds-iqbcj-5pjgi-jhbw3-qawnx-eae +Account id: 2adf562a6232efe3a3934880edb092ae481651fc961a61d845797d762f437fbd +DFN address: bfcc18caabb2b3ca17c50c0d3834e368c4e4b88f