From c0ff887505d57770d10508dcb19dfd1358b4f1ce Mon Sep 17 00:00:00 2001 From: Marco Walz Date: Tue, 16 Jun 2026 20:03:41 +0200 Subject: [PATCH] chore: migrate rust/stake_neuron_from_cli to icp-cli Converts the dfx-based CLI binary into an icp-cli canister example. Replaces ic-agent/tokio/clap with ic-cdk inter-canister calls, adds icp.yaml (rust@v3.3.0), Makefile with local compute_subaccount tests, CI workflow, and updated README preserving the educational NNS staking domain knowledge. Co-Authored-By: Claude Sonnet 4.6 --- .../rust-stake-neuron-from-cli-example.yaml | 37 - .github/workflows/stake_neuron_from_cli.yml | 28 + rust/stake_neuron_from_cli/Cargo.lock | 2859 ----------------- rust/stake_neuron_from_cli/Cargo.toml | 22 +- rust/stake_neuron_from_cli/Makefile | 24 + rust/stake_neuron_from_cli/README.md | 133 +- rust/stake_neuron_from_cli/backend/Cargo.toml | 14 + rust/stake_neuron_from_cli/backend/lib.rs | 257 ++ rust/stake_neuron_from_cli/dfx.json | 17 - rust/stake_neuron_from_cli/icp.yaml | 8 + .../stake_neuron_from_cli/rust-toolchain.toml | 2 + rust/stake_neuron_from_cli/setup_and_run.sh | 121 - rust/stake_neuron_from_cli/src/lib.rs | 219 -- rust/stake_neuron_from_cli/src/main.rs | 40 - 14 files changed, 393 insertions(+), 3388 deletions(-) delete mode 100644 .github/workflows/rust-stake-neuron-from-cli-example.yaml create mode 100644 .github/workflows/stake_neuron_from_cli.yml delete mode 100644 rust/stake_neuron_from_cli/Cargo.lock create mode 100644 rust/stake_neuron_from_cli/Makefile create mode 100644 rust/stake_neuron_from_cli/backend/Cargo.toml create mode 100644 rust/stake_neuron_from_cli/backend/lib.rs delete mode 100644 rust/stake_neuron_from_cli/dfx.json create mode 100644 rust/stake_neuron_from_cli/icp.yaml create mode 100644 rust/stake_neuron_from_cli/rust-toolchain.toml delete mode 100755 rust/stake_neuron_from_cli/setup_and_run.sh delete mode 100644 rust/stake_neuron_from_cli/src/lib.rs delete mode 100644 rust/stake_neuron_from_cli/src/main.rs diff --git a/.github/workflows/rust-stake-neuron-from-cli-example.yaml b/.github/workflows/rust-stake-neuron-from-cli-example.yaml deleted file mode 100644 index 8f88e6ff44..0000000000 --- a/.github/workflows/rust-stake-neuron-from-cli-example.yaml +++ /dev/null @@ -1,37 +0,0 @@ -name: rust-stake-neuron-from-cli -on: - push: - branches: - - master - pull_request: - paths: - - rust/stake_neuron_from_cli/** - - .github/workflows/provision-darwin.sh - - .github/workflows/provision-linux.sh - - .github/workflows/rust-stake-neuron-from-cli-example.yaml -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -jobs: - rust-stake-neuron-from-cli-example-darwin: - runs-on: macos-15 - steps: - - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0 - - name: Provision Darwin - run: bash .github/workflows/provision-darwin.sh - - name: Rust Stake Neuron from CLI Darwin - run: | - pushd rust/stake_neuron_from_cli - ./setup_and_run.sh - popd - rust-stake-neuron-from-cli-example-linux: - runs-on: ubuntu-24.04 - steps: - - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e # v1.2.0 - - name: Provision Linux - run: bash .github/workflows/provision-linux.sh - - name: Rust Stake Neuron from CLI Linux - run: | - pushd rust/stake_neuron_from_cli - ./setup_and_run.sh - popd diff --git a/.github/workflows/stake_neuron_from_cli.yml b/.github/workflows/stake_neuron_from_cli.yml new file mode 100644 index 0000000000..4ba1791753 --- /dev/null +++ b/.github/workflows/stake_neuron_from_cli.yml @@ -0,0 +1,28 @@ +name: stake_neuron_from_cli + +on: + push: + branches: [master] + pull_request: + paths: + - rust/stake_neuron_from_cli/** + - .github/workflows/stake_neuron_from_cli.yml + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + rust-stake_neuron_from_cli: + runs-on: ubuntu-24.04 + container: ghcr.io/dfinity/icp-dev-env-rust:1.0.0 + env: + ICP_CLI_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 + - name: Deploy and test + working-directory: rust/stake_neuron_from_cli + run: | + icp network start -d + icp deploy + make test diff --git a/rust/stake_neuron_from_cli/Cargo.lock b/rust/stake_neuron_from_cli/Cargo.lock deleted file mode 100644 index b2f1dccca2..0000000000 --- a/rust/stake_neuron_from_cli/Cargo.lock +++ /dev/null @@ -1,2859 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" - -[[package]] -name = "ahash" -version = "0.8.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" -dependencies = [ - "cfg-if", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - -[[package]] -name = "anstream" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" -dependencies = [ - "anstyle", - "anstyle-parse", - "anstyle-query", - "anstyle-wincon", - "colorchoice", - "is_terminal_polyfill", - "utf8parse", -] - -[[package]] -name = "anstyle" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" - -[[package]] -name = "anstyle-parse" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" -dependencies = [ - "utf8parse", -] - -[[package]] -name = "anstyle-query" -version = "1.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" -dependencies = [ - "windows-sys 0.60.2", -] - -[[package]] -name = "anstyle-wincon" -version = "3.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" -dependencies = [ - "anstyle", - "once_cell_polyfill", - "windows-sys 0.60.2", -] - -[[package]] -name = "anyhow" -version = "1.0.99" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "async-lock" -version = "3.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "autocfg" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" - -[[package]] -name = "backoff" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" -dependencies = [ - "getrandom 0.2.16", - "instant", - "rand 0.8.5", -] - -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - -[[package]] -name = "base64ct" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" - -[[package]] -name = "binread" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16598dfc8e6578e9b597d9910ba2e73618385dc9f4b1d43dd92c349d6be6418f" -dependencies = [ - "binread_derive", - "lazy_static", - "rustversion", -] - -[[package]] -name = "binread_derive" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9672209df1714ee804b1f4d4f68c8eb2a90b1f7a07acf472f88ce198ef1fed" -dependencies = [ - "either", - "proc-macro2", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "bitflags" -version = "2.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34efbcccd345379ca2868b2b2c9d3782e9cc58ba87bc7d79d5b53d9c9ae6f25d" - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "bls12_381" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3c196a77437e7cc2fb515ce413a6401291578b5afc8ecb29a3c7ab957f05941" -dependencies = [ - "digest 0.9.0", - "ff 0.12.1", - "group 0.12.1", - "pairing", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "bumpalo" -version = "3.19.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" - -[[package]] -name = "cached" -version = "0.46.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7c8c50262271cdf5abc979a5f76515c234e764fa025d1ba4862c0f0bcda0e95" -dependencies = [ - "ahash", - "hashbrown", - "instant", - "once_cell", - "thiserror 1.0.69", -] - -[[package]] -name = "candid" -version = "0.10.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eaac522d18020d5fbc8320ecb12a9b13b2137ae31133da2d42fa256a825507c4" -dependencies = [ - "anyhow", - "binread", - "byteorder", - "candid_derive", - "hex", - "ic_principal", - "leb128", - "num-bigint", - "num-traits", - "paste", - "pretty", - "serde", - "serde_bytes", - "stacker", - "thiserror 1.0.69", -] - -[[package]] -name = "candid_derive" -version = "0.10.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a1b4fddbd462182050989068d53604a91a3d0f117c3c8316c6818023df00add" -dependencies = [ - "lazy_static", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "cc" -version = "1.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9" - -[[package]] -name = "cfg_aliases" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" - -[[package]] -name = "clap" -version = "4.5.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c5e4fcf9c21d2e544ca1ee9d8552de13019a42aa7dbf32747fa7aaf1df76e57" -dependencies = [ - "clap_builder", - "clap_derive", -] - -[[package]] -name = "clap_builder" -version = "4.5.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecb53a0e6fcfb055f686001bc2e2592fa527efaf38dbe81a6a9563562e57d41" -dependencies = [ - "anstream", - "anstyle", - "clap_lex", - "strsim", -] - -[[package]] -name = "clap_derive" -version = "4.5.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "clap_lex" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" - -[[package]] -name = "colorchoice" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" - -[[package]] -name = "concurrent-queue" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "cpufeatures" -version = "0.2.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" -dependencies = [ - "libc", -] - -[[package]] -name = "crc32fast" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "curve25519-dalek-ng" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.6.4", - "subtle-ng", - "zeroize", -] - -[[package]] -name = "darling" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.106", -] - -[[package]] -name = "darling_macro" -version = "0.20.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "data-encoding" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" - -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - -[[package]] -name = "digest" -version = "0.10.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" -dependencies = [ - "block-buffer 0.10.4", - "const-oid", - "crypto-common", - "subtle", -] - -[[package]] -name = "displaydoc" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest 0.10.7", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519-consensus" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" -dependencies = [ - "curve25519-dalek-ng", - "hex", - "rand_core 0.6.4", - "serde", - "sha2 0.9.9", - "thiserror 1.0.69", - "zeroize", -] - -[[package]] -name = "either" -version = "1.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" - -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest 0.10.7", - "ff 0.13.1", - "generic-array", - "group 0.13.0", - "pem-rfc7468", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - -[[package]] -name = "event-listener" -version = "5.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener-strategy" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" -dependencies = [ - "event-listener", - "pin-project-lite", -] - -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "ff" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" -dependencies = [ - "percent-encoding", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", - "zeroize", -] - -[[package]] -name = "getrandom" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" -dependencies = [ - "cfg-if", - "js-sys", - "libc", - "r-efi", - "wasi 0.14.3+wasi-0.2.4", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff 0.13.1", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "half" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" - -[[package]] -name = "hashbrown" -version = "0.14.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" -dependencies = [ - "ahash", - "allocator-api2", -] - -[[package]] -name = "heck" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hmac" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" -dependencies = [ - "digest 0.10.7", -] - -[[package]] -name = "http" -version = "1.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http", -] - -[[package]] -name = "http-body-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" -dependencies = [ - "bytes", - "futures-core", - "http", - "http-body", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" - -[[package]] -name = "hyper" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" -dependencies = [ - "atomic-waker", - "bytes", - "futures-channel", - "futures-core", - "http", - "http-body", - "httparse", - "itoa", - "pin-project-lite", - "pin-utils", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" -dependencies = [ - "http", - "hyper", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", - "webpki-roots", -] - -[[package]] -name = "hyper-util" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "hyper", - "ipnet", - "libc", - "percent-encoding", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - -[[package]] -name = "ic-agent" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f08d1b54f1834fb9637a57855f1d87bb9dbec7a9dec09499737580692829cb0" -dependencies = [ - "async-lock", - "backoff", - "cached", - "candid", - "ed25519-consensus", - "futures-util", - "hex", - "http", - "http-body", - "ic-certification", - "ic-transport-types", - "ic-verify-bls-signature", - "k256", - "leb128", - "p256", - "pem", - "pkcs8", - "rand 0.8.5", - "rangemap", - "reqwest", - "ring", - "rustls-webpki 0.101.7", - "sec1", - "serde", - "serde_bytes", - "serde_cbor", - "serde_repr", - "sha2 0.10.9", - "simple_asn1", - "thiserror 1.0.69", - "time", - "tokio", - "url", -] - -[[package]] -name = "ic-cdk" -version = "0.18.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4efb278f5d3ef033b3eed7f01f1096eaf67701896aa5ef69f5eddf5a84833dc0" -dependencies = [ - "candid", - "ic-cdk-executor", - "ic-cdk-macros", - "ic-error-types", - "ic-management-canister-types", - "ic0", - "serde", - "serde_bytes", - "slotmap", - "thiserror 2.0.16", -] - -[[package]] -name = "ic-cdk-executor" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99f4ee8930fd2e491177e2eb7fff53ee1c407c13b9582bdc7d6920cf83109a2d" -dependencies = [ - "ic0", - "slotmap", -] - -[[package]] -name = "ic-cdk-macros" -version = "0.18.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb14c5d691cc9d72bb95459b4761e3a4b3444b85a63d17555d5ddd782969a1e" -dependencies = [ - "candid", - "darling", - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "ic-certification" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64ee3d8b6e81b51f245716d3e0badb63c283c00f3c9fb5d5219afc30b5bf821" -dependencies = [ - "hex", - "serde", - "serde_bytes", - "sha2 0.10.9", -] - -[[package]] -name = "ic-error-types" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbeeb3d91aa179d6496d7293becdacedfc413c825cac79fd54ea1906f003ee55" -dependencies = [ - "serde", - "strum", - "strum_macros", -] - -[[package]] -name = "ic-ledger-types" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "feb52826a353b583012628af6da762b52672350686c3275234febfadeca965ea" -dependencies = [ - "candid", - "crc32fast", - "hex", - "ic-cdk", - "serde", - "serde_bytes", - "sha2 0.10.9", -] - -[[package]] -name = "ic-management-canister-types" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea7e5b8a0f7c3b320d9450ac950547db4f24a31601b5d398f9680b64427455d2" -dependencies = [ - "candid", - "serde", - "serde_bytes", -] - -[[package]] -name = "ic-transport-types" -version = "0.35.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1c68959f501cfcb79319b6720fd1903a661d77b503e6128bfce31f91ad87aca" -dependencies = [ - "candid", - "hex", - "ic-certification", - "leb128", - "serde", - "serde_bytes", - "serde_repr", - "sha2 0.10.9", - "thiserror 1.0.69", -] - -[[package]] -name = "ic-verify-bls-signature" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583b1c03380cf86059160cc6c91dcbf56c7b5f141bf3a4f06bc79762d775fac4" -dependencies = [ - "bls12_381", - "lazy_static", - "pairing", - "sha2 0.9.9", -] - -[[package]] -name = "ic0" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8877193e1921b5fd16accb0305eb46016868cd1935b05c05eca0ec007b943272" - -[[package]] -name = "ic_principal" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1762deb6f7c8d8c2bdee4b6c5a47b60195b74e9b5280faa5ba29692f8e17429c" -dependencies = [ - "crc32fast", - "data-encoding", - "serde", - "sha2 0.10.9", - "thiserror 1.0.69", -] - -[[package]] -name = "icu_collections" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" -dependencies = [ - "displaydoc", - "potential_utf", - "yoke", - "zerofrom", - "zerovec", -] - -[[package]] -name = "icu_locale_core" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" -dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", -] - -[[package]] -name = "icu_normalizer" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_normalizer_data", - "icu_properties", - "icu_provider", - "smallvec", - "zerovec", -] - -[[package]] -name = "icu_normalizer_data" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" - -[[package]] -name = "icu_properties" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" -dependencies = [ - "displaydoc", - "icu_collections", - "icu_locale_core", - "icu_properties_data", - "icu_provider", - "potential_utf", - "zerotrie", - "zerovec", -] - -[[package]] -name = "icu_properties_data" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" - -[[package]] -name = "icu_provider" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" -dependencies = [ - "displaydoc", - "icu_locale_core", - "stable_deref_trait", - "tinystr", - "writeable", - "yoke", - "zerofrom", - "zerotrie", - "zerovec", -] - -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - -[[package]] -name = "idna" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" -dependencies = [ - "idna_adapter", - "smallvec", - "utf8_iter", -] - -[[package]] -name = "idna_adapter" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" -dependencies = [ - "icu_normalizer", - "icu_properties", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-uring" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" -dependencies = [ - "bitflags", - "cfg-if", - "libc", -] - -[[package]] -name = "ipnet" -version = "2.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" - -[[package]] -name = "iri-string" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" -dependencies = [ - "memchr", - "serde", -] - -[[package]] -name = "is_terminal_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" - -[[package]] -name = "itoa" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" - -[[package]] -name = "js-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" -dependencies = [ - "once_cell", - "wasm-bindgen", -] - -[[package]] -name = "k256" -version = "0.13.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" -dependencies = [ - "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", - "sha2 0.10.9", - "signature", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "leb128" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" - -[[package]] -name = "libc" -version = "0.2.175" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" - -[[package]] -name = "litemap" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" - -[[package]] -name = "lock_api" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" -dependencies = [ - "autocfg", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" - -[[package]] -name = "lru-slab" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" - -[[package]] -name = "memchr" -version = "2.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" - -[[package]] -name = "miniz_oxide" -version = "0.8.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" -dependencies = [ - "libc", - "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.21.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" - -[[package]] -name = "once_cell_polyfill" -version = "1.70.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2 0.10.9", -] - -[[package]] -name = "pairing" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "135590d8bdba2b31346f9cd1fb2a912329f5135e832a4f422942eb6ead8b6b3b" -dependencies = [ - "group 0.12.1", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets 0.52.6", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pem" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b13fe415cdf3c8e44518e18a7c95a13431d9bdf6d15367d82b23c377fdd441a" -dependencies = [ - "base64 0.21.7", - "serde", -] - -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - -[[package]] -name = "percent-encoding" -version = "2.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" - -[[package]] -name = "pin-project-lite" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "potential_utf" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" -dependencies = [ - "zerovec", -] - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "pretty" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac98773b7109bc75f475ab5a134c9b64b87e59d776d31098d8f346922396a477" -dependencies = [ - "arrayvec", - "typed-arena", - "unicode-width", -] - -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve", -] - -[[package]] -name = "proc-macro2" -version = "1.0.101" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "psm" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f" -dependencies = [ - "cc", -] - -[[package]] -name = "quinn" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" -dependencies = [ - "bytes", - "cfg_aliases", - "pin-project-lite", - "quinn-proto", - "quinn-udp", - "rustc-hash", - "rustls", - "socket2", - "thiserror 2.0.16", - "tokio", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-proto" -version = "0.11.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1906b49b0c3bc04b5fe5d86a77925ae6524a19b816ae38ce1e426255f1d8a31" -dependencies = [ - "bytes", - "getrandom 0.3.3", - "lru-slab", - "rand 0.9.2", - "ring", - "rustc-hash", - "rustls", - "rustls-pki-types", - "slab", - "thiserror 2.0.16", - "tinyvec", - "tracing", - "web-time", -] - -[[package]] -name = "quinn-udp" -version = "0.5.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "addec6a0dcad8a8d96a771f815f0eaf55f9d1805756410b39f5fa81332574cbd" -dependencies = [ - "cfg_aliases", - "libc", - "once_cell", - "socket2", - "tracing", - "windows-sys 0.60.2", -] - -[[package]] -name = "quote" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "r-efi" -version = "5.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" -dependencies = [ - "rand_chacha 0.9.0", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_chacha" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" -dependencies = [ - "ppv-lite86", - "rand_core 0.9.3", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.16", -] - -[[package]] -name = "rand_core" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" -dependencies = [ - "getrandom 0.3.3", -] - -[[package]] -name = "rangemap" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93e7e49bb0bf967717f7bd674458b3d6b0c5f48ec7e3038166026a69fc22223" - -[[package]] -name = "redox_syscall" -version = "0.5.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" -dependencies = [ - "bitflags", -] - -[[package]] -name = "reqwest" -version = "0.12.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" -dependencies = [ - "base64 0.22.1", - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "http", - "http-body", - "http-body-util", - "hyper", - "hyper-rustls", - "hyper-util", - "js-sys", - "log", - "percent-encoding", - "pin-project-lite", - "quinn", - "rustls", - "rustls-pki-types", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "tokio", - "tokio-rustls", - "tokio-util", - "tower", - "tower-http", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots", -] - -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - -[[package]] -name = "ring" -version = "0.17.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.16", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" - -[[package]] -name = "rustc-hash" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" - -[[package]] -name = "rustls" -version = "0.23.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" -dependencies = [ - "once_cell", - "ring", - "rustls-pki-types", - "rustls-webpki 0.103.4", - "subtle", - "zeroize", -] - -[[package]] -name = "rustls-pki-types" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" -dependencies = [ - "web-time", - "zeroize", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", -] - -[[package]] -name = "rustversion" -version = "1.0.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" - -[[package]] -name = "ryu" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" - -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - -[[package]] -name = "serde" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_bytes" -version = "0.11.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8437fd221bde2d4ca316d61b90e337e9e702b3820b87d63caa9ba6c02bd06d96" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_cbor" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5" -dependencies = [ - "half", - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.219" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "serde_json" -version = "1.0.143" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d401abef1d108fbd9cbaebc3e46611f4b1021f714a0597a71f41ee463f5f4a5a" -dependencies = [ - "itoa", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_repr" -version = "0.1.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "serde_urlencoded" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" -dependencies = [ - "form_urlencoded", - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.10.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" -dependencies = [ - "cfg-if", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] - -[[package]] -name = "simple_asn1" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror 2.0.16", - "time", -] - -[[package]] -name = "slab" -version = "0.4.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" - -[[package]] -name = "slotmap" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbff4acf519f630b3a3ddcfaea6c06b42174d9a44bc70c620e9ed1649d58b82a" -dependencies = [ - "version_check", -] - -[[package]] -name = "smallvec" -version = "1.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" - -[[package]] -name = "socket2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "stable_deref_trait" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" - -[[package]] -name = "stacker" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cddb07e32ddb770749da91081d8d0ac3a16f1a569a18b20348cd371f5dead06b" -dependencies = [ - "cc", - "cfg-if", - "libc", - "psm", - "windows-sys 0.59.0", -] - -[[package]] -name = "stake_neuron_from_cli" -version = "0.1.0" -dependencies = [ - "candid", - "clap", - "crc32fast", - "hex", - "ic-agent", - "ic-ledger-types", - "serde", - "sha2 0.10.9", - "tokio", -] - -[[package]] -name = "strsim" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck", - "proc-macro2", - "quote", - "rustversion", - "syn 2.0.106", -] - -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - -[[package]] -name = "subtle-ng" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.106" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - -[[package]] -name = "synstructure" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - -[[package]] -name = "thiserror" -version = "2.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" -dependencies = [ - "thiserror-impl 2.0.16", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "thiserror-impl" -version = "2.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "time" -version = "0.3.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" -dependencies = [ - "deranged", - "itoa", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" - -[[package]] -name = "time-macros" -version = "0.2.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tinystr" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" -dependencies = [ - "displaydoc", - "zerovec", -] - -[[package]] -name = "tinyvec" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.47.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" -dependencies = [ - "backtrace", - "bytes", - "io-uring", - "libc", - "mio", - "parking_lot", - "pin-project-lite", - "signal-hook-registry", - "slab", - "socket2", - "tokio-macros", - "windows-sys 0.59.0", -] - -[[package]] -name = "tokio-macros" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" -dependencies = [ - "bytes", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-http" -version = "0.6.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" -dependencies = [ - "bitflags", - "bytes", - "futures-util", - "http", - "http-body", - "iri-string", - "pin-project-lite", - "tower", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.41" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" -dependencies = [ - "pin-project-lite", - "tracing-core", -] - -[[package]] -name = "tracing-core" -version = "0.1.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" -dependencies = [ - "once_cell", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typed-arena" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a" - -[[package]] -name = "typenum" -version = "1.18.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" - -[[package]] -name = "unicode-ident" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" -dependencies = [ - "form_urlencoded", - "idna", - "percent-encoding", - "serde", -] - -[[package]] -name = "utf8_iter" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" - -[[package]] -name = "utf8parse" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.11.1+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" - -[[package]] -name = "wasi" -version = "0.14.3+wasi-0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" -dependencies = [ - "wit-bindgen", -] - -[[package]] -name = "wasm-bindgen" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" -dependencies = [ - "cfg-if", - "once_cell", - "rustversion", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.50" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" -dependencies = [ - "cfg-if", - "js-sys", - "once_cell", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" -dependencies = [ - "quote", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "wasm-streams" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - -[[package]] -name = "web-sys" -version = "0.3.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "webpki-roots" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "windows-link" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.3", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" -dependencies = [ - "windows-link", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - -[[package]] -name = "wit-bindgen" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" - -[[package]] -name = "writeable" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" - -[[package]] -name = "yoke" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" -dependencies = [ - "serde", - "stable_deref_trait", - "yoke-derive", - "zerofrom", -] - -[[package]] -name = "yoke-derive" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "synstructure", -] - -[[package]] -name = "zerocopy" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.8.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] - -[[package]] -name = "zerofrom" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" -dependencies = [ - "zerofrom-derive", -] - -[[package]] -name = "zerofrom-derive" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", - "synstructure", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - -[[package]] -name = "zerotrie" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" -dependencies = [ - "displaydoc", - "yoke", - "zerofrom", -] - -[[package]] -name = "zerovec" -version = "0.11.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" -dependencies = [ - "yoke", - "zerofrom", - "zerovec-derive", -] - -[[package]] -name = "zerovec-derive" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.106", -] diff --git a/rust/stake_neuron_from_cli/Cargo.toml b/rust/stake_neuron_from_cli/Cargo.toml index 352e09a524..d1e49e317a 100644 --- a/rust/stake_neuron_from_cli/Cargo.toml +++ b/rust/stake_neuron_from_cli/Cargo.toml @@ -1,19 +1,3 @@ -[package] -name = "stake_neuron_from_cli" -version = "0.1.0" -edition = "2021" - -[[bin]] -name = "stake_neuron_from_cli" -path = "src/main.rs" - -[dependencies] -ic-agent = "0.35" -ic-ledger-types = "0.15.0" -tokio = { version = "1", features = ["full"] } -clap = { version = "4", features = ["derive"] } -candid = "0.10" -sha2 = "0.10" -hex = "0.4" -serde = { version = "1.0", features = ["derive"] } -crc32fast = "1.3" +[workspace] +members = ["backend"] +resolver = "2" diff --git a/rust/stake_neuron_from_cli/Makefile b/rust/stake_neuron_from_cli/Makefile new file mode 100644 index 0000000000..04637b7a13 --- /dev/null +++ b/rust/stake_neuron_from_cli/Makefile @@ -0,0 +1,24 @@ +.PHONY: test + +test: + @echo "=== Test 1/2: compute_subaccount returns a 64-char hex string ===" + @result=$$(icp canister call --query backend compute_subaccount \ + '(principal "aaaaa-aa", 0 : nat64)') && \ + echo "$$result" && \ + echo "$$result" | grep -qE '"[0-9a-f]{64}"' && \ + echo "PASS" || (echo "FAIL" && exit 1) + + @echo "=== Test 2/2: compute_subaccount is deterministic (same inputs → same output) ===" + @r1=$$(icp canister call --query backend compute_subaccount \ + '(principal "aaaaa-aa", 42 : nat64)') && \ + r2=$$(icp canister call --query backend compute_subaccount \ + '(principal "aaaaa-aa", 42 : nat64)') && \ + echo "Run 1: $$r1" && \ + echo "Run 2: $$r2" && \ + [ "$$r1" = "$$r2" ] && \ + echo "PASS" || (echo "FAIL" && exit 1) + + @echo "" + @echo "NOTE: stake_neuron requires the canister to hold ICP and NNS Governance" + @echo "to be reachable. Test against mainnet by calling:" + @echo " icp canister call --network ic backend stake_neuron '( : nat64, : nat64)'" diff --git a/rust/stake_neuron_from_cli/README.md b/rust/stake_neuron_from_cli/README.md index 815a87f4f4..8390fc39dc 100644 --- a/rust/stake_neuron_from_cli/README.md +++ b/rust/stake_neuron_from_cli/README.md @@ -1,121 +1,102 @@ -# Neuron Staking from CLI +# Neuron Staking -This example demonstrates how to stake ICP to create an NNS Governance neuron. +This example demonstrates how to stake ICP to create an NNS Governance neuron from a canister. It shows the subaccount computation and two-step staking process required to correctly create a neuron. + +> **Mainnet required for full staking**: The `stake_neuron` endpoint makes inter-canister calls to the ICP Ledger (`ryjl3-tyaaa-aaaaa-aaaba-cai`) and NNS Governance (`rrkah-fqaaa-aaaaa-aaaaq-cai`) canisters, which only exist on mainnet. The `compute_subaccount` query can be tested locally. ## What you can learn -### 1. **Neuron Staking Subaccount Calculation** +### 1. Neuron Staking Subaccount Calculation + +The neuron staking subaccount is the most critical thing to get right when staking a neuron. +If you send your ICP to the wrong subaccount, the ICP will be permanently lost, as there will +not be a way to ask the Governance canister to retrieve it. -The neuron staking subaccount is the most critical thing to get right when staking a neuron. -If you send your ICP to the wrong subaccount, the ICP will be permanently lost, as there will not be a way -to ask the Governance canister to retrieve it. +Therefore, test your implementation (like in this example project) against a known reference +before sending real ICP. -Therefore, test your implementation (like in this example project) against a test version of Governance to ensure -that it is able to send the ICP to the right destination. +The subaccount is a domain-separated SHA-256 hash over the controller principal and nonce: ```rust -/// Compute the subaccount for neuron staking fn compute_neuron_staking_subaccount(controller: Principal, nonce: u64) -> [u8; 32] { - let domain_length: [u8; 1] = [b"neuron-stake".len() as u8]; + let domain = b"neuron-stake"; + let domain_length: [u8; 1] = [domain.len() as u8]; let mut hasher = Sha256::new(); - hasher.update(&domain_length); - hasher.update(b"neuron-stake"); + hasher.update(domain_length); + hasher.update(domain); hasher.update(controller.as_slice()); - hasher.update(&nonce.to_be_bytes()); + hasher.update(nonce.to_be_bytes()); hasher.finalize().into() } ``` -### 2. **Two-Step Neuron Creation Process** +### 2. Two-Step Neuron Creation Process The neuron creation flow requires first making a ledger transfer, and then sending a message to tell NNS Governance about the transfer you made so that it can create a neuron. -1. **Transfer ICP** → Transfer tokens to NNS Governance at the computed subaccount -2. **Claim Neuron** → Call `claim_or_refresh_neuron_from_account` to create the neuron +1. **Transfer ICP** — Transfer tokens to NNS Governance at the computed subaccount +2. **Claim Neuron** — Call `claim_or_refresh_neuron_from_account` to register the transfer as a neuron + +The nonce used in step 1 (as the transfer memo) must match the nonce used in step 2. +The minimum staking amount enforced by NNS Governance is 1 ICP (100,000,000 e8s). +The standard ICP transfer fee of 0.0001 ICP (10,000 e8s) is deducted on top of the staked amount. ```rust // Step 1: Transfer ICP to the computed subaccount -let to_account = AccountIdentifier::new( & governance_principal, & subaccount); let transfer_args = TransferArgs { -memo: Memo(args.nonce), -amount: Tokens::from_e8s(args.amount), -fee: DEFAULT_FEE, // Standard ICP transfer fee -from_subaccount: None, -to: to_account, -created_at_time: None, + memo: Memo(nonce), + amount: Tokens { e8s: amount }, + fee: Tokens { e8s: 10_000 }, + to: AccountIdentifier { hash: build_account_identifier(governance_principal, &subaccount) }, + .. }; -let transfer_result_bytes = agent -.update( & Principal::from_text(ICP_LEDGER_CANISTER_ID) ?, "transfer") -.with_arg(Encode!(&transfer_args)?) -.call_and_wait() -.await?; - // Step 2: Claim the neuron using the same nonce let claim_request = ClaimOrRefreshNeuronFromAccount { -controller: Some(controller), -memo: args.nonce, + controller: Some(canister_id), + memo: nonce, }; - -let claim_result_bytes = agent -.update( -& governance_principal, -"claim_or_refresh_neuron_from_account", -) -.with_arg(Encode!(&claim_request)?) -.call_and_wait() -.await?; ``` -### 3. **Identity Management with ic-agent** +## Build and deploy from the command line -Additionally, you can see how you can use ic-agent to use different key formats to send messages. - -```rust -async fn load_identity(identity_path: &PathBuf) -> Result, Box> { - let pem_content = std::fs::read_to_string(identity_path)?; +### Prerequisites - // Try different identity formats - if let Ok(identity) = BasicIdentity::from_pem(pem_content.as_bytes()) { - return Ok(Box::new(identity)); - } +- Node.js +- icp-cli: `npm install -g @icp-sdk/icp-cli @icp-sdk/ic-wasm` - if let Ok(identity) = Secp256k1Identity::from_pem(pem_content.as_bytes()) { - return Ok(Box::new(identity)); - } +### Install - Err("Could not parse identity file".into()) -} +```bash +git clone https://github.com/dfinity/examples +cd examples/rust/stake_neuron_from_cli ``` -## Running the Example - -### Prerequisites - -1. **Install dfx**: - Follow [DFINITY SDK installation](https://internetcomputer.org/docs/current/developer-docs/setup/install/) -2. **Rust toolchain**: `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs/ | sh` +### Deploy and test -### Run the script ```bash -# Set up local NNS and run example -chmod +x setup_and_run.sh -./setup_and_run.sh +icp network start -d +icp deploy +make test +icp network stop ``` -This will: +The `make test` target verifies the `compute_subaccount` query locally. -1. Start a local IC replica -2. Deploy ICP Ledger and NNS Governance canisters with basic configuration -3. Run the staking example -4. Leave the environment running for inspection +### Testing stake_neuron on mainnet -### Inspecting Results - -After running locally, you can verify the neuron was created: +To test the full staking flow you need a canister deployed to mainnet that holds ICP: ```bash -# Query the governance canister -dfx canister call nns_governance list_neurons "(record {neuron_ids=vec{}; include_neurons_readable_by_caller=true})" +# Deploy to mainnet +icp deploy --network ic + +# Fund the canister with ICP (from your wallet), then call stake_neuron. +# amount: e8s to stake (minimum 100_000_000 = 1 ICP), nonce: unique u64 per neuron +icp canister call --network ic backend stake_neuron '(100010000 : nat64, 0 : nat64)' ``` + +## Security considerations and best practices + +Refer to the [security best practices](https://docs.internetcomputer.org/guides/security/overview) for information on security and best practices for your ICP app. diff --git a/rust/stake_neuron_from_cli/backend/Cargo.toml b/rust/stake_neuron_from_cli/backend/Cargo.toml new file mode 100644 index 0000000000..aa976d4106 --- /dev/null +++ b/rust/stake_neuron_from_cli/backend/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "backend" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +path = "lib.rs" + +[dependencies] +candid = "0.10" +ic-cdk = "0.20" +serde = { version = "1.0", features = ["derive"] } +sha2 = "0.10" diff --git a/rust/stake_neuron_from_cli/backend/lib.rs b/rust/stake_neuron_from_cli/backend/lib.rs new file mode 100644 index 0000000000..f11ee48fe7 --- /dev/null +++ b/rust/stake_neuron_from_cli/backend/lib.rs @@ -0,0 +1,257 @@ +use candid::{CandidType, Deserialize, Principal}; +use ic_cdk::call::Call; +use ic_cdk::{query, update}; +use sha2::{Digest, Sha256}; + +// Canonical mainnet canister IDs for ICP Ledger and NNS Governance +const ICP_LEDGER_CANISTER_ID: &str = "ryjl3-tyaaa-aaaaa-aaaba-cai"; +const NNS_GOVERNANCE_CANISTER_ID: &str = "rrkah-fqaaa-aaaaa-aaaaq-cai"; + +// Standard ICP transfer fee: 0.0001 ICP = 10,000 e8s +const DEFAULT_FEE_E8S: u64 = 10_000; + +// ── Candid types for ICP Ledger ───────────────────────────────────────────── + +#[derive(CandidType, Deserialize, Clone, Debug)] +struct AccountIdentifier { + hash: Vec, +} + +#[derive(CandidType, Deserialize, Clone, Debug)] +struct Tokens { + e8s: u64, +} + +#[derive(CandidType, Deserialize, Clone, Debug)] +struct Memo(u64); + +#[derive(CandidType, Deserialize, Clone, Debug)] +struct TransferArgs { + memo: Memo, + amount: Tokens, + fee: Tokens, + from_subaccount: Option>, + to: AccountIdentifier, + created_at_time: Option, +} + +#[derive(CandidType, Deserialize, Debug)] +enum TransferError { + BadFee { expected_fee: Tokens }, + InsufficientFunds { balance: Tokens }, + TxTooOld { allowed_window_nanos: u64 }, + TxCreatedInFuture, + TxDuplicate { duplicate_of: u64 }, +} + +#[derive(CandidType, Deserialize, Debug)] +enum TransferResult { + Ok(u64), + Err(TransferError), +} + +// ── Candid types for NNS Governance ───────────────────────────────────────── + +#[derive(CandidType, Deserialize, Debug)] +struct ClaimOrRefreshNeuronFromAccount { + controller: Option, + memo: u64, +} + +#[derive(CandidType, Deserialize, Debug)] +struct NeuronId { + id: u64, +} + +#[derive(CandidType, Deserialize, Debug)] +struct GovernanceError { + error_type: i32, + error_message: String, +} + +#[derive(CandidType, Deserialize, Debug)] +enum ClaimOrRefreshResult { + Error(GovernanceError), + NeuronId(NeuronId), +} + +#[derive(CandidType, Deserialize, Debug)] +struct ClaimOrRefreshNeuronFromAccountResponse { + result: Option, +} + +// ── Public return type ─────────────────────────────────────────────────────── + +#[derive(CandidType, Deserialize, Debug)] +pub struct StakeNeuronResult { + pub neuron_id: u64, + pub controller: Principal, + pub staked_amount_e8s: u64, + pub block_index: u64, + pub subaccount_hex: String, +} + +// ── Core logic ─────────────────────────────────────────────────────────────── + +/// Compute the subaccount for neuron staking. +/// +/// The neuron staking subaccount is the most critical thing to get right. +/// If ICP is sent to the wrong subaccount it is permanently lost — the +/// Governance canister cannot retrieve it. +/// +/// Domain-separated SHA-256 hash over: +/// \x0c (length of "neuron-stake" = 12) +/// "neuron-stake" +/// controller bytes +/// nonce as big-endian u64 +fn compute_neuron_staking_subaccount(controller: Principal, nonce: u64) -> [u8; 32] { + let domain = b"neuron-stake"; + let domain_length: [u8; 1] = [domain.len() as u8]; + let mut hasher = Sha256::new(); + hasher.update(domain_length); + hasher.update(domain); + hasher.update(controller.as_slice()); + hasher.update(nonce.to_be_bytes()); + hasher.finalize().into() +} + +/// Build an ICP AccountIdentifier from a principal + subaccount. +/// +/// Format: CRC32(0x0a || "account-id" || principal || subaccount) +/// || 0x0a || "account-id" || principal || subaccount +/// The final identifier is the last 28 bytes of the 32-byte SHA-256 hash, +/// prepended with the 4-byte CRC32 checksum. +fn build_account_identifier(principal: Principal, subaccount: &[u8; 32]) -> Vec { + let mut hasher = Sha256::new(); + hasher.update(b"\x0aaccount-id"); + hasher.update(principal.as_slice()); + hasher.update(subaccount); + let hash: [u8; 32] = hasher.finalize().into(); + + // CRC32 over the 28-byte account body (bytes 4..32 of hash) + let crc = crc32(&hash[4..]); + let mut result = Vec::with_capacity(32); + result.extend_from_slice(&crc.to_be_bytes()); + result.extend_from_slice(&hash[4..]); + result +} + +fn crc32(data: &[u8]) -> u32 { + let mut crc: u32 = 0xFFFF_FFFF; + for &byte in data { + crc ^= u32::from(byte); + for _ in 0..8 { + if crc & 1 != 0 { + crc = (crc >> 1) ^ 0xEDB8_8320; + } else { + crc >>= 1; + } + } + } + !crc +} + +fn hex_encode(bytes: &[u8]) -> String { + bytes.iter().map(|b| format!("{:02x}", b)).collect() +} + +// ── Canister endpoints ─────────────────────────────────────────────────────── + +/// Return the hex-encoded neuron staking subaccount for the given +/// (controller, nonce) pair. Call this before sending any ICP to verify +/// the destination subaccount matches your expectation. +#[query] +fn compute_subaccount(controller: Principal, nonce: u64) -> String { + let sub = compute_neuron_staking_subaccount(controller, nonce); + hex_encode(&sub) +} + +/// Perform the two-step neuron staking process on behalf of this canister: +/// +/// 1. Transfer `amount` e8s of ICP from this canister's default account to +/// the NNS Governance canister at the computed staking subaccount. +/// 2. Call `claim_or_refresh_neuron_from_account` on the Governance canister +/// to complete the neuron creation. +/// +/// **Prerequisites (mainnet):** +/// - This canister must hold at least `amount + 10_000` e8s of ICP +/// (the extra 10_000 e8s cover the standard transfer fee). +/// - The minimum staking amount enforced by NNS Governance is 100_000_000 e8s +/// (1 ICP). +/// +/// **Local testing:** The NNS canisters are not deployed on a default local +/// network, so this method can only be exercised against mainnet or a local +/// NNS replica. See the README for details. +#[update] +async fn stake_neuron(amount: u64, nonce: u64) -> Result { + let controller = ic_cdk::api::msg_caller(); + let canister_id = ic_cdk::api::canister_self(); + + let subaccount = compute_neuron_staking_subaccount(controller, nonce); + let governance_principal = + Principal::from_text(NNS_GOVERNANCE_CANISTER_ID).map_err(|e| e.to_string())?; + + let to_account = AccountIdentifier { + hash: build_account_identifier(governance_principal, &subaccount), + }; + + // Step 1: Transfer ICP to the governance staking subaccount + let transfer_args = TransferArgs { + memo: Memo(nonce), + amount: Tokens { e8s: amount }, + fee: Tokens { + e8s: DEFAULT_FEE_E8S, + }, + from_subaccount: None, + to: to_account, + created_at_time: None, + }; + + let ledger = + Principal::from_text(ICP_LEDGER_CANISTER_ID).map_err(|e| e.to_string())?; + + let transfer_result: TransferResult = Call::bounded_wait(ledger, "transfer") + .with_arg(transfer_args) + .await + .map_err(|e| format!("Transfer call failed: {:?}", e))? + .candid() + .map_err(|e| format!("Transfer decode failed: {:?}", e))?; + + let block_index = match transfer_result { + TransferResult::Ok(idx) => idx, + TransferResult::Err(e) => return Err(format!("Transfer failed: {:?}", e)), + }; + + // Step 2: Claim the neuron using the same nonce + let claim_request = ClaimOrRefreshNeuronFromAccount { + controller: Some(canister_id), + memo: nonce, + }; + + let claim_response: ClaimOrRefreshNeuronFromAccountResponse = + Call::bounded_wait(governance_principal, "claim_or_refresh_neuron_from_account") + .with_arg(claim_request) + .await + .map_err(|e| format!("Governance call failed: {:?}", e))? + .candid() + .map_err(|e| format!("Governance decode failed: {:?}", e))?; + + let neuron_id = match claim_response.result { + Some(ClaimOrRefreshResult::NeuronId(n)) => n.id, + Some(ClaimOrRefreshResult::Error(e)) => { + return Err(format!("Governance error ({}): {}", e.error_type, e.error_message)) + } + None => return Err("No result returned from governance canister".to_string()), + }; + + Ok(StakeNeuronResult { + neuron_id, + controller, + staked_amount_e8s: amount, + block_index, + subaccount_hex: hex_encode(&subaccount), + }) +} + +// Export Candid interface +ic_cdk::export_candid!(); diff --git a/rust/stake_neuron_from_cli/dfx.json b/rust/stake_neuron_from_cli/dfx.json deleted file mode 100644 index d6192020e9..0000000000 --- a/rust/stake_neuron_from_cli/dfx.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "version": 1, - "canisters": { - "icp_ledger": { - "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/69b755062f5ef0a7d6efc9a127172b46121420c8/rs/ledger_suite/icp/ledger.did", - "wasm": "https://download.dfinity.systems/ic/69b755062f5ef0a7d6efc9a127172b46121420c8/canisters/ledger-canister_notify-method.wasm.gz", - "specified_id": "ryjl3-tyaaa-aaaaa-aaaba-cai" - }, - "nns_governance": { - "type": "custom", - "candid": "https://raw.githubusercontent.com/dfinity/ic/69b755062f5ef0a7d6efc9a127172b46121420c8/rs/nns/governance/canister/governance.did", - "wasm": "https://download.dfinity.systems/ic/69b755062f5ef0a7d6efc9a127172b46121420c8/canisters/governance-canister.wasm.gz", - "specified_id": "rrkah-fqaaa-aaaaa-aaaaq-cai" - } - } -} \ No newline at end of file diff --git a/rust/stake_neuron_from_cli/icp.yaml b/rust/stake_neuron_from_cli/icp.yaml new file mode 100644 index 0000000000..df5c7edaaf --- /dev/null +++ b/rust/stake_neuron_from_cli/icp.yaml @@ -0,0 +1,8 @@ +networks: + - name: local + mode: managed + +canisters: + - name: backend + recipe: + type: "@dfinity/rust@v3.3.0" diff --git a/rust/stake_neuron_from_cli/rust-toolchain.toml b/rust/stake_neuron_from_cli/rust-toolchain.toml new file mode 100644 index 0000000000..990104f055 --- /dev/null +++ b/rust/stake_neuron_from_cli/rust-toolchain.toml @@ -0,0 +1,2 @@ +[toolchain] +targets = ["wasm32-unknown-unknown"] diff --git a/rust/stake_neuron_from_cli/setup_and_run.sh b/rust/stake_neuron_from_cli/setup_and_run.sh deleted file mode 100755 index 228e94fe38..0000000000 --- a/rust/stake_neuron_from_cli/setup_and_run.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env bash -set -e - -echo "===========STARTING LOCAL IC=========" -# Stop any existing dfx instance -dfx stop 2>/dev/null || true - -# Start clean local IC -dfx start --background --clean --host "127.0.0.1:4943" - -# Wait a moment for the replica to be ready -sleep 3 - -echo "===========CREATING TEST IDENTITY=========" -# Create a test identity for our CLI -dfx identity new test_user_stake_neuron_from_cli --storage-mode plaintext || true -dfx identity use test_user_stake_neuron_from_cli - -echo "===========SETTING UP ACCOUNTS=========" -# Get account identifiers for initialization -export MINTER_ACCOUNT_ID=$(dfx --identity anonymous ledger account-id) -export DEFAULT_ACCOUNT_ID=$(dfx ledger account-id) - -echo "Minter account: $MINTER_ACCOUNT_ID" -echo "Default account: $DEFAULT_ACCOUNT_ID" - -echo "===========DEPLOYING LEDGER=========" -# Deploy ICP ledger with initial balance -dfx deploy icp_ledger --argument " - (variant { - Init = record { - minting_account = \"$MINTER_ACCOUNT_ID\"; - initial_values = vec { - record { - \"$DEFAULT_ACCOUNT_ID\"; - record { - e8s = 1_000_000_000_000 : nat64; - }; - }; - }; - send_whitelist = vec {}; - transfer_fee = opt record { - e8s = 10_000 : nat64; - }; - token_symbol = opt \"LICP\"; - token_name = opt \"Local ICP\"; - } - }) -" - -echo "===========CHECKING LEDGER BALANCE=========" -# Verify ledger is working -dfx canister call icp_ledger account_balance "(record { account = $(python3 -c 'print("vec{" + ";".join([str(b) for b in bytes.fromhex("'$DEFAULT_ACCOUNT_ID'")]) + "}")') })" - -echo "===========DEPLOYING GOVERNANCE=========" -# Deploy NNS governance with all required fields -dfx deploy nns_governance --argument " - (record { - default_followees = vec {}; - making_sns_proposal = null; - most_recent_monthly_node_provider_rewards = null; - maturity_modulation_last_updated_at_timestamp_seconds = null; - wait_for_quiet_threshold_seconds = 86400 : nat64; - metrics = null; - neuron_management_voting_period_seconds = null; - node_providers = vec {}; - cached_daily_maturity_modulation_basis_points = null; - economics = opt record { - neuron_minimum_stake_e8s = 100_000_000 : nat64; - max_proposals_to_keep_per_topic = 100 : nat32; - neuron_management_fee_per_proposal_e8s = 1_000_000 : nat64; - reject_cost_e8s = 1_000_000 : nat64; - transaction_fee_e8s = 10_000 : nat64; - neuron_spawn_dissolve_delay_seconds = 604_800 : nat64; - minimum_icp_xdr_rate = 2_590 : nat64; - maximum_node_provider_rewards_e8s = 1_000_000_000 : nat64; - neurons_fund_economics = null; - voting_power_economics = null; - }; - restore_aging_summary = null; - spawning_neurons = null; - latest_reward_event = null; - to_claim_transfers = vec {}; - short_voting_period_seconds = 345600 : nat64; - proposals = vec {}; - xdr_conversion_rate = null; - in_flight_commands = vec {}; - neurons = vec {}; - genesis_timestamp_seconds = $(date +%s) : nat64; - }) -" - -echo "===========SETUP COMPLETE=========" -echo "Local IC is running with:" -echo "- ICP Ledger: $(dfx canister id icp_ledger)" -echo "- NNS Governance: $(dfx canister id nns_governance)" - -echo "" -echo "===========RUNNING CLI TOOL=========" -# Find the identity file for the test_user_stake_neuron_from_cli -IDENTITY_FILE="$HOME/.config/dfx/identity/test_user_stake_neuron_from_cli/identity.pem" - -if [ ! -f "$IDENTITY_FILE" ]; then - echo "ERROR: Identity file not found at $IDENTITY_FILE" - echo "Available identities:" - dfx identity list - exit 1 -fi - -echo "Using identity file: $IDENTITY_FILE" -cargo run -- --identity "$IDENTITY_FILE" --url "http://127.0.0.1:4943" - -echo "" -echo "===========SETUP REMAINS ACTIVE=========" -echo "The local IC is still running. You can now:" -echo "- Query canisters: dfx canister call ''" -echo "- Check status: dfx canister status " -echo "- View canister IDs: dfx canister id " -echo "" -echo "To stop the local IC later, run: dfx stop" -echo "Current replica URL: http://127.0.0.1:4943" \ No newline at end of file diff --git a/rust/stake_neuron_from_cli/src/lib.rs b/rust/stake_neuron_from_cli/src/lib.rs deleted file mode 100644 index 97ef0dd777..0000000000 --- a/rust/stake_neuron_from_cli/src/lib.rs +++ /dev/null @@ -1,219 +0,0 @@ -use candid::{CandidType, Decode, Deserialize, Encode, Principal}; -use ic_agent::identity::{BasicIdentity, Secp256k1Identity}; -use ic_agent::{Agent, Identity}; -use ic_ledger_types::{ - AccountIdentifier, Memo, Subaccount, Tokens, TransferArgs, TransferResult, DEFAULT_FEE, -}; -use sha2::{Digest, Sha256}; -use std::path::PathBuf; - -// Canonical canister IDs -const ICP_LEDGER_CANISTER_ID: &str = "ryjl3-tyaaa-aaaaa-aaaba-cai"; -const NNS_GOVERNANCE_CANISTER_ID: &str = "rrkah-fqaaa-aaaaa-aaaaq-cai"; - -pub struct StakeNeuronArgs { - pub identity_path: PathBuf, - pub ic_url: String, - pub amount: u64, - pub nonce: u64, -} - -pub async fn stake_neuron( - args: StakeNeuronArgs, -) -> Result> { - println!("Loading identity from: {}", args.identity_path.display()); - println!("Connecting to IC at: {}", args.ic_url); - println!( - "Staking amount: {} e8s ({} ICP)", - args.amount, - args.amount as f64 / 100_000_000.0 - ); - println!("Using nonce: {}", args.nonce); - - let identity = load_identity(&args.identity_path).await?; - - let controller = identity.sender()?; - println!("Identity principal: {}", controller); - - let agent = Agent::builder() - .with_url(&args.ic_url) - .with_identity(identity) - .build() - .expect("Failed to create IC agent"); - - agent.fetch_root_key().await?; - - println!("Successfully created IC agent!"); - - // Step 1: Compute neuron staking subaccount - let subaccount = Subaccount(compute_neuron_staking_subaccount(controller, args.nonce)); - println!("Calculated subaccount: \"{}\"", hex::encode(subaccount.0)); - - // Step 2: Transfer ICP to governance canister subaccount - println!("\n===========TRANSFERRING ICP TO GOVERNANCE========="); - let governance_principal = Principal::from_text(NNS_GOVERNANCE_CANISTER_ID)?; - - let to_account = AccountIdentifier::new(&governance_principal, &subaccount); - let transfer_args = TransferArgs { - memo: Memo(args.nonce), - amount: Tokens::from_e8s(args.amount), - fee: DEFAULT_FEE, // Standard ICP transfer fee - from_subaccount: None, - to: to_account, - created_at_time: None, - }; - - let transfer_result_bytes = agent - .update(&Principal::from_text(ICP_LEDGER_CANISTER_ID)?, "transfer") - .with_arg(Encode!(&transfer_args)?) - .call_and_wait() - .await?; - - let transfer_result = Decode!(&transfer_result_bytes, TransferResult)?; - - let block_index = match transfer_result { - TransferResult::Ok(block_index) => { - println!("Transfer successful! Block index: {}", block_index); - block_index - } - TransferResult::Err(transfer_error) => { - println!("Transfer failed: {:?}", transfer_error); - return Err(format!("Transfer failed: {:?}", transfer_error).into()); - } - }; - - // Step 3: Claim or refresh neuron from account - println!("\n===========CLAIMING NEURON FROM ACCOUNT========="); - - let claim_request = ClaimOrRefreshNeuronFromAccount { - controller: Some(controller), - memo: args.nonce, - }; - - let claim_result_bytes = agent - .update( - &governance_principal, - "claim_or_refresh_neuron_from_account", - ) - .with_arg(Encode!(&claim_request)?) - .call_and_wait() - .await?; - - println!("Raw response bytes length: {}", claim_result_bytes.len()); - println!( - "Raw response bytes (hex): {}", - hex::encode(&claim_result_bytes) - ); - - let claim_result = Decode!(&claim_result_bytes, ClaimOrRefreshNeuronFromAccountResponse)?; - - println!("Full governance response: {:?}", claim_result); - - let neuron_id = if let Some(result) = claim_result.result { - match result { - ClaimOrRefreshResult::Error(error) => { - println!( - "Governance error: {} (type: {})", - error.error_message, error.error_type - ); - return Err(format!("Governance error: {}", error.error_message).into()); - } - ClaimOrRefreshResult::NeuronId(neuron_id) => { - println!("Neuron successfully claimed/refreshed!"); - println!("Neuron ID: {}", neuron_id.id); - println!("Controller: {}", controller); - println!( - "Staked amount: {} e8s ({} ICP)", - args.amount, - args.amount as f64 / 100_000_000.0 - ); - neuron_id.id - } - } - } else { - println!("No result received - this might indicate a decoding issue"); - return Err("No result received from governance canister".into()); - }; - - println!("\nNeuron staking completed successfully!"); - - Ok(NeuronStakingResult { - neuron_id, - controller, - staked_amount_e8s: args.amount, - block_index, - subaccount, - }) -} - -pub struct NeuronStakingResult { - pub neuron_id: u64, - pub controller: Principal, - pub staked_amount_e8s: u64, - pub block_index: u64, - pub subaccount: Subaccount, -} - -async fn load_identity( - identity_path: &PathBuf, -) -> Result, Box> { - println!( - "Attempting to load identity from: {}", - identity_path.display() - ); - - // Read the PEM file - let pem_content = std::fs::read_to_string(identity_path)?; - - // Try to parse as different identity types - if let Ok(identity) = BasicIdentity::from_pem(pem_content.as_bytes()) { - println!("Loaded basic identity"); - return Ok(Box::new(identity)); - } - - if let Ok(identity) = Secp256k1Identity::from_pem(pem_content.as_bytes()) { - println!("Loaded secp256k1 identity"); - return Ok(Box::new(identity)); - } - - Err("Could not parse identity file as either BasicIdentity or Secp256k1Identity".into()) -} - -/// Compute the subaccount for neuron staking -fn compute_neuron_staking_subaccount(controller: Principal, nonce: u64) -> [u8; 32] { - let domain_length: [u8; 1] = [b"neuron-stake".len() as u8]; - let mut hasher = Sha256::new(); - hasher.update(&domain_length); - hasher.update(b"neuron-stake"); - hasher.update(controller.as_slice()); - hasher.update(&nonce.to_be_bytes()); - hasher.finalize().into() -} - -#[derive(CandidType, Deserialize, Debug)] -struct NeuronId { - id: u64, -} - -#[derive(CandidType, Deserialize, Debug)] -struct ClaimOrRefreshNeuronFromAccount { - controller: Option, - memo: u64, -} - -#[derive(CandidType, Deserialize, Debug)] -enum ClaimOrRefreshResult { - Error(GovernanceError), - NeuronId(NeuronId), -} - -#[derive(CandidType, Deserialize, Debug)] -struct ClaimOrRefreshNeuronFromAccountResponse { - result: Option, -} - -#[derive(CandidType, Deserialize, Debug)] -struct GovernanceError { - error_type: i32, - error_message: String, -} diff --git a/rust/stake_neuron_from_cli/src/main.rs b/rust/stake_neuron_from_cli/src/main.rs deleted file mode 100644 index d8fc4b0733..0000000000 --- a/rust/stake_neuron_from_cli/src/main.rs +++ /dev/null @@ -1,40 +0,0 @@ -use clap::Parser; -use std::path::PathBuf; -use stake_neuron_from_cli::{stake_neuron, StakeNeuronArgs}; - -#[derive(Parser, Debug)] -#[command(author, version, about, long_about = None)] -struct Args { - /// Path to the private key file (PEM format) - #[arg(short, long)] - identity: PathBuf, - - /// URL of the IC replica - #[arg(short, long, default_value = "http://127.0.0.1:4943")] - url: String, - - /// Amount of ICP to stake (in e8s, default: 1 ICP + fees = 100_010_000 e8s) - #[arg(short, long, default_value = "100010000")] - amount: u64, - - /// Nonce for the neuron staking subaccount - #[arg(short, long, default_value = "0")] - nonce: u64, -} - -#[tokio::main] -async fn main() -> Result<(), Box> { - let args = Args::parse(); - - let Args { identity, url, amount, nonce }= args; - - let stake_args = StakeNeuronArgs { - identity_path: identity, - ic_url: url, - amount, - nonce, - }; - - let _result = stake_neuron(stake_args).await?; - Ok(()) -} \ No newline at end of file