From 2e501871409a2d7ca6e5a03560c211b4921a6595 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 13:28:23 +0200 Subject: [PATCH 001/156] Init Orbit cli executable --- Cargo.lock | 4 ++++ Cargo.toml | 1 + tools/dfx-orbit/Cargo.toml | 13 +++++++++++++ tools/dfx-orbit/src/main.rs | 3 +++ 4 files changed, 21 insertions(+) create mode 100644 tools/dfx-orbit/Cargo.toml create mode 100644 tools/dfx-orbit/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index b87382d45..5dfbcfb7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -431,6 +431,10 @@ version = "1.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" +[[package]] +name = "dfx-orbit" +version = "0.1.0" + [[package]] name = "digest" version = "0.10.7" diff --git a/Cargo.toml b/Cargo.toml index d90113adb..84c242e73 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ members = [ "libs/orbit-essentials", "libs/orbit-essentials-macros", "libs/orbit-essentials-macros-tests", + "tools/dfx-orbit", ] [workspace.package] diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml new file mode 100644 index 000000000..f64f1e4ff --- /dev/null +++ b/tools/dfx-orbit/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "dfx-orbit" +version = "0.1.0" +description = "Command line tool for interacting with the Orbit digital asset manager on the ICP blockchain." +authors.workspace = true +edition.workspace = true +repository.workspace = true +homepage.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs new file mode 100644 index 000000000..e7a11a969 --- /dev/null +++ b/tools/dfx-orbit/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + println!("Hello, world!"); +} From ac6fd6b400af153a16264676383731d2d885121e Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 13:50:20 +0200 Subject: [PATCH 002/156] Add clap library --- Cargo.lock | 97 +++++++++++++++++++++++++++++++++++++ Cargo.toml | 7 +-- tools/dfx-orbit/Cargo.toml | 1 + tools/dfx-orbit/src/main.rs | 4 ++ 4 files changed, 106 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5dfbcfb7b..1e4c50df6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,12 +26,55 @@ dependencies = [ "memchr", ] +[[package]] +name = "anstream" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418c75fa768af9c03be99d17643f93f79bbba589895012a80e3452a19ddda15b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + [[package]] name = "anstyle" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +[[package]] +name = "anstyle-parse" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c03a11a9034d92058ceb6ee011ce58af4a9bf61491aa7e1e59ecd24bd40d22d4" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad186efb764318d35165f1758e7dcef3b10628e26d41a44bc5550652e6804391" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a38449feb7068f52bb06c12759005cf459ee52bb4adc1d5a7c4322d716fb19" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + [[package]] name = "anyhow" version = "1.0.82" @@ -290,6 +333,33 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -300,6 +370,12 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "colorchoice" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" + [[package]] name = "control-panel" version = "0.0.2-alpha.2" @@ -434,6 +510,9 @@ checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" [[package]] name = "dfx-orbit" version = "0.1.0" +dependencies = [ + "clap", +] [[package]] name = "digest" @@ -979,6 +1058,12 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" + [[package]] name = "itertools" version = "0.11.0" @@ -2091,6 +2176,12 @@ dependencies = [ "precomputed-hash", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "subtle" version = "2.5.0" @@ -2524,6 +2615,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.8.0" diff --git a/Cargo.toml b/Cargo.toml index 84c242e73..f1ad98048 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,17 +1,17 @@ [workspace] resolver = "2" members = [ - "tests/integration", "core/control-panel/api", "core/control-panel/impl", - "core/upgrader/api", - "core/upgrader/impl", "core/station/api", "core/station/impl", + "core/upgrader/api", + "core/upgrader/impl", "libs/canfund", "libs/orbit-essentials", "libs/orbit-essentials-macros", "libs/orbit-essentials-macros-tests", + "tests/integration", "tools/dfx-orbit", ] @@ -35,6 +35,7 @@ byteorder = "1.5" canbench-rs = "0.1.1" candid = "0.10.3" candid_parser = "0.1.3" +clap = "4.5.7" convert_case = "0.6" futures = "0.3" getrandom = { version = "0.2", features = ["custom"] } diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index f64f1e4ff..0009761b9 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -11,3 +11,4 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +clap.workspace = true diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index e7a11a969..4757e8c18 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -1,3 +1,7 @@ +//! # `dfx orbit` tool for managing digital assets. +//! +//! Note: This will initially be a standalone executable, but will be converted into a dfx extension once the dfx subcommand extension framework is well defined. + fn main() { println!("Hello, world!"); } From 8ae66d56faa6e02539f5bbf49d3bd2566665c5ea Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 14:00:29 +0200 Subject: [PATCH 003/156] Use clap to parse command line arguments --- Cargo.lock | 19 +++++++++++++++++++ Cargo.toml | 2 +- tools/dfx-orbit/src/lib.rs | 12 ++++++++++++ tools/dfx-orbit/src/main.rs | 5 ++++- 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 tools/dfx-orbit/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 1e4c50df6..323fe1a9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -340,6 +340,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f" dependencies = [ "clap_builder", + "clap_derive", ] [[package]] @@ -354,6 +355,18 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_derive" +version = "4.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "clap_lex" version = "0.7.1" @@ -773,6 +786,12 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index f1ad98048..4c0df3455 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ byteorder = "1.5" canbench-rs = "0.1.1" candid = "0.10.3" candid_parser = "0.1.3" -clap = "4.5.7" +clap = {version = "4.5.7", features = ["derive"]} convert_case = "0.6" futures = "0.3" getrandom = { version = "0.2", features = ["custom"] } diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs new file mode 100644 index 000000000..e93083245 --- /dev/null +++ b/tools/dfx-orbit/src/lib.rs @@ -0,0 +1,12 @@ +//! Library for interacting with Orbit on the Internet Computer. +use clap::Parser; + +/// Manages Orbit on the Internet Computer. +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +pub struct DfxOrbitArgs { +} + +pub fn main(args: DfxOrbitArgs) { + println!("Hello args: {args:?}"); +} \ No newline at end of file diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index 4757e8c18..af59a1a58 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -1,7 +1,10 @@ //! # `dfx orbit` tool for managing digital assets. //! //! Note: This will initially be a standalone executable, but will be converted into a dfx extension once the dfx subcommand extension framework is well defined. +use dfx_orbit::{self as lib, DfxOrbitArgs}; +use clap::Parser; fn main() { - println!("Hello, world!"); + let args = DfxOrbitArgs::parse(); + lib::main(args) } From 0a548f30c3a5a47a93adcf945e988e12663769e1 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 14:28:03 +0200 Subject: [PATCH 004/156] Define wallet subcommands --- Cargo.lock | 1 + Cargo.toml | 2 +- tools/dfx-orbit/Cargo.toml | 1 + tools/dfx-orbit/src/lib.rs | 8 ++++- tools/dfx-orbit/src/main.rs | 2 +- tools/dfx-orbit/src/wallet/mod.rs | 52 +++++++++++++++++++++++++++++++ 6 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 tools/dfx-orbit/src/wallet/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 323fe1a9c..578fe8bfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -524,6 +524,7 @@ checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" name = "dfx-orbit" version = "0.1.0" dependencies = [ + "candid", "clap", ] diff --git a/Cargo.toml b/Cargo.toml index 4c0df3455..9ee11e1b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ byteorder = "1.5" canbench-rs = "0.1.1" candid = "0.10.3" candid_parser = "0.1.3" -clap = {version = "4.5.7", features = ["derive"]} +clap = { version = "4.5.7", features = ["derive"] } convert_case = "0.6" futures = "0.3" getrandom = { version = "0.2", features = ["custom"] } diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 0009761b9..5ae5f146b 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -11,4 +11,5 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +candid.workspace = true clap.workspace = true diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index e93083245..8cd84c7c0 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -1,12 +1,18 @@ //! Library for interacting with Orbit on the Internet Computer. use clap::Parser; +pub mod wallet; +use wallet::OrbitWalletArgs; + /// Manages Orbit on the Internet Computer. #[derive(Parser, Debug)] #[command(version, about, long_about = None)] pub struct DfxOrbitArgs { + /// Manage Orbit wallets. + #[command(subcommand)] + field: OrbitWalletArgs, } pub fn main(args: DfxOrbitArgs) { println!("Hello args: {args:?}"); -} \ No newline at end of file +} diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index af59a1a58..dd940bc09 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -1,8 +1,8 @@ //! # `dfx orbit` tool for managing digital assets. //! //! Note: This will initially be a standalone executable, but will be converted into a dfx extension once the dfx subcommand extension framework is well defined. -use dfx_orbit::{self as lib, DfxOrbitArgs}; use clap::Parser; +use dfx_orbit::{self as lib, DfxOrbitArgs}; fn main() { let args = DfxOrbitArgs::parse(); diff --git a/tools/dfx-orbit/src/wallet/mod.rs b/tools/dfx-orbit/src/wallet/mod.rs new file mode 100644 index 000000000..61d95f923 --- /dev/null +++ b/tools/dfx-orbit/src/wallet/mod.rs @@ -0,0 +1,52 @@ +//! dfx-orbit wallet management commands. + +use candid::Principal; +use clap::{Parser, Subcommand}; + +/// Wallet management commands. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum OrbitWalletArgs { + Add(AddWallet), + List(ListWallets), + Rename(RenameWallet), + Remove(RemoveWallet), +} + +/// Adds an Orbit wallet. +#[derive(Debug, Parser)] +pub struct AddWallet { + /// Wallet name. + #[structopt(long)] + name: String, + /// Wallet canister ID. + #[structopt(long)] + canister_id: Principal, +} + +/// Lists Orbit wallets. +#[derive(Debug, Parser)] +pub struct ListWallets { + /// List all wallets. + #[structopt(long)] + all: bool, +} + +/// Renames an Orbit wallet. +#[derive(Debug, Parser)] +pub struct RenameWallet { + /// Wallet name. + #[structopt(long)] + name: String, + /// New wallet name. + #[structopt(long)] + new_name: String, +} + +/// Removes an Orbit wallet. +#[derive(Debug, Parser)] +pub struct RemoveWallet { + /// Wallet name. + #[structopt(long)] + name: String, +} From 6f265e385cb5f7baddc399bf29148d4562718d9b Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 15:28:15 +0200 Subject: [PATCH 005/156] Rename wallet -> station --- tools/dfx-orbit/src/lib.rs | 8 ++--- tools/dfx-orbit/src/station/mod.rs | 48 +++++++++++++++++++++++++++ tools/dfx-orbit/src/wallet/mod.rs | 52 ------------------------------ 3 files changed, 52 insertions(+), 56 deletions(-) create mode 100644 tools/dfx-orbit/src/station/mod.rs delete mode 100644 tools/dfx-orbit/src/wallet/mod.rs diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index 8cd84c7c0..ca181f288 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -1,16 +1,16 @@ //! Library for interacting with Orbit on the Internet Computer. use clap::Parser; -pub mod wallet; -use wallet::OrbitWalletArgs; +pub mod station; +use station::StationArgs; /// Manages Orbit on the Internet Computer. #[derive(Parser, Debug)] #[command(version, about, long_about = None)] pub struct DfxOrbitArgs { - /// Manage Orbit wallets. + /// Manage Orbit stations. #[command(subcommand)] - field: OrbitWalletArgs, + field: StationArgs, } pub fn main(args: DfxOrbitArgs) { diff --git a/tools/dfx-orbit/src/station/mod.rs b/tools/dfx-orbit/src/station/mod.rs new file mode 100644 index 000000000..d9e50531f --- /dev/null +++ b/tools/dfx-orbit/src/station/mod.rs @@ -0,0 +1,48 @@ +//! dfx-orbit station management commands. + +use candid::Principal; +use clap::{Parser, Subcommand}; + +/// Station management commands. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum StationArgs { + Add(Add), + List(List), + Rename(Rename), + Remove(Remove), +} + +/// Adds an Orbit station to the local dfx configuration. +#[derive(Debug, Parser)] +pub struct Add { + /// Wallet name. + #[structopt(long)] + name: String, + /// Wallet canister ID. + #[structopt(long)] + canister_id: Principal, +} + +/// Lists Orbit station in the local dfx configuration. +#[derive(Debug, Parser)] +pub struct List {} + +/// Renames an Orbit station in the local dfx configuration. +#[derive(Debug, Parser)] +pub struct Rename { + /// Station name. + #[structopt(long)] + name: String, + /// New station name. + #[structopt(long)] + new_name: String, +} + +/// Removes an Orbit station from the local dfx configuration. +#[derive(Debug, Parser)] +pub struct Remove { + /// Station name. + #[structopt(long)] + name: String, +} diff --git a/tools/dfx-orbit/src/wallet/mod.rs b/tools/dfx-orbit/src/wallet/mod.rs deleted file mode 100644 index 61d95f923..000000000 --- a/tools/dfx-orbit/src/wallet/mod.rs +++ /dev/null @@ -1,52 +0,0 @@ -//! dfx-orbit wallet management commands. - -use candid::Principal; -use clap::{Parser, Subcommand}; - -/// Wallet management commands. -#[derive(Debug, Subcommand)] -#[command(version, about, long_about = None)] -pub enum OrbitWalletArgs { - Add(AddWallet), - List(ListWallets), - Rename(RenameWallet), - Remove(RemoveWallet), -} - -/// Adds an Orbit wallet. -#[derive(Debug, Parser)] -pub struct AddWallet { - /// Wallet name. - #[structopt(long)] - name: String, - /// Wallet canister ID. - #[structopt(long)] - canister_id: Principal, -} - -/// Lists Orbit wallets. -#[derive(Debug, Parser)] -pub struct ListWallets { - /// List all wallets. - #[structopt(long)] - all: bool, -} - -/// Renames an Orbit wallet. -#[derive(Debug, Parser)] -pub struct RenameWallet { - /// Wallet name. - #[structopt(long)] - name: String, - /// New wallet name. - #[structopt(long)] - new_name: String, -} - -/// Removes an Orbit wallet. -#[derive(Debug, Parser)] -pub struct RemoveWallet { - /// Wallet name. - #[structopt(long)] - name: String, -} From 1c4d0957af149ddea7602f00eac506f0d6d838e3 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 16:36:12 +0200 Subject: [PATCH 006/156] Fix the station subcommand --- tools/dfx-orbit/src/lib.rs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index ca181f288..ec2378007 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -1,5 +1,5 @@ //! Library for interacting with Orbit on the Internet Computer. -use clap::Parser; +use clap::{Parser, Subcommand}; pub mod station; use station::StationArgs; @@ -10,7 +10,14 @@ use station::StationArgs; pub struct DfxOrbitArgs { /// Manage Orbit stations. #[command(subcommand)] - field: StationArgs, + field: DfxOrbitSubcommands, +} + +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum DfxOrbitSubcommands { + #[command(subcommand)] + Station(StationArgs), } pub fn main(args: DfxOrbitArgs) { From 88993183a21b372ac59779511e55c3fad4f316be Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 18:29:48 +0200 Subject: [PATCH 007/156] Split out commands --- tools/dfx-orbit/src/lib.rs | 2 +- tools/dfx-orbit/src/station/commands.rs | 47 ++++++++++++++++++++++++ tools/dfx-orbit/src/station/mod.rs | 48 +------------------------ 3 files changed, 49 insertions(+), 48 deletions(-) create mode 100644 tools/dfx-orbit/src/station/commands.rs diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index ec2378007..3a30f01d0 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -2,7 +2,7 @@ use clap::{Parser, Subcommand}; pub mod station; -use station::StationArgs; +use station::commands::StationArgs; /// Manages Orbit on the Internet Computer. #[derive(Parser, Debug)] diff --git a/tools/dfx-orbit/src/station/commands.rs b/tools/dfx-orbit/src/station/commands.rs new file mode 100644 index 000000000..5d9392d29 --- /dev/null +++ b/tools/dfx-orbit/src/station/commands.rs @@ -0,0 +1,47 @@ +//! dfx-orbit station management commands. +use candid::Principal; +use clap::{Parser, Subcommand}; + +/// Station management commands. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum StationArgs { + Add(Add), + List(List), + Rename(Rename), + Remove(Remove), +} + +/// Adds an Orbit station to the local dfx configuration. +#[derive(Debug, Parser)] +pub struct Add { + /// Wallet name. + #[structopt(long)] + name: String, + /// Wallet canister ID. + #[structopt(long)] + canister_id: Principal, +} + +/// Lists Orbit station in the local dfx configuration. +#[derive(Debug, Parser)] +pub struct List {} + +/// Renames an Orbit station in the local dfx configuration. +#[derive(Debug, Parser)] +pub struct Rename { + /// Station name. + #[structopt(long)] + name: String, + /// New station name. + #[structopt(long)] + new_name: String, +} + +/// Removes an Orbit station from the local dfx configuration. +#[derive(Debug, Parser)] +pub struct Remove { + /// Station name. + #[structopt(long)] + name: String, +} diff --git a/tools/dfx-orbit/src/station/mod.rs b/tools/dfx-orbit/src/station/mod.rs index d9e50531f..b36694c4d 100644 --- a/tools/dfx-orbit/src/station/mod.rs +++ b/tools/dfx-orbit/src/station/mod.rs @@ -1,48 +1,2 @@ //! dfx-orbit station management commands. - -use candid::Principal; -use clap::{Parser, Subcommand}; - -/// Station management commands. -#[derive(Debug, Subcommand)] -#[command(version, about, long_about = None)] -pub enum StationArgs { - Add(Add), - List(List), - Rename(Rename), - Remove(Remove), -} - -/// Adds an Orbit station to the local dfx configuration. -#[derive(Debug, Parser)] -pub struct Add { - /// Wallet name. - #[structopt(long)] - name: String, - /// Wallet canister ID. - #[structopt(long)] - canister_id: Principal, -} - -/// Lists Orbit station in the local dfx configuration. -#[derive(Debug, Parser)] -pub struct List {} - -/// Renames an Orbit station in the local dfx configuration. -#[derive(Debug, Parser)] -pub struct Rename { - /// Station name. - #[structopt(long)] - name: String, - /// New station name. - #[structopt(long)] - new_name: String, -} - -/// Removes an Orbit station from the local dfx configuration. -#[derive(Debug, Parser)] -pub struct Remove { - /// Station name. - #[structopt(long)] - name: String, -} +pub mod commands; From 6655610372fd93f8a9cb8a3650e8d4b29ee1e60d Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 11 Jun 2024 18:38:53 +0200 Subject: [PATCH 008/156] Define station config --- Cargo.lock | 2 ++ tools/dfx-orbit/Cargo.toml | 2 ++ tools/dfx-orbit/src/station/config.rs | 17 +++++++++++++++++ tools/dfx-orbit/src/station/mod.rs | 1 + 4 files changed, 22 insertions(+) create mode 100644 tools/dfx-orbit/src/station/config.rs diff --git a/Cargo.lock b/Cargo.lock index 578fe8bfe..30ab513b4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -526,6 +526,8 @@ version = "0.1.0" dependencies = [ "candid", "clap", + "serde", + "serde_json", ] [[package]] diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 5ae5f146b..1da0decbe 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -13,3 +13,5 @@ license.workspace = true [dependencies] candid.workspace = true clap.workspace = true +serde.workspace = true +serde_json.workspace = true diff --git a/tools/dfx-orbit/src/station/config.rs b/tools/dfx-orbit/src/station/config.rs new file mode 100644 index 000000000..d081129f5 --- /dev/null +++ b/tools/dfx-orbit/src/station/config.rs @@ -0,0 +1,17 @@ +//! Local dfx configuration of Orbit stations. + +/// Configuration that lives in e.g. ~/.config/dfx/orbit.json +#[derive(Debug, serde::Serialize, serde::Deserialize)] +pub struct CommonConfig { + /// Default station name. + pub default_station: String, +} + +/// Configuration for a given station that lives in e.g. ~/.config/dfx/orbit/stations/.json +pub struct StationConfig { + /// Station name. + pub name: String, + /// Wallet canister ID. + pub canister_id: String, +} + diff --git a/tools/dfx-orbit/src/station/mod.rs b/tools/dfx-orbit/src/station/mod.rs index b36694c4d..e7cd061b1 100644 --- a/tools/dfx-orbit/src/station/mod.rs +++ b/tools/dfx-orbit/src/station/mod.rs @@ -1,2 +1,3 @@ //! dfx-orbit station management commands. pub mod commands; +pub mod config; From 9d115327788352ef05f9305b46b7c86355d978df Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 00:46:16 +0200 Subject: [PATCH 009/156] Refactor --- tools/dfx-orbit/src/args.rs | 21 ++++++++++++++++++ .../{station/commands.rs => args/station.rs} | 0 tools/dfx-orbit/src/lib.rs | 22 +++---------------- .../{station/config.rs => local_config.rs} | 1 - tools/dfx-orbit/src/station/mod.rs | 3 --- 5 files changed, 24 insertions(+), 23 deletions(-) create mode 100644 tools/dfx-orbit/src/args.rs rename tools/dfx-orbit/src/{station/commands.rs => args/station.rs} (100%) rename tools/dfx-orbit/src/{station/config.rs => local_config.rs} (99%) delete mode 100644 tools/dfx-orbit/src/station/mod.rs diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs new file mode 100644 index 000000000..264b9549b --- /dev/null +++ b/tools/dfx-orbit/src/args.rs @@ -0,0 +1,21 @@ +//! Command line interface for `dfx-orbit`. +pub mod station; + +use clap::{Parser, Subcommand}; +use station::StationArgs; + +/// Manages Orbit on the Internet Computer. +#[derive(Parser, Debug)] +#[command(version, about, long_about = None)] +pub struct DfxOrbitArgs { + /// Manage Orbit stations. + #[command(subcommand)] + field: DfxOrbitSubcommands, +} + +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum DfxOrbitSubcommands { + #[command(subcommand)] + Station(StationArgs), +} diff --git a/tools/dfx-orbit/src/station/commands.rs b/tools/dfx-orbit/src/args/station.rs similarity index 100% rename from tools/dfx-orbit/src/station/commands.rs rename to tools/dfx-orbit/src/args/station.rs diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index 3a30f01d0..523bf749e 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -1,24 +1,8 @@ //! Library for interacting with Orbit on the Internet Computer. -use clap::{Parser, Subcommand}; +pub mod args; +pub mod local_config; -pub mod station; -use station::commands::StationArgs; - -/// Manages Orbit on the Internet Computer. -#[derive(Parser, Debug)] -#[command(version, about, long_about = None)] -pub struct DfxOrbitArgs { - /// Manage Orbit stations. - #[command(subcommand)] - field: DfxOrbitSubcommands, -} - -#[derive(Debug, Subcommand)] -#[command(version, about, long_about = None)] -pub enum DfxOrbitSubcommands { - #[command(subcommand)] - Station(StationArgs), -} +pub use args::DfxOrbitArgs; pub fn main(args: DfxOrbitArgs) { println!("Hello args: {args:?}"); diff --git a/tools/dfx-orbit/src/station/config.rs b/tools/dfx-orbit/src/local_config.rs similarity index 99% rename from tools/dfx-orbit/src/station/config.rs rename to tools/dfx-orbit/src/local_config.rs index d081129f5..6fab006dc 100644 --- a/tools/dfx-orbit/src/station/config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -14,4 +14,3 @@ pub struct StationConfig { /// Wallet canister ID. pub canister_id: String, } - diff --git a/tools/dfx-orbit/src/station/mod.rs b/tools/dfx-orbit/src/station/mod.rs deleted file mode 100644 index e7cd061b1..000000000 --- a/tools/dfx-orbit/src/station/mod.rs +++ /dev/null @@ -1,3 +0,0 @@ -//! dfx-orbit station management commands. -pub mod commands; -pub mod config; From dd28cbf521334f97502c146a767f54253e81beb4 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 01:33:08 +0200 Subject: [PATCH 010/156] ++ --- Cargo.lock | 1 + tools/dfx-orbit/Cargo.toml | 1 + tools/dfx-orbit/src/commands.rs | 7 +++++ tools/dfx-orbit/src/dfx_extension_api.rs | 37 ++++++++++++++++++++++++ tools/dfx-orbit/src/lib.rs | 8 ++--- tools/dfx-orbit/src/local_config.rs | 4 +++ tools/dfx-orbit/src/main.rs | 4 +-- 7 files changed, 54 insertions(+), 8 deletions(-) create mode 100644 tools/dfx-orbit/src/commands.rs create mode 100644 tools/dfx-orbit/src/dfx_extension_api.rs diff --git a/Cargo.lock b/Cargo.lock index 30ab513b4..0c0a2a68f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -524,6 +524,7 @@ checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" name = "dfx-orbit" version = "0.1.0" dependencies = [ + "anyhow", "candid", "clap", "serde", diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 1da0decbe..c63fecbea 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -11,6 +11,7 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +anyhow.workspace = true candid.workspace = true clap.workspace = true serde.workspace = true diff --git a/tools/dfx-orbit/src/commands.rs b/tools/dfx-orbit/src/commands.rs new file mode 100644 index 000000000..23e8422e2 --- /dev/null +++ b/tools/dfx-orbit/src/commands.rs @@ -0,0 +1,7 @@ +//! Implementation of the `dfx-orbit` commands. + +use crate::args::DfxOrbitArgs; + +pub fn main(args: DfxOrbitArgs) { + println!("Hello args: {args:?}"); +} diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs new file mode 100644 index 000000000..9e0fb78d6 --- /dev/null +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -0,0 +1,37 @@ +//! Placeholders for the proposed dfx extension API methods. +use std::process::{Command, Stdio}; + +use anyhow::Context; + +/// Calls the dfx cli. +/// +/// Methods are implemented as calls to the dfx cli until a library is available. +fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { + let output = Command::new("dfx") + .args(args) + // Tell the OS to record the command's output + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + // Execute the command, wait for it to complete, then capture the output + .output() + // Blow up if the OS was unable to start the program + .with_context(|| "Failed to call dfx. Is the dfx cli installed?")?; + + if output.status.success() { + Ok(String::from_utf8(output.stdout) + .context("Failed to parse dfx output as UTF-8")? + .trim() + .to_string()) + } else { + Err(anyhow::anyhow!("dfx failed with status: {}", output.status)) + } +} + +pub mod identity { + use super::call_dfx_cli; + + /// The name of the default identity. This is the identity given by `dfx identity whoami` (if any). + pub fn default() -> anyhow::Result { + call_dfx_cli(vec!["identity", "whoami"]) + } +} diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index 523bf749e..d500590ef 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -1,9 +1,5 @@ //! Library for interacting with Orbit on the Internet Computer. pub mod args; +pub mod commands; +pub mod dfx_extension_api; pub mod local_config; - -pub use args::DfxOrbitArgs; - -pub fn main(args: DfxOrbitArgs) { - println!("Hello args: {args:?}"); -} diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 6fab006dc..c62d6cc7f 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -14,3 +14,7 @@ pub struct StationConfig { /// Wallet canister ID. pub canister_id: String, } + +pub fn list_stations() -> Vec { + vec![] +} diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index dd940bc09..1838e193b 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -2,9 +2,9 @@ //! //! Note: This will initially be a standalone executable, but will be converted into a dfx extension once the dfx subcommand extension framework is well defined. use clap::Parser; -use dfx_orbit::{self as lib, DfxOrbitArgs}; +use dfx_orbit::{self as lib, args::DfxOrbitArgs}; fn main() { let args = DfxOrbitArgs::parse(); - lib::main(args) + lib::commands::main(args) } From f7de4b1f7c7159fc98a22a3f98a656592c8c34bd Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 02:36:08 +0200 Subject: [PATCH 011/156] ++ --- Cargo.lock | 2337 ++++++++++++++++- Cargo.toml | 2 + tools/dfx-orbit/Cargo.toml | 2 + tools/dfx-orbit/src/args.rs | 5 +- tools/dfx-orbit/src/args/dfx_extension_api.rs | 12 + .../src/args/dfx_extension_api/config.rs | 11 + tools/dfx-orbit/src/commands.rs | 24 +- tools/dfx-orbit/src/dfx_extension_api.rs | 24 +- 8 files changed, 2322 insertions(+), 95 deletions(-) create mode 100644 tools/dfx-orbit/src/args/dfx_extension_api.rs create mode 100644 tools/dfx-orbit/src/args/dfx_extension_api/config.rs diff --git a/Cargo.lock b/Cargo.lock index 0c0a2a68f..93a99a05f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,65 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "opaque-debug", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes 0.8.4", + "cipher 0.4.4", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -26,6 +85,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "ambient-authority" +version = "0.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9d4ee0d472d1cd2e28c97dfa124b3d8d992e10eb0a035f33f5d12e3a177ba3b" + [[package]] name = "anstream" version = "0.6.14" @@ -87,6 +158,17 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +[[package]] +name = "argon2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db4ce4441f99dbd377ca8a8f57b698c44d0d6e712d8329b5040da5a64aa1ce73" +dependencies = [ + "base64ct", + "blake2", + "password-hash", +] + [[package]] name = "arrayvec" version = "0.5.2" @@ -102,6 +184,46 @@ dependencies = [ "term", ] +[[package]] +name = "async-io" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" +dependencies = [ + "async-lock 2.8.0", + "autocfg", + "cfg-if", + "concurrent-queue", + "futures-lite", + "log", + "parking", + "polling", + "rustix 0.37.27", + "slab", + "socket2 0.4.10", + "waker-fn", +] + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + [[package]] name = "async-trait" version = "0.1.80" @@ -119,6 +241,17 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "getrandom", + "instant", + "rand", +] + [[package]] name = "backtrace" version = "0.3.71" @@ -134,18 +267,42 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" +[[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.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "beef" version = "0.5.2" @@ -175,6 +332,24 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "bip32" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b30ed1d6f8437a487a266c8293aeb95b61a23261273e3e02912cdb8b68bf798b" +dependencies = [ + "bs58", + "hmac 0.12.1", + "k256 0.11.6", + "once_cell", + "pbkdf2", + "rand_core", + "ripemd", + "sha2 0.10.8", + "subtle", + "zeroize", +] + [[package]] name = "bit-set" version = "0.5.3" @@ -202,6 +377,24 @@ version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[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" @@ -211,12 +404,61 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-modes" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cb03d1bed155d89dce0f845b7899b18a9a163e148fd004e1c28421a783e2d8e" +dependencies = [ + "block-padding", + "cipher 0.3.0", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[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", + "subtle", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +dependencies = [ + "sha2 0.9.9", +] + [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "byte-unit" +version = "4.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da78b32057b8fdfc352504708feeba7216dcd65a2c9ab02978cbd288d1279b6c" +dependencies = [ + "serde", + "utf8-width", +] + [[package]] name = "byteorder" version = "1.5.0" @@ -229,6 +471,19 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" +[[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", +] + [[package]] name = "canbench-rs" version = "0.1.1" @@ -265,7 +520,7 @@ dependencies = [ "hex", "ic_principal", "leb128", - "num-bigint", + "num-bigint 0.4.4", "num-traits", "paste", "pretty", @@ -301,7 +556,7 @@ dependencies = [ "lalrpop", "lalrpop-util", "logos", - "num-bigint", + "num-bigint 0.4.4", "pretty", "thiserror", ] @@ -315,12 +570,41 @@ dependencies = [ "futures", "ic-cdk 0.13.2", "ic-cdk-timers", - "num-bigint", + "num-bigint 0.4.4", "serde", "serde_bytes", "thiserror", ] +[[package]] +name = "cap-primitives" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00172660727e2d7f808e7cc2bfffd093fdb3ea2ff2ef819289418a3c3ffab5ac" +dependencies = [ + "ambient-authority", + "fs-set-times", + "io-extras", + "io-lifetimes 2.0.3", + "ipnet", + "maybe-owned", + "rustix 0.38.34", + "windows-sys 0.52.0", + "winx", +] + +[[package]] +name = "cap-std" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cd9187bb3f7478a4c135ea10473a41a5f029d2ac800c1adf64f35ec7d4c8603" +dependencies = [ + "cap-primitives", + "io-extras", + "io-lifetimes 2.0.3", + "rustix 0.38.34", +] + [[package]] name = "cc" version = "1.0.96" @@ -333,6 +617,25 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", +] + [[package]] name = "clap" version = "4.5.7" @@ -361,7 +664,7 @@ version = "4.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c780290ccf4fb26629baa7a1081e68ced113f1d3ec302fa5948f1c381ebf06c6" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", "syn 2.0.60", @@ -373,6 +676,15 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70" +[[package]] +name = "cmake" +version = "0.1.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130" +dependencies = [ + "cc", +] + [[package]] name = "codespan-reporting" version = "0.11.1" @@ -389,6 +701,34 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[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 = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.52.0", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + [[package]] name = "control-panel" version = "0.0.2-alpha.2" @@ -490,65 +830,232 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" [[package]] -name = "crypto-common" -version = "0.1.6" +name = "crypto-bigint" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" dependencies = [ "generic-array", - "typenum", + "rand_core", + "subtle", + "zeroize", ] [[package]] -name = "data-encoding" -version = "2.6.0" +name = "crypto-bigint" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] [[package]] -name = "deranged" -version = "0.3.11" +name = "crypto-common" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "powerfmt", + "generic-array", + "rand_core", + "typenum", ] [[package]] -name = "deunicode" -version = "1.4.4" +name = "crypto-mac" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" - -[[package]] -name = "dfx-orbit" -version = "0.1.0" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" dependencies = [ - "anyhow", - "candid", - "clap", - "serde", - "serde_json", + "generic-array", + "subtle", ] [[package]] -name = "digest" -version = "0.10.7" +name = "ctr" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "block-buffer", - "crypto-common", + "cipher 0.4.4", ] [[package]] -name = "dirs-next" -version = "2.0.0" +name = "curve25519-dalek-ng" +version = "4.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" dependencies = [ - "cfg-if", - "dirs-sys-next", + "byteorder", + "digest 0.9.0", + "rand_core", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "pem-rfc7468 0.6.0", + "zeroize", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468 0.7.0", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "deunicode" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" + +[[package]] +name = "dfx-core" +version = "0.0.1" +source = "git+https://github.com/dfinity/sdk.git?tag=0.20.1#aae11965e0ab3fe2b702205ec911ac1c675e0cfe" +dependencies = [ + "aes-gcm", + "argon2", + "bip32", + "byte-unit", + "bytes", + "candid", + "clap", + "dialoguer", + "directories-next", + "dunce", + "flate2", + "handlebars", + "hex", + "humantime-serde", + "ic-agent", + "ic-identity-hsm", + "ic-utils", + "k256 0.11.6", + "keyring", + "lazy_static", + "reqwest 0.11.27", + "ring 0.16.20", + "schemars", + "sec1 0.3.0", + "semver", + "serde", + "serde_json", + "slog", + "tar", + "tempfile", + "thiserror", + "time", + "tiny-bip39", + "url", +] + +[[package]] +name = "dfx-orbit" +version = "0.1.0" +dependencies = [ + "anyhow", + "candid", + "cap-std", + "clap", + "dfx-core", + "serde", + "serde_json", +] + +[[package]] +name = "dialoguer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" +dependencies = [ + "console", + "shell-words", + "tempfile", + "thiserror", + "zeroize", +] + +[[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 = "directories-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339ee130d97a610ea5a5872d2bbb130fdf68884ff09d3028b81bec8a1ac23bbc" +dependencies = [ + "cfg-if", + "dirs-sys-next", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if", + "dirs-sys-next", ] [[package]] @@ -568,18 +1075,106 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1" +[[package]] +name = "dunce" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" + [[package]] name = "dyn-clone" version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.9", + "digest 0.10.7", + "elliptic-curve 0.13.8", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", +] + +[[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", + "serde", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + [[package]] name = "either" version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array", + "group 0.12.1", + "pem-rfc7468 0.6.0", + "pkcs8 0.9.0", + "rand_core", + "sec1 0.3.0", + "subtle", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array", + "group 0.13.0", + "pem-rfc7468 0.7.0", + "pkcs8 0.10.2", + "rand_core", + "sec1 0.7.3", + "subtle", + "zeroize", +] + [[package]] name = "email_address" version = "0.2.4" @@ -598,18 +1193,149 @@ dependencies = [ "log", ] +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enumflags2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83c8d82922337cd23a15f88b70d8e4ef5f11da38dd7cdb55e84dd5de99695da0" +dependencies = [ + "enumflags2_derive", + "serde", +] + +[[package]] +name = "enumflags2_derive" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "946ee94e3dbf58fdd324f9ce245c7b238d46a66f00e86a020b71996349e46cce" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "equivalent" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + +[[package]] +name = "fastrand" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" +dependencies = [ + "instant", +] + +[[package]] +name = "fastrand" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "windows-sys 0.52.0", +] + [[package]] name = "fixedbitset" version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f54427cfd1c7829e2a139fcefea601bf088ebca651d2bf53ebc600eac295dae" +dependencies = [ + "crc32fast", + "libz-ng-sys", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" @@ -631,6 +1357,17 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" +[[package]] +name = "fs-set-times" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "033b337d725b97690d86893f9de22b67b80dcc4e9ad815f348254c38119db8fb" +dependencies = [ + "io-lifetimes 2.0.3", + "rustix 0.38.34", + "windows-sys 0.52.0", +] + [[package]] name = "futures" version = "0.3.30" @@ -679,6 +1416,21 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" +dependencies = [ + "fastrand 1.9.0", + "futures-core", + "futures-io", + "memchr", + "parking", + "pin-project-lite", + "waker-fn", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -734,6 +1486,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -747,6 +1500,16 @@ dependencies = [ "wasi", ] +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + [[package]] name = "gimli" version = "0.28.1" @@ -759,6 +1522,47 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[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", + "subtle", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core", + "subtle", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "h2" version = "0.4.4" @@ -770,7 +1574,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -784,11 +1588,35 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403" +[[package]] +name = "handlebars" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa67bab9ff362228eb3d00bd024a4965d8231bbb7921167f0cfa66c6626b225" +dependencies = [ + "log", + "pest", + "pest_derive", + "serde", + "serde_json", + "thiserror", +] + [[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.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "heck" @@ -811,6 +1639,46 @@ dependencies = [ "serde", ] +[[package]] +name = "hkdf" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" +dependencies = [ + "digest 0.9.0", + "hmac 0.11.0", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest 0.9.0", +] + +[[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 = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -822,6 +1690,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.0" @@ -829,7 +1708,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -840,8 +1719,8 @@ checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", "futures-core", - "http", - "http-body", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -851,6 +1730,52 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime", + "serde", +] + +[[package]] +name = "hyper" +version = "0.14.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", + "want", +] + [[package]] name = "hyper" version = "1.3.1" @@ -860,9 +1785,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.4", + "http 1.1.0", + "http-body 1.0.0", "httparse", "itoa", "pin-project-lite", @@ -871,6 +1796,20 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http 0.2.12", + "hyper 0.14.29", + "rustls 0.21.12", + "tokio", + "tokio-rustls 0.24.1", +] + [[package]] name = "hyper-rustls" version = "0.26.0" @@ -878,13 +1817,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http", - "hyper", + "http 1.1.0", + "hyper 1.3.1", "hyper-util", - "rustls", + "rustls 0.22.4", "rustls-pki-types", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tower-service", ] @@ -897,17 +1836,57 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", - "hyper", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.3.1", "pin-project-lite", - "socket2", + "socket2 0.5.7", "tokio", "tower", "tower-service", "tracing", ] +[[package]] +name = "ic-agent" +version = "0.34.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +dependencies = [ + "async-lock 3.4.0", + "backoff", + "cached", + "candid", + "ed25519-consensus", + "futures-util", + "hex", + "http 1.1.0", + "http-body 1.0.0", + "ic-certification", + "ic-transport-types", + "ic-verify-bls-signature", + "k256 0.13.3", + "leb128", + "p256", + "pem", + "pkcs8 0.10.2", + "rand", + "rangemap", + "reqwest 0.11.27", + "ring 0.17.8", + "rustls-webpki 0.101.7", + "sec1 0.7.3", + "serde", + "serde_bytes", + "serde_cbor", + "serde_repr", + "sha2 0.10.8", + "simple_asn1", + "thiserror", + "time", + "tokio", + "url", +] + [[package]] name = "ic-cdk" version = "0.12.1" @@ -990,6 +1969,31 @@ dependencies = [ "slotmap", ] +[[package]] +name = "ic-certification" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20052ce9255fbe2de7041a4f6996fddd095ba1f31ae83b6c0ccdee5be6e7bbcf" +dependencies = [ + "hex", + "serde", + "serde_bytes", + "sha2 0.10.8", +] + +[[package]] +name = "ic-identity-hsm" +version = "0.34.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +dependencies = [ + "hex", + "ic-agent", + "pkcs11", + "sha2 0.10.8", + "simple_asn1", + "thiserror", +] + [[package]] name = "ic-ledger-types" version = "0.10.0" @@ -1002,7 +2006,7 @@ dependencies = [ "ic-cdk 0.13.2", "serde", "serde_bytes", - "sha2", + "sha2 0.10.8", ] [[package]] @@ -1014,6 +2018,55 @@ dependencies = [ "ic_principal", ] +[[package]] +name = "ic-transport-types" +version = "0.34.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +dependencies = [ + "candid", + "hex", + "ic-certification", + "leb128", + "serde", + "serde_bytes", + "serde_repr", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "ic-utils" +version = "0.34.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +dependencies = [ + "async-trait", + "candid", + "futures-util", + "ic-agent", + "once_cell", + "semver", + "serde", + "serde_bytes", + "sha2 0.10.8", + "strum", + "strum_macros", + "thiserror", + "time", + "tokio", +] + +[[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 = "0.21.1" @@ -1030,7 +2083,7 @@ dependencies = [ "crc32fast", "data-encoding", "serde", - "sha2", + "sha2 0.10.8", "thiserror", ] @@ -1054,6 +2107,24 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", +] + [[package]] name = "integration-tests" version = "0.0.1" @@ -1065,16 +2136,43 @@ dependencies = [ "ic-cdk 0.13.2", "ic-ledger-types", "lazy_static", - "num-bigint", + "num-bigint 0.4.4", "orbit-essentials", "pocket-ic", "serde", - "sha2", + "sha2 0.10.8", "station-api", "upgrader-api", "wat", ] +[[package]] +name = "io-extras" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9f046b9af244f13b3bd939f55d16830ac3a201e8a9ba9661bfcb03e2be72b9b" +dependencies = [ + "io-lifetimes 2.0.3", + "windows-sys 0.52.0", +] + +[[package]] +name = "io-lifetimes" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "io-lifetimes" +version = "2.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a611371471e98973dbcab4e0ec66c31a10bc356eeb4d54a0e05eac8158fe38c" + [[package]] name = "ipnet" version = "2.9.0" @@ -1111,6 +2209,54 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", + "sha3", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keyring" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba264b266563c1363dcce004776cbf198d7422a4262f77f4ca285bf26ae30955" +dependencies = [ + "byteorder", + "secret-service", + "security-framework", + "winapi", +] + [[package]] name = "lalrpop" version = "0.20.2" @@ -1160,6 +2306,16 @@ version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" +[[package]] +name = "libloading" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" +dependencies = [ + "cc", + "winapi", +] + [[package]] name = "libredox" version = "0.1.3" @@ -1170,6 +2326,28 @@ dependencies = [ "libc", ] +[[package]] +name = "libz-ng-sys" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6409efc61b12687963e602df8ecf70e8ddacf95bc6576bcf16e3ac6328083c5" +dependencies = [ + "cmake", + "libc", +] + +[[package]] +name = "linux-raw-sys" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + [[package]] name = "lock_api" version = "0.4.12" @@ -1227,12 +2405,27 @@ dependencies = [ "regex-automata 0.1.10", ] +[[package]] +name = "maybe-owned" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4facc753ae494aeb6e3c22f839b158aebd4f9270f55cd3c79906c45476c47ab4" + [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -1286,12 +2479,35 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "nb-connect" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1bb540dc6ef51cfe1916ec038ce7a620daf3a111e2502d745197cd53d6bca15" +dependencies = [ + "libc", + "socket2 0.4.10", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "nix" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4916f159ed8e5de0082076562152a76b7a1f64a01fd9d1e0fea002c37624faf" +dependencies = [ + "bitflags 1.3.2", + "cc", + "cfg-if", + "libc", + "memoffset", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -1302,6 +2518,31 @@ dependencies = [ "winapi", ] +[[package]] +name = "num" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" +dependencies = [ + "num-bigint 0.4.4", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "090c7f9998ee0ff65aa5b723e4009f7b217707f1fb5ea551329cc4d6231fb304" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.4" @@ -1314,6 +2555,15 @@ dependencies = [ "serde", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1329,6 +2579,28 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint 0.4.4", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.18" @@ -1363,6 +2635,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + [[package]] name = "openssl-probe" version = "0.1.5" @@ -1387,7 +2665,7 @@ dependencies = [ "serde_bytes", "serde_cbor", "serde_json", - "sha2", + "sha2 0.10.8", "thiserror", "time", "tokio", @@ -1420,6 +2698,33 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa 0.16.9", + "elliptic-curve 0.13.8", + "primeorder", + "sha2 0.10.8", +] + +[[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.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + [[package]] name = "parking_lot" version = "0.12.2" @@ -1438,22 +2743,115 @@ checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.1", "smallvec", "windows-targets 0.52.5", ] [[package]] -name = "paste" -version = "1.0.14" +name = "password-hash" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" +dependencies = [ + "base64ct", + "rand_core", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917" +dependencies = [ + "digest 0.10.7", +] + +[[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.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d159833a9105500e0398934e205e0773f0b27529557134ecfc51c27646adac" +dependencies = [ + "base64ct", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "560131c633294438da9f7c4b08189194b20946c8274c6b9e38881a7874dc8ee8" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.60", +] [[package]] -name = "percent-encoding" -version = "2.3.1" +name = "pest_meta" +version = "2.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "d7a240022f37c361ec1878d646fc5b7d7c4d28d5946e1a80ad5a7a4f4ca0bdcd" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] [[package]] name = "petgraph" @@ -1512,6 +2910,36 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs11" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3aca6d67e4c8613bfe455599d0233d00735f85df2001f6bfd9bb7ac0496b10af" +dependencies = [ + "libloading", + "num-bigint 0.2.6", +] + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.9", + "spki 0.7.3", +] + [[package]] name = "pocket-ic" version = "3.0.0" @@ -1523,7 +2951,7 @@ dependencies = [ "candid", "hex", "ic-cdk 0.13.2", - "reqwest", + "reqwest 0.12.4", "schemars", "serde", "serde_bytes", @@ -1533,6 +2961,34 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "polling" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "concurrent-queue", + "libc", + "log", + "pin-project-lite", + "windows-sys 0.48.0", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1588,6 +3044,34 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve 0.13.8", +] + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.81" @@ -1636,6 +3120,17 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + [[package]] name = "rand_chacha" version = "0.3.1" @@ -1651,6 +3146,24 @@ name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rangemap" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] [[package]] name = "redox_syscall" @@ -1722,6 +3235,49 @@ version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.29", + "hyper-rustls 0.24.2", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.12", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls 0.24.1", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots 0.25.4", + "winreg 0.50.0", +] + [[package]] name = "reqwest" version = "0.12.4" @@ -1733,12 +3289,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.4.4", + "http 1.1.0", + "http-body 1.0.0", "http-body-util", - "hyper", - "hyper-rustls", + "hyper 1.3.1", + "hyper-rustls 0.26.0", "hyper-util", "ipnet", "js-sys", @@ -1747,16 +3303,16 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls", + "rustls 0.22.4", "rustls-native-certs", - "rustls-pemfile", + "rustls-pemfile 2.1.2", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", - "tokio-rustls", + "tokio-rustls 0.25.0", "tokio-socks", "tokio-util", "tower-service", @@ -1765,8 +3321,44 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots", - "winreg", + "webpki-roots 0.26.1", + "winreg 0.52.0", +] + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac 0.12.1", + "zeroize", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", ] [[package]] @@ -1779,11 +3371,20 @@ dependencies = [ "cfg-if", "getrandom", "libc", - "spin", - "untrusted", + "spin 0.9.8", + "untrusted 0.9.0", "windows-sys 0.52.0", ] +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + [[package]] name = "rstest" version = "0.18.2" @@ -1819,6 +3420,12 @@ version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc_version" version = "0.4.0" @@ -1828,6 +3435,47 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.37.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +dependencies = [ + "bitflags 1.3.2", + "errno", + "io-lifetimes 1.0.11", + "libc", + "linux-raw-sys 0.3.8", + "windows-sys 0.48.0", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "itoa", + "libc", + "linux-raw-sys 0.4.14", + "once_cell", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" +dependencies = [ + "log", + "ring 0.17.8", + "rustls-webpki 0.101.7", + "sct", +] + [[package]] name = "rustls" version = "0.22.4" @@ -1835,9 +3483,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432" dependencies = [ "log", - "ring", + "ring 0.17.8", "rustls-pki-types", - "rustls-webpki", + "rustls-webpki 0.102.3", "subtle", "zeroize", ] @@ -1849,12 +3497,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile", + "rustls-pemfile 2.1.2", "rustls-pki-types", "schannel", "security-framework", ] +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + [[package]] name = "rustls-pemfile" version = "2.1.2" @@ -1871,15 +3528,25 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + [[package]] name = "rustls-webpki" version = "0.102.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3bce581c0dd41bce533ce695a1437fa16a7ab5ac3ccfa99fe1a620a7885eabf" dependencies = [ - "ring", + "ring 0.17.8", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -1936,12 +3603,76 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array", + "pkcs8 0.9.0", + "subtle", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.9", + "generic-array", + "pkcs8 0.10.2", + "subtle", + "zeroize", +] + +[[package]] +name = "secret-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1da5c423b8783185fd3fecd1c8796c267d2c089d894ce5a93c280a5d3f780a2" +dependencies = [ + "aes 0.7.5", + "block-modes", + "hkdf", + "lazy_static", + "num", + "rand", + "serde", + "sha2 0.9.9", + "zbus", + "zbus_macros", + "zvariant", + "zvariant_derive", +] + [[package]] name = "security-framework" version = "2.10.0" @@ -1970,6 +3701,9 @@ name = "semver" version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +dependencies = [ + "serde", +] [[package]] name = "serde" @@ -2032,6 +3766,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "serde_tokenstream" version = "0.1.7" @@ -2056,14 +3801,37 @@ dependencies = [ ] [[package]] -name = "sha2" +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.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "cfg-if", - "cpufeatures", - "digest", + "digest 0.10.7", + "keccak", ] [[package]] @@ -2075,6 +3843,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -2084,6 +3858,38 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[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", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint 0.4.4", + "num-traits", + "thiserror", + "time", +] + [[package]] name = "siphasher" version = "0.3.11" @@ -2099,6 +3905,12 @@ dependencies = [ "autocfg", ] +[[package]] +name = "slog" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" + [[package]] name = "slotmap" version = "1.0.7" @@ -2114,6 +3926,16 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "socket2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +dependencies = [ + "libc", + "winapi", +] + [[package]] name = "socket2" version = "0.5.7" @@ -2124,12 +3946,38 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.9", +] + [[package]] name = "stacker" version = "0.1.15" @@ -2143,6 +3991,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "station" version = "0.0.2-alpha.3" @@ -2162,13 +4016,13 @@ dependencies = [ "ic-ledger-types", "ic-stable-structures", "lazy_static", - "num-bigint", + "num-bigint 0.4.4", "orbit-essentials", "rstest", "serde", "serde_bytes", "serde_cbor", - "sha2", + "sha2 0.10.8", "station-api", "thiserror", "tokio", @@ -2205,12 +4059,37 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "strum" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063e6045c0e62079840579a7e47a355ae92f60eb74daaf156fb1e84ba164e63f" + +[[package]] +name = "strum_macros" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + [[package]] name = "subtle" version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +[[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" @@ -2239,6 +4118,50 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tar" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb797dad5fb5b76fcf519e702f4a589483b5ef06567f160c392832c1f5e44909" +dependencies = [ + "filetime", + "libc", + "xattr", +] + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand 2.1.0", + "rustix 0.38.34", + "windows-sys 0.52.0", +] + [[package]] name = "term" version = "0.7.0" @@ -2326,6 +4249,25 @@ dependencies = [ "time-core", ] +[[package]] +name = "tiny-bip39" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62cc94d358b5a1e84a5cb9109f559aa3c4d634d2b1b4de3d0fa4adc7c78e2861" +dependencies = [ + "anyhow", + "hmac 0.12.1", + "once_cell", + "pbkdf2", + "rand", + "rustc-hash", + "sha2 0.10.8", + "thiserror", + "unicode-normalization", + "wasm-bindgen", + "zeroize", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -2364,7 +4306,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2", + "socket2 0.5.7", "tokio-macros", "windows-sys 0.48.0", ] @@ -2380,13 +4322,23 @@ dependencies = [ "syn 2.0.60", ] +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.12", + "tokio", +] + [[package]] name = "tokio-rustls" version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls", + "rustls 0.22.4", "rustls-pki-types", "tokio", ] @@ -2417,6 +4369,32 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -2550,6 +4528,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + [[package]] name = "unicode-bidi" version = "0.3.15" @@ -2589,6 +4573,22 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -2612,7 +4612,7 @@ dependencies = [ "orbit-essentials", "serde", "serde_cbor", - "sha2", + "sha2 0.10.8", "thiserror", "tokio", "upgrader-api", @@ -2638,6 +4638,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "utf8-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3" + [[package]] name = "utf8parse" version = "0.2.2" @@ -2666,6 +4672,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "waker-fn" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317211a0dc0ceedd78fb2ca9a44aed3d7b9b26f81870d485c07122b4350673b7" + [[package]] name = "walkdir" version = "2.5.0" @@ -2811,6 +4823,12 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webpki-roots" version = "0.26.1" @@ -2990,6 +5008,25 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + [[package]] name = "winreg" version = "0.52.0" @@ -3000,8 +5037,124 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "winx" +version = "0.36.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9643b83820c0cd246ecabe5fa454dd04ba4fa67996369466d0747472d337346" +dependencies = [ + "bitflags 2.5.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "xattr" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" +dependencies = [ + "libc", + "linux-raw-sys 0.4.14", + "rustix 0.38.34", +] + +[[package]] +name = "zbus" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cbeb2291cd7267a94489b71376eda33496c1b9881adf6b36f26cc2779f3fc49" +dependencies = [ + "async-io", + "byteorder", + "derivative", + "enumflags2", + "fastrand 1.9.0", + "futures", + "nb-connect", + "nix", + "once_cell", + "polling", + "scoped-tls", + "serde", + "serde_repr", + "zbus_macros", + "zvariant", +] + +[[package]] +name = "zbus_macros" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3959a7847cf95e3d51e312856617c5b1b77191176c65a79a5f14d778bbe0a6" +dependencies = [ + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "zerocopy" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "zeroize" version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "zvariant" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a68c7b55f2074489b7e8e07d2d0a6ee6b4f233867a653c664d8020ba53692525" +dependencies = [ + "byteorder", + "enumflags2", + "libc", + "serde", + "static_assertions", + "zvariant_derive", +] + +[[package]] +name = "zvariant_derive" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ca5e22593eb4212382d60d26350065bf2a02c34b85bc850474a74b589a3de9" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] diff --git a/Cargo.toml b/Cargo.toml index 9ee11e1b4..f7095612c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,9 @@ byteorder = "1.5" canbench-rs = "0.1.1" candid = "0.10.3" candid_parser = "0.1.3" +cap-std = "3.1.0" clap = { version = "4.5.7", features = ["derive"] } +dfx-core = { git = "https://github.com/dfinity/sdk.git", tag = "0.20.1" } convert_case = "0.6" futures = "0.3" getrandom = { version = "0.2", features = ["custom"] } diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index c63fecbea..6f2b3d388 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -16,3 +16,5 @@ candid.workspace = true clap.workspace = true serde.workspace = true serde_json.workspace = true +cap-std.workspace = true +dfx-core.workspace = true \ No newline at end of file diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs index 264b9549b..2f935f9c8 100644 --- a/tools/dfx-orbit/src/args.rs +++ b/tools/dfx-orbit/src/args.rs @@ -1,4 +1,5 @@ //! Command line interface for `dfx-orbit`. +pub mod dfx_extension_api; pub mod station; use clap::{Parser, Subcommand}; @@ -10,7 +11,7 @@ use station::StationArgs; pub struct DfxOrbitArgs { /// Manage Orbit stations. #[command(subcommand)] - field: DfxOrbitSubcommands, + pub command: DfxOrbitSubcommands, } #[derive(Debug, Subcommand)] @@ -18,4 +19,6 @@ pub struct DfxOrbitArgs { pub enum DfxOrbitSubcommands { #[command(subcommand)] Station(StationArgs), + #[command(subcommand)] + DfxExtension(dfx_extension_api::Args), } diff --git a/tools/dfx-orbit/src/args/dfx_extension_api.rs b/tools/dfx-orbit/src/args/dfx_extension_api.rs new file mode 100644 index 000000000..996347ef7 --- /dev/null +++ b/tools/dfx-orbit/src/args/dfx_extension_api.rs @@ -0,0 +1,12 @@ +//! dfx-orbit station management commands. +pub mod config; + +use clap::Subcommand; + +/// Station management commands. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + #[command(subcommand)] + Config(config::Args), +} diff --git a/tools/dfx-orbit/src/args/dfx_extension_api/config.rs b/tools/dfx-orbit/src/args/dfx_extension_api/config.rs new file mode 100644 index 000000000..fe91bb604 --- /dev/null +++ b/tools/dfx-orbit/src/args/dfx_extension_api/config.rs @@ -0,0 +1,11 @@ +//! Access to the DFX extension configuration. +use clap::{Parser, Subcommand}; + +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + Dir(Dir), +} + +#[derive(Debug, Parser)] +pub struct Dir {} diff --git a/tools/dfx-orbit/src/commands.rs b/tools/dfx-orbit/src/commands.rs index 23e8422e2..6d6462e76 100644 --- a/tools/dfx-orbit/src/commands.rs +++ b/tools/dfx-orbit/src/commands.rs @@ -1,7 +1,29 @@ //! Implementation of the `dfx-orbit` commands. -use crate::args::DfxOrbitArgs; +use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands, dfx_extension_api}; + + pub fn main(args: DfxOrbitArgs) { println!("Hello args: {args:?}"); + + match args.command { + DfxOrbitSubcommands::Station(station_args) => { + println!("Hello station args: {station_args:?}"); + } + DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { + println!("Hello dfx extension args: {dfx_extension_args:?}"); + match dfx_extension_args { + dfx_extension_api::Args::Config(config_args) => { + match config_args { + dfx_extension_api::config::Args::Dir(_dir_args) => { + let extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let ans = extension_agent.extension_config_dir(); + println!("{ans:?}"); + } + } + } + } + } + } } diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 9e0fb78d6..cc5140bf5 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -23,7 +23,29 @@ fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { .trim() .to_string()) } else { - Err(anyhow::anyhow!("dfx failed with status: {}", output.status)) + let stderr = String::from_utf8_lossy(&output.stderr); + Err(anyhow::anyhow!("dfx failed with status {}: {stderr}", output.status)) + } +} + +pub struct DfxExtensionAgent { + name: String, +} + +impl DfxExtensionAgent { + pub fn new(name: &str) -> Self { + Self { + name: name.to_string(), + } + } + + pub fn extension_config_dir(&self) -> anyhow::Result { + let user_config_dir = dfx_core::config::directories::get_user_dfx_config_dir().with_context(|| "Could not find user dfx config dir")?; + let extension_config_dir = user_config_dir.join("extensions").join(&self.name); + std::fs::create_dir_all(&extension_config_dir).with_context(|| format!("Could not create directory at: {}", extension_config_dir.display()))?; + let std_dir = std::fs::File::open(&extension_config_dir).with_context(|| format!("Could not open directory at: {}", extension_config_dir.display()))?; + let cap_dir = cap_std::fs::Dir::from_std_file(std_dir); + Ok(cap_dir) } } From 88f3f0fae45367f59f1ff67a95bcc2ead0b20818 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 03:06:00 +0200 Subject: [PATCH 012/156] ++ --- .../src/args/dfx_extension_api/config.rs | 1 + tools/dfx-orbit/src/commands.rs | 31 +++++++---- tools/dfx-orbit/src/dfx_extension_api.rs | 55 +++++++++++++++++-- 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/tools/dfx-orbit/src/args/dfx_extension_api/config.rs b/tools/dfx-orbit/src/args/dfx_extension_api/config.rs index fe91bb604..8cb0c424a 100644 --- a/tools/dfx-orbit/src/args/dfx_extension_api/config.rs +++ b/tools/dfx-orbit/src/args/dfx_extension_api/config.rs @@ -5,6 +5,7 @@ use clap::{Parser, Subcommand}; #[command(version, about, long_about = None)] pub enum Args { Dir(Dir), + File, } #[derive(Debug, Parser)] diff --git a/tools/dfx-orbit/src/commands.rs b/tools/dfx-orbit/src/commands.rs index 6d6462e76..09be16950 100644 --- a/tools/dfx-orbit/src/commands.rs +++ b/tools/dfx-orbit/src/commands.rs @@ -1,8 +1,7 @@ //! Implementation of the `dfx-orbit` commands. -use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands, dfx_extension_api}; - - +use crate::args::{dfx_extension_api, DfxOrbitArgs, DfxOrbitSubcommands}; +use std::io::Read; pub fn main(args: DfxOrbitArgs) { println!("Hello args: {args:?}"); @@ -14,16 +13,24 @@ pub fn main(args: DfxOrbitArgs) { DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { println!("Hello dfx extension args: {dfx_extension_args:?}"); match dfx_extension_args { - dfx_extension_api::Args::Config(config_args) => { - match config_args { - dfx_extension_api::config::Args::Dir(_dir_args) => { - let extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); - let ans = extension_agent.extension_config_dir(); - println!("{ans:?}"); - } + dfx_extension_api::Args::Config(config_args) => match config_args { + dfx_extension_api::config::Args::Dir(_dir_args) => { + let extension_agent = + crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let ans = extension_agent.extension_config_dir(); + println!("{ans:?}"); + } + dfx_extension_api::config::Args::File => { + let extension_agent = + crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let mut file = extension_agent.extension_config_file().expect("Could not open file"); + let mut ans = String::new(); + file.read_to_string(&mut ans).expect("Could not read file"); + // let config: crate::local_config::CommonConfig = serde_json::from_reader(&mut file).unwrap(); + println!("{ans:?}"); } - } + }, } } } -} +} \ No newline at end of file diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index cc5140bf5..9c1f69123 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -24,7 +24,10 @@ fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { .to_string()) } else { let stderr = String::from_utf8_lossy(&output.stderr); - Err(anyhow::anyhow!("dfx failed with status {}: {stderr}", output.status)) + Err(anyhow::anyhow!( + "dfx failed with status {}: {stderr}", + output.status + )) } } @@ -39,14 +42,54 @@ impl DfxExtensionAgent { } } - pub fn extension_config_dir(&self) -> anyhow::Result { - let user_config_dir = dfx_core::config::directories::get_user_dfx_config_dir().with_context(|| "Could not find user dfx config dir")?; - let extension_config_dir = user_config_dir.join("extensions").join(&self.name); - std::fs::create_dir_all(&extension_config_dir).with_context(|| format!("Could not create directory at: {}", extension_config_dir.display()))?; - let std_dir = std::fs::File::open(&extension_config_dir).with_context(|| format!("Could not open directory at: {}", extension_config_dir.display()))?; + /// Gets the extensions directory, typically at `~/.config/dfx/extensions` + fn extensions_dir() -> anyhow::Result { + let user_config_dir = dfx_core::config::directories::get_user_dfx_config_dir() + .with_context(|| "Could not find user dfx config dir")?; + let extensions_dir = user_config_dir.join("extensions"); + std::fs::create_dir_all(&extensions_dir).with_context(|| { + format!( + "Could not create directory at: {}", + extensions_dir.display() + ) + })?; + let std_dir = std::fs::File::open(&extensions_dir).with_context(|| { + format!( + "Could not open directory at: {}", + extensions_dir.display() + ) + })?; let cap_dir = cap_std::fs::Dir::from_std_file(std_dir); Ok(cap_dir) } + + pub fn extension_config_file(&self) -> anyhow::Result { + let extension_config_dir = self.extension_config_dir()?; + let mut open_options = cap_std::fs::OpenOptions::new(); + let open_options = open_options + .write(true) + .create(true); + extension_config_dir.open_with(format!("{}.json", &self.name), &open_options).with_context(|| { + format!( + "Could not create extension config file for extension: {}", &self.name + ) + }) + } + + /// Gets the extension config directory for this extension. + pub fn extension_config_dir(&self) -> anyhow::Result { + let extensions_dir = Self::extensions_dir()?; + extensions_dir.create_dir_all(&self.name).with_context(|| { + format!( + "Could not create extension directory for extension: {}", &self.name + ) + })?; + extensions_dir.open_dir(&self.name).with_context(|| { + format!( + "Could not open extension directory for extension: {}", &self.name + ) + }) + } } pub mod identity { From 8ae42bb53819e45df45e5e52f642a5dc512bf3a0 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 03:23:23 +0200 Subject: [PATCH 013/156] ++ --- tools/dfx-orbit/src/commands.rs | 6 ++-- tools/dfx-orbit/src/dfx_extension_api.rs | 43 ++++++++++++++---------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/tools/dfx-orbit/src/commands.rs b/tools/dfx-orbit/src/commands.rs index 09be16950..c03c07613 100644 --- a/tools/dfx-orbit/src/commands.rs +++ b/tools/dfx-orbit/src/commands.rs @@ -23,7 +23,9 @@ pub fn main(args: DfxOrbitArgs) { dfx_extension_api::config::Args::File => { let extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); - let mut file = extension_agent.extension_config_file().expect("Could not open file"); + let mut file = extension_agent + .extension_config_file() + .expect("Could not open file"); let mut ans = String::new(); file.read_to_string(&mut ans).expect("Could not read file"); // let config: crate::local_config::CommonConfig = serde_json::from_reader(&mut file).unwrap(); @@ -33,4 +35,4 @@ pub fn main(args: DfxOrbitArgs) { } } } -} \ No newline at end of file +} diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 9c1f69123..002dc6bfe 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -1,5 +1,5 @@ //! Placeholders for the proposed dfx extension API methods. -use std::process::{Command, Stdio}; +use std::{io::Write, process::{Command, Stdio}}; use anyhow::Context; @@ -33,12 +33,14 @@ fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { pub struct DfxExtensionAgent { name: String, + extensions_dir: cap_std::fs::Dir, } impl DfxExtensionAgent { pub fn new(name: &str) -> Self { Self { name: name.to_string(), + extensions_dir: Self::extensions_dir().unwrap(), } } @@ -54,39 +56,44 @@ impl DfxExtensionAgent { ) })?; let std_dir = std::fs::File::open(&extensions_dir).with_context(|| { - format!( - "Could not open directory at: {}", - extensions_dir.display() - ) + format!("Could not open directory at: {}", extensions_dir.display()) })?; let cap_dir = cap_std::fs::Dir::from_std_file(std_dir); Ok(cap_dir) } + fn config_file_name(&self) -> String { + format!("{}.json", &self.name) + } + pub fn extension_config_file(&self) -> anyhow::Result { - let extension_config_dir = self.extension_config_dir()?; - let mut open_options = cap_std::fs::OpenOptions::new(); - let open_options = open_options - .write(true) - .create(true); - extension_config_dir.open_with(format!("{}.json", &self.name), &open_options).with_context(|| { - format!( - "Could not create extension config file for extension: {}", &self.name - ) - }) + let extension_config_dir = &self.extensions_dir; + let filename = self.config_file_name(); + let mut open_options = cap_std::fs::OpenOptions::new(); + let open_options = open_options.read(true).write(true).create(true); + extension_config_dir + .open_with(&filename, &open_options) + .with_context(|| { + format!( + "Could not create extension config file for extension: {}", + &self.name + ) + }) } /// Gets the extension config directory for this extension. pub fn extension_config_dir(&self) -> anyhow::Result { - let extensions_dir = Self::extensions_dir()?; + let extensions_dir = &self.extensions_dir; extensions_dir.create_dir_all(&self.name).with_context(|| { format!( - "Could not create extension directory for extension: {}", &self.name + "Could not create extension directory for extension: {}", + &self.name ) })?; extensions_dir.open_dir(&self.name).with_context(|| { format!( - "Could not open extension directory for extension: {}", &self.name + "Could not open extension directory for extension: {}", + &self.name ) }) } From ff52a154e40519d12698f352bdec935e425eeb06 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 10:04:18 +0200 Subject: [PATCH 014/156] clippy --- tools/dfx-orbit/src/dfx_extension_api.rs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 002dc6bfe..d1fce2df5 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -1,5 +1,5 @@ //! Placeholders for the proposed dfx extension API methods. -use std::{io::Write, process::{Command, Stdio}}; +use std::process::{Command, Stdio}; use anyhow::Context; @@ -69,16 +69,16 @@ impl DfxExtensionAgent { pub fn extension_config_file(&self) -> anyhow::Result { let extension_config_dir = &self.extensions_dir; let filename = self.config_file_name(); - let mut open_options = cap_std::fs::OpenOptions::new(); - let open_options = open_options.read(true).write(true).create(true); - extension_config_dir - .open_with(&filename, &open_options) - .with_context(|| { - format!( - "Could not create extension config file for extension: {}", - &self.name - ) - }) + let mut open_options = cap_std::fs::OpenOptions::new(); + let open_options = open_options.read(true).write(true).create(true); + extension_config_dir + .open_with(&filename, &open_options) + .with_context(|| { + format!( + "Could not create extension config file for extension: {}", + &self.name + ) + }) } /// Gets the extension config directory for this extension. From 239505f6fc41c34998683e8d2f3207b3432dd959 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 10:05:07 +0200 Subject: [PATCH 015/156] clippy --- tools/dfx-orbit/src/args.rs | 5 ++++ tools/dfx-orbit/src/args/dfx_extension_api.rs | 1 + .../src/args/dfx_extension_api/config.rs | 10 ++++---- tools/dfx-orbit/src/args/station.rs | 4 ++++ tools/dfx-orbit/src/commands.rs | 3 ++- tools/dfx-orbit/src/dfx_extension_api.rs | 23 ++++++++++++------- tools/dfx-orbit/src/lib.rs | 4 ++++ tools/dfx-orbit/src/local_config.rs | 3 ++- 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs index 2f935f9c8..43b05392a 100644 --- a/tools/dfx-orbit/src/args.rs +++ b/tools/dfx-orbit/src/args.rs @@ -14,11 +14,16 @@ pub struct DfxOrbitArgs { pub command: DfxOrbitSubcommands, } +/// CLI commands for managing Orbit on the Internet Computer. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum DfxOrbitSubcommands { + /// Manages Orbit stations. #[command(subcommand)] Station(StationArgs), + /// Exercises the experimental DFX extension API. + /// + /// As the API is brand new and prototypical, this is exposed as a subcommand. Once stable it can be removed. #[command(subcommand)] DfxExtension(dfx_extension_api::Args), } diff --git a/tools/dfx-orbit/src/args/dfx_extension_api.rs b/tools/dfx-orbit/src/args/dfx_extension_api.rs index 996347ef7..ba6cc900c 100644 --- a/tools/dfx-orbit/src/args/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/args/dfx_extension_api.rs @@ -7,6 +7,7 @@ use clap::Subcommand; #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { + /// CLI subcommands for getting the local dfx configuration for this extension. #[command(subcommand)] Config(config::Args), } diff --git a/tools/dfx-orbit/src/args/dfx_extension_api/config.rs b/tools/dfx-orbit/src/args/dfx_extension_api/config.rs index 8cb0c424a..89e63fbc5 100644 --- a/tools/dfx-orbit/src/args/dfx_extension_api/config.rs +++ b/tools/dfx-orbit/src/args/dfx_extension_api/config.rs @@ -1,12 +1,12 @@ //! Access to the DFX extension configuration. -use clap::{Parser, Subcommand}; +use clap::Subcommand; +/// CLI subcommands for getting the local dfx configuration for this extension. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { - Dir(Dir), + /// Gets the local configuration directory. + Dir, + /// Gets the local configuration file. File, } - -#[derive(Debug, Parser)] -pub struct Dir {} diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index 5d9392d29..effefb912 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -6,9 +6,13 @@ use clap::{Parser, Subcommand}; #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum StationArgs { + /// Adds an Orbit station to the local dfx configuration. Add(Add), + /// Lists Orbit stations in the local dfx configuration. List(List), + /// Renames an Orbit station in the local dfx configuration. Rename(Rename), + /// Removes an Orbit station from the local dfx configuration. Remove(Remove), } diff --git a/tools/dfx-orbit/src/commands.rs b/tools/dfx-orbit/src/commands.rs index c03c07613..ef5ec3a34 100644 --- a/tools/dfx-orbit/src/commands.rs +++ b/tools/dfx-orbit/src/commands.rs @@ -3,6 +3,7 @@ use crate::args::{dfx_extension_api, DfxOrbitArgs, DfxOrbitSubcommands}; use std::io::Read; +/// A command line tool for interacting with Orbit on the Internet Computer. pub fn main(args: DfxOrbitArgs) { println!("Hello args: {args:?}"); @@ -14,7 +15,7 @@ pub fn main(args: DfxOrbitArgs) { println!("Hello dfx extension args: {dfx_extension_args:?}"); match dfx_extension_args { dfx_extension_api::Args::Config(config_args) => match config_args { - dfx_extension_api::config::Args::Dir(_dir_args) => { + dfx_extension_api::config::Args::Dir => { let extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); let ans = extension_agent.extension_config_dir(); diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index d1fce2df5..1568166b4 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -31,16 +31,21 @@ fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { } } +/// The API through which extensions SHOULD interact with ICP networks and dfx configuration. pub struct DfxExtensionAgent { + /// The name of the dfx extension. name: String, + /// The directory where all extension configuration files are stored, including those of other extensions. extensions_dir: cap_std::fs::Dir, } impl DfxExtensionAgent { + /// Creates a new DfxExtensionAgent for the extension with the given name. pub fn new(name: &str) -> Self { Self { name: name.to_string(), - extensions_dir: Self::extensions_dir().unwrap(), + extensions_dir: Self::extensions_dir() + .expect("Could not get the dfx extensions directory"), } } @@ -62,17 +67,23 @@ impl DfxExtensionAgent { Ok(cap_dir) } + /// Gets the basename of the extension config file. fn config_file_name(&self) -> String { format!("{}.json", &self.name) } + /// Gets the extension config file for this extension. If the file does not exist, it will be created. + /// + /// E.g. `~/.config/dfx/extensions/.json` + /// + /// Note: The file SHOULD be JSON but this is not enforced. pub fn extension_config_file(&self) -> anyhow::Result { let extension_config_dir = &self.extensions_dir; let filename = self.config_file_name(); let mut open_options = cap_std::fs::OpenOptions::new(); let open_options = open_options.read(true).write(true).create(true); extension_config_dir - .open_with(&filename, &open_options) + .open_with(filename, open_options) .with_context(|| { format!( "Could not create extension config file for extension: {}", @@ -97,13 +108,9 @@ impl DfxExtensionAgent { ) }) } -} - -pub mod identity { - use super::call_dfx_cli; - /// The name of the default identity. This is the identity given by `dfx identity whoami` (if any). - pub fn default() -> anyhow::Result { + /// The name of the default dfx user identity. This is the identity given by `dfx identity whoami` (if any). + pub fn identity() -> anyhow::Result { call_dfx_cli(vec!["identity", "whoami"]) } } diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index d500590ef..79d092d32 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -1,4 +1,8 @@ //! Library for interacting with Orbit on the Internet Computer. +#![warn(missing_docs)] +#![warn(clippy::missing_docs_in_private_items)] +#![deny(clippy::panic)] +#![deny(clippy::unwrap_used)] pub mod args; pub mod commands; pub mod dfx_extension_api; diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index c62d6cc7f..dbaeb8373 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -15,6 +15,7 @@ pub struct StationConfig { pub canister_id: String, } +/// Lists all Orbit stations in the local dfx configuration. pub fn list_stations() -> Vec { - vec![] + todo!() } From 5acd6849865a91d57d3b908e6b94cb5b7ce287aa Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 10:53:29 +0200 Subject: [PATCH 016/156] Rename commands to cli --- tools/dfx-orbit/src/{commands.rs => cli.rs} | 0 tools/dfx-orbit/src/lib.rs | 2 +- tools/dfx-orbit/src/main.rs | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename tools/dfx-orbit/src/{commands.rs => cli.rs} (100%) diff --git a/tools/dfx-orbit/src/commands.rs b/tools/dfx-orbit/src/cli.rs similarity index 100% rename from tools/dfx-orbit/src/commands.rs rename to tools/dfx-orbit/src/cli.rs diff --git a/tools/dfx-orbit/src/lib.rs b/tools/dfx-orbit/src/lib.rs index 79d092d32..e975aaded 100644 --- a/tools/dfx-orbit/src/lib.rs +++ b/tools/dfx-orbit/src/lib.rs @@ -4,6 +4,6 @@ #![deny(clippy::panic)] #![deny(clippy::unwrap_used)] pub mod args; -pub mod commands; +pub mod cli; pub mod dfx_extension_api; pub mod local_config; diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index 1838e193b..38c658128 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -6,5 +6,5 @@ use dfx_orbit::{self as lib, args::DfxOrbitArgs}; fn main() { let args = DfxOrbitArgs::parse(); - lib::commands::main(args) + lib::cli::main(args) } From 16a191594236f39a7a472377df5ea1a1c48d7d39 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 11:01:04 +0200 Subject: [PATCH 017/156] Move code to a submodule --- tools/dfx-orbit/src/cli.rs | 26 +++----------------- tools/dfx-orbit/src/cli/dfx_extension_cli.rs | 26 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 23 deletions(-) create mode 100644 tools/dfx-orbit/src/cli/dfx_extension_cli.rs diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index ef5ec3a34..8034d2b7f 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -1,7 +1,7 @@ //! Implementation of the `dfx-orbit` commands. +pub mod dfx_extension_cli; -use crate::args::{dfx_extension_api, DfxOrbitArgs, DfxOrbitSubcommands}; -use std::io::Read; +use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; /// A command line tool for interacting with Orbit on the Internet Computer. pub fn main(args: DfxOrbitArgs) { @@ -13,27 +13,7 @@ pub fn main(args: DfxOrbitArgs) { } DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { println!("Hello dfx extension args: {dfx_extension_args:?}"); - match dfx_extension_args { - dfx_extension_api::Args::Config(config_args) => match config_args { - dfx_extension_api::config::Args::Dir => { - let extension_agent = - crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); - let ans = extension_agent.extension_config_dir(); - println!("{ans:?}"); - } - dfx_extension_api::config::Args::File => { - let extension_agent = - crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); - let mut file = extension_agent - .extension_config_file() - .expect("Could not open file"); - let mut ans = String::new(); - file.read_to_string(&mut ans).expect("Could not read file"); - // let config: crate::local_config::CommonConfig = serde_json::from_reader(&mut file).unwrap(); - println!("{ans:?}"); - } - }, - } + dfx_extension_cli::main(dfx_extension_args); } } } diff --git a/tools/dfx-orbit/src/cli/dfx_extension_cli.rs b/tools/dfx-orbit/src/cli/dfx_extension_cli.rs new file mode 100644 index 000000000..982912dcf --- /dev/null +++ b/tools/dfx-orbit/src/cli/dfx_extension_cli.rs @@ -0,0 +1,26 @@ +//! Implements the dfx extension CLI commands +use crate::args::dfx_extension_api; +use std::io::Read; + +/// Implements CLI commands for getting data from the dfx extension API. +pub fn main(dfx_extension_args: dfx_extension_api::Args) { + match dfx_extension_args { + dfx_extension_api::Args::Config(config_args) => match config_args { + dfx_extension_api::config::Args::Dir => { + let extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let ans = extension_agent.extension_config_dir(); + println!("{ans:?}"); + } + dfx_extension_api::config::Args::File => { + let extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let mut file = extension_agent + .extension_config_file() + .expect("Could not open file"); + let mut ans = String::new(); + file.read_to_string(&mut ans).expect("Could not read file"); + // let config: crate::local_config::CommonConfig = serde_json::from_reader(&mut file).unwrap(); + println!("{ans:?}"); + } + }, + } +} From dde5de2690f819d2445c16ea599dc40583ab1ea7 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 11:02:41 +0200 Subject: [PATCH 018/156] ++ --- tools/dfx-orbit/src/dfx_extension_api.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 1568166b4..29c4b7e73 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -5,7 +5,7 @@ use anyhow::Context; /// Calls the dfx cli. /// -/// Methods are implemented as calls to the dfx cli until a library is available. +/// Some methods are implemented as calls to the dfx cli until a library is available. fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { let output = Command::new("dfx") .args(args) From 932ed774739948c7085c92b5a486a0f1c2bb1e7f Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 11:09:49 +0200 Subject: [PATCH 019/156] ++ --- tools/dfx-orbit/src/cli.rs | 4 ++-- tools/dfx-orbit/src/cli/station.rs | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 tools/dfx-orbit/src/cli/station.rs diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 8034d2b7f..19ec9c93e 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -1,5 +1,6 @@ //! Implementation of the `dfx-orbit` commands. pub mod dfx_extension_cli; +pub mod station; use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; @@ -9,10 +10,9 @@ pub fn main(args: DfxOrbitArgs) { match args.command { DfxOrbitSubcommands::Station(station_args) => { - println!("Hello station args: {station_args:?}"); + station::main(station_args); } DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { - println!("Hello dfx extension args: {dfx_extension_args:?}"); dfx_extension_cli::main(dfx_extension_args); } } diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs new file mode 100644 index 000000000..4fbb61eff --- /dev/null +++ b/tools/dfx-orbit/src/cli/station.rs @@ -0,0 +1,24 @@ +//! Implements the dfx extension CLI commands for managing stations. +use crate::args::station::{StationArgs}; + +/// Implements CLI commands for managing Orbit stations. +pub fn main(args: StationArgs) { + match args { + StationArgs::Add(add_args) => { + todo!("Implement the `add` command for managing stations with args: {add_args:?}."); + } + StationArgs::List(list_args) => { + todo!("Implement the `list` command for managing stations with args: {list_args:?}."); + } + StationArgs::Remove(remove_args) => { + todo!( + "Implement the `remove` command for managing stations with args: {remove_args:?}." + ); + } + StationArgs::Rename(rename_args) => { + todo!( + "Implement the `rename` command for managing stations with args: {rename_args:?}." + ); + } + } +} From 5d65b86d6898859eb867b3fca638640ecd37a5ab Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 11:10:02 +0200 Subject: [PATCH 020/156] ++ --- tools/dfx-orbit/src/cli/station.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 4fbb61eff..3b15b1bf8 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -1,5 +1,5 @@ //! Implements the dfx extension CLI commands for managing stations. -use crate::args::station::{StationArgs}; +use crate::args::station::StationArgs; /// Implements CLI commands for managing Orbit stations. pub fn main(args: StationArgs) { From 5dbb1d0c7a7b5863be453e06797560673f94be70 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 11:17:16 +0200 Subject: [PATCH 021/156] ++ --- tools/dfx-orbit/src/cli/station.rs | 7 +++++-- tools/dfx-orbit/src/local_config.rs | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 3b15b1bf8..47c29f3d0 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -1,5 +1,6 @@ //! Implements the dfx extension CLI commands for managing stations. use crate::args::station::StationArgs; +use crate::local_config; /// Implements CLI commands for managing Orbit stations. pub fn main(args: StationArgs) { @@ -7,8 +8,10 @@ pub fn main(args: StationArgs) { StationArgs::Add(add_args) => { todo!("Implement the `add` command for managing stations with args: {add_args:?}."); } - StationArgs::List(list_args) => { - todo!("Implement the `list` command for managing stations with args: {list_args:?}."); + StationArgs::List(_list_args) => { + let stations = local_config::list_stations(); + let json = serde_json::to_string_pretty(&stations).expect("Failed to serialize list of stations"); + println!("{json}"); } StationArgs::Remove(remove_args) => { todo!( diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index dbaeb8373..2175be1d5 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -1,13 +1,15 @@ //! Local dfx configuration of Orbit stations. +use serde::{Deserialize, Serialize}; /// Configuration that lives in e.g. ~/.config/dfx/orbit.json -#[derive(Debug, serde::Serialize, serde::Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct CommonConfig { /// Default station name. pub default_station: String, } /// Configuration for a given station that lives in e.g. ~/.config/dfx/orbit/stations/.json +#[derive(Debug, Serialize, Deserialize)] pub struct StationConfig { /// Station name. pub name: String, From ded534e97d4b625262a2848e33bddb15b100eb33 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 11:58:07 +0200 Subject: [PATCH 022/156] ++ --- tools/dfx-orbit/src/cli/station.rs | 3 +- tools/dfx-orbit/src/local_config.rs | 61 ++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 47c29f3d0..4e37db767 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -10,7 +10,8 @@ pub fn main(args: StationArgs) { } StationArgs::List(_list_args) => { let stations = local_config::list_stations(); - let json = serde_json::to_string_pretty(&stations).expect("Failed to serialize list of stations"); + let json = serde_json::to_string_pretty(&stations) + .expect("Failed to serialize list of stations"); println!("{json}"); } StationArgs::Remove(remove_args) => { diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 2175be1d5..93bbf4c77 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -1,6 +1,8 @@ //! Local dfx configuration of Orbit stations. use serde::{Deserialize, Serialize}; +use crate::dfx_extension_api::DfxExtensionAgent; + /// Configuration that lives in e.g. ~/.config/dfx/orbit.json #[derive(Debug, Serialize, Deserialize)] pub struct CommonConfig { @@ -17,7 +19,62 @@ pub struct StationConfig { pub canister_id: String, } +/// The directoy in the orbit dfx config directory where stations are stored. +pub const STATIONS_DIR: &str = "stations"; +/// The directory in the orbit dfx config directory where stations are recorded. +pub fn stations_dir() -> anyhow::Result { + let dfx_extension_agent = DfxExtensionAgent::new("orbit"); + let config_dir = dfx_extension_agent + .extension_config_dir() + .expect("Failed to get extension config dir"); + let stations_dir = config_dir + .open_dir(STATIONS_DIR) + .expect("Failed to open stations dir"); + Ok(stations_dir) +} +/// The file in which the config for a particular station is stored. +pub fn station_file(name: &str) -> anyhow::Result { + let basename = format!("{}.json", name); + let stations_dir = stations_dir()?; + let station_file = stations_dir + .open(basename) + .expect("Failed to open station file"); + Ok(station_file) +} + /// Lists all Orbit stations in the local dfx configuration. -pub fn list_stations() -> Vec { - todo!() +pub fn list_stations() -> Vec { + // Get all entries in the station dir that are valid station configs. + let stations_dir = stations_dir().expect("Failed to get stations dir"); + stations_dir + .entries() + .expect("Failed to read stations dir") + // Filter out directory entries that could not be read. (Maybe we have no permissions to access the file or something like that?) + .filter_map(|entry| entry.ok()) + // Filter out entries that are not files. + .filter(|dir_entry| { + dir_entry + .file_type() + .expect("Failed to get file type") + .is_file() + }) + // Filter out entries that don't have the .json suffix. Return the filename without the suffix. This is the station name. + .filter_map(|dir_entry| { + dir_entry + .file_name() + .to_string_lossy() + .strip_suffix(".json") + .map(|name| name.to_string()) + }) + // Filter out entries that are not valid station configs. + .filter(|station_name| station(station_name).is_ok()) + .collect() +} + +/// Gets the local stored dfx configuration for a given station. +pub fn station(name: &str) -> anyhow::Result { + let station_file = station_file(name)?; + let station: StationConfig = + serde_json::from_reader(station_file).expect("Failed to parse station file"); + Ok(station) } From 16deaf5e8a8aeb436cd4fda48f8faeb2c0f5f0b7 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 12:01:58 +0200 Subject: [PATCH 023/156] Lista ll stations --- tools/dfx-orbit/src/local_config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 93bbf4c77..5d09562db 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -27,6 +27,7 @@ pub fn stations_dir() -> anyhow::Result { let config_dir = dfx_extension_agent .extension_config_dir() .expect("Failed to get extension config dir"); + config_dir.create_dir_all(STATIONS_DIR)?; let stations_dir = config_dir .open_dir(STATIONS_DIR) .expect("Failed to open stations dir"); From 21aee9fd7d84f09c84bcf19fae5320551539d7ce Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 12:57:57 +0200 Subject: [PATCH 024/156] Command to show --- tools/dfx-orbit/src/args/station.rs | 20 +++++++++++++++----- tools/dfx-orbit/src/cli/station.rs | 9 ++++++++- tools/dfx-orbit/src/local_config.rs | 23 +++++++++++++++++++++-- 3 files changed, 44 insertions(+), 8 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index effefb912..cc2046149 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -10,6 +10,8 @@ pub enum StationArgs { Add(Add), /// Lists Orbit stations in the local dfx configuration. List(List), + /// Shows the local configuration for an Orbit station. + Show(Show), /// Renames an Orbit station in the local dfx configuration. Rename(Rename), /// Removes an Orbit station from the local dfx configuration. @@ -21,25 +23,33 @@ pub enum StationArgs { pub struct Add { /// Wallet name. #[structopt(long)] - name: String, + pub name: String, /// Wallet canister ID. #[structopt(long)] - canister_id: Principal, + pub canister_id: Principal, } /// Lists Orbit station in the local dfx configuration. #[derive(Debug, Parser)] pub struct List {} +/// Shows the local configuration for an Orbit station. +#[derive(Debug, Parser)] +pub struct Show { + /// Station name. + #[structopt(long)] + pub name: String, +} + /// Renames an Orbit station in the local dfx configuration. #[derive(Debug, Parser)] pub struct Rename { /// Station name. #[structopt(long)] - name: String, + pub name: String, /// New station name. #[structopt(long)] - new_name: String, + pub new_name: String, } /// Removes an Orbit station from the local dfx configuration. @@ -47,5 +57,5 @@ pub struct Rename { pub struct Remove { /// Station name. #[structopt(long)] - name: String, + pub name: String, } diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 4e37db767..c190ecfbf 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -6,7 +6,8 @@ use crate::local_config; pub fn main(args: StationArgs) { match args { StationArgs::Add(add_args) => { - todo!("Implement the `add` command for managing stations with args: {add_args:?}."); + local_config::add_station(&add_args) + .expect("Failed to add station to local dfx config"); } StationArgs::List(_list_args) => { let stations = local_config::list_stations(); @@ -14,6 +15,12 @@ pub fn main(args: StationArgs) { .expect("Failed to serialize list of stations"); println!("{json}"); } + StationArgs::Show(show_args) => { + let station = local_config::station(&show_args.name) + .expect("Failed to get station from local dfx config"); + let json = serde_json::to_string_pretty(&station).expect("Failed to serialize station"); + println!("{json}"); + } StationArgs::Remove(remove_args) => { todo!( "Implement the `remove` command for managing stations with args: {remove_args:?}." diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 5d09562db..c13eb4d8e 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -1,7 +1,7 @@ //! Local dfx configuration of Orbit stations. use serde::{Deserialize, Serialize}; -use crate::dfx_extension_api::DfxExtensionAgent; +use crate::{args::station::Add, dfx_extension_api::DfxExtensionAgent}; /// Configuration that lives in e.g. ~/.config/dfx/orbit.json #[derive(Debug, Serialize, Deserialize)] @@ -34,11 +34,15 @@ pub fn stations_dir() -> anyhow::Result { Ok(stations_dir) } /// The file in which the config for a particular station is stored. +/// +/// If the file does not exist, it will be created. pub fn station_file(name: &str) -> anyhow::Result { let basename = format!("{}.json", name); let stations_dir = stations_dir()?; + let mut open_options = cap_std::fs::OpenOptions::new(); + let open_options = open_options.read(true).write(true).create(true); let station_file = stations_dir - .open(basename) + .open_with(basename, open_options) .expect("Failed to open station file"); Ok(station_file) } @@ -72,6 +76,21 @@ pub fn list_stations() -> Vec { .collect() } +/// Adds a new Orbit station to the local dfx configuration. +pub fn add_station(args: &Add) -> anyhow::Result<()> { + let Add { name, canister_id } = args; + let station = StationConfig { + name: name.to_string(), + canister_id: canister_id.to_string(), + }; + let station_file = station_file(name)?; + if station_file.metadata()?.len() > 0 { + anyhow::bail!("Station already exists"); + } + serde_json::to_writer_pretty(station_file, &station).expect("Failed to write station file"); + Ok(()) +} + /// Gets the local stored dfx configuration for a given station. pub fn station(name: &str) -> anyhow::Result { let station_file = station_file(name)?; From ac118cad0927a30b2757852a0e58f359a8bfc322 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 12:58:57 +0200 Subject: [PATCH 025/156] Remove println --- tools/dfx-orbit/src/cli.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 19ec9c93e..e749e7780 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -6,8 +6,6 @@ use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; /// A command line tool for interacting with Orbit on the Internet Computer. pub fn main(args: DfxOrbitArgs) { - println!("Hello args: {args:?}"); - match args.command { DfxOrbitSubcommands::Station(station_args) => { station::main(station_args); From 8f935408769ca6948eb6306d655d4e0c6ee98844 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 13:47:00 +0200 Subject: [PATCH 026/156] Support removing stations --- tools/dfx-orbit/src/cli/station.rs | 5 ++--- tools/dfx-orbit/src/local_config.rs | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index c190ecfbf..4ed3fa7b2 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -22,9 +22,8 @@ pub fn main(args: StationArgs) { println!("{json}"); } StationArgs::Remove(remove_args) => { - todo!( - "Implement the `remove` command for managing stations with args: {remove_args:?}." - ); + local_config::remove_station(&remove_args.name) + .expect("Failed to remove station from local dfx config"); } StationArgs::Rename(rename_args) => { todo!( diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index c13eb4d8e..bcaee9018 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -1,4 +1,5 @@ //! Local dfx configuration of Orbit stations. +use anyhow::Context; use serde::{Deserialize, Serialize}; use crate::{args::station::Add, dfx_extension_api::DfxExtensionAgent}; @@ -33,11 +34,16 @@ pub fn stations_dir() -> anyhow::Result { .expect("Failed to open stations dir"); Ok(stations_dir) } +/// The name of the file in which the config for a given station is stored. +pub fn station_file_name(name: &str) -> String { + format!("{}.json", name) +} + /// The file in which the config for a particular station is stored. /// /// If the file does not exist, it will be created. pub fn station_file(name: &str) -> anyhow::Result { - let basename = format!("{}.json", name); + let basename = station_file_name(name); let stations_dir = stations_dir()?; let mut open_options = cap_std::fs::OpenOptions::new(); let open_options = open_options.read(true).write(true).create(true); @@ -98,3 +104,11 @@ pub fn station(name: &str) -> anyhow::Result { serde_json::from_reader(station_file).expect("Failed to parse station file"); Ok(station) } + +/// Removes an Orbit station from the local dfx configuration. +pub fn remove_station(name: &str) -> anyhow::Result<()> { + let dir = stations_dir()?; + let path = station_file_name(name); + dir.remove_file(path) + .with_context(|| format!("Failed to remove dfx config file for station {}", name)) +} From 091384a75145d6a0836fd59f6fabc3d64dad18b6 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 13:51:46 +0200 Subject: [PATCH 027/156] Implement rename --- tools/dfx-orbit/src/cli/station.rs | 5 ++--- tools/dfx-orbit/src/local_config.rs | 13 +++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 4ed3fa7b2..b74bfb7cf 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -26,9 +26,8 @@ pub fn main(args: StationArgs) { .expect("Failed to remove station from local dfx config"); } StationArgs::Rename(rename_args) => { - todo!( - "Implement the `rename` command for managing stations with args: {rename_args:?}." - ); + local_config::rename_station(&rename_args.name, &rename_args.new_name) + .expect("Failed to rename station in local dfx config"); } } } diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index bcaee9018..e74f528f0 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -112,3 +112,16 @@ pub fn remove_station(name: &str) -> anyhow::Result<()> { dir.remove_file(path) .with_context(|| format!("Failed to remove dfx config file for station {}", name)) } + +/// Renames an Orbit station in the local dfx configuration. +pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { + let dir = stations_dir()?; + let old_path = station_file_name(name); + let new_path = station_file_name(new_name); + dir.rename(old_path, &dir, new_path).with_context(|| { + format!( + "Failed to rename dfx config file for station {} to {}", + name, new_name + ) + }) +} From c905a08d6e804f75d6c44de51213295d14ef2ccd Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 14:06:51 +0200 Subject: [PATCH 028/156] Command to get the default station --- tools/dfx-orbit/src/args/station.rs | 2 ++ tools/dfx-orbit/src/cli/station.rs | 7 +++++++ tools/dfx-orbit/src/local_config.rs | 16 +++++++++++++++- 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index cc2046149..8198c8f6e 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -10,6 +10,8 @@ pub enum StationArgs { Add(Add), /// Lists Orbit stations in the local dfx configuration. List(List), + /// The default station. + Default, /// Shows the local configuration for an Orbit station. Show(Show), /// Renames an Orbit station in the local dfx configuration. diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index b74bfb7cf..664a265e4 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -15,6 +15,13 @@ pub fn main(args: StationArgs) { .expect("Failed to serialize list of stations"); println!("{json}"); } + StationArgs::Default => { + let default_station = local_config::default_station_name() + .expect("Failed to get default station from local dfx config"); + let json = serde_json::to_string_pretty(&default_station) + .expect("Failed to serialize default station"); + println!("{json}"); + } StationArgs::Show(show_args) => { let station = local_config::station(&show_args.name) .expect("Failed to get station from local dfx config"); diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index e74f528f0..ac119bd17 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -38,7 +38,6 @@ pub fn stations_dir() -> anyhow::Result { pub fn station_file_name(name: &str) -> String { format!("{}.json", name) } - /// The file in which the config for a particular station is stored. /// /// If the file does not exist, it will be created. @@ -125,3 +124,18 @@ pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { ) }) } + +/// Gets the common configuration for this dfx extension. +pub fn common_config() -> anyhow::Result { + // TODO: Make orbit a const + let dfx_extension_agent = DfxExtensionAgent::new("orbit"); + let common_config_file = dfx_extension_agent.extension_config_file()?; + let common_config: CommonConfig = serde_json::from_reader(common_config_file).with_context(||"Failed to parse extension config file as JSON.")?; + Ok(common_config) +} + +/// Gets the default Orbit station from the local dfx configuration. +pub fn default_station_name() -> anyhow::Result { + let common_config = common_config()?; + Ok(common_config.default_station) +} \ No newline at end of file From cbb5a9fb53e51c42cc5840cc26c2ea9499286f7c Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 14:23:21 +0200 Subject: [PATCH 029/156] ++ --- tools/dfx-orbit/src/cli/station.rs | 6 ++---- tools/dfx-orbit/src/local_config.rs | 10 +++++----- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 664a265e4..290e883b3 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -17,10 +17,8 @@ pub fn main(args: StationArgs) { } StationArgs::Default => { let default_station = local_config::default_station_name() - .expect("Failed to get default station from local dfx config"); - let json = serde_json::to_string_pretty(&default_station) - .expect("Failed to serialize default station"); - println!("{json}"); + .expect("Failed to get default station from local dfx config").unwrap_or_default(); + println!("{default_station}"); } StationArgs::Show(show_args) => { let station = local_config::station(&show_args.name) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index ac119bd17..2c7314418 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -8,7 +8,7 @@ use crate::{args::station::Add, dfx_extension_api::DfxExtensionAgent}; #[derive(Debug, Serialize, Deserialize)] pub struct CommonConfig { /// Default station name. - pub default_station: String, + pub default_station: Option, } /// Configuration for a given station that lives in e.g. ~/.config/dfx/orbit/stations/.json @@ -130,12 +130,12 @@ pub fn common_config() -> anyhow::Result { // TODO: Make orbit a const let dfx_extension_agent = DfxExtensionAgent::new("orbit"); let common_config_file = dfx_extension_agent.extension_config_file()?; - let common_config: CommonConfig = serde_json::from_reader(common_config_file).with_context(||"Failed to parse extension config file as JSON.")?; + let common_config: CommonConfig = serde_json::from_reader(common_config_file) + .with_context(|| "Failed to parse extension config file as JSON.")?; Ok(common_config) } /// Gets the default Orbit station from the local dfx configuration. -pub fn default_station_name() -> anyhow::Result { - let common_config = common_config()?; - Ok(common_config.default_station) +pub fn default_station_name() -> anyhow::Result> { + Ok(common_config()?.default_station) } \ No newline at end of file From 0a5b9484c0208e7170c0a4666a678f04f7310bb2 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 14:33:13 +0200 Subject: [PATCH 030/156] Command to set teh default station --- tools/dfx-orbit/src/args/station.rs | 10 ++++++++++ tools/dfx-orbit/src/cli/station.rs | 7 ++++++- tools/dfx-orbit/src/local_config.rs | 16 +++++++++++++++- 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index 8198c8f6e..b6c00f979 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -12,6 +12,8 @@ pub enum StationArgs { List(List), /// The default station. Default, + /// Sets the default station in the local dfx configuration. + Use(Use), /// Shows the local configuration for an Orbit station. Show(Show), /// Renames an Orbit station in the local dfx configuration. @@ -61,3 +63,11 @@ pub struct Remove { #[structopt(long)] pub name: String, } + +/// Sets the default station in the local dfx configuration. +#[derive(Debug, Parser)] +pub struct Use { + /// Station name. + #[structopt(long)] + pub name: String, +} diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 290e883b3..1e960c17d 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -17,9 +17,14 @@ pub fn main(args: StationArgs) { } StationArgs::Default => { let default_station = local_config::default_station_name() - .expect("Failed to get default station from local dfx config").unwrap_or_default(); + .expect("Failed to get default station from local dfx config") + .unwrap_or_default(); println!("{default_station}"); } + StationArgs::Use(use_args) => { + local_config::set_default_station(&use_args.name) + .expect("Failed to set default station in local dfx config"); + } StationArgs::Show(show_args) => { let station = local_config::station(&show_args.name) .expect("Failed to get station from local dfx config"); diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 2c7314418..f6a68dfe5 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -138,4 +138,18 @@ pub fn common_config() -> anyhow::Result { /// Gets the default Orbit station from the local dfx configuration. pub fn default_station_name() -> anyhow::Result> { Ok(common_config()?.default_station) -} \ No newline at end of file +} + +/// Sets the default Orbit station in the local dfx configuration. +pub fn set_default_station(name: &str) -> anyhow::Result<()> { + // Check if the station exists. + station(name)?; + // Set the default station. + let mut common_config = common_config()?; + common_config.default_station = Some(name.to_string()); + let dfx_extension_agent = DfxExtensionAgent::new("orbit"); + let common_config_file = dfx_extension_agent.extension_config_file()?; + serde_json::to_writer_pretty(common_config_file, &common_config) + .with_context(|| "Failed to write extension config file as JSON.")?; + Ok(()) +} From a90ad471739e82cbc6c792e76220cf13f005127f Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 14:35:59 +0200 Subject: [PATCH 031/156] Update teh default station name on rename --- tools/dfx-orbit/src/local_config.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index f6a68dfe5..ff99bbfd0 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -113,6 +113,8 @@ pub fn remove_station(name: &str) -> anyhow::Result<()> { } /// Renames an Orbit station in the local dfx configuration. +/// +/// If teh station being renamed is the default station, the common config is updated to reflect the new name. pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { let dir = stations_dir()?; let old_path = station_file_name(name); @@ -122,7 +124,13 @@ pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { "Failed to rename dfx config file for station {} to {}", name, new_name ) - }) + })?; + + let common_config = common_config()?; + if common_config.default_station == Some(name.to_string()) { + set_default_station(new_name)?; + } + Ok(()) } /// Gets the common configuration for this dfx extension. From b63aafe036e90ccf7397d17a5478e49de828787d Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 14:38:35 +0200 Subject: [PATCH 032/156] cleaner --- tools/dfx-orbit/src/local_config.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index ff99bbfd0..f3346a091 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -114,7 +114,7 @@ pub fn remove_station(name: &str) -> anyhow::Result<()> { /// Renames an Orbit station in the local dfx configuration. /// -/// If teh station being renamed is the default station, the common config is updated to reflect the new name. +/// If the station being renamed is the default station, the common config is updated to reflect the new name. pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { let dir = stations_dir()?; let old_path = station_file_name(name); @@ -126,8 +126,7 @@ pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { ) })?; - let common_config = common_config()?; - if common_config.default_station == Some(name.to_string()) { + if default_station_name()? == Some(name.to_string()) { set_default_station(new_name)?; } Ok(()) From 9d8703871a236751b4719966ee943ba914f69a45 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 14:44:26 +0200 Subject: [PATCH 033/156] Update default when adding or removing --- tools/dfx-orbit/src/cli/station.rs | 2 +- tools/dfx-orbit/src/local_config.rs | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 1e960c17d..7b7ceac35 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -22,7 +22,7 @@ pub fn main(args: StationArgs) { println!("{default_station}"); } StationArgs::Use(use_args) => { - local_config::set_default_station(&use_args.name) + local_config::set_default_station(Some(use_args.name)) .expect("Failed to set default station in local dfx config"); } StationArgs::Show(show_args) => { diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index f3346a091..e62fb825a 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -93,6 +93,11 @@ pub fn add_station(args: &Add) -> anyhow::Result<()> { anyhow::bail!("Station already exists"); } serde_json::to_writer_pretty(station_file, &station).expect("Failed to write station file"); + + if default_station_name()?.is_none() { + set_default_station(Some(name.to_string()))?; + } + Ok(()) } @@ -109,7 +114,12 @@ pub fn remove_station(name: &str) -> anyhow::Result<()> { let dir = stations_dir()?; let path = station_file_name(name); dir.remove_file(path) - .with_context(|| format!("Failed to remove dfx config file for station {}", name)) + .with_context(|| format!("Failed to remove dfx config file for station {}", name))?; + + if default_station_name()? == Some(name.to_string()) { + set_default_station(None)?; + } + Ok(()) } /// Renames an Orbit station in the local dfx configuration. @@ -127,7 +137,7 @@ pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { })?; if default_station_name()? == Some(name.to_string()) { - set_default_station(new_name)?; + set_default_station(Some(name.to_string()))?; } Ok(()) } @@ -148,12 +158,14 @@ pub fn default_station_name() -> anyhow::Result> { } /// Sets the default Orbit station in the local dfx configuration. -pub fn set_default_station(name: &str) -> anyhow::Result<()> { +pub fn set_default_station(name_maybe: Option) -> anyhow::Result<()> { // Check if the station exists. - station(name)?; + if let Some(name) = &name_maybe { + station(name)?; + } // Set the default station. let mut common_config = common_config()?; - common_config.default_station = Some(name.to_string()); + common_config.default_station = name_maybe; let dfx_extension_agent = DfxExtensionAgent::new("orbit"); let common_config_file = dfx_extension_agent.extension_config_file()?; serde_json::to_writer_pretty(common_config_file, &common_config) From b48f3117441234e340f27fb59e9bc98c98f67515 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:00:35 +0200 Subject: [PATCH 034/156] Format List response --- tools/dfx-orbit/src/args/station.rs | 17 +++++++++++++++++ tools/dfx-orbit/src/cli/station.rs | 7 +++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index b6c00f979..d096e9870 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -1,4 +1,6 @@ //! dfx-orbit station management commands. +use std::fmt::{self, Display, Formatter}; + use candid::Principal; use clap::{Parser, Subcommand}; @@ -37,6 +39,21 @@ pub struct Add { #[derive(Debug, Parser)] pub struct List {} +/// Response to a List command. +#[derive(Debug, serde::Serialize)] +pub struct ListResponse { + /// List of station names. + pub stations: Vec, +} +impl Display for ListResponse { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + for station in &self.stations { + writeln!(f, "{station}")?; + } + Ok(()) + } +} + /// Shows the local configuration for an Orbit station. #[derive(Debug, Parser)] pub struct Show { diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 7b7ceac35..df3b63c1b 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -1,5 +1,5 @@ //! Implements the dfx extension CLI commands for managing stations. -use crate::args::station::StationArgs; +use crate::args::station::{ListResponse, StationArgs}; use crate::local_config; /// Implements CLI commands for managing Orbit stations. @@ -11,9 +11,8 @@ pub fn main(args: StationArgs) { } StationArgs::List(_list_args) => { let stations = local_config::list_stations(); - let json = serde_json::to_string_pretty(&stations) - .expect("Failed to serialize list of stations"); - println!("{json}"); + let ans = ListResponse { stations }; + println!("{ans}"); } StationArgs::Default => { let default_station = local_config::default_station_name() From a14aae28d19db341f60f1a910c102aa81c959c81 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:01:52 +0200 Subject: [PATCH 035/156] Format default response --- tools/dfx-orbit/src/cli/station.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index df3b63c1b..165b34c41 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -16,9 +16,10 @@ pub fn main(args: StationArgs) { } StationArgs::Default => { let default_station = local_config::default_station_name() - .expect("Failed to get default station from local dfx config") - .unwrap_or_default(); - println!("{default_station}"); + .expect("Failed to get default station from local dfx config"); + if let Some(station) = default_station { + println!("{station}"); + } } StationArgs::Use(use_args) => { local_config::set_default_station(Some(use_args.name)) From d6b8da7c73ba9d73b8a389f0f2ecfb91a83aeb15 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:05:56 +0200 Subject: [PATCH 036/156] format list --- tools/dfx-orbit/src/cli/station.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 165b34c41..d7ff66fe7 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -12,7 +12,8 @@ pub fn main(args: StationArgs) { StationArgs::List(_list_args) => { let stations = local_config::list_stations(); let ans = ListResponse { stations }; - println!("{ans}"); + // Note: The formatted ans is a sequence of complete lines, so an additional newline, as provided by println, is not needed. + print!("{ans}"); } StationArgs::Default => { let default_station = local_config::default_station_name() From 0fc9b05dcaae4913c8107dc849e72bcfceb247cc Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:10:09 +0200 Subject: [PATCH 037/156] Rename for clarity --- tools/dfx-orbit/src/local_config.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index e62fb825a..9c3895338 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -6,7 +6,7 @@ use crate::{args::station::Add, dfx_extension_api::DfxExtensionAgent}; /// Configuration that lives in e.g. ~/.config/dfx/orbit.json #[derive(Debug, Serialize, Deserialize)] -pub struct CommonConfig { +pub struct ExtensionConfig { /// Default station name. pub default_station: Option, } @@ -143,11 +143,11 @@ pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { } /// Gets the common configuration for this dfx extension. -pub fn common_config() -> anyhow::Result { +pub fn common_config() -> anyhow::Result { // TODO: Make orbit a const let dfx_extension_agent = DfxExtensionAgent::new("orbit"); let common_config_file = dfx_extension_agent.extension_config_file()?; - let common_config: CommonConfig = serde_json::from_reader(common_config_file) + let common_config: ExtensionConfig = serde_json::from_reader(common_config_file) .with_context(|| "Failed to parse extension config file as JSON.")?; Ok(common_config) } From f86d8c8ef3719df3534d85e2e7e3bf4ca85094ae Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:16:13 +0200 Subject: [PATCH 038/156] If the extension config is missing, assume defaults --- tools/dfx-orbit/src/local_config.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 9c3895338..eb4afc3d6 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -5,7 +5,7 @@ use serde::{Deserialize, Serialize}; use crate::{args::station::Add, dfx_extension_api::DfxExtensionAgent}; /// Configuration that lives in e.g. ~/.config/dfx/orbit.json -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Default, Serialize, Deserialize)] pub struct ExtensionConfig { /// Default station name. pub default_station: Option, @@ -124,7 +124,7 @@ pub fn remove_station(name: &str) -> anyhow::Result<()> { /// Renames an Orbit station in the local dfx configuration. /// -/// If the station being renamed is the default station, the common config is updated to reflect the new name. +/// If the station being renamed is the default station, the default is updated to reflect the new name. pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { let dir = stations_dir()?; let old_path = station_file_name(name); @@ -143,18 +143,23 @@ pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { } /// Gets the common configuration for this dfx extension. -pub fn common_config() -> anyhow::Result { +/// +/// If the config does not exist or is empty, default values are assumed. +pub fn extension_config() -> anyhow::Result { // TODO: Make orbit a const let dfx_extension_agent = DfxExtensionAgent::new("orbit"); let common_config_file = dfx_extension_agent.extension_config_file()?; - let common_config: ExtensionConfig = serde_json::from_reader(common_config_file) - .with_context(|| "Failed to parse extension config file as JSON.")?; - Ok(common_config) + if common_config_file.metadata()?.len() == 0 { + Ok(ExtensionConfig::default()) + } else { + serde_json::from_reader(common_config_file) + .with_context(|| "Failed to parse extension config file as JSON.") + } } /// Gets the default Orbit station from the local dfx configuration. pub fn default_station_name() -> anyhow::Result> { - Ok(common_config()?.default_station) + Ok(extension_config()?.default_station) } /// Sets the default Orbit station in the local dfx configuration. @@ -164,11 +169,11 @@ pub fn set_default_station(name_maybe: Option) -> anyhow::Result<()> { station(name)?; } // Set the default station. - let mut common_config = common_config()?; - common_config.default_station = name_maybe; + let mut extension_config = extension_config()?; + extension_config.default_station = name_maybe; let dfx_extension_agent = DfxExtensionAgent::new("orbit"); let common_config_file = dfx_extension_agent.extension_config_file()?; - serde_json::to_writer_pretty(common_config_file, &common_config) + serde_json::to_writer_pretty(common_config_file, &extension_config) .with_context(|| "Failed to write extension config file as JSON.")?; Ok(()) } From 029dc94e3a663337d95e65241d9ceecaf425d551 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:22:47 +0200 Subject: [PATCH 039/156] Tweak --- tools/dfx-orbit/src/args/station.rs | 4 ++-- tools/dfx-orbit/src/cli/station.rs | 2 +- tools/dfx-orbit/src/local_config.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index d096e9870..c2194c0c3 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -67,10 +67,10 @@ pub struct Show { pub struct Rename { /// Station name. #[structopt(long)] - pub name: String, + pub old: String, /// New station name. #[structopt(long)] - pub new_name: String, + pub new: String, } /// Removes an Orbit station from the local dfx configuration. diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index d7ff66fe7..2455a35ec 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -37,7 +37,7 @@ pub fn main(args: StationArgs) { .expect("Failed to remove station from local dfx config"); } StationArgs::Rename(rename_args) => { - local_config::rename_station(&rename_args.name, &rename_args.new_name) + local_config::rename_station(&rename_args.old, &rename_args.new) .expect("Failed to rename station in local dfx config"); } } diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index eb4afc3d6..53a55b8f0 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -137,7 +137,7 @@ pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { })?; if default_station_name()? == Some(name.to_string()) { - set_default_station(Some(name.to_string()))?; + set_default_station(Some(new_name.to_string()))?; } Ok(()) } From 8fa3665083c1d3bfcb1e35deb048ccc1529f6add Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:26:54 +0200 Subject: [PATCH 040/156] Result not expect --- tools/dfx-orbit/src/local_config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 53a55b8f0..61768082f 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -105,7 +105,7 @@ pub fn add_station(args: &Add) -> anyhow::Result<()> { pub fn station(name: &str) -> anyhow::Result { let station_file = station_file(name)?; let station: StationConfig = - serde_json::from_reader(station_file).expect("Failed to parse station file"); + serde_json::from_reader(station_file).with_context(|| "Failed to parse station file")?; Ok(station) } From 3f5e4093f43a271656f6ec9d5f2697ee396bb3c1 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:41:41 +0200 Subject: [PATCH 041/156] ++ --- tools/dfx-orbit/src/local_config.rs | 35 ++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 61768082f..983067d87 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -40,16 +40,32 @@ pub fn station_file_name(name: &str) -> String { } /// The file in which the config for a particular station is stored. /// -/// If the file does not exist, it will be created. +/// If the file does not exist, this will return an error. pub fn station_file(name: &str) -> anyhow::Result { + open_station_file(name, false).with_context(|| { + format!("Failed to open station file for station '{name}': Is the station name correct?") + }) +} + +/// Creates and returne file in which the config for a particular station is stored. +/// +/// If the file already exists, this will return an error. +pub fn create_station_file(name: &str) -> anyhow::Result { + open_station_file(name, true).with_context(|| { + format!("Failed to create station file for station '{name}'. Does it already exist?") + }) +} + +/// The file in which the config for a particular station is stored. +/// +/// Optionally create the file if it does not exist. +pub fn open_station_file(name: &str, create_new: bool) -> anyhow::Result { let basename = station_file_name(name); let stations_dir = stations_dir()?; let mut open_options = cap_std::fs::OpenOptions::new(); - let open_options = open_options.read(true).write(true).create(true); - let station_file = stations_dir - .open_with(basename, open_options) - .expect("Failed to open station file"); - Ok(station_file) + let open_options = open_options.read(true).write(true).create_new(create_new); + let file = stations_dir.open_with(basename, open_options)?; + Ok(file) } /// Lists all Orbit stations in the local dfx configuration. @@ -82,16 +98,15 @@ pub fn list_stations() -> Vec { } /// Adds a new Orbit station to the local dfx configuration. +/// +/// If there is no default station, the new station is set as the default. pub fn add_station(args: &Add) -> anyhow::Result<()> { let Add { name, canister_id } = args; let station = StationConfig { name: name.to_string(), canister_id: canister_id.to_string(), }; - let station_file = station_file(name)?; - if station_file.metadata()?.len() > 0 { - anyhow::bail!("Station already exists"); - } + let station_file = create_station_file(name)?; serde_json::to_writer_pretty(station_file, &station).expect("Failed to write station file"); if default_station_name()?.is_none() { From d88e3d90b5dbaae5a7fa8e0390bb81ada002ae99 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:51:33 +0200 Subject: [PATCH 042/156] Tweak --- tools/dfx-orbit/src/local_config.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 983067d87..e805bd126 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -107,6 +107,7 @@ pub fn add_station(args: &Add) -> anyhow::Result<()> { canister_id: canister_id.to_string(), }; let station_file = create_station_file(name)?; + station_file.set_len(0)?; serde_json::to_writer_pretty(station_file, &station).expect("Failed to write station file"); if default_station_name()?.is_none() { @@ -188,6 +189,7 @@ pub fn set_default_station(name_maybe: Option) -> anyhow::Result<()> { extension_config.default_station = name_maybe; let dfx_extension_agent = DfxExtensionAgent::new("orbit"); let common_config_file = dfx_extension_agent.extension_config_file()?; + common_config_file.set_len(0)?; serde_json::to_writer_pretty(common_config_file, &extension_config) .with_context(|| "Failed to write extension config file as JSON.")?; Ok(()) From b24f45e8511a92248e17084c0f5f4c93fda521a4 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 16:54:46 +0200 Subject: [PATCH 043/156] Update --- tools/dfx-orbit/src/local_config.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index e805bd126..8a1fa82f2 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -189,6 +189,9 @@ pub fn set_default_station(name_maybe: Option) -> anyhow::Result<()> { extension_config.default_station = name_maybe; let dfx_extension_agent = DfxExtensionAgent::new("orbit"); let common_config_file = dfx_extension_agent.extension_config_file()?; + // TODO: Update atomically rather than rewriting. + // TODO: Have a dedicated function for doing the update rather than updating the file directly. + // Something like with_config_update(|config| { config.default_station = name_maybe; }) that provides the current config and writes the modified config back. common_config_file.set_len(0)?; serde_json::to_writer_pretty(common_config_file, &extension_config) .with_context(|| "Failed to write extension config file as JSON.")?; From 9bac90318b315d9cde356f3c4496c15fdee6eab3 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 12 Jun 2024 17:10:12 +0200 Subject: [PATCH 044/156] Clap for claiming a canister --- tools/dfx-orbit/src/args.rs | 4 ++++ tools/dfx-orbit/src/args/canister.rs | 23 +++++++++++++++++++++++ tools/dfx-orbit/src/cli.rs | 4 ++++ tools/dfx-orbit/src/cli/canister.rs | 12 ++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 tools/dfx-orbit/src/args/canister.rs create mode 100644 tools/dfx-orbit/src/cli/canister.rs diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs index 43b05392a..e2051a2ca 100644 --- a/tools/dfx-orbit/src/args.rs +++ b/tools/dfx-orbit/src/args.rs @@ -1,6 +1,7 @@ //! Command line interface for `dfx-orbit`. pub mod dfx_extension_api; pub mod station; +pub mod canister; use clap::{Parser, Subcommand}; use station::StationArgs; @@ -21,6 +22,9 @@ pub enum DfxOrbitSubcommands { /// Manages Orbit stations. #[command(subcommand)] Station(StationArgs), + /// Manages external canisters with Orbit. + #[command(subcommand)] + Canister(canister::Args), /// Exercises the experimental DFX extension API. /// /// As the API is brand new and prototypical, this is exposed as a subcommand. Once stable it can be removed. diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs new file mode 100644 index 000000000..a7f271b4d --- /dev/null +++ b/tools/dfx-orbit/src/args/canister.rs @@ -0,0 +1,23 @@ +//! dfx-orbit external canister management commands. + +use candid::Principal; +use clap::{Parser, Subcommand}; + +/// Station management commands. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Puts a canister controlled by the user under Orbit control. + Claim(Claim), +} + +/// Puts a canister controlled by the user under Orbit control. +#[derive(Debug, Parser)] +pub struct Claim { + /// The canister ID. + #[structopt(long)] + pub canister_id: Principal, + /// Make Orbit the exclusive controller of the canister. + #[clap(long, short, action)] + pub exclusive: bool, +} \ No newline at end of file diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index e749e7780..57edd6503 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -1,6 +1,7 @@ //! Implementation of the `dfx-orbit` commands. pub mod dfx_extension_cli; pub mod station; +pub mod canister; use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; @@ -13,5 +14,8 @@ pub fn main(args: DfxOrbitArgs) { DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { dfx_extension_cli::main(dfx_extension_args); } + DfxOrbitSubcommands::Canister(canister_args) => { + canister::main(canister_args); + } } } diff --git a/tools/dfx-orbit/src/cli/canister.rs b/tools/dfx-orbit/src/cli/canister.rs new file mode 100644 index 000000000..052e17173 --- /dev/null +++ b/tools/dfx-orbit/src/cli/canister.rs @@ -0,0 +1,12 @@ +//! Implements the dfx extension CLI commands for managing external canisters. + +use crate::args::canister::Args; + +/// The main entry point for the `dfx orbit` CLI. +pub fn main(args: Args) { + match args { + Args::Claim(_claim_args) => { + todo!("Implement claiming a canister."); + } + } +} \ No newline at end of file From a9353c8bfd1955b890322be9c87cc5d1bdb6e0b0 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 01:01:47 +0200 Subject: [PATCH 045/156] Start claim command --- tools/dfx-orbit/src/args.rs | 2 +- tools/dfx-orbit/src/args/canister.rs | 2 +- tools/dfx-orbit/src/cli.rs | 2 +- tools/dfx-orbit/src/cli/canister.rs | 3 ++- tools/dfx-orbit/src/cli/canister/claim.rs | 1 + 5 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 tools/dfx-orbit/src/cli/canister/claim.rs diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs index e2051a2ca..3ee37bb26 100644 --- a/tools/dfx-orbit/src/args.rs +++ b/tools/dfx-orbit/src/args.rs @@ -1,7 +1,7 @@ //! Command line interface for `dfx-orbit`. +pub mod canister; pub mod dfx_extension_api; pub mod station; -pub mod canister; use clap::{Parser, Subcommand}; use station::StationArgs; diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index a7f271b4d..0c7654857 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -20,4 +20,4 @@ pub struct Claim { /// Make Orbit the exclusive controller of the canister. #[clap(long, short, action)] pub exclusive: bool, -} \ No newline at end of file +} diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 57edd6503..23c47da31 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -1,7 +1,7 @@ //! Implementation of the `dfx-orbit` commands. +pub mod canister; pub mod dfx_extension_cli; pub mod station; -pub mod canister; use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; diff --git a/tools/dfx-orbit/src/cli/canister.rs b/tools/dfx-orbit/src/cli/canister.rs index 052e17173..34b0ea675 100644 --- a/tools/dfx-orbit/src/cli/canister.rs +++ b/tools/dfx-orbit/src/cli/canister.rs @@ -1,4 +1,5 @@ //! Implements the dfx extension CLI commands for managing external canisters. +mod claim; use crate::args::canister::Args; @@ -9,4 +10,4 @@ pub fn main(args: Args) { todo!("Implement claiming a canister."); } } -} \ No newline at end of file +} diff --git a/tools/dfx-orbit/src/cli/canister/claim.rs b/tools/dfx-orbit/src/cli/canister/claim.rs new file mode 100644 index 000000000..1f40780c1 --- /dev/null +++ b/tools/dfx-orbit/src/cli/canister/claim.rs @@ -0,0 +1 @@ +//! Command to put a canister under Orbit control. \ No newline at end of file From c2d90cb93ec223f3e8ba6c0d68820842db25b7a0 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 01:31:27 +0200 Subject: [PATCH 046/156] Step towards claiming --- tools/dfx-orbit/src/args/canister.rs | 6 +++--- tools/dfx-orbit/src/cli/canister.rs | 4 +--- tools/dfx-orbit/src/cli/canister/claim.rs | 8 +++++++- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index 0c7654857..68d0ea4fb 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -1,7 +1,7 @@ //! dfx-orbit external canister management commands. -use candid::Principal; use clap::{Parser, Subcommand}; +use std::fmt::Debug; /// Station management commands. #[derive(Debug, Subcommand)] @@ -14,9 +14,9 @@ pub enum Args { /// Puts a canister controlled by the user under Orbit control. #[derive(Debug, Parser)] pub struct Claim { - /// The canister ID. + /// The canister name or `canister_id`. #[structopt(long)] - pub canister_id: Principal, + pub canister: String, /// Make Orbit the exclusive controller of the canister. #[clap(long, short, action)] pub exclusive: bool, diff --git a/tools/dfx-orbit/src/cli/canister.rs b/tools/dfx-orbit/src/cli/canister.rs index 34b0ea675..572f575db 100644 --- a/tools/dfx-orbit/src/cli/canister.rs +++ b/tools/dfx-orbit/src/cli/canister.rs @@ -6,8 +6,6 @@ use crate::args::canister::Args; /// The main entry point for the `dfx orbit` CLI. pub fn main(args: Args) { match args { - Args::Claim(_claim_args) => { - todo!("Implement claiming a canister."); - } + Args::Claim(claim_args) => claim::main(claim_args), } } diff --git a/tools/dfx-orbit/src/cli/canister/claim.rs b/tools/dfx-orbit/src/cli/canister/claim.rs index 1f40780c1..884407dc2 100644 --- a/tools/dfx-orbit/src/cli/canister/claim.rs +++ b/tools/dfx-orbit/src/cli/canister/claim.rs @@ -1 +1,7 @@ -//! Command to put a canister under Orbit control. \ No newline at end of file +//! Command to put a canister under Orbit control. +use crate::args::canister::Claim; + +/// Puts a canister controlled by the user under Orbit control. +pub fn main(_args: Claim) { + todo!("Implement claiming a canister."); +} From 12c2c8c75be943f0722e4421048f7f6839a3fb6b Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 01:53:15 +0200 Subject: [PATCH 047/156] ++ --- tools/dfx-orbit/src/cli.rs | 12 +++------ tools/dfx-orbit/src/cli/canister.rs | 2 +- tools/dfx-orbit/src/cli/canister/claim.rs | 28 +++++++++++++++++--- tools/dfx-orbit/src/cli/dfx_extension_cli.rs | 3 ++- tools/dfx-orbit/src/cli/station.rs | 3 ++- tools/dfx-orbit/src/dfx_extension_api.rs | 2 +- tools/dfx-orbit/src/local_config.rs | 12 ++++++++- tools/dfx-orbit/src/main.rs | 2 +- 8 files changed, 47 insertions(+), 17 deletions(-) diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 23c47da31..7ef984c25 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -6,16 +6,12 @@ pub mod station; use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; /// A command line tool for interacting with Orbit on the Internet Computer. -pub fn main(args: DfxOrbitArgs) { +pub fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { match args.command { - DfxOrbitSubcommands::Station(station_args) => { - station::main(station_args); - } + DfxOrbitSubcommands::Station(station_args) => station::main(station_args), DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { - dfx_extension_cli::main(dfx_extension_args); - } - DfxOrbitSubcommands::Canister(canister_args) => { - canister::main(canister_args); + dfx_extension_cli::main(dfx_extension_args) } + DfxOrbitSubcommands::Canister(canister_args) => canister::main(canister_args), } } diff --git a/tools/dfx-orbit/src/cli/canister.rs b/tools/dfx-orbit/src/cli/canister.rs index 572f575db..9a6bb3d54 100644 --- a/tools/dfx-orbit/src/cli/canister.rs +++ b/tools/dfx-orbit/src/cli/canister.rs @@ -4,7 +4,7 @@ mod claim; use crate::args::canister::Args; /// The main entry point for the `dfx orbit` CLI. -pub fn main(args: Args) { +pub fn main(args: Args) -> anyhow::Result<()> { match args { Args::Claim(claim_args) => claim::main(claim_args), } diff --git a/tools/dfx-orbit/src/cli/canister/claim.rs b/tools/dfx-orbit/src/cli/canister/claim.rs index 884407dc2..aa3d144dc 100644 --- a/tools/dfx-orbit/src/cli/canister/claim.rs +++ b/tools/dfx-orbit/src/cli/canister/claim.rs @@ -1,7 +1,29 @@ //! Command to put a canister under Orbit control. -use crate::args::canister::Claim; +use anyhow::anyhow; + +use crate::{args::canister::Claim, dfx_extension_api, local_config}; /// Puts a canister controlled by the user under Orbit control. -pub fn main(_args: Claim) { - todo!("Implement claiming a canister."); +pub fn main(args: Claim) -> anyhow::Result<()> { + let Claim { + canister, + exclusive, + } = args; + // TODO: Need to be able to specify which Orbit to use, e.g. as a global flag. + let orbit_principal = &local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .canister_id; + let claim_type = if exclusive { + "--set-controller" + } else { + "--add-controller" + }; + dfx_extension_api::call_dfx_cli(vec![ + "canister", + "update-settings", + claim_type, + orbit_principal, + &canister, + ])?; + Ok(()) } diff --git a/tools/dfx-orbit/src/cli/dfx_extension_cli.rs b/tools/dfx-orbit/src/cli/dfx_extension_cli.rs index 982912dcf..a72e11237 100644 --- a/tools/dfx-orbit/src/cli/dfx_extension_cli.rs +++ b/tools/dfx-orbit/src/cli/dfx_extension_cli.rs @@ -3,7 +3,7 @@ use crate::args::dfx_extension_api; use std::io::Read; /// Implements CLI commands for getting data from the dfx extension API. -pub fn main(dfx_extension_args: dfx_extension_api::Args) { +pub fn main(dfx_extension_args: dfx_extension_api::Args) -> anyhow::Result<()> { match dfx_extension_args { dfx_extension_api::Args::Config(config_args) => match config_args { dfx_extension_api::config::Args::Dir => { @@ -23,4 +23,5 @@ pub fn main(dfx_extension_args: dfx_extension_api::Args) { } }, } + Ok(()) } diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 2455a35ec..d7d9fce5a 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -3,7 +3,7 @@ use crate::args::station::{ListResponse, StationArgs}; use crate::local_config; /// Implements CLI commands for managing Orbit stations. -pub fn main(args: StationArgs) { +pub fn main(args: StationArgs) -> anyhow::Result<()> { match args { StationArgs::Add(add_args) => { local_config::add_station(&add_args) @@ -41,4 +41,5 @@ pub fn main(args: StationArgs) { .expect("Failed to rename station in local dfx config"); } } + Ok(()) } diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 29c4b7e73..a97e875cb 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -6,7 +6,7 @@ use anyhow::Context; /// Calls the dfx cli. /// /// Some methods are implemented as calls to the dfx cli until a library is available. -fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { +pub fn call_dfx_cli(args: Vec<&str>) -> anyhow::Result { let output = Command::new("dfx") .args(args) // Tell the OS to record the command's output diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 8a1fa82f2..280f84776 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -17,6 +17,7 @@ pub struct StationConfig { /// Station name. pub name: String, /// Wallet canister ID. + // TODO: This should be a principal. pub canister_id: String, } @@ -173,11 +174,20 @@ pub fn extension_config() -> anyhow::Result { } } -/// Gets the default Orbit station from the local dfx configuration. +/// Gets the name of the default Orbit station from the local dfx configuration. pub fn default_station_name() -> anyhow::Result> { Ok(extension_config()?.default_station) } +/// Gets the default Orbit station from the local dfx configuration. +pub fn default_station() -> anyhow::Result> { + if let Some(name) = default_station_name()? { + Ok(Some(station(&name)?)) + } else { + Ok(None) + } +} + /// Sets the default Orbit station in the local dfx configuration. pub fn set_default_station(name_maybe: Option) -> anyhow::Result<()> { // Check if the station exists. diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index 38c658128..a1e6bd1c8 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -6,5 +6,5 @@ use dfx_orbit::{self as lib, args::DfxOrbitArgs}; fn main() { let args = DfxOrbitArgs::parse(); - lib::cli::main(args) + lib::cli::main(args).unwrap(); } From 0cbd96efbe39534d418b6503411f2510ec620561 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 02:41:31 +0200 Subject: [PATCH 048/156] Command to get my own info --- tools/dfx-orbit/src/args.rs | 2 ++ tools/dfx-orbit/src/cli.rs | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs index 3ee37bb26..52d958792 100644 --- a/tools/dfx-orbit/src/args.rs +++ b/tools/dfx-orbit/src/args.rs @@ -30,4 +30,6 @@ pub enum DfxOrbitSubcommands { /// As the API is brand new and prototypical, this is exposed as a subcommand. Once stable it can be removed. #[command(subcommand)] DfxExtension(dfx_extension_api::Args), + /// Gets the caller's profile on an Orbit station. + Me, } diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 7ef984c25..b92c16554 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -4,10 +4,24 @@ pub mod dfx_extension_cli; pub mod station; use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; +use anyhow::anyhow; /// A command line tool for interacting with Orbit on the Internet Computer. pub fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { match args.command { + DfxOrbitSubcommands::Me => { + let station_principal = &crate::local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .canister_id; + let ans = crate::dfx_extension_api::call_dfx_cli(vec![ + "canister", + "call", + station_principal, + "me", + ])?; + print!("{ans}"); + Ok(()) + } DfxOrbitSubcommands::Station(station_args) => station::main(station_args), DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { dfx_extension_cli::main(dfx_extension_args) From 2b0988dc07fe8366505148b148db8c25090c3fdd Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 13:45:49 +0200 Subject: [PATCH 049/156] Step towards being able to update canisters --- Cargo.lock | 1 + tools/dfx-orbit/Cargo.toml | 4 +- tools/dfx-orbit/src/args.rs | 4 ++ tools/dfx-orbit/src/args/request.rs | 13 ++++ tools/dfx-orbit/src/args/request/canister.rs | 71 ++++++++++++++++++++ tools/dfx-orbit/src/cli.rs | 2 + tools/dfx-orbit/src/cli/request.rs | 12 ++++ tools/dfx-orbit/src/cli/request/canister.rs | 20 ++++++ 8 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 tools/dfx-orbit/src/args/request.rs create mode 100644 tools/dfx-orbit/src/args/request/canister.rs create mode 100644 tools/dfx-orbit/src/cli/request.rs create mode 100644 tools/dfx-orbit/src/cli/request/canister.rs diff --git a/Cargo.lock b/Cargo.lock index 93a99a05f..db6f48992 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1002,6 +1002,7 @@ dependencies = [ "dfx-core", "serde", "serde_json", + "station-api", ] [[package]] diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 6f2b3d388..ed8ee520a 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -17,4 +17,6 @@ clap.workspace = true serde.workspace = true serde_json.workspace = true cap-std.workspace = true -dfx-core.workspace = true \ No newline at end of file +dfx-core.workspace = true + +orbit-station-api = { path = "../../core/station/api", package = "station-api" } \ No newline at end of file diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs index 52d958792..137f5c77c 100644 --- a/tools/dfx-orbit/src/args.rs +++ b/tools/dfx-orbit/src/args.rs @@ -1,6 +1,7 @@ //! Command line interface for `dfx-orbit`. pub mod canister; pub mod dfx_extension_api; +pub mod request; pub mod station; use clap::{Parser, Subcommand}; @@ -25,6 +26,9 @@ pub enum DfxOrbitSubcommands { /// Manages external canisters with Orbit. #[command(subcommand)] Canister(canister::Args), + /// Make requests to Orbit + #[command(subcommand)] + Request(request::Args), /// Exercises the experimental DFX extension API. /// /// As the API is brand new and prototypical, this is exposed as a subcommand. Once stable it can be removed. diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs new file mode 100644 index 000000000..25bd5580f --- /dev/null +++ b/tools/dfx-orbit/src/args/request.rs @@ -0,0 +1,13 @@ +//! Makes requests to Orbit. +pub mod canister; + +use clap::Subcommand; + +/// Request canister changes. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Request changes to a canister. + #[command(subcommand)] + Canister(canister::Args), +} diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs new file mode 100644 index 000000000..a26410d93 --- /dev/null +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -0,0 +1,71 @@ +//! Makes requests to Orbit. + +use candid::Principal; +use clap::{Parser, Subcommand, ValueEnum}; + +/// Request canister changes. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Request to update the canister. + Change(ChangeExternalCanister), +} + +/// Requests that a canister be installed or updated. +#[derive(Debug, Parser)] +pub struct ChangeExternalCanister { + /// The canister ID to install or update. + #[clap(short, long)] + canister_id: Principal, + /// The installation mode. + #[clap(long, value_enum)] + mode: CanisterInstallMode, + /// The path to the Wasm file to install. + #[clap(short, long)] + wasm: String, + /// The argument to pass to the canister. + #[clap(short, long)] + arg: Option, + // TODO: exclusive OR + /// The path to a file containing the argument to pass to the canister. + #[clap(short, long)] + arg_file: Option, +} + +/// Canister installation mode corresponding to `dfx canister install --mode XXX`. +#[derive(Copy, Clone, Eq, PartialEq, Debug, ValueEnum)] +pub enum CanisterInstallMode { + /// Corresponds to `dfx canister install` + Install, + /// Corresponds to `dfx canister reinstall` + Reinstall, + /// Corresponds to `dfx canister upgrade` + Upgrade, +} + +/* +impl From for orbit_station_api::ChangeExternalCanisterOperationInput { + fn from(input: ChangeExternalCanister) -> Self { + let ChangeExternalCanister{canister_id, mode, wasm, arg, arg_file} = input; + let module = std::fs::read(&input.wasm).unwrap(); + let arg = if let Some(file) = arg_file { + Some(std::fs::read(&file).unwrap()) + } else if let Some(arg) = arg { + Some(arg.as_bytes().to_vec()) + } else { + None + }; + orbit_station_api::ChangeExternalCanisterOperationInput {canister_id, mode, module, arg} + } +} + +impl From for orbit_station_api::CanisterInstallMode { + fn from(mode: CanisterInstallMode) -> Self { + match mode { + CanisterInstallMode::Install => orbit_station_api::CanisterInstallMode::Install, + CanisterInstallMode::Reinstall => orbit_station_api::CanisterInstallMode::Reinstall, + CanisterInstallMode::Upgrade => orbit_station_api::CanisterInstallMode::Upgrade, + } + } +} + */ diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index b92c16554..dae71881e 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -1,6 +1,7 @@ //! Implementation of the `dfx-orbit` commands. pub mod canister; pub mod dfx_extension_cli; +pub mod request; pub mod station; use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; @@ -27,5 +28,6 @@ pub fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { dfx_extension_cli::main(dfx_extension_args) } DfxOrbitSubcommands::Canister(canister_args) => canister::main(canister_args), + DfxOrbitSubcommands::Request(request_args) => request::main(request_args), } } diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs new file mode 100644 index 000000000..531d24d0b --- /dev/null +++ b/tools/dfx-orbit/src/cli/request.rs @@ -0,0 +1,12 @@ +//! Implements the dfx extension CLI commands for making requests. + +pub mod canister; + +use crate::args::request::Args; + +/// The main entry point for the `dfx orbit` CLI. +pub fn main(args: Args) -> anyhow::Result<()> { + match args { + Args::Canister(canister_args) => canister::main(canister_args), + } +} diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs new file mode 100644 index 000000000..eee2460ff --- /dev/null +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -0,0 +1,20 @@ +//! Implements the dfx extension CLI commands for making requests about canisters. + +use crate::args::request::canister::Args; + +/// The main entry point for the `dfx orbit` CLI. +pub fn main(args: Args) -> anyhow::Result<()> { + match args { + Args::Change(_change_args) => todo!(), //change(change_args), + } +} + +/* +fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { + Change + + let Args::Change(change_args) = args; + println!("Changing request: {:?}", change_args); + Ok(()) +} + */ From abca735331cbd6423dd776b3be62c667b94ce04a Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 13:58:59 +0200 Subject: [PATCH 050/156] Convert cli types --- tools/dfx-orbit/src/args/request/canister.rs | 36 ++++++++++++++------ tools/dfx-orbit/src/cli/request/canister.rs | 13 +++---- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index a26410d93..2f9455712 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -11,7 +11,7 @@ pub enum Args { Change(ChangeExternalCanister), } -/// Requests that a canister be installed or updated. +/// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. #[derive(Debug, Parser)] pub struct ChangeExternalCanister { /// The canister ID to install or update. @@ -32,7 +32,7 @@ pub struct ChangeExternalCanister { arg_file: Option, } -/// Canister installation mode corresponding to `dfx canister install --mode XXX`. +/// Canister installation mode equivalent to `dfx canister install --mode XXX` and `orbit_station_api::CanisterInstallMode`. #[derive(Copy, Clone, Eq, PartialEq, Debug, ValueEnum)] pub enum CanisterInstallMode { /// Corresponds to `dfx canister install` @@ -43,19 +43,34 @@ pub enum CanisterInstallMode { Upgrade, } -/* impl From for orbit_station_api::ChangeExternalCanisterOperationInput { fn from(input: ChangeExternalCanister) -> Self { - let ChangeExternalCanister{canister_id, mode, wasm, arg, arg_file} = input; - let module = std::fs::read(&input.wasm).unwrap(); + let ChangeExternalCanister { + canister_id, + mode, + wasm, + arg, + arg_file, + } = input; + let module = std::fs::read(wasm) + .expect("Could not read Wasm file") + .to_vec(); let arg = if let Some(file) = arg_file { - Some(std::fs::read(&file).unwrap()) - } else if let Some(arg) = arg { - Some(arg.as_bytes().to_vec()) + Some( + std::fs::read(file) + .expect("Could not read argument file") + .to_vec(), + ) } else { - None + arg.map(|arg| arg.as_bytes().to_vec()) }; - orbit_station_api::ChangeExternalCanisterOperationInput {canister_id, mode, module, arg} + let mode = mode.into(); + orbit_station_api::ChangeExternalCanisterOperationInput { + canister_id, + mode, + module, + arg, + } } } @@ -68,4 +83,3 @@ impl From for orbit_station_api::CanisterInstallMode { } } } - */ diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index eee2460ff..6f8a85f6c 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -1,20 +1,17 @@ //! Implements the dfx extension CLI commands for making requests about canisters. -use crate::args::request::canister::Args; +use crate::args::request::canister::{Args, ChangeExternalCanister}; /// The main entry point for the `dfx orbit` CLI. pub fn main(args: Args) -> anyhow::Result<()> { match args { - Args::Change(_change_args) => todo!(), //change(change_args), + Args::Change(change_args) => change(change_args), } } -/* +/// Makes an API call to chnage an external canister. fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { - Change + let _args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); - let Args::Change(change_args) = args; - println!("Changing request: {:?}", change_args); - Ok(()) + todo!() } - */ From cd4ba084da1906752550406e2170224a39cd7498 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 17:29:13 +0200 Subject: [PATCH 051/156] ++ --- Cargo.lock | 1 + Cargo.toml | 1 + tools/dfx-orbit/Cargo.toml | 1 + tools/dfx-orbit/src/args/request/canister.rs | 4 +- tools/dfx-orbit/src/cli/request/canister.rs | 39 +++++++++++++++++++- 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index db6f48992..924cf44c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1003,6 +1003,7 @@ dependencies = [ "serde", "serde_json", "station-api", + "tempfile", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f7095612c..a9b40aad9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ serde_json = "1.0" serde_cbor = "0.11.2" sha2 = "0.10" syn = { version = "2.0", features = ["extra-traits", "full"] } +tempfile = "3.10.1" thiserror = "1.0.48" time = { version = "0.3", features = ["formatting", "parsing"] } tokio = { version = "1.33.0" } diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index ed8ee520a..eada55c11 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -18,5 +18,6 @@ serde.workspace = true serde_json.workspace = true cap-std.workspace = true dfx-core.workspace = true +tempfile.workspace = true orbit-station-api = { path = "../../core/station/api", package = "station-api" } \ No newline at end of file diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index 2f9455712..c474540b9 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -18,7 +18,7 @@ pub struct ChangeExternalCanister { #[clap(short, long)] canister_id: Principal, /// The installation mode. - #[clap(long, value_enum)] + #[clap(long, value_enum, rename_all = "kebab-case")] mode: CanisterInstallMode, /// The path to the Wasm file to install. #[clap(short, long)] @@ -28,7 +28,7 @@ pub struct ChangeExternalCanister { arg: Option, // TODO: exclusive OR /// The path to a file containing the argument to pass to the canister. - #[clap(short, long)] + #[clap(short = 'f', long)] arg_file: Option, } diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index 6f8a85f6c..a50618f2b 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -1,6 +1,11 @@ //! Implements the dfx extension CLI commands for making requests about canisters. use crate::args::request::canister::{Args, ChangeExternalCanister}; +use anyhow::anyhow; +use candid::{CandidType, IDLArgs}; +use std::fs::File; +use std::io::Write; +use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. pub fn main(args: Args) -> anyhow::Result<()> { @@ -11,7 +16,37 @@ pub fn main(args: Args) -> anyhow::Result<()> { /// Makes an API call to chnage an external canister. fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { - let _args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); + // If we can be SURE that the orbit `station_api` types remain in sync with the .did files, we can use these types. + let args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); + let idl_text = serialize_one_to_text(&args)?; + // The idl text can be too large to pass on gthe command line. We write it to a file and pass the file name instead. + let dir = tempdir()?; + let file_path = dir.path().join("args.idl"); + let file_name = file_path + .to_str() + .ok_or_else(|| anyhow!("Could not convert path to string"))?; + let mut arg_file = File::create(&file_path)?; + arg_file.write_all(idl_text.as_bytes())?; + arg_file.flush()?; + let orbit_canister_id = crate::local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .canister_id; + crate::dfx_extension_api::call_dfx_cli(vec![ + "canister", + "call", + &orbit_canister_id, + "create_request", + "--arg-file", + &file_name, + ])?; // TODO: Replace with actual API call + Ok(()) +} - todo!() +/// Serializes a value to a Candid string. +fn serialize_one_to_text(value: &T) -> anyhow::Result { + // Afaik there still is no better way of doing this than serializing to binary candid, then convertingh the binary candid to text-type candid. If true this is really unfortunate. + let bytes = candid::encode_one(value)?; + let decoded: IDLArgs = IDLArgs::from_bytes(&bytes)?; + let text = decoded.to_string(); + Ok(text) } From a5c506cc2c738e1f9778b1b6cc053f60054a546e Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 17:41:35 +0200 Subject: [PATCH 052/156] Upgrade not working yet --- tools/dfx-orbit/src/cli/request/canister.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index a50618f2b..e7a136b81 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -3,6 +3,7 @@ use crate::args::request::canister::{Args, ChangeExternalCanister}; use anyhow::anyhow; use candid::{CandidType, IDLArgs}; +use orbit_station_api::{CreateRequestInput, RequestOperationInput}; use std::fs::File; use std::io::Write; use tempfile::tempdir; @@ -18,6 +19,9 @@ pub fn main(args: Args) -> anyhow::Result<()> { fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { // If we can be SURE that the orbit `station_api` types remain in sync with the .did files, we can use these types. let args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); + let args = RequestOperationInput::ChangeExternalCanister(args); + // TODO: Add title, summary and execution_plan to the CLI. + let args = CreateRequestInput{operation: args, title: None, summary: None, execution_plan: None}; let idl_text = serialize_one_to_text(&args)?; // The idl text can be too large to pass on gthe command line. We write it to a file and pass the file name instead. let dir = tempdir()?; @@ -36,7 +40,7 @@ fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { "call", &orbit_canister_id, "create_request", - "--arg-file", + "--argument-file", &file_name, ])?; // TODO: Replace with actual API call Ok(()) From 8748ec21127b8d24a4de5a7da9cc5e08061471f5 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 13 Jun 2024 18:11:13 +0200 Subject: [PATCH 053/156] ++ --- tools/dfx-orbit/src/cli/request/canister.rs | 25 ++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index e7a136b81..31eab9f35 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -1,10 +1,10 @@ //! Implements the dfx extension CLI commands for making requests about canisters. use crate::args::request::canister::{Args, ChangeExternalCanister}; -use anyhow::anyhow; +use anyhow::{anyhow, Context}; use candid::{CandidType, IDLArgs}; use orbit_station_api::{CreateRequestInput, RequestOperationInput}; -use std::fs::File; +use std::fs::{self, File}; use std::io::Write; use tempfile::tempdir; @@ -21,7 +21,12 @@ fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { let args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); let args = RequestOperationInput::ChangeExternalCanister(args); // TODO: Add title, summary and execution_plan to the CLI. - let args = CreateRequestInput{operation: args, title: None, summary: None, execution_plan: None}; + let args = CreateRequestInput { + operation: args, + title: None, + summary: None, + execution_plan: None, + }; let idl_text = serialize_one_to_text(&args)?; // The idl text can be too large to pass on gthe command line. We write it to a file and pass the file name instead. let dir = tempdir()?; @@ -35,14 +40,24 @@ fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { let orbit_canister_id = crate::local_config::default_station()? .ok_or_else(|| anyhow!("No default station specified"))? .canister_id; - crate::dfx_extension_api::call_dfx_cli(vec![ + let command = vec![ "canister", "call", &orbit_canister_id, "create_request", "--argument-file", &file_name, - ])?; // TODO: Replace with actual API call + ]; + crate::dfx_extension_api::call_dfx_cli(command.clone()) + .with_context(|| { + let saved_filename = "args.idl"; + fs::rename(file_name, saved_filename).ok(); + format!( + "Failed to call the Orbit canister. The argument file has been saved as {}. The command was:\n dfx {}", + saved_filename, + command.join(" ") + ) + })?; // TODO: Replace with actual API call Ok(()) } From bebaeb9e6b7aa8fa5439a2129d5e463f93a24d18 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Mon, 17 Jun 2024 16:05:26 +0200 Subject: [PATCH 054/156] Command to update a canister --- Cargo.lock | 336 +++++--------------- Cargo.toml | 7 +- tools/dfx-orbit/Cargo.toml | 5 + tools/dfx-orbit/src/cli.rs | 4 +- tools/dfx-orbit/src/cli/request.rs | 4 +- tools/dfx-orbit/src/cli/request/canister.rs | 44 +-- tools/dfx-orbit/src/dfx_extension_api.rs | 35 +- tools/dfx-orbit/src/main.rs | 6 +- 8 files changed, 154 insertions(+), 287 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 924cf44c4..c5337f90a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -953,7 +953,7 @@ checksum = "322ef0094744e63628e6f0eb2295517f79276a5b342a4c2ff3042566ca181d4e" [[package]] name = "dfx-core" version = "0.0.1" -source = "git+https://github.com/dfinity/sdk.git?tag=0.20.1#aae11965e0ab3fe2b702205ec911ac1c675e0cfe" +source = "git+https://github.com/dfinity/sdk.git?tag=0.20.2-beta.0#06eaa58f9c52d27a015cd8f754ecd3d0d0ba555b" dependencies = [ "aes-gcm", "argon2", @@ -975,7 +975,7 @@ dependencies = [ "k256 0.11.6", "keyring", "lazy_static", - "reqwest 0.11.27", + "reqwest", "ring 0.16.20", "schemars", "sec1 0.3.0", @@ -1000,10 +1000,15 @@ dependencies = [ "cap-std", "clap", "dfx-core", + "ic-agent", "serde", "serde_json", + "slog", + "slog-async", + "slog-term", "station-api", "tempfile", + "tokio", ] [[package]] @@ -1201,15 +1206,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "encoding_rs" -version = "0.8.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" -dependencies = [ - "cfg-if", -] - [[package]] name = "enumflags2" version = "0.6.4" @@ -1546,25 +1542,6 @@ dependencies = [ "subtle", ] -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "h2" version = "0.4.4" @@ -1576,7 +1553,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 1.1.0", + "http", "indexmap", "slab", "tokio", @@ -1670,17 +1647,6 @@ dependencies = [ "digest 0.10.7", ] -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http" version = "1.1.0" @@ -1692,17 +1658,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes", - "http 0.2.12", - "pin-project-lite", -] - [[package]] name = "http-body" version = "1.0.0" @@ -1710,7 +1665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http 1.1.0", + "http", ] [[package]] @@ -1721,8 +1676,8 @@ checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", "futures-core", - "http 1.1.0", - "http-body 1.0.0", + "http", + "http-body", "pin-project-lite", ] @@ -1732,12 +1687,6 @@ version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" -[[package]] -name = "httpdate" -version = "1.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" - [[package]] name = "humantime" version = "2.1.0" @@ -1754,30 +1703,6 @@ dependencies = [ "serde", ] -[[package]] -name = "hyper" -version = "0.14.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" -dependencies = [ - "bytes", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa", - "pin-project-lite", - "socket2 0.5.7", - "tokio", - "tower-service", - "tracing", - "want", -] - [[package]] name = "hyper" version = "1.3.1" @@ -1787,9 +1712,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.4", - "http 1.1.0", - "http-body 1.0.0", + "h2", + "http", + "http-body", "httparse", "itoa", "pin-project-lite", @@ -1798,20 +1723,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper-rustls" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" -dependencies = [ - "futures-util", - "http 0.2.12", - "hyper 0.14.29", - "rustls 0.21.12", - "tokio", - "tokio-rustls 0.24.1", -] - [[package]] name = "hyper-rustls" version = "0.26.0" @@ -1819,13 +1730,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http 1.1.0", - "hyper 1.3.1", + "http", + "hyper", "hyper-util", - "rustls 0.22.4", + "rustls", "rustls-pki-types", "tokio", - "tokio-rustls 0.25.0", + "tokio-rustls", "tower-service", ] @@ -1838,9 +1749,9 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.3.1", + "http", + "http-body", + "hyper", "pin-project-lite", "socket2 0.5.7", "tokio", @@ -1851,8 +1762,8 @@ dependencies = [ [[package]] name = "ic-agent" -version = "0.34.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +version = "0.35.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" dependencies = [ "async-lock 3.4.0", "backoff", @@ -1861,8 +1772,8 @@ dependencies = [ "ed25519-consensus", "futures-util", "hex", - "http 1.1.0", - "http-body 1.0.0", + "http", + "http-body", "ic-certification", "ic-transport-types", "ic-verify-bls-signature", @@ -1873,7 +1784,7 @@ dependencies = [ "pkcs8 0.10.2", "rand", "rangemap", - "reqwest 0.11.27", + "reqwest", "ring 0.17.8", "rustls-webpki 0.101.7", "sec1 0.7.3", @@ -1985,8 +1896,8 @@ dependencies = [ [[package]] name = "ic-identity-hsm" -version = "0.34.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +version = "0.35.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" dependencies = [ "hex", "ic-agent", @@ -2022,8 +1933,8 @@ dependencies = [ [[package]] name = "ic-transport-types" -version = "0.34.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +version = "0.35.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" dependencies = [ "candid", "hex", @@ -2038,8 +1949,8 @@ dependencies = [ [[package]] name = "ic-utils" -version = "0.34.0" -source = "git+https://github.com/dfinity/agent-rs.git?rev=dac18df939dd7e63295083a2a9b2d024cb9b0c71#dac18df939dd7e63295083a2a9b2d024cb9b0c71" +version = "0.35.0" +source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4e38b0676ec6ad9c260#8273d321e9a09fd8373bd4e38b0676ec6ad9c260" dependencies = [ "async-trait", "candid", @@ -2181,6 +2092,17 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "is_terminal_polyfill" version = "1.70.0" @@ -2953,7 +2875,7 @@ dependencies = [ "candid", "hex", "ic-cdk 0.13.2", - "reqwest 0.12.4", + "reqwest", "schemars", "serde", "serde_bytes", @@ -3237,49 +3159,6 @@ version = "1.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e898588f33fdd5b9420719948f9f2a32c922a246964576f71ba7f24f80610fbc" -[[package]] -name = "reqwest" -version = "0.11.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" -dependencies = [ - "base64 0.21.7", - "bytes", - "encoding_rs", - "futures-core", - "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.29", - "hyper-rustls 0.24.2", - "ipnet", - "js-sys", - "log", - "mime", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls 0.21.12", - "rustls-pemfile 1.0.4", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper", - "system-configuration", - "tokio", - "tokio-rustls 0.24.1", - "tokio-util", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-streams", - "web-sys", - "webpki-roots 0.25.4", - "winreg 0.50.0", -] - [[package]] name = "reqwest" version = "0.12.4" @@ -3291,12 +3170,12 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.4", - "http 1.1.0", - "http-body 1.0.0", + "h2", + "http", + "http-body", "http-body-util", - "hyper 1.3.1", - "hyper-rustls 0.26.0", + "hyper", + "hyper-rustls", "hyper-util", "ipnet", "js-sys", @@ -3305,16 +3184,16 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls 0.22.4", + "rustls", "rustls-native-certs", - "rustls-pemfile 2.1.2", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", - "tokio-rustls 0.25.0", + "tokio-rustls", "tokio-socks", "tokio-util", "tower-service", @@ -3323,8 +3202,8 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.1", - "winreg 0.52.0", + "webpki-roots", + "winreg", ] [[package]] @@ -3466,18 +3345,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rustls" -version = "0.21.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring 0.17.8", - "rustls-webpki 0.101.7", - "sct", -] - [[package]] name = "rustls" version = "0.22.4" @@ -3499,21 +3366,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f1fb85efa936c42c6d5fc28d2629bb51e4b2f4b8a5211e297d599cc5a093792" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.2", + "rustls-pemfile", "rustls-pki-types", "schannel", "security-framework", ] -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", -] - [[package]] name = "rustls-pemfile" version = "2.1.2" @@ -3617,16 +3475,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - [[package]] name = "sec1" version = "0.3.0" @@ -3913,6 +3761,31 @@ version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06" +[[package]] +name = "slog-async" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c8038f898a2c79507940990f05386455b3a317d8f18d4caea7cbc3d5096b84" +dependencies = [ + "crossbeam-channel", + "slog", + "take_mut", + "thread_local", +] + +[[package]] +name = "slog-term" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6e022d0b998abfe5c3782c1f03551a596269450ccd677ea51c56f8b214610e8" +dependencies = [ + "is-terminal", + "slog", + "term", + "thread_local", + "time", +] + [[package]] name = "slotmap" version = "1.0.7" @@ -4121,25 +3994,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" [[package]] -name = "system-configuration" -version = "0.5.1" +name = "take_mut" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "system-configuration-sys", -] - -[[package]] -name = "system-configuration-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" -dependencies = [ - "core-foundation-sys", - "libc", -] +checksum = "f764005d11ee5f36500a149ace24e00e3da98b0158b3e2d53a7495660d3f4d60" [[package]] name = "tar" @@ -4324,23 +4182,13 @@ dependencies = [ "syn 2.0.60", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f" dependencies = [ - "rustls 0.22.4", + "rustls", "rustls-pki-types", "tokio", ] @@ -4825,12 +4673,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webpki-roots" version = "0.26.1" @@ -5019,16 +4861,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if", - "windows-sys 0.48.0", -] - [[package]] name = "winreg" version = "0.52.0" diff --git a/Cargo.toml b/Cargo.toml index a9b40aad9..c59dcedf2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -37,11 +37,13 @@ candid = "0.10.3" candid_parser = "0.1.3" cap-std = "3.1.0" clap = { version = "4.5.7", features = ["derive"] } -dfx-core = { git = "https://github.com/dfinity/sdk.git", tag = "0.20.1" } +dfx-core = { git = "https://github.com/dfinity/sdk.git", tag = "0.20.2-beta.0" } convert_case = "0.6" futures = "0.3" getrandom = { version = "0.2", features = ["custom"] } hex = "0.4" +# The ic-agent matches the one sed by bthe +ic-agent = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } ic-cdk = "0.13.2" ic-cdk-macros = "0.9" ic-cdk-timers = "0.7.0" @@ -64,6 +66,9 @@ serde_bytes = "0.11" serde_json = "1.0" serde_cbor = "0.11.2" sha2 = "0.10" +slog = "2.5.2" +slog-async = "2.4.0" +slog-term = "2.9.0" syn = { version = "2.0", features = ["extra-traits", "full"] } tempfile = "3.10.1" thiserror = "1.0.48" diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index eada55c11..5ad481b59 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -19,5 +19,10 @@ serde_json.workspace = true cap-std.workspace = true dfx-core.workspace = true tempfile.workspace = true +ic-agent.workspace = true +slog.workspace = true +slog-term.workspace = true +slog-async.workspace = true +tokio.workspace = true orbit-station-api = { path = "../../core/station/api", package = "station-api" } \ No newline at end of file diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index dae71881e..2fa07b0fc 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -8,7 +8,7 @@ use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; use anyhow::anyhow; /// A command line tool for interacting with Orbit on the Internet Computer. -pub fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { +pub async fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { match args.command { DfxOrbitSubcommands::Me => { let station_principal = &crate::local_config::default_station()? @@ -28,6 +28,6 @@ pub fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { dfx_extension_cli::main(dfx_extension_args) } DfxOrbitSubcommands::Canister(canister_args) => canister::main(canister_args), - DfxOrbitSubcommands::Request(request_args) => request::main(request_args), + DfxOrbitSubcommands::Request(request_args) => request::main(request_args).await, } } diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 531d24d0b..9a66bb0ec 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -5,8 +5,8 @@ pub mod canister; use crate::args::request::Args; /// The main entry point for the `dfx orbit` CLI. -pub fn main(args: Args) -> anyhow::Result<()> { +pub async fn main(args: Args) -> anyhow::Result<()> { match args { - Args::Canister(canister_args) => canister::main(canister_args), + Args::Canister(canister_args) => canister::main(canister_args).await, } } diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index 31eab9f35..345e51534 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -1,22 +1,22 @@ //! Implements the dfx extension CLI commands for making requests about canisters. use crate::args::request::canister::{Args, ChangeExternalCanister}; -use anyhow::{anyhow, Context}; -use candid::{CandidType, IDLArgs}; +use anyhow::anyhow; +use candid::{CandidType, IDLArgs, Principal}; use orbit_station_api::{CreateRequestInput, RequestOperationInput}; -use std::fs::{self, File}; +use std::fs::File; use std::io::Write; use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. -pub fn main(args: Args) -> anyhow::Result<()> { +pub async fn main(args: Args) -> anyhow::Result<()> { match args { - Args::Change(change_args) => change(change_args), + Args::Change(change_args) => change(change_args).await, } } /// Makes an API call to chnage an external canister. -fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { +async fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { // If we can be SURE that the orbit `station_api` types remain in sync with the .did files, we can use these types. let args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); let args = RequestOperationInput::ChangeExternalCanister(args); @@ -31,39 +31,27 @@ fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { // The idl text can be too large to pass on gthe command line. We write it to a file and pass the file name instead. let dir = tempdir()?; let file_path = dir.path().join("args.idl"); - let file_name = file_path - .to_str() - .ok_or_else(|| anyhow!("Could not convert path to string"))?; let mut arg_file = File::create(&file_path)?; arg_file.write_all(idl_text.as_bytes())?; arg_file.flush()?; let orbit_canister_id = crate::local_config::default_station()? .ok_or_else(|| anyhow!("No default station specified"))? .canister_id; - let command = vec![ - "canister", - "call", - &orbit_canister_id, - "create_request", - "--argument-file", - &file_name, - ]; - crate::dfx_extension_api::call_dfx_cli(command.clone()) - .with_context(|| { - let saved_filename = "args.idl"; - fs::rename(file_name, saved_filename).ok(); - format!( - "Failed to call the Orbit canister. The argument file has been saved as {}. The command was:\n dfx {}", - saved_filename, - command.join(" ") - ) - })?; // TODO: Replace with actual API call + + let mut extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let agent = extension_agent.agent().await?; + let canister_id = Principal::from_text(&orbit_canister_id)?; + agent + .update(&canister_id, "create_request") + .with_arg(candid::encode_one(args)?) + .call_and_wait() + .await?; Ok(()) } /// Serializes a value to a Candid string. fn serialize_one_to_text(value: &T) -> anyhow::Result { - // Afaik there still is no better way of doing this than serializing to binary candid, then convertingh the binary candid to text-type candid. If true this is really unfortunate. + // Afaik there still is no better way of doing this than serializing to binary candid, then converting the binary candid to text-type candid. If true this is really unfortunate. let bytes = candid::encode_one(value)?; let decoded: IDLArgs = IDLArgs::from_bytes(&bytes)?; let text = decoded.to_string(); diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index a97e875cb..17cffd5e9 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -1,7 +1,13 @@ //! Placeholders for the proposed dfx extension API methods. -use std::process::{Command, Stdio}; +use std::{ + process::{Command, Stdio}, + str::FromStr, +}; use anyhow::Context; +use candid::Principal; +use dfx_core::interface::dfx::DfxInterface; +use ic_agent::Agent; /// Calls the dfx cli. /// @@ -37,6 +43,8 @@ pub struct DfxExtensionAgent { name: String, /// The directory where all extension configuration files are stored, including those of other extensions. extensions_dir: cap_std::fs::Dir, + /// The dfx interface. + dfx_interface: Option, } impl DfxExtensionAgent { @@ -46,6 +54,7 @@ impl DfxExtensionAgent { name: name.to_string(), extensions_dir: Self::extensions_dir() .expect("Could not get the dfx extensions directory"), + dfx_interface: None, } } @@ -113,4 +122,28 @@ impl DfxExtensionAgent { pub fn identity() -> anyhow::Result { call_dfx_cli(vec!["identity", "whoami"]) } + + /// Gets the dfx interface + pub async fn dfx_interface(&mut self) -> anyhow::Result<&DfxInterface> { + if self.dfx_interface.is_none() { + self.dfx_interface = Some(DfxInterface::builder().build().await?); + } + Ok(self + .dfx_interface + .as_ref() + .expect("Failed to get dfx interface")) + } + + /// Gets the dfx agent. + pub async fn agent(&mut self) -> anyhow::Result<&Agent> { + Ok(self.dfx_interface().await?.agent()) + } + + /// Gets a canister ID + // TODO: Pass network. + pub fn canister_id(&self, canister_name: &str) -> anyhow::Result { + let id = call_dfx_cli(vec!["canister", "id", canister_name]) + .with_context(|| format!("Failed to look up canister '{canister_name}'"))?; + Principal::from_str(&id).with_context(|| format!("Could not parse canister ID: {}", id)) + } } diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index a1e6bd1c8..3a908f324 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -3,8 +3,12 @@ //! Note: This will initially be a standalone executable, but will be converted into a dfx extension once the dfx subcommand extension framework is well defined. use clap::Parser; use dfx_orbit::{self as lib, args::DfxOrbitArgs}; +use tokio::runtime::Runtime; fn main() { let args = DfxOrbitArgs::parse(); - lib::cli::main(args).unwrap(); + let runtime = Runtime::new().expect("Unable to create a runtime"); + runtime.block_on(async { + lib::cli::main(args).await.unwrap(); + }); } From 3f67891728aa21b8260e80cf86eed2a835dc48b9 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 10:37:37 +0200 Subject: [PATCH 055/156] Make types serde serializable --- core/station/api/src/account.rs | 28 +++++------ core/station/api/src/address_book.rs | 26 +++++----- core/station/api/src/change_canister.rs | 12 ++--- core/station/api/src/common.rs | 6 +-- core/station/api/src/external_canister.rs | 10 ++-- core/station/api/src/metadata.rs | 8 ++- core/station/api/src/permission.rs | 20 ++++---- core/station/api/src/request.rs | 56 ++++++++++----------- core/station/api/src/request_policy.rs | 34 ++++++------- core/station/api/src/resource.rs | 34 ++++++------- core/station/api/src/system.rs | 18 +++---- core/station/api/src/transfer.rs | 24 ++++----- core/station/api/src/user.rs | 30 +++++------ core/station/api/src/user_group.rs | 24 ++++----- tools/dfx-orbit/src/cli/request/canister.rs | 8 ++- 15 files changed, 173 insertions(+), 165 deletions(-) diff --git a/core/station/api/src/account.rs b/core/station/api/src/account.rs index b60ff1231..b5a4e67d7 100644 --- a/core/station/api/src/account.rs +++ b/core/station/api/src/account.rs @@ -3,14 +3,14 @@ use crate::{ }; use candid::{CandidType, Deserialize}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AccountCallerPrivilegesDTO { pub id: UuidDTO, pub can_transfer: bool, pub can_edit: bool, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AccountDTO { pub id: UuidDTO, pub name: String, @@ -26,7 +26,7 @@ pub struct AccountDTO { pub last_modification_timestamp: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditAccountOperationInput { pub account_id: UuidDTO, pub name: Option, @@ -37,12 +37,12 @@ pub struct EditAccountOperationInput { pub transfer_request_policy: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditAccountOperationDTO { pub input: EditAccountOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddAccountOperationInput { pub name: String, pub blockchain: String, @@ -55,29 +55,29 @@ pub struct AddAccountOperationInput { pub transfer_request_policy: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddAccountOperationDTO { pub account: Option, pub input: AddAccountOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetAccountInput { pub account_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetAccountResponse { pub account: AccountDTO, pub privileges: AccountCallerPrivilegesDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct FetchAccountBalancesInput { pub account_ids: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AccountBalanceDTO { pub account_id: String, pub balance: candid::Nat, @@ -85,25 +85,25 @@ pub struct AccountBalanceDTO { pub last_update_timestamp: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AccountBalanceInfoDTO { pub balance: candid::Nat, pub decimals: u32, pub last_update_timestamp: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct FetchAccountBalancesResponse { pub balances: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListAccountsInput { pub search_term: Option, pub paginate: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListAccountsResponse { pub accounts: Vec, pub next_offset: Option, diff --git a/core/station/api/src/address_book.rs b/core/station/api/src/address_book.rs index 1c0b1def9..84d78f243 100644 --- a/core/station/api/src/address_book.rs +++ b/core/station/api/src/address_book.rs @@ -1,7 +1,7 @@ use crate::{ChangeMetadataDTO, MetadataDTO, PaginationInput, UuidDTO}; use candid::{CandidType, Deserialize}; -#[derive(CandidType, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub struct AddressBookEntryDTO { pub id: UuidDTO, pub address_owner: String, @@ -12,20 +12,20 @@ pub struct AddressBookEntryDTO { pub last_modification_timestamp: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddressBookEntryCallerPrivilegesDTO { pub id: UuidDTO, pub can_edit: bool, pub can_delete: bool, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddAddressBookEntryOperationDTO { pub address_book_entry: Option, pub input: AddAddressBookEntryOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddAddressBookEntryOperationInput { pub address_owner: String, pub address: String, @@ -34,46 +34,46 @@ pub struct AddAddressBookEntryOperationInput { pub metadata: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditAddressBookEntryOperationDTO { pub input: EditAddressBookEntryOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditAddressBookEntryOperationInput { pub address_book_entry_id: UuidDTO, pub address_owner: Option, pub change_metadata: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RemoveAddressBookEntryOperationDTO { pub input: RemoveAddressBookEntryOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RemoveAddressBookEntryOperationInput { pub address_book_entry_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetAddressBookEntryInputDTO { pub address_book_entry_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetAddressBookEntryResponseDTO { pub address_book_entry: AddressBookEntryDTO, pub privileges: AddressBookEntryCallerPrivilegesDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddressChainInput { pub blockchain: String, pub standard: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListAddressBookEntriesInputDTO { pub ids: Option>, pub addresses: Option>, @@ -81,7 +81,7 @@ pub struct ListAddressBookEntriesInputDTO { pub paginate: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListAddressBookEntriesResponseDTO { pub address_book_entries: Vec, pub next_offset: Option, diff --git a/core/station/api/src/change_canister.rs b/core/station/api/src/change_canister.rs index 733c8a18c..57c008236 100644 --- a/core/station/api/src/change_canister.rs +++ b/core/station/api/src/change_canister.rs @@ -2,7 +2,7 @@ use candid::{CandidType, Deserialize, Principal}; use crate::Sha256HashDTO; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum CanisterInstallMode { #[serde(rename = "install")] Install = 1, @@ -12,13 +12,13 @@ pub enum CanisterInstallMode { Upgrade = 3, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ChangeCanisterTargetDTO { UpgradeStation, UpgradeUpgrader, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ChangeCanisterOperationInput { pub target: ChangeCanisterTargetDTO, #[serde(with = "serde_bytes")] @@ -27,14 +27,14 @@ pub struct ChangeCanisterOperationInput { pub arg: Option>, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ChangeCanisterOperationDTO { pub target: ChangeCanisterTargetDTO, pub module_checksum: Sha256HashDTO, pub arg_checksum: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ChangeExternalCanisterOperationInput { pub canister_id: Principal, pub mode: CanisterInstallMode, @@ -44,7 +44,7 @@ pub struct ChangeExternalCanisterOperationInput { pub arg: Option>, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ChangeExternalCanisterOperationDTO { pub canister_id: Principal, pub mode: CanisterInstallMode, diff --git a/core/station/api/src/common.rs b/core/station/api/src/common.rs index b2d3a4bc6..54bba0de0 100644 --- a/core/station/api/src/common.rs +++ b/core/station/api/src/common.rs @@ -6,7 +6,7 @@ pub type UuidDTO = String; pub type Sha256HashDTO = String; /// Generic error type used for calls. -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct ApiErrorDTO { /// The error code uppercased and underscored (e.g. `INVALID_ARGUMENT`). pub code: String, @@ -16,13 +16,13 @@ pub struct ApiErrorDTO { pub details: Option>, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct PaginationInput { pub offset: Option, pub limit: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum SortDirection { Asc, Desc, diff --git a/core/station/api/src/external_canister.rs b/core/station/api/src/external_canister.rs index b0bfcdab9..e82050b53 100644 --- a/core/station/api/src/external_canister.rs +++ b/core/station/api/src/external_canister.rs @@ -1,21 +1,21 @@ use crate::Sha256HashDTO; use candid::{CandidType, Deserialize, Principal}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CreateExternalCanisterOperationInput {} -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CreateExternalCanisterOperationDTO { pub canister_id: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CanisterMethodDTO { pub canister_id: Principal, pub method_name: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CallExternalCanisterOperationInput { pub validation_method: Option, pub execution_method: CanisterMethodDTO, @@ -24,7 +24,7 @@ pub struct CallExternalCanisterOperationInput { pub execution_method_cycles: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CallExternalCanisterOperationDTO { pub validation_method: Option, pub execution_method: CanisterMethodDTO, diff --git a/core/station/api/src/metadata.rs b/core/station/api/src/metadata.rs index 9b4fade46..45b804c30 100644 --- a/core/station/api/src/metadata.rs +++ b/core/station/api/src/metadata.rs @@ -1,12 +1,16 @@ use candid::{CandidType, Deserialize}; -#[derive(CandidType, Deserialize, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive( + CandidType, serde::Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, +)] pub struct MetadataDTO { pub key: String, pub value: String, } -#[derive(CandidType, Deserialize, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] +#[derive( + CandidType, serde::Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, +)] pub enum ChangeMetadataDTO { ReplaceAllBy(Vec), OverrideSpecifiedBy(Vec), diff --git a/core/station/api/src/permission.rs b/core/station/api/src/permission.rs index b71ed6e9c..acca65aa5 100644 --- a/core/station/api/src/permission.rs +++ b/core/station/api/src/permission.rs @@ -1,39 +1,39 @@ use crate::{BasicUserDTO, PaginationInput, ResourceDTO, UserGroupDTO, UuidDTO}; use candid::{CandidType, Deserialize}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct PermissionCallerPrivilegesDTO { pub resource: ResourceDTO, pub can_edit: bool, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct PermissionDTO { pub allow: AllowDTO, pub resource: ResourceDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AllowDTO { pub auth_scope: AuthScopeDTO, pub users: Vec, pub user_groups: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum AuthScopeDTO { Public = 1, Authenticated = 2, Restricted = 3, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListPermissionsInput { pub resources: Option>, pub paginate: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListPermissionsResponse { pub permissions: Vec, pub user_groups: Vec, @@ -43,23 +43,23 @@ pub struct ListPermissionsResponse { pub privileges: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetPermissionInput { pub resource: ResourceDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetPermissionResponse { pub permission: PermissionDTO, pub privileges: PermissionCallerPrivilegesDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditPermissionOperationDTO { pub input: EditPermissionOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditPermissionOperationInput { pub resource: ResourceDTO, pub auth_scope: Option, diff --git a/core/station/api/src/request.rs b/core/station/api/src/request.rs index 43cd31834..eb2efffc7 100644 --- a/core/station/api/src/request.rs +++ b/core/station/api/src/request.rs @@ -18,7 +18,7 @@ use crate::{ }; use candid::{CandidType, Deserialize, Principal}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestStatusDTO { Created, Approved, @@ -30,7 +30,7 @@ pub enum RequestStatusDTO { Failed { reason: Option }, } -#[derive(CandidType, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] pub enum RequestStatusCodeDTO { Created = 0, Approved = 1, @@ -42,19 +42,19 @@ pub enum RequestStatusCodeDTO { Failed = 7, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestApprovalStatusDTO { Approved, Rejected, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestExecutionScheduleDTO { Immediate, Scheduled { execution_time: TimestampRfc3339 }, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestOperationDTO { Transfer(Box), AddAccount(Box), @@ -78,7 +78,7 @@ pub enum RequestOperationDTO { ManageSystemInfo(Box), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestOperationInput { Transfer(TransferOperationInput), AddAccount(AddAccountOperationInput), @@ -102,7 +102,7 @@ pub enum RequestOperationInput { ManageSystemInfo(ManageSystemInfoOperationInput), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestOperationTypeDTO { Transfer, AddAccount, @@ -126,7 +126,7 @@ pub enum RequestOperationTypeDTO { ManageSystemInfo, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ListRequestsOperationTypeDTO { Transfer(Option), AddAccount, @@ -150,7 +150,7 @@ pub enum ListRequestsOperationTypeDTO { ManageSystemInfo, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestApprovalDTO { pub approver_id: UuidDTO, pub status: RequestApprovalStatusDTO, @@ -158,7 +158,7 @@ pub struct RequestApprovalDTO { pub decided_at: TimestampRfc3339, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestDTO { pub id: UuidDTO, pub title: String, @@ -172,13 +172,13 @@ pub struct RequestDTO { pub execution_plan: RequestExecutionScheduleDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestCallerPrivilegesDTO { pub id: UuidDTO, pub can_approve: bool, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestAdditionalInfoDTO { pub id: UuidDTO, pub requester_name: String, @@ -186,7 +186,7 @@ pub struct RequestAdditionalInfoDTO { pub evaluation_result: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CreateRequestInput { pub operation: RequestOperationInput, pub title: Option, @@ -194,40 +194,40 @@ pub struct CreateRequestInput { pub execution_plan: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct SubmitRequestApprovalInput { pub decision: RequestApprovalStatusDTO, pub request_id: UuidDTO, pub reason: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct SubmitRequestApprovalResponse { pub request: RequestDTO, pub privileges: RequestCallerPrivilegesDTO, pub additional_info: RequestAdditionalInfoDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetRequestInput { pub request_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetRequestResponse { pub request: RequestDTO, pub privileges: RequestCallerPrivilegesDTO, pub additional_info: RequestAdditionalInfoDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ListRequestsSortBy { CreatedAt(SortDirection), ExpirationDt(SortDirection), LastModificationDt(SortDirection), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListRequestsInput { pub requester_ids: Option>, pub approver_ids: Option>, @@ -243,7 +243,7 @@ pub struct ListRequestsInput { pub with_evaluation_results: bool, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListRequestsResponse { pub requests: Vec, pub next_offset: Option, @@ -252,7 +252,7 @@ pub struct ListRequestsResponse { pub additional_info: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetNextApprovableRequestInput { pub excluded_request_ids: Vec, pub operation_types: Option>, @@ -260,43 +260,43 @@ pub struct GetNextApprovableRequestInput { pub type GetNextApprovableRequestResponse = Option; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CreateRequestResponse { pub request: RequestDTO, pub privileges: RequestCallerPrivilegesDTO, pub additional_info: RequestAdditionalInfoDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddRequestPolicyOperationInput { pub specifier: RequestSpecifierDTO, pub rule: RequestPolicyRuleDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddRequestPolicyOperationDTO { pub policy_id: Option, pub input: AddRequestPolicyOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditRequestPolicyOperationInput { pub policy_id: UuidDTO, pub specifier: Option, pub rule: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditRequestPolicyOperationDTO { pub input: EditRequestPolicyOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RemoveRequestPolicyOperationInput { pub policy_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RemoveRequestPolicyOperationDTO { pub input: RemoveRequestPolicyOperationInput, } diff --git a/core/station/api/src/request_policy.rs b/core/station/api/src/request_policy.rs index c93279994..bb4fdd7a3 100644 --- a/core/station/api/src/request_policy.rs +++ b/core/station/api/src/request_policy.rs @@ -5,7 +5,7 @@ use crate::{ }; use candid::{CandidType, Deserialize}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestSpecifierDTO { AddAccount, AddUser, @@ -29,45 +29,45 @@ pub enum RequestSpecifierDTO { ManageSystemInfo, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum UserSpecifierDTO { Any, Group(Vec), Id(Vec), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ResourceSpecifierDTO { Any, Resource(ResourceDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct QuorumPercentageDTO { pub approvers: UserSpecifierDTO, pub min_approved: u16, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct QuorumDTO { pub approvers: UserSpecifierDTO, pub min_approved: u16, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestPolicyRuleInput { Remove, Set(RequestPolicyRuleDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum EvaluationStatusDTO { Approved, Rejected, Pending, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestPolicyRuleDTO { AutoApproved, QuorumPercentage(QuorumPercentageDTO), @@ -79,7 +79,7 @@ pub enum RequestPolicyRuleDTO { Not(Box), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum EvaluatedRequestPolicyRuleDTO { AutoApproved, QuorumPercentage { @@ -101,13 +101,13 @@ pub enum EvaluatedRequestPolicyRuleDTO { Not(Box), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestPolicyRuleResultDTO { pub status: EvaluationStatusDTO, pub evaluated_rule: EvaluatedRequestPolicyRuleDTO, } -#[derive(CandidType, Deserialize, Debug, Clone, Hash, PartialEq, Eq)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone, Hash, PartialEq, Eq)] pub enum EvaluationSummaryReasonDTO { ApprovalQuorum, AllowList, @@ -115,7 +115,7 @@ pub enum EvaluationSummaryReasonDTO { AutoApproved, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestEvaluationResultDTO { pub request_id: UuidDTO, pub status: EvaluationStatusDTO, @@ -123,26 +123,26 @@ pub struct RequestEvaluationResultDTO { pub result_reasons: Option>, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestPolicyCallerPrivilegesDTO { pub id: UuidDTO, pub can_edit: bool, pub can_delete: bool, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct RequestPolicyDTO { pub id: UuidDTO, pub specifier: RequestSpecifierDTO, pub rule: RequestPolicyRuleDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetRequestPolicyInput { pub id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetRequestPolicyResponse { pub policy: RequestPolicyDTO, pub privileges: RequestPolicyCallerPrivilegesDTO, @@ -150,7 +150,7 @@ pub struct GetRequestPolicyResponse { pub type ListRequestPoliciesInput = PaginationInput; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListRequestPoliciesResponse { pub policies: Vec, pub next_offset: Option, diff --git a/core/station/api/src/resource.rs b/core/station/api/src/resource.rs index f546a6f6e..ee813ea54 100644 --- a/core/station/api/src/resource.rs +++ b/core/station/api/src/resource.rs @@ -1,7 +1,7 @@ use crate::{CanisterMethodDTO, UuidDTO}; use candid::{CandidType, Deserialize, Principal}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ResourceDTO { Permission(PermissionResourceActionDTO), Account(AccountResourceActionDTO), @@ -15,19 +15,19 @@ pub enum ResourceDTO { UserGroup(ResourceActionDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ResourceIdDTO { Any, Id(UuidDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ResourceIdsDTO { Any, Ids(Vec), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ResourceActionDTO { List, Create, @@ -36,13 +36,13 @@ pub enum ResourceActionDTO { Delete(ResourceIdDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum PermissionResourceActionDTO { Read, Update, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum UserResourceActionDTO { List, Create, @@ -50,7 +50,7 @@ pub enum UserResourceActionDTO { Update(ResourceIdDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum AccountResourceActionDTO { List, Create, @@ -59,36 +59,36 @@ pub enum AccountResourceActionDTO { Update(ResourceIdDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum SystemResourceActionDTO { SystemInfo, Capabilities, ManageSystemInfo, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ChangeCanisterResourceActionDTO { Create, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum CreateExternalCanisterResourceTargetDTO { Any, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ChangeExternalCanisterResourceTargetDTO { Any, Canister(Principal), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ReadExternalCanisterResourceTargetDTO { Any, Canister(Principal), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ExternalCanisterResourceActionDTO { Create(CreateExternalCanisterResourceTargetDTO), Change(ChangeExternalCanisterResourceTargetDTO), @@ -96,25 +96,25 @@ pub enum ExternalCanisterResourceActionDTO { Read(ReadExternalCanisterResourceTargetDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ValidationMethodResourceTargetDTO { No, ValidationMethod(CanisterMethodDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum ExecutionMethodResourceTargetDTO { Any, ExecutionMethod(CanisterMethodDTO), } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct CallExternalCanisterResourceTargetDTO { pub validation_method: ValidationMethodResourceTargetDTO, pub execution_method: ExecutionMethodResourceTargetDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum RequestResourceActionDTO { List, Read(ResourceIdDTO), diff --git a/core/station/api/src/system.rs b/core/station/api/src/system.rs index bc18834dc..732e23f03 100644 --- a/core/station/api/src/system.rs +++ b/core/station/api/src/system.rs @@ -1,7 +1,7 @@ use super::TimestampRfc3339; use candid::{CandidType, Deserialize, Principal}; -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct SystemInfoDTO { pub name: String, pub version: String, @@ -11,28 +11,28 @@ pub struct SystemInfoDTO { pub raw_rand_successful: bool, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ManageSystemInfoOperationDTO { pub input: ManageSystemInfoOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ManageSystemInfoOperationInput { pub name: Option, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct SystemInfoResponse { pub system: SystemInfoDTO, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct AdminInitInput { pub name: String, pub identity: Principal, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct SystemInit { pub name: String, pub admins: Vec, @@ -40,18 +40,18 @@ pub struct SystemInit { pub upgrader_wasm_module: Vec, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct SystemUpgrade { pub name: Option, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub enum SystemInstall { Init(SystemInit), Upgrade(SystemUpgrade), } -#[derive(CandidType, Deserialize, Clone, Debug, PartialEq, Eq)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] pub enum HealthStatus { Healthy, Uninitialized, diff --git a/core/station/api/src/transfer.rs b/core/station/api/src/transfer.rs index 2879a5d12..3e3c1a2e3 100644 --- a/core/station/api/src/transfer.rs +++ b/core/station/api/src/transfer.rs @@ -4,13 +4,13 @@ use candid::{CandidType, Deserialize}; pub type NetworkIdDTO = String; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct NetworkDTO { pub id: NetworkIdDTO, pub name: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct TransferOperationInput { pub from_account_id: UuidDTO, pub to: String, @@ -20,7 +20,7 @@ pub struct TransferOperationInput { pub network: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct TransferOperationDTO { pub from_account: Option, pub network: NetworkDTO, @@ -28,7 +28,7 @@ pub struct TransferOperationDTO { pub transfer_id: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub enum TransferStatusDTO { Created, Processing { @@ -44,7 +44,7 @@ pub enum TransferStatusDTO { }, } -#[derive(CandidType, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub enum TransferStatusTypeDTO { Created, Processing, @@ -52,7 +52,7 @@ pub enum TransferStatusTypeDTO { Failed, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct TransferDTO { pub id: UuidDTO, pub request_id: UuidDTO, @@ -65,22 +65,22 @@ pub struct TransferDTO { pub metadata: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct TransferResponse { pub transfer: TransferDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetTransfersInput { pub transfer_ids: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetTransfersResponse { pub transfers: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListAccountTransfersInput { pub status: Option, pub to_dt: Option, @@ -88,7 +88,7 @@ pub struct ListAccountTransfersInput { pub account_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct TransferListItemDTO { pub transfer_id: UuidDTO, pub request_id: UuidDTO, @@ -98,7 +98,7 @@ pub struct TransferListItemDTO { pub created_at: TimestampRfc3339, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListAccountTransfersResponse { pub transfers: Vec, } diff --git a/core/station/api/src/user.rs b/core/station/api/src/user.rs index c21da7648..f9fe1afa4 100644 --- a/core/station/api/src/user.rs +++ b/core/station/api/src/user.rs @@ -2,19 +2,19 @@ use super::TimestampRfc3339; use crate::{PaginationInput, UserGroupDTO, UuidDTO}; use candid::{CandidType, Deserialize, Principal}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct UserCallerPrivilegesDTO { pub id: UuidDTO, pub can_edit: bool, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub enum UserStatusDTO { Active, Inactive, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct UserDTO { pub id: UuidDTO, pub identities: Vec, @@ -24,31 +24,31 @@ pub struct UserDTO { pub last_modification_timestamp: TimestampRfc3339, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct BasicUserDTO { pub id: UuidDTO, pub name: String, pub status: UserStatusDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct DisplayUserDTO { pub id: UuidDTO, pub name: String, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetUserInput { pub user_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetUserResponse { pub user: UserDTO, pub privileges: UserCallerPrivilegesDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddUserOperationInput { pub name: String, pub identities: Vec, @@ -56,13 +56,13 @@ pub struct AddUserOperationInput { pub status: UserStatusDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct AddUserOperationDTO { pub user: Option, pub input: AddUserOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditUserOperationInput { pub id: UuidDTO, pub name: Option, @@ -71,19 +71,19 @@ pub struct EditUserOperationInput { pub status: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct EditUserOperationDTO { pub input: EditUserOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListUsersInput { pub search_term: Option, pub statuses: Option>, pub paginate: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListUsersResponse { pub users: Vec, pub next_offset: Option, @@ -91,7 +91,7 @@ pub struct ListUsersResponse { pub privileges: Vec, } -#[derive(CandidType, Deserialize, Debug, Clone, PartialEq, Eq)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] pub enum UserPrivilege { Capabilities, SystemInfo, @@ -111,7 +111,7 @@ pub enum UserPrivilege { ListRequests, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct MeResponse { pub me: UserDTO, pub privileges: Vec, diff --git a/core/station/api/src/user_group.rs b/core/station/api/src/user_group.rs index e8b575442..e19c56b5d 100644 --- a/core/station/api/src/user_group.rs +++ b/core/station/api/src/user_group.rs @@ -1,69 +1,69 @@ use crate::{PaginationInput, UuidDTO}; use candid::{CandidType, Deserialize}; -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct UserGroupCallerPrivilegesDTO { pub id: UuidDTO, pub can_edit: bool, pub can_delete: bool, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct UserGroupDTO { pub id: UuidDTO, pub name: String, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct AddUserGroupOperationInput { pub name: String, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct AddUserGroupOperationDTO { pub user_group: Option, pub input: AddUserGroupOperationInput, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct EditUserGroupOperationInput { pub user_group_id: UuidDTO, pub name: String, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct EditUserGroupOperationDTO { pub input: EditUserGroupOperationInput, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct RemoveUserGroupOperationInput { pub user_group_id: UuidDTO, } -#[derive(CandidType, Deserialize, Clone, Debug)] +#[derive(CandidType, serde::Serialize, Deserialize, Clone, Debug)] pub struct RemoveUserGroupOperationDTO { pub input: RemoveUserGroupOperationInput, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetUserGroupInput { pub user_group_id: UuidDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct GetUserGroupResponse { pub user_group: UserGroupDTO, pub privileges: UserGroupCallerPrivilegesDTO, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListUserGroupsInput { pub search_term: Option, pub paginate: Option, } -#[derive(CandidType, Deserialize, Debug, Clone)] +#[derive(CandidType, serde::Serialize, Deserialize, Debug, Clone)] pub struct ListUserGroupsResponse { pub user_groups: Vec, pub next_offset: Option, diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index 345e51534..8e80b3eeb 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -3,7 +3,9 @@ use crate::args::request::canister::{Args, ChangeExternalCanister}; use anyhow::anyhow; use candid::{CandidType, IDLArgs, Principal}; -use orbit_station_api::{CreateRequestInput, RequestOperationInput}; +use orbit_station_api::{ + ApiErrorDTO, CreateRequestInput, CreateRequestResponse, RequestOperationInput, +}; use std::fs::File; use std::io::Write; use tempfile::tempdir; @@ -41,11 +43,13 @@ async fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { let mut extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); let agent = extension_agent.agent().await?; let canister_id = Principal::from_text(&orbit_canister_id)?; - agent + let bytes = agent .update(&canister_id, "create_request") .with_arg(candid::encode_one(args)?) .call_and_wait() .await?; + let ans: Result = candid::decode_one(&bytes)?; + println!("{}", serde_json::to_string_pretty(&ans)?); Ok(()) } From 6211e3390a461be7ad407d883d17d45c718e6f12 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 11:03:27 +0200 Subject: [PATCH 056/156] ++ --- tools/dfx-orbit/src/cli/request/canister.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index 8e80b3eeb..14393a6bb 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -49,7 +49,7 @@ async fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { .call_and_wait() .await?; let ans: Result = candid::decode_one(&bytes)?; - println!("{}", serde_json::to_string_pretty(&ans)?); + println!("{ans:#?}"); Ok(()) } From 7d4c1fb43f59864a9908e661dd517c53abebd364 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 11:05:32 +0200 Subject: [PATCH 057/156] Add TODOs --- tools/dfx-orbit/src/args/request/canister.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index c474540b9..afa461a13 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -14,7 +14,9 @@ pub enum Args { /// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. #[derive(Debug, Parser)] pub struct ChangeExternalCanister { + // TODO: Poll, waiting for the request to be accepted. /// The canister ID to install or update. + // TODO: Canister by name #[clap(short, long)] canister_id: Principal, /// The installation mode. From 57e4e54e33e9b37a30a27fd15fbbc25740c051e3 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 13:45:05 +0200 Subject: [PATCH 058/156] Use the default stationif none is specified --- tools/dfx-orbit/src/args/station.rs | 2 +- tools/dfx-orbit/src/cli/station.rs | 2 +- tools/dfx-orbit/src/local_config.rs | 13 +++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index c2194c0c3..bbe24ece8 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -59,7 +59,7 @@ impl Display for ListResponse { pub struct Show { /// Station name. #[structopt(long)] - pub name: String, + pub name: Option, } /// Renames an Orbit station in the local dfx configuration. diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index d7d9fce5a..31234aab0 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -27,7 +27,7 @@ pub fn main(args: StationArgs) -> anyhow::Result<()> { .expect("Failed to set default station in local dfx config"); } StationArgs::Show(show_args) => { - let station = local_config::station(&show_args.name) + let station = local_config::station_or_default(show_args.name.as_deref()) .expect("Failed to get station from local dfx config"); let json = serde_json::to_string_pretty(&station).expect("Failed to serialize station"); println!("{json}"); diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 280f84776..a96ffc904 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -118,6 +118,19 @@ pub fn add_station(args: &Add) -> anyhow::Result<()> { Ok(()) } +/// Gets the local stored dfx configuration for a given station, or the default station if none is specified. +pub fn station_or_default(name: Option<&str>) -> anyhow::Result { + if let Some(name) = name { + station(name) + } else { + let name = default_station() + .with_context(|| "Station not specified and failed to get default.")? + .with_context(|| "Station not specified and no default station set.")? + .name; + station(&name) + } +} + /// Gets the local stored dfx configuration for a given station. pub fn station(name: &str) -> anyhow::Result { let station_file = station_file(name)?; From 708d8883a00bd44c5f818766e466cddb467c9c71 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 14:03:59 +0200 Subject: [PATCH 059/156] Placeholders for request permission command --- tools/dfx-orbit/src/args/request.rs | 4 ++++ tools/dfx-orbit/src/args/request/permission.rs | 13 +++++++++++++ .../src/args/request/permission/canister.rs | 18 ++++++++++++++++++ tools/dfx-orbit/src/cli/request.rs | 2 ++ tools/dfx-orbit/src/cli/request/permission.rs | 11 +++++++++++ .../src/cli/request/permission/canister.rs | 10 ++++++++++ 6 files changed, 58 insertions(+) create mode 100644 tools/dfx-orbit/src/args/request/permission.rs create mode 100644 tools/dfx-orbit/src/args/request/permission/canister.rs create mode 100644 tools/dfx-orbit/src/cli/request/permission.rs create mode 100644 tools/dfx-orbit/src/cli/request/permission/canister.rs diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 25bd5580f..6cd665334 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -1,5 +1,6 @@ //! Makes requests to Orbit. pub mod canister; +pub mod permission; use clap::Subcommand; @@ -10,4 +11,7 @@ pub enum Args { /// Request changes to a canister. #[command(subcommand)] Canister(canister::Args), + /// Request changes to a canister. + #[command(subcommand)] + Permission(permission::Args), } diff --git a/tools/dfx-orbit/src/args/request/permission.rs b/tools/dfx-orbit/src/args/request/permission.rs new file mode 100644 index 000000000..5ae2ca9a6 --- /dev/null +++ b/tools/dfx-orbit/src/args/request/permission.rs @@ -0,0 +1,13 @@ +//! Makes `EditPermission` requests to Orbit. +pub mod canister; + +use clap::Subcommand; + +/// Request permission. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Request changes to canister permissions. + #[command(subcommand)] + Canister(canister::Args), +} diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs new file mode 100644 index 000000000..fc67a00e8 --- /dev/null +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -0,0 +1,18 @@ +//! Makes `EditPermission` requests regarding `ExternalCanister` to Orbit. +use clap::{Parser, Subcommand}; + +/// Request canister changes. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Request changes to canister permissions. + Change(ChangeCanister), +} + +/// Requests permissions to change a canister. +#[derive(Debug, Parser)] +pub struct ChangeCanister { + /// Station name. + #[structopt(long)] + pub name: Option, +} diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 9a66bb0ec..92ca516c3 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -1,6 +1,7 @@ //! Implements the dfx extension CLI commands for making requests. pub mod canister; +pub mod permission; use crate::args::request::Args; @@ -8,5 +9,6 @@ use crate::args::request::Args; pub async fn main(args: Args) -> anyhow::Result<()> { match args { Args::Canister(canister_args) => canister::main(canister_args).await, + Args::Permission(permission_args) => permission::main(permission_args).await, } } diff --git a/tools/dfx-orbit/src/cli/request/permission.rs b/tools/dfx-orbit/src/cli/request/permission.rs new file mode 100644 index 000000000..21f2713a6 --- /dev/null +++ b/tools/dfx-orbit/src/cli/request/permission.rs @@ -0,0 +1,11 @@ +//! Implements the dfx extension CLI commands for making requests. +pub mod canister; + +use crate::args::request::permission::Args; + +/// The main entry point for the `dfx orbit` CLI. +pub async fn main(args: Args) -> anyhow::Result<()> { + match args { + Args::Canister(canister_args) => canister::main(canister_args).await, + } +} diff --git a/tools/dfx-orbit/src/cli/request/permission/canister.rs b/tools/dfx-orbit/src/cli/request/permission/canister.rs new file mode 100644 index 000000000..c6d0e03e9 --- /dev/null +++ b/tools/dfx-orbit/src/cli/request/permission/canister.rs @@ -0,0 +1,10 @@ +//! Implements the dfx extension CLI commands for making requests. + +use crate::args::request::permission::canister::Args; + +/// The main entry point for the `dfx orbit` CLI. +pub async fn main(args: Args) -> anyhow::Result<()> { + match args { + Args::Change(_change_args) => todo!(), + } +} From 8ec108235a9545bdde37f4362336a2b0eb592d81 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 15:52:35 +0200 Subject: [PATCH 060/156] Adapt signatures --- tools/dfx-orbit/src/cli.rs | 6 +++++- tools/dfx-orbit/src/cli/request.rs | 4 +++- tools/dfx-orbit/src/cli/request/canister.rs | 8 ++++--- tools/dfx-orbit/src/cli/request/permission.rs | 5 ++++- .../src/cli/request/permission/canister.rs | 21 +++++++++++++++++-- 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 2fa07b0fc..285943335 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -28,6 +28,10 @@ pub async fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { dfx_extension_cli::main(dfx_extension_args) } DfxOrbitSubcommands::Canister(canister_args) => canister::main(canister_args), - DfxOrbitSubcommands::Request(request_args) => request::main(request_args).await, + DfxOrbitSubcommands::Request(request_args) => match request::main(request_args).await { + Ok(Ok(_response)) => Ok(()), + Ok(Err(e)) => Err(anyhow!("Error response from the station: {e:?}")), + Err(e) => Err(e), + }, } } diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 92ca516c3..0f01ca740 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -3,10 +3,12 @@ pub mod canister; pub mod permission; +use orbit_station_api::{ApiErrorDTO, CreateRequestResponse}; + use crate::args::request::Args; /// The main entry point for the `dfx orbit` CLI. -pub async fn main(args: Args) -> anyhow::Result<()> { +pub async fn main(args: Args) -> anyhow::Result> { match args { Args::Canister(canister_args) => canister::main(canister_args).await, Args::Permission(permission_args) => permission::main(permission_args).await, diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs index 14393a6bb..cfeee5588 100644 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ b/tools/dfx-orbit/src/cli/request/canister.rs @@ -11,14 +11,16 @@ use std::io::Write; use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. -pub async fn main(args: Args) -> anyhow::Result<()> { +pub async fn main(args: Args) -> anyhow::Result> { match args { Args::Change(change_args) => change(change_args).await, } } /// Makes an API call to chnage an external canister. -async fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { +async fn change( + args: ChangeExternalCanister, +) -> anyhow::Result> { // If we can be SURE that the orbit `station_api` types remain in sync with the .did files, we can use these types. let args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); let args = RequestOperationInput::ChangeExternalCanister(args); @@ -50,7 +52,7 @@ async fn change(args: ChangeExternalCanister) -> anyhow::Result<()> { .await?; let ans: Result = candid::decode_one(&bytes)?; println!("{ans:#?}"); - Ok(()) + Ok(ans) } /// Serializes a value to a Candid string. diff --git a/tools/dfx-orbit/src/cli/request/permission.rs b/tools/dfx-orbit/src/cli/request/permission.rs index 21f2713a6..3d6144c51 100644 --- a/tools/dfx-orbit/src/cli/request/permission.rs +++ b/tools/dfx-orbit/src/cli/request/permission.rs @@ -4,7 +4,10 @@ pub mod canister; use crate::args::request::permission::Args; /// The main entry point for the `dfx orbit` CLI. -pub async fn main(args: Args) -> anyhow::Result<()> { +pub async fn main( + args: Args, +) -> anyhow::Result> +{ match args { Args::Canister(canister_args) => canister::main(canister_args).await, } diff --git a/tools/dfx-orbit/src/cli/request/permission/canister.rs b/tools/dfx-orbit/src/cli/request/permission/canister.rs index c6d0e03e9..439dd2a6e 100644 --- a/tools/dfx-orbit/src/cli/request/permission/canister.rs +++ b/tools/dfx-orbit/src/cli/request/permission/canister.rs @@ -3,8 +3,25 @@ use crate::args::request::permission::canister::Args; /// The main entry point for the `dfx orbit` CLI. -pub async fn main(args: Args) -> anyhow::Result<()> { +pub async fn main( + args: Args, +) -> anyhow::Result> +{ match args { - Args::Change(_change_args) => todo!(), + Args::Change(_change_args) => main_change().await, } } + +/// Change permissions for a user to interact with a canister. +async fn main_change( +) -> anyhow::Result> +{ + // TODO: Add title, summary and execution_plan to the CLI. + // let args = CreateRequestInput { + // operation: args, + // title: None, + // summary: None, + // execution_plan: None, + //}; + todo!() +} From 2a9715274ea001b1b7faf26560d31997ee6c897d Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 16:06:19 +0200 Subject: [PATCH 061/156] ++ --- tools/dfx-orbit/src/args/request.rs | 10 ++++++++++ tools/dfx-orbit/src/args/request/canister.rs | 8 ++++++++ tools/dfx-orbit/src/cli/request/permission/canister.rs | 8 ++++++-- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 6cd665334..c3776f285 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -3,6 +3,7 @@ pub mod canister; pub mod permission; use clap::Subcommand; +use orbit_station_api::RequestOperationInput; /// Request canister changes. #[derive(Debug, Subcommand)] @@ -15,3 +16,12 @@ pub enum Args { #[command(subcommand)] Permission(permission::Args), } + +impl From for RequestOperationInput { + fn from(args: Args) -> Self { + match args { + Args::Canister(canister_args) => RequestOperationInput::from(canister_args), + Args::Permission(_permission_args) => unimplemented!(), //RequestOperationInput::from(permission_args), + } + } +} diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index afa461a13..fcdd74fd4 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -11,6 +11,14 @@ pub enum Args { Change(ChangeExternalCanister), } +impl From for orbit_station_api::RequestOperationInput { + fn from(args: Args) -> Self { + match args { + Args::Change(_change_args) => unimplemented!(), //orbit_station_api::ChangeExternalCanisterOperationInput::(change_args.into()), + } + } +} + /// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. #[derive(Debug, Parser)] pub struct ChangeExternalCanister { diff --git a/tools/dfx-orbit/src/cli/request/permission/canister.rs b/tools/dfx-orbit/src/cli/request/permission/canister.rs index 439dd2a6e..feb3d1830 100644 --- a/tools/dfx-orbit/src/cli/request/permission/canister.rs +++ b/tools/dfx-orbit/src/cli/request/permission/canister.rs @@ -1,6 +1,8 @@ //! Implements the dfx extension CLI commands for making requests. -use crate::args::request::permission::canister::Args; +//use orbit_station_api::RequestOperationInput; + +use crate::args::request::permission::canister::{Args, ChangeCanister}; /// The main entry point for the `dfx orbit` CLI. pub async fn main( @@ -8,14 +10,16 @@ pub async fn main( ) -> anyhow::Result> { match args { - Args::Change(_change_args) => main_change().await, + Args::Change(change_args) => main_change(change_args).await, } } /// Change permissions for a user to interact with a canister. async fn main_change( + _args: ChangeCanister, ) -> anyhow::Result> { + //let _args = RequestOperationInput::ChangeExternalCanister(args); // TODO: Add title, summary and execution_plan to the CLI. // let args = CreateRequestInput { // operation: args, From 2066dc8179dfe91c43e4dbce2eb56d6153cdcc0d Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 16:14:31 +0200 Subject: [PATCH 062/156] Implement into --- tools/dfx-orbit/src/args/request/canister.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index fcdd74fd4..a00275e51 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -1,4 +1,4 @@ -//! Makes requests to Orbit. +//! Makes requests to do things to canisters. Such as update the Wasm, deploy frontend assets or make API calls to them. use candid::Principal; use clap::{Parser, Subcommand, ValueEnum}; @@ -14,7 +14,9 @@ pub enum Args { impl From for orbit_station_api::RequestOperationInput { fn from(args: Args) -> Self { match args { - Args::Change(_change_args) => unimplemented!(), //orbit_station_api::ChangeExternalCanisterOperationInput::(change_args.into()), + Args::Change(change_args) => { + orbit_station_api::RequestOperationInput::ChangeExternalCanister(change_args.into()) + } } } } From e0dab349a07f0a20c6889153777641e852401bcc Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 16:22:12 +0200 Subject: [PATCH 063/156] Move the call up one level --- tools/dfx-orbit/src/cli/request.rs | 53 ++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 6 deletions(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 0f01ca740..ce7585bdb 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -3,14 +3,55 @@ pub mod canister; pub mod permission; -use orbit_station_api::{ApiErrorDTO, CreateRequestResponse}; - use crate::args::request::Args; +use anyhow::anyhow; +use candid::{CandidType, IDLArgs, Principal}; +use orbit_station_api::{ApiErrorDTO, CreateRequestInput, CreateRequestResponse}; +use std::fs::File; +use std::io::Write; +use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. pub async fn main(args: Args) -> anyhow::Result> { - match args { - Args::Canister(canister_args) => canister::main(canister_args).await, - Args::Permission(permission_args) => permission::main(permission_args).await, - } + // Converts the CLI arg type into the equivalent Orbit API type. + let args = orbit_station_api::RequestOperationInput::from(args); + // TODO: Add title, summary and execution_plan to the CLI. + // TODO: Mopve this conversion to the cli types module. + let args = CreateRequestInput { + operation: args, + title: None, + summary: None, + execution_plan: None, + }; + let idl_text = serialize_one_to_text(&args)?; + // The idl text can be too large to pass on gthe command line. We write it to a file and pass the file name instead. + let dir = tempdir()?; + let file_path = dir.path().join("args.idl"); + let mut arg_file = File::create(&file_path)?; + arg_file.write_all(idl_text.as_bytes())?; + arg_file.flush()?; + let orbit_canister_id = crate::local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .canister_id; + + let mut extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let agent = extension_agent.agent().await?; + let canister_id = Principal::from_text(&orbit_canister_id)?; + let bytes = agent + .update(&canister_id, "create_request") + .with_arg(candid::encode_one(args)?) + .call_and_wait() + .await?; + let ans: Result = candid::decode_one(&bytes)?; + println!("{ans:#?}"); + Ok(ans) +} + +/// Serializes a value to a Candid string. +fn serialize_one_to_text(value: &T) -> anyhow::Result { + // Afaik there still is no better way of doing this than serializing to binary candid, then converting the binary candid to text-type candid. If true this is really unfortunate. + let bytes = candid::encode_one(value)?; + let decoded: IDLArgs = IDLArgs::from_bytes(&bytes)?; + let text = decoded.to_string(); + Ok(text) } From f151dec425ebdc9e1c441f0423068959682c4171 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 16:24:20 +0200 Subject: [PATCH 064/156] Implement by generalization --- tools/dfx-orbit/src/cli/request.rs | 3 - tools/dfx-orbit/src/cli/request/canister.rs | 65 ------------------- tools/dfx-orbit/src/cli/request/permission.rs | 14 ---- .../src/cli/request/permission/canister.rs | 31 --------- 4 files changed, 113 deletions(-) delete mode 100644 tools/dfx-orbit/src/cli/request/canister.rs delete mode 100644 tools/dfx-orbit/src/cli/request/permission.rs delete mode 100644 tools/dfx-orbit/src/cli/request/permission/canister.rs diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index ce7585bdb..c5b1546b2 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -1,8 +1,5 @@ //! Implements the dfx extension CLI commands for making requests. -pub mod canister; -pub mod permission; - use crate::args::request::Args; use anyhow::anyhow; use candid::{CandidType, IDLArgs, Principal}; diff --git a/tools/dfx-orbit/src/cli/request/canister.rs b/tools/dfx-orbit/src/cli/request/canister.rs deleted file mode 100644 index cfeee5588..000000000 --- a/tools/dfx-orbit/src/cli/request/canister.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! Implements the dfx extension CLI commands for making requests about canisters. - -use crate::args::request::canister::{Args, ChangeExternalCanister}; -use anyhow::anyhow; -use candid::{CandidType, IDLArgs, Principal}; -use orbit_station_api::{ - ApiErrorDTO, CreateRequestInput, CreateRequestResponse, RequestOperationInput, -}; -use std::fs::File; -use std::io::Write; -use tempfile::tempdir; - -/// The main entry point for the `dfx orbit` CLI. -pub async fn main(args: Args) -> anyhow::Result> { - match args { - Args::Change(change_args) => change(change_args).await, - } -} - -/// Makes an API call to chnage an external canister. -async fn change( - args: ChangeExternalCanister, -) -> anyhow::Result> { - // If we can be SURE that the orbit `station_api` types remain in sync with the .did files, we can use these types. - let args = orbit_station_api::ChangeExternalCanisterOperationInput::from(args); - let args = RequestOperationInput::ChangeExternalCanister(args); - // TODO: Add title, summary and execution_plan to the CLI. - let args = CreateRequestInput { - operation: args, - title: None, - summary: None, - execution_plan: None, - }; - let idl_text = serialize_one_to_text(&args)?; - // The idl text can be too large to pass on gthe command line. We write it to a file and pass the file name instead. - let dir = tempdir()?; - let file_path = dir.path().join("args.idl"); - let mut arg_file = File::create(&file_path)?; - arg_file.write_all(idl_text.as_bytes())?; - arg_file.flush()?; - let orbit_canister_id = crate::local_config::default_station()? - .ok_or_else(|| anyhow!("No default station specified"))? - .canister_id; - - let mut extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); - let agent = extension_agent.agent().await?; - let canister_id = Principal::from_text(&orbit_canister_id)?; - let bytes = agent - .update(&canister_id, "create_request") - .with_arg(candid::encode_one(args)?) - .call_and_wait() - .await?; - let ans: Result = candid::decode_one(&bytes)?; - println!("{ans:#?}"); - Ok(ans) -} - -/// Serializes a value to a Candid string. -fn serialize_one_to_text(value: &T) -> anyhow::Result { - // Afaik there still is no better way of doing this than serializing to binary candid, then converting the binary candid to text-type candid. If true this is really unfortunate. - let bytes = candid::encode_one(value)?; - let decoded: IDLArgs = IDLArgs::from_bytes(&bytes)?; - let text = decoded.to_string(); - Ok(text) -} diff --git a/tools/dfx-orbit/src/cli/request/permission.rs b/tools/dfx-orbit/src/cli/request/permission.rs deleted file mode 100644 index 3d6144c51..000000000 --- a/tools/dfx-orbit/src/cli/request/permission.rs +++ /dev/null @@ -1,14 +0,0 @@ -//! Implements the dfx extension CLI commands for making requests. -pub mod canister; - -use crate::args::request::permission::Args; - -/// The main entry point for the `dfx orbit` CLI. -pub async fn main( - args: Args, -) -> anyhow::Result> -{ - match args { - Args::Canister(canister_args) => canister::main(canister_args).await, - } -} diff --git a/tools/dfx-orbit/src/cli/request/permission/canister.rs b/tools/dfx-orbit/src/cli/request/permission/canister.rs deleted file mode 100644 index feb3d1830..000000000 --- a/tools/dfx-orbit/src/cli/request/permission/canister.rs +++ /dev/null @@ -1,31 +0,0 @@ -//! Implements the dfx extension CLI commands for making requests. - -//use orbit_station_api::RequestOperationInput; - -use crate::args::request::permission::canister::{Args, ChangeCanister}; - -/// The main entry point for the `dfx orbit` CLI. -pub async fn main( - args: Args, -) -> anyhow::Result> -{ - match args { - Args::Change(change_args) => main_change(change_args).await, - } -} - -/// Change permissions for a user to interact with a canister. -async fn main_change( - _args: ChangeCanister, -) -> anyhow::Result> -{ - //let _args = RequestOperationInput::ChangeExternalCanister(args); - // TODO: Add title, summary and execution_plan to the CLI. - // let args = CreateRequestInput { - // operation: args, - // title: None, - // summary: None, - // execution_plan: None, - //}; - todo!() -} From 5c6e880db13958619a49472da75a951d2c83ea26 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 16:27:03 +0200 Subject: [PATCH 065/156] Generalize --- tools/dfx-orbit/src/args/request.rs | 14 +++++++++++++- tools/dfx-orbit/src/cli/request.rs | 10 +--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index c3776f285..086807c6b 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -3,7 +3,7 @@ pub mod canister; pub mod permission; use clap::Subcommand; -use orbit_station_api::RequestOperationInput; +use orbit_station_api::{CreateRequestInput, RequestOperationInput}; /// Request canister changes. #[derive(Debug, Subcommand)] @@ -25,3 +25,15 @@ impl From for RequestOperationInput { } } } + +impl From for CreateRequestInput { + fn from(args: Args) -> Self { + let operation = RequestOperationInput::from(args); + CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + } + } +} diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index c5b1546b2..fb9710bf9 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -11,15 +11,7 @@ use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. pub async fn main(args: Args) -> anyhow::Result> { // Converts the CLI arg type into the equivalent Orbit API type. - let args = orbit_station_api::RequestOperationInput::from(args); - // TODO: Add title, summary and execution_plan to the CLI. - // TODO: Mopve this conversion to the cli types module. - let args = CreateRequestInput { - operation: args, - title: None, - summary: None, - execution_plan: None, - }; + let args = CreateRequestInput::from(args); let idl_text = serialize_one_to_text(&args)?; // The idl text can be too large to pass on gthe command line. We write it to a file and pass the file name instead. let dir = tempdir()?; From 019491f4adb5f6747f3d010769a8ef2bfb061992 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 16:38:41 +0200 Subject: [PATCH 066/156] todo --- tools/dfx-orbit/src/args/request.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 086807c6b..84039b9c2 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -6,6 +6,8 @@ use clap::Subcommand; use orbit_station_api::{CreateRequestInput, RequestOperationInput}; /// Request canister changes. +/// +/// TODO: Add flags for --title, --summary, and --execution-plan. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { @@ -29,6 +31,7 @@ impl From for RequestOperationInput { impl From for CreateRequestInput { fn from(args: Args) -> Self { let operation = RequestOperationInput::from(args); + // TODO: Get title, summary, and execution_plan from args. CreateRequestInput { operation, title: None, From 7f6d0ae8e69c1914bd78a5948a0548743d6cd796 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 18 Jun 2024 16:46:07 +0200 Subject: [PATCH 067/156] ++ --- tools/dfx-orbit/src/args/request.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 84039b9c2..659813b4f 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -7,7 +7,8 @@ use orbit_station_api::{CreateRequestInput, RequestOperationInput}; /// Request canister changes. /// -/// TODO: Add flags for --title, --summary, and --execution-plan. +// TODO: Add flags for --title, --summary, and --execution-plan. +// Note: I have looked at the docs and the anwer for how to do this really doesn't jump out at me. Google foo failed as well. Maybe the sdk repo has some examples. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { From b5fe67a069c34bdf4158b7e8771d018fb4c6aacf Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 00:46:50 +0200 Subject: [PATCH 068/156] Implement permission giving without canister lookup --- tools/dfx-orbit/src/args/request.rs | 4 +- .../dfx-orbit/src/args/request/permission.rs | 8 ++++ .../src/args/request/permission/canister.rs | 44 +++++++++++++++++-- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 659813b4f..16c1938ab 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -8,7 +8,7 @@ use orbit_station_api::{CreateRequestInput, RequestOperationInput}; /// Request canister changes. /// // TODO: Add flags for --title, --summary, and --execution-plan. -// Note: I have looked at the docs and the anwer for how to do this really doesn't jump out at me. Google foo failed as well. Maybe the sdk repo has some examples. +// Note: I have looked at the docs and the anwer for how to do this really doesn't jump out at me. Google foo failed as well. Maybe the sdk repo has some examples. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { @@ -24,7 +24,7 @@ impl From for RequestOperationInput { fn from(args: Args) -> Self { match args { Args::Canister(canister_args) => RequestOperationInput::from(canister_args), - Args::Permission(_permission_args) => unimplemented!(), //RequestOperationInput::from(permission_args), + Args::Permission(permission_args) => RequestOperationInput::from(permission_args), } } } diff --git a/tools/dfx-orbit/src/args/request/permission.rs b/tools/dfx-orbit/src/args/request/permission.rs index 5ae2ca9a6..85523a15a 100644 --- a/tools/dfx-orbit/src/args/request/permission.rs +++ b/tools/dfx-orbit/src/args/request/permission.rs @@ -11,3 +11,11 @@ pub enum Args { #[command(subcommand)] Canister(canister::Args), } + +impl From for orbit_station_api::RequestOperationInput { + fn from(args: Args) -> Self { + match args { + Args::Canister(change_args) => change_args.try_into().expect("TODO: bubble this up"), + } + } +} diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs index fc67a00e8..25dc99c76 100644 --- a/tools/dfx-orbit/src/args/request/permission/canister.rs +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -1,4 +1,5 @@ //! Makes `EditPermission` requests regarding `ExternalCanister` to Orbit. +use candid::Principal; use clap::{Parser, Subcommand}; /// Request canister changes. @@ -9,10 +10,47 @@ pub enum Args { Change(ChangeCanister), } -/// Requests permissions to change a canister. +/// Requests the privilige of proposing canister upgrades. #[derive(Debug, Parser)] pub struct ChangeCanister { - /// Station name. + /// Canister name or ID. #[structopt(long)] - pub name: Option, + pub canister: Option, +} + +impl TryFrom for orbit_station_api::RequestOperationInput { + type Error = anyhow::Error; + fn try_from(args: Args) -> anyhow::Result { + match args { + Args::Change(change_args) => Ok( + orbit_station_api::RequestOperationInput::EditPermission(change_args.try_into()?), + ), + } + } +} + +impl TryFrom for orbit_station_api::EditPermissionOperationInput { + type Error = anyhow::Error; + + fn try_from(args: ChangeCanister) -> anyhow::Result { + if let Some(canister_name_or_id) = args.canister { + // Grant permission for just this one canister. + let canister_id = Principal::from_text(canister_name_or_id)?; + let resource = orbit_station_api::ResourceDTO::ExternalCanister( + orbit_station_api::ExternalCanisterResourceActionDTO::Change( + orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister( + canister_id, + ), + ), + ); + Ok(orbit_station_api::EditPermissionOperationInput { + resource, + auth_scope: None, + users: None, + user_groups: None, + }) + } else { + unimplemented!("Need to implement granting access to all canisters.") + } + } } From 554da2c4c94ce303909f4c7421f87f725afe757e Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 00:48:41 +0200 Subject: [PATCH 069/156] README++ --- tools/dfx-orbit/src/cli/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index fb9710bf9..750d6e213 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -1,4 +1,4 @@ -//! Implements the dfx extension CLI commands for making requests. +//! Implements `dfx request` commands. These correspond to Orbit station `create_request` API calls. use crate::args::request::Args; use anyhow::anyhow; From 2fbd7ec4210ad7d112eb51d35edec9843b5c5a5d Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 00:49:55 +0200 Subject: [PATCH 070/156] typo --- tools/dfx-orbit/src/cli/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 750d6e213..bb95ac198 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -13,7 +13,7 @@ pub async fn main(args: Args) -> anyhow::Result Date: Wed, 19 Jun 2024 01:08:01 +0200 Subject: [PATCH 071/156] Create an agent for communicating with a specific station --- tools/dfx-orbit/src/args/station.rs | 3 +++ tools/dfx-orbit/src/cli/request.rs | 6 +++--- tools/dfx-orbit/src/lib.rs | 4 ++++ tools/dfx-orbit/src/local_config.rs | 9 ++++++++- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index bbe24ece8..b8ef77c73 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -33,6 +33,9 @@ pub struct Add { /// Wallet canister ID. #[structopt(long)] pub canister_id: Principal, + /// The dfx network name. + #[structopt(long)] + pub network: String, } /// Lists Orbit station in the local dfx configuration. diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index bb95ac198..0fdc81a14 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -11,6 +11,8 @@ use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. pub async fn main(args: Args) -> anyhow::Result> { // Converts the CLI arg type into the equivalent Orbit API type. + let mut extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); + let ic_agent = extension_agent.agent().await?; let args = CreateRequestInput::from(args); let idl_text = serialize_one_to_text(&args)?; // The idl text can be too large to pass on the command line. We write it to a file and pass the file name instead. @@ -23,10 +25,8 @@ pub async fn main(args: Args) -> anyhow::Result Vec { /// /// If there is no default station, the new station is set as the default. pub fn add_station(args: &Add) -> anyhow::Result<()> { - let Add { name, canister_id } = args; + let Add { + name, + canister_id, + network, + } = args; let station = StationConfig { name: name.to_string(), canister_id: canister_id.to_string(), + network: network.to_string(), }; let station_file = create_station_file(name)?; station_file.set_len(0)?; From 136aa4011d5a171fb075e79e177f9cda1ccd004e Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 01:43:54 +0200 Subject: [PATCH 072/156] comment --- tools/dfx-orbit/src/args/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 16c1938ab..65823a08e 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -1,4 +1,4 @@ -//! Makes requests to Orbit. +//! Defines the command line arguments for `dfx-orbit request`. These correspond to Orbit station `create_request` API calls. pub mod canister; pub mod permission; From 66b70ff0af040cb5da1cd87cff82d2767744203f Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:06:30 +0200 Subject: [PATCH 073/156] ++ --- tools/dfx-orbit/src/args/request.rs | 17 ++++++ tools/dfx-orbit/src/args/request/canister.rs | 58 ++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 65823a08e..f8defd023 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -5,6 +5,8 @@ pub mod permission; use clap::Subcommand; use orbit_station_api::{CreateRequestInput, RequestOperationInput}; +use crate::orbit_station_agent::StationAgent; + /// Request canister changes. /// // TODO: Add flags for --title, --summary, and --execution-plan. @@ -20,6 +22,21 @@ pub enum Args { Permission(permission::Args), } +/// Converts the CLI arg type into the equivalent Orbit API type. +pub trait CreateRequestArgs { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input(self, station_agent: &StationAgent) -> CreateRequestInput; +} + +impl CreateRequestArgs for Args { + fn into_create_request_input(self, station_agent: &StationAgent) -> CreateRequestInput { + match self { + Args::Canister(canister_args) => canister_args.into_create_request_input(station_agent), + Args::Permission(_permission_args) => todo!(), // permission_args.into_create_request_input(station_agent), + } + } +} + impl From for RequestOperationInput { fn from(args: Args) -> Self { match args { diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index a00275e51..8ce1bd658 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -1,5 +1,7 @@ //! Makes requests to do things to canisters. Such as update the Wasm, deploy frontend assets or make API calls to them. +use super::CreateRequestArgs; +use crate::orbit_station_agent::StationAgent; use candid::Principal; use clap::{Parser, Subcommand, ValueEnum}; @@ -11,6 +13,18 @@ pub enum Args { Change(ChangeExternalCanister), } +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> orbit_station_api::CreateRequestInput { + match self { + Args::Change(change_args) => change_args.into_create_request_input(station_agent), + } + } +} + impl From for orbit_station_api::RequestOperationInput { fn from(args: Args) -> Self { match args { @@ -44,6 +58,50 @@ pub struct ChangeExternalCanister { arg_file: Option, } +impl CreateRequestArgs for ChangeExternalCanister { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + _station_agent: &StationAgent, + ) -> orbit_station_api::CreateRequestInput { + let ChangeExternalCanister { + canister_id, + mode, + wasm, + arg, + arg_file, + } = self; + let operation = { + let module = std::fs::read(wasm) + .expect("Could not read Wasm file") + .to_vec(); + let arg = if let Some(file) = arg_file { + Some( + std::fs::read(file) + .expect("Could not read argument file") + .to_vec(), + ) + } else { + arg.map(|arg| arg.as_bytes().to_vec()) + }; + let mode = mode.into(); + orbit_station_api::ChangeExternalCanisterOperationInput { + canister_id, + mode, + module, + arg, + } + }; + let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); + orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + } + } +} + /// Canister installation mode equivalent to `dfx canister install --mode XXX` and `orbit_station_api::CanisterInstallMode`. #[derive(Copy, Clone, Eq, PartialEq, Debug, ValueEnum)] pub enum CanisterInstallMode { From 352da9431468a2f95067217114759b160ca21688 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:10:10 +0200 Subject: [PATCH 074/156] Allow conversion to fail --- tools/dfx-orbit/src/args/request.rs | 10 ++++++++-- tools/dfx-orbit/src/args/request/canister.rs | 8 ++++---- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index f8defd023..dd2ace6cc 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -25,11 +25,17 @@ pub enum Args { /// Converts the CLI arg type into the equivalent Orbit API type. pub trait CreateRequestArgs { /// Converts the CLI arg type into the equivalent Orbit API type. - fn into_create_request_input(self, station_agent: &StationAgent) -> CreateRequestInput; + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result; } impl CreateRequestArgs for Args { - fn into_create_request_input(self, station_agent: &StationAgent) -> CreateRequestInput { + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { match self { Args::Canister(canister_args) => canister_args.into_create_request_input(station_agent), Args::Permission(_permission_args) => todo!(), // permission_args.into_create_request_input(station_agent), diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index 8ce1bd658..ebe5e96c9 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -18,7 +18,7 @@ impl CreateRequestArgs for Args { fn into_create_request_input( self, station_agent: &StationAgent, - ) -> orbit_station_api::CreateRequestInput { + ) -> anyhow::Result { match self { Args::Change(change_args) => change_args.into_create_request_input(station_agent), } @@ -63,7 +63,7 @@ impl CreateRequestArgs for ChangeExternalCanister { fn into_create_request_input( self, _station_agent: &StationAgent, - ) -> orbit_station_api::CreateRequestInput { + ) -> anyhow::Result { let ChangeExternalCanister { canister_id, mode, @@ -93,12 +93,12 @@ impl CreateRequestArgs for ChangeExternalCanister { } }; let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); - orbit_station_api::CreateRequestInput { + Ok(orbit_station_api::CreateRequestInput { operation, title: None, summary: None, execution_plan: None, - } + }) } } From 4eebca02548e7b46c082727e3d3ad55612b699d4 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:24:02 +0200 Subject: [PATCH 075/156] ++ --- tools/dfx-orbit/src/args/request.rs | 4 +- .../dfx-orbit/src/args/request/permission.rs | 16 +++++++ .../src/args/request/permission/canister.rs | 48 +++++++++++++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index dd2ace6cc..9099e0d0f 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -38,7 +38,9 @@ impl CreateRequestArgs for Args { ) -> anyhow::Result { match self { Args::Canister(canister_args) => canister_args.into_create_request_input(station_agent), - Args::Permission(_permission_args) => todo!(), // permission_args.into_create_request_input(station_agent), + Args::Permission(permission_args) => { + permission_args.into_create_request_input(station_agent) + } } } } diff --git a/tools/dfx-orbit/src/args/request/permission.rs b/tools/dfx-orbit/src/args/request/permission.rs index 85523a15a..f52892bb6 100644 --- a/tools/dfx-orbit/src/args/request/permission.rs +++ b/tools/dfx-orbit/src/args/request/permission.rs @@ -3,6 +3,10 @@ pub mod canister; use clap::Subcommand; +use crate::orbit_station_agent::StationAgent; + +use super::CreateRequestArgs; + /// Request permission. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] @@ -12,6 +16,18 @@ pub enum Args { Canister(canister::Args), } +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { + match self { + Args::Canister(canister_args) => canister_args.into_create_request_input(station_agent), + } + } +} + impl From for orbit_station_api::RequestOperationInput { fn from(args: Args) -> Self { match args { diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs index 25dc99c76..fd8c700ea 100644 --- a/tools/dfx-orbit/src/args/request/permission/canister.rs +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -2,6 +2,8 @@ use candid::Principal; use clap::{Parser, Subcommand}; +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; + /// Request canister changes. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] @@ -10,6 +12,18 @@ pub enum Args { Change(ChangeCanister), } +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { + match self { + Args::Change(change_args) => change_args.into_create_request_input(station_agent), + } + } +} + /// Requests the privilige of proposing canister upgrades. #[derive(Debug, Parser)] pub struct ChangeCanister { @@ -18,6 +32,40 @@ pub struct ChangeCanister { pub canister: Option, } +impl CreateRequestArgs for ChangeCanister { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { + if let Some(canister_name_or_id) = self.canister { + let canister_id = station_agent.canister_id(&canister_name_or_id)?; + let resource = orbit_station_api::ResourceDTO::ExternalCanister( + orbit_station_api::ExternalCanisterResourceActionDTO::Change( + orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister( + canister_id, + ), + ), + ); + Ok(orbit_station_api::CreateRequestInput { + operation: orbit_station_api::RequestOperationInput::EditPermission( + orbit_station_api::EditPermissionOperationInput { + resource, + auth_scope: None, + users: None, + user_groups: None, + }, + ), + title: None, + summary: None, + execution_plan: None, + }) + } else { + unimplemented!("Need to implement granting access to all canisters.") + } + } +} + impl TryFrom for orbit_station_api::RequestOperationInput { type Error = anyhow::Error; fn try_from(args: Args) -> anyhow::Result { From 29378bfaa3f776e004e3cde8fb1d0b25b49499e0 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:27:02 +0200 Subject: [PATCH 076/156] Convert canister name --- tools/dfx-orbit/src/dfx_extension_api.rs | 6 ++-- tools/dfx-orbit/src/orbit_station_agent.rs | 32 ++++++++++++++++++++++ 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 tools/dfx-orbit/src/orbit_station_agent.rs diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 17cffd5e9..5a16b3b97 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -140,9 +140,9 @@ impl DfxExtensionAgent { } /// Gets a canister ID - // TODO: Pass network. - pub fn canister_id(&self, canister_name: &str) -> anyhow::Result { - let id = call_dfx_cli(vec!["canister", "id", canister_name]) + // TODO: This is a bad API as the two names can be swapped and it will still compile. + pub fn canister_id(&self, canister_name: &str, network_name: &str) -> anyhow::Result { + let id = call_dfx_cli(vec!["canister", "id", "--network", network_name, canister_name]) .with_context(|| format!("Failed to look up canister '{canister_name}'"))?; Principal::from_str(&id).with_context(|| format!("Could not parse canister ID: {}", id)) } diff --git a/tools/dfx-orbit/src/orbit_station_agent.rs b/tools/dfx-orbit/src/orbit_station_agent.rs new file mode 100644 index 000000000..0af641c17 --- /dev/null +++ b/tools/dfx-orbit/src/orbit_station_agent.rs @@ -0,0 +1,32 @@ +//! A dfx and IC agent for communicating with an Orbit station. + +use candid::Principal; + +use crate::{ + dfx_extension_api::DfxExtensionAgent, + local_config::{self, StationConfig}, +}; + +/// A dfx agent for communicating with a specific station. +pub struct StationAgent { + /// The station to communicate with. + pub station: StationConfig, + /// The dfx agent. + pub dfx: DfxExtensionAgent, +} + +impl StationAgent { + /// Creates a new agent for communicating with the default station. + pub fn new() -> anyhow::Result { + let dfx = DfxExtensionAgent::new(crate::ORBIT_EXTENSION_NAME); + let station = local_config::default_station()? + .ok_or_else(|| anyhow::format_err!("No default station specified"))?; + Ok(Self { station, dfx }) + } + + /// Gets the ID of a given canister name. If the name is already an ID, it is returned as is. + pub fn canister_id(&self, canister_name: &str) -> anyhow::Result { + let network = &self.station.network; + self.dfx.canister_id(canister_name, network) + } +} From 291031756e1e0ef0241e7b19aa491fa9d8d82288 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:30:12 +0200 Subject: [PATCH 077/156] Use a station agent --- tools/dfx-orbit/src/cli/request.rs | 4 ++-- tools/dfx-orbit/src/dfx_extension_api.rs | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 0fdc81a14..65c0bae90 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -11,8 +11,8 @@ use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. pub async fn main(args: Args) -> anyhow::Result> { // Converts the CLI arg type into the equivalent Orbit API type. - let mut extension_agent = crate::dfx_extension_api::DfxExtensionAgent::new("orbit"); - let ic_agent = extension_agent.agent().await?; + let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + let ic_agent = station_agent.dfx.agent().await?; let args = CreateRequestInput::from(args); let idl_text = serialize_one_to_text(&args)?; // The idl text can be too large to pass on the command line. We write it to a file and pass the file name instead. diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 5a16b3b97..3ed6675ce 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -141,9 +141,19 @@ impl DfxExtensionAgent { /// Gets a canister ID // TODO: This is a bad API as the two names can be swapped and it will still compile. - pub fn canister_id(&self, canister_name: &str, network_name: &str) -> anyhow::Result { - let id = call_dfx_cli(vec!["canister", "id", "--network", network_name, canister_name]) - .with_context(|| format!("Failed to look up canister '{canister_name}'"))?; + pub fn canister_id( + &self, + canister_name: &str, + network_name: &str, + ) -> anyhow::Result { + let id = call_dfx_cli(vec![ + "canister", + "id", + "--network", + network_name, + canister_name, + ]) + .with_context(|| format!("Failed to look up canister '{canister_name}'"))?; Principal::from_str(&id).with_context(|| format!("Could not parse canister ID: {}", id)) } } From ee2430ec479a9195dd50a270b9060cfa7eda19f6 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:32:37 +0200 Subject: [PATCH 078/156] Convert arguments with more context --- tools/dfx-orbit/src/cli/request.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 65c0bae90..ef57192d0 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -1,9 +1,9 @@ //! Implements `dfx request` commands. These correspond to Orbit station `create_request` API calls. -use crate::args::request::Args; +use crate::args::request::{Args, CreateRequestArgs}; use anyhow::anyhow; use candid::{CandidType, IDLArgs, Principal}; -use orbit_station_api::{ApiErrorDTO, CreateRequestInput, CreateRequestResponse}; +use orbit_station_api::{ApiErrorDTO, CreateRequestResponse}; use std::fs::File; use std::io::Write; use tempfile::tempdir; @@ -12,8 +12,8 @@ use tempfile::tempdir; pub async fn main(args: Args) -> anyhow::Result> { // Converts the CLI arg type into the equivalent Orbit API type. let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + let args = args.into_create_request_input(&station_agent)?; let ic_agent = station_agent.dfx.agent().await?; - let args = CreateRequestInput::from(args); let idl_text = serialize_one_to_text(&args)?; // The idl text can be too large to pass on the command line. We write it to a file and pass the file name instead. let dir = tempdir()?; From e3d379dde4b312e98009f005c148339c398cdfc2 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:38:17 +0200 Subject: [PATCH 079/156] ++ --- tools/dfx-orbit/src/args/request/canister.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index ebe5e96c9..6c88cb085 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -42,7 +42,7 @@ pub struct ChangeExternalCanister { /// The canister ID to install or update. // TODO: Canister by name #[clap(short, long)] - canister_id: Principal, + canister: String, /// The installation mode. #[clap(long, value_enum, rename_all = "kebab-case")] mode: CanisterInstallMode, @@ -62,15 +62,16 @@ impl CreateRequestArgs for ChangeExternalCanister { /// Converts the CLI arg type into the equivalent Orbit API type. fn into_create_request_input( self, - _station_agent: &StationAgent, + station_agent: &StationAgent, ) -> anyhow::Result { let ChangeExternalCanister { - canister_id, + canister, mode, wasm, arg, arg_file, } = self; + let canister_id = station_agent.canister_id(&canister)?; let operation = { let module = std::fs::read(wasm) .expect("Could not read Wasm file") @@ -116,12 +117,13 @@ pub enum CanisterInstallMode { impl From for orbit_station_api::ChangeExternalCanisterOperationInput { fn from(input: ChangeExternalCanister) -> Self { let ChangeExternalCanister { - canister_id, + canister, mode, wasm, arg, arg_file, } = input; + let canister_id = Principal::from_text(canister).expect("Invalid canister ID"); let module = std::fs::read(wasm) .expect("Could not read Wasm file") .to_vec(); From afe51e5b9c73d91f7f61c1515b1057ab1eeda7f5 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:47:04 +0200 Subject: [PATCH 080/156] Remove unused conversion --- tools/dfx-orbit/src/args/request.rs | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index 9099e0d0f..d447e13d8 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -3,7 +3,7 @@ pub mod canister; pub mod permission; use clap::Subcommand; -use orbit_station_api::{CreateRequestInput, RequestOperationInput}; +use orbit_station_api::CreateRequestInput; use crate::orbit_station_agent::StationAgent; @@ -44,25 +44,3 @@ impl CreateRequestArgs for Args { } } } - -impl From for RequestOperationInput { - fn from(args: Args) -> Self { - match args { - Args::Canister(canister_args) => RequestOperationInput::from(canister_args), - Args::Permission(permission_args) => RequestOperationInput::from(permission_args), - } - } -} - -impl From for CreateRequestInput { - fn from(args: Args) -> Self { - let operation = RequestOperationInput::from(args); - // TODO: Get title, summary, and execution_plan from args. - CreateRequestInput { - operation, - title: None, - summary: None, - execution_plan: None, - } - } -} From 95a2dbdc45d478815908d1c65b1acd8c47e20e80 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 02:52:26 +0200 Subject: [PATCH 081/156] Rm unused conversions --- tools/dfx-orbit/src/args/request/canister.rs | 43 ------------------- .../dfx-orbit/src/args/request/permission.rs | 8 ---- 2 files changed, 51 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index 6c88cb085..20ad15b6c 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -2,7 +2,6 @@ use super::CreateRequestArgs; use crate::orbit_station_agent::StationAgent; -use candid::Principal; use clap::{Parser, Subcommand, ValueEnum}; /// Request canister changes. @@ -25,16 +24,6 @@ impl CreateRequestArgs for Args { } } -impl From for orbit_station_api::RequestOperationInput { - fn from(args: Args) -> Self { - match args { - Args::Change(change_args) => { - orbit_station_api::RequestOperationInput::ChangeExternalCanister(change_args.into()) - } - } - } -} - /// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. #[derive(Debug, Parser)] pub struct ChangeExternalCanister { @@ -114,38 +103,6 @@ pub enum CanisterInstallMode { Upgrade, } -impl From for orbit_station_api::ChangeExternalCanisterOperationInput { - fn from(input: ChangeExternalCanister) -> Self { - let ChangeExternalCanister { - canister, - mode, - wasm, - arg, - arg_file, - } = input; - let canister_id = Principal::from_text(canister).expect("Invalid canister ID"); - let module = std::fs::read(wasm) - .expect("Could not read Wasm file") - .to_vec(); - let arg = if let Some(file) = arg_file { - Some( - std::fs::read(file) - .expect("Could not read argument file") - .to_vec(), - ) - } else { - arg.map(|arg| arg.as_bytes().to_vec()) - }; - let mode = mode.into(); - orbit_station_api::ChangeExternalCanisterOperationInput { - canister_id, - mode, - module, - arg, - } - } -} - impl From for orbit_station_api::CanisterInstallMode { fn from(mode: CanisterInstallMode) -> Self { match mode { diff --git a/tools/dfx-orbit/src/args/request/permission.rs b/tools/dfx-orbit/src/args/request/permission.rs index f52892bb6..25918970b 100644 --- a/tools/dfx-orbit/src/args/request/permission.rs +++ b/tools/dfx-orbit/src/args/request/permission.rs @@ -27,11 +27,3 @@ impl CreateRequestArgs for Args { } } } - -impl From for orbit_station_api::RequestOperationInput { - fn from(args: Args) -> Self { - match args { - Args::Canister(change_args) => change_args.try_into().expect("TODO: bubble this up"), - } - } -} From 1c693cebc6f11d07afe68eb8bed51b23bd0d9fa2 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 03:07:41 +0200 Subject: [PATCH 082/156] tweak --- .../src/args/request/permission/canister.rs | 49 ++++++++++--------- 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs index fd8c700ea..3b8b6f78e 100644 --- a/tools/dfx-orbit/src/args/request/permission/canister.rs +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -38,31 +38,36 @@ impl CreateRequestArgs for ChangeCanister { self, station_agent: &StationAgent, ) -> anyhow::Result { - if let Some(canister_name_or_id) = self.canister { - let canister_id = station_agent.canister_id(&canister_name_or_id)?; - let resource = orbit_station_api::ResourceDTO::ExternalCanister( - orbit_station_api::ExternalCanisterResourceActionDTO::Change( + let canisters: anyhow::Result = + if let Some(canister_name_or_id) = self.canister { + let canister_id = station_agent.canister_id(&canister_name_or_id)?; + Ok( orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister( canister_id, ), - ), - ); - Ok(orbit_station_api::CreateRequestInput { - operation: orbit_station_api::RequestOperationInput::EditPermission( - orbit_station_api::EditPermissionOperationInput { - resource, - auth_scope: None, - users: None, - user_groups: None, - }, - ), - title: None, - summary: None, - execution_plan: None, - }) - } else { - unimplemented!("Need to implement granting access to all canisters.") - } + ) + } else { + Ok(orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Any) + }; + + let resource = orbit_station_api::ResourceDTO::ExternalCanister( + orbit_station_api::ExternalCanisterResourceActionDTO::Change(canisters?), + ); + + let operation = orbit_station_api::RequestOperationInput::EditPermission( + orbit_station_api::EditPermissionOperationInput { + resource, + auth_scope: None, + users: None, + user_groups: None, + }, + ); + Ok(orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + }) } } From 03e0a749ef5a070bb52ac2dc6bde44cd3cccd489 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 03:10:59 +0200 Subject: [PATCH 083/156] clean --- tools/dfx-orbit/src/args/request/permission/canister.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs index 3b8b6f78e..baf896ab2 100644 --- a/tools/dfx-orbit/src/args/request/permission/canister.rs +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -40,12 +40,9 @@ impl CreateRequestArgs for ChangeCanister { ) -> anyhow::Result { let canisters: anyhow::Result = if let Some(canister_name_or_id) = self.canister { - let canister_id = station_agent.canister_id(&canister_name_or_id)?; - Ok( - orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister( - canister_id, - ), - ) + station_agent + .canister_id(&canister_name_or_id) + .map(orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister) } else { Ok(orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Any) }; From 5c9187c8a3505c4600ce33ab73c403c9b2095b9a Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 03:13:05 +0200 Subject: [PATCH 084/156] ++ --- tools/dfx-orbit/src/args/request/permission/canister.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs index baf896ab2..9728b984f 100644 --- a/tools/dfx-orbit/src/args/request/permission/canister.rs +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -28,6 +28,7 @@ impl CreateRequestArgs for Args { #[derive(Debug, Parser)] pub struct ChangeCanister { /// Canister name or ID. + // TODO: If a canister is not specified, require --all. #[structopt(long)] pub canister: Option, } From cf69e38e0006abf37c24ac005ea0fbedb5c7e1ef Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 16:29:54 +0200 Subject: [PATCH 085/156] Manual --- CLI.md | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 CLI.md diff --git a/CLI.md b/CLI.md new file mode 100644 index 000000000..a4d3dea9c --- /dev/null +++ b/CLI.md @@ -0,0 +1,87 @@ +# Command Line Interface + +The `dfx-orbit` command line is a tool for interacting with Orbit. Currently it focuses on deploying canisters controlled by Orbit but the scope is expected to grow. + +## Getting started + +### Installation +Build the tool: +``` +$ cargo build -p dfx-orbit +``` + +Verify that the tool works: +``` +$ ./target/debug/dfx-orbit --version +dfx-orbit 0.1.0 + +$ ./target/debug/dfx-orbit --help +Command line tool for interacting with the Orbit digital asset manager on the ICP blockchain. + +Usage: dfx-orbit + +Commands: + station Manages Orbit stations +... +``` + +Add `dfx-orbit` to your `PATH`. + +### Connect to Orbit + +Connect your local dfx identity to your Orbit identity: + +* Log in to Orbit. +* Navigate to Settings -> Users -> Edit a user -> Identities +* Add the principal provided by `dfx identity get-principal` + +Tell the command line tool where to find the orbit station: + +* Log in to Orbit. +* Navigate to station settings. +* Copy the wallet ID +* Store the station details locally. If your wallet is called `shiny` and is running locally, the command is: + ``` + dfx-orbit station add --name shiny --canister-id "$WALLET_ID" --network local + ``` +* Verify that the station is in your list of stations: + ``` + dfx-orbit station list + ``` +* If you have multiple stations, set this as your default: + ``` + dfx-orbit station use --name shiny + ``` +* Verify that you can get your profile on the Orbit station: + ``` + dfx-orbit me + ``` + +## Control a canister with Orbit + +### Grant Orbit control of the canister +Assume that you have a canister called `MY_CANISTER` in `dfx`. You may also refer to your canister by canister ID. + +Add Orbit as a controller while keeping existing controllers: +``` +( + orbit_station="$(dfx-orbit station show | jq -r .canister_id)" + dfx canister update-settings --add-controller "$orbit_station" MY_CANISTER +) +``` + +### Register yourself as a developer for your canister +This will allow you to propose upgrades to `MY_CANISTER`: + +``` +dfx-orbit request permission canister change --canister MY_CANISTER +``` +This will create an Orbit request. Once approved you will be able to propose canister upgrades. + +> :warning: **The Orbit GUI does not currently show this proposal unless you enter the proposal URL directly, under /en/settings/requests?reqid=THE_ID** + +### Upgrade a canister +Suppose that you have built a new Wasm and put a copy at `./MY-CANISTER.wasm.gz`. To upgrade your canister to the new Wasm: +``` +dfx-orbit request canister change --canister MY_CANISTER --mode upgrade --wasm ./MY-CANISTER.wasm.gz +``` \ No newline at end of file From 360890ddf53374cd93f93e961892f545a7cc5293 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 16:34:26 +0200 Subject: [PATCH 086/156] Rm unused --- .../src/args/request/permission/canister.rs | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs index 9728b984f..8fcade636 100644 --- a/tools/dfx-orbit/src/args/request/permission/canister.rs +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -1,5 +1,4 @@ //! Makes `EditPermission` requests regarding `ExternalCanister` to Orbit. -use candid::Principal; use clap::{Parser, Subcommand}; use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; @@ -68,40 +67,3 @@ impl CreateRequestArgs for ChangeCanister { }) } } - -impl TryFrom for orbit_station_api::RequestOperationInput { - type Error = anyhow::Error; - fn try_from(args: Args) -> anyhow::Result { - match args { - Args::Change(change_args) => Ok( - orbit_station_api::RequestOperationInput::EditPermission(change_args.try_into()?), - ), - } - } -} - -impl TryFrom for orbit_station_api::EditPermissionOperationInput { - type Error = anyhow::Error; - - fn try_from(args: ChangeCanister) -> anyhow::Result { - if let Some(canister_name_or_id) = args.canister { - // Grant permission for just this one canister. - let canister_id = Principal::from_text(canister_name_or_id)?; - let resource = orbit_station_api::ResourceDTO::ExternalCanister( - orbit_station_api::ExternalCanisterResourceActionDTO::Change( - orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister( - canister_id, - ), - ), - ); - Ok(orbit_station_api::EditPermissionOperationInput { - resource, - auth_scope: None, - users: None, - user_groups: None, - }) - } else { - unimplemented!("Need to implement granting access to all canisters.") - } - } -} From 5f59249964c99819993acd63f7dc2bd567d0c429 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 16:39:53 +0200 Subject: [PATCH 087/156] Convention: Use exec rather than main in the lib --- tools/dfx-orbit/src/cli.rs | 10 +++++----- tools/dfx-orbit/src/cli/canister.rs | 4 ++-- tools/dfx-orbit/src/cli/canister/claim.rs | 2 +- tools/dfx-orbit/src/cli/dfx_extension_cli.rs | 2 +- tools/dfx-orbit/src/cli/request.rs | 2 +- tools/dfx-orbit/src/cli/station.rs | 2 +- tools/dfx-orbit/src/main.rs | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 285943335..2865cfe7e 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -8,7 +8,7 @@ use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; use anyhow::anyhow; /// A command line tool for interacting with Orbit on the Internet Computer. -pub async fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { +pub async fn exec(args: DfxOrbitArgs) -> anyhow::Result<()> { match args.command { DfxOrbitSubcommands::Me => { let station_principal = &crate::local_config::default_station()? @@ -23,12 +23,12 @@ pub async fn main(args: DfxOrbitArgs) -> anyhow::Result<()> { print!("{ans}"); Ok(()) } - DfxOrbitSubcommands::Station(station_args) => station::main(station_args), + DfxOrbitSubcommands::Station(station_args) => station::exec(station_args), DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { - dfx_extension_cli::main(dfx_extension_args) + dfx_extension_cli::exec(dfx_extension_args) } - DfxOrbitSubcommands::Canister(canister_args) => canister::main(canister_args), - DfxOrbitSubcommands::Request(request_args) => match request::main(request_args).await { + DfxOrbitSubcommands::Canister(canister_args) => canister::exec(canister_args), + DfxOrbitSubcommands::Request(request_args) => match request::exec(request_args).await { Ok(Ok(_response)) => Ok(()), Ok(Err(e)) => Err(anyhow!("Error response from the station: {e:?}")), Err(e) => Err(e), diff --git a/tools/dfx-orbit/src/cli/canister.rs b/tools/dfx-orbit/src/cli/canister.rs index 9a6bb3d54..a40a25099 100644 --- a/tools/dfx-orbit/src/cli/canister.rs +++ b/tools/dfx-orbit/src/cli/canister.rs @@ -4,8 +4,8 @@ mod claim; use crate::args::canister::Args; /// The main entry point for the `dfx orbit` CLI. -pub fn main(args: Args) -> anyhow::Result<()> { +pub fn exec(args: Args) -> anyhow::Result<()> { match args { - Args::Claim(claim_args) => claim::main(claim_args), + Args::Claim(claim_args) => claim::exec(claim_args), } } diff --git a/tools/dfx-orbit/src/cli/canister/claim.rs b/tools/dfx-orbit/src/cli/canister/claim.rs index aa3d144dc..92896a56b 100644 --- a/tools/dfx-orbit/src/cli/canister/claim.rs +++ b/tools/dfx-orbit/src/cli/canister/claim.rs @@ -4,7 +4,7 @@ use anyhow::anyhow; use crate::{args::canister::Claim, dfx_extension_api, local_config}; /// Puts a canister controlled by the user under Orbit control. -pub fn main(args: Claim) -> anyhow::Result<()> { +pub fn exec(args: Claim) -> anyhow::Result<()> { let Claim { canister, exclusive, diff --git a/tools/dfx-orbit/src/cli/dfx_extension_cli.rs b/tools/dfx-orbit/src/cli/dfx_extension_cli.rs index a72e11237..22667bcc4 100644 --- a/tools/dfx-orbit/src/cli/dfx_extension_cli.rs +++ b/tools/dfx-orbit/src/cli/dfx_extension_cli.rs @@ -3,7 +3,7 @@ use crate::args::dfx_extension_api; use std::io::Read; /// Implements CLI commands for getting data from the dfx extension API. -pub fn main(dfx_extension_args: dfx_extension_api::Args) -> anyhow::Result<()> { +pub fn exec(dfx_extension_args: dfx_extension_api::Args) -> anyhow::Result<()> { match dfx_extension_args { dfx_extension_api::Args::Config(config_args) => match config_args { dfx_extension_api::config::Args::Dir => { diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index ef57192d0..1e666dcfc 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -9,7 +9,7 @@ use std::io::Write; use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. -pub async fn main(args: Args) -> anyhow::Result> { +pub async fn exec(args: Args) -> anyhow::Result> { // Converts the CLI arg type into the equivalent Orbit API type. let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let args = args.into_create_request_input(&station_agent)?; diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index 31234aab0..b93dece53 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -3,7 +3,7 @@ use crate::args::station::{ListResponse, StationArgs}; use crate::local_config; /// Implements CLI commands for managing Orbit stations. -pub fn main(args: StationArgs) -> anyhow::Result<()> { +pub fn exec(args: StationArgs) -> anyhow::Result<()> { match args { StationArgs::Add(add_args) => { local_config::add_station(&add_args) diff --git a/tools/dfx-orbit/src/main.rs b/tools/dfx-orbit/src/main.rs index 3a908f324..198125da8 100644 --- a/tools/dfx-orbit/src/main.rs +++ b/tools/dfx-orbit/src/main.rs @@ -9,6 +9,6 @@ fn main() { let args = DfxOrbitArgs::parse(); let runtime = Runtime::new().expect("Unable to create a runtime"); runtime.block_on(async { - lib::cli::main(args).await.unwrap(); + lib::cli::exec(args).await.unwrap(); }); } From f3bea56f30dd1079cae3f0597508007099dd4307 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 16:57:02 +0200 Subject: [PATCH 088/156] Cleanup --- Cargo.toml | 1 - tools/dfx-orbit/src/args/dfx_extension_api.rs | 2 +- tools/dfx-orbit/src/cli/canister.rs | 2 +- tools/dfx-orbit/src/cli/canister/claim.rs | 3 ++- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6ddb18605..84ce72002 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,6 @@ members = [ "libs/orbit-essentials", "libs/orbit-essentials-macros", "libs/orbit-essentials-macros-tests", - "tools/dfx-orbit", "tests/integration", "tools/dfx-orbit", ] diff --git a/tools/dfx-orbit/src/args/dfx_extension_api.rs b/tools/dfx-orbit/src/args/dfx_extension_api.rs index ba6cc900c..fc399a099 100644 --- a/tools/dfx-orbit/src/args/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/args/dfx_extension_api.rs @@ -1,4 +1,4 @@ -//! dfx-orbit station management commands. +//! `dfx` does not have an extension API, yet. So imagine one existed and create a polyfill. This is it. pub mod config; use clap::Subcommand; diff --git a/tools/dfx-orbit/src/cli/canister.rs b/tools/dfx-orbit/src/cli/canister.rs index a40a25099..8a5173406 100644 --- a/tools/dfx-orbit/src/cli/canister.rs +++ b/tools/dfx-orbit/src/cli/canister.rs @@ -1,4 +1,4 @@ -//! Implements the dfx extension CLI commands for managing external canisters. +//! Implements the `dfx-orbit canister *` CLI commands. mod claim; use crate::args::canister::Args; diff --git a/tools/dfx-orbit/src/cli/canister/claim.rs b/tools/dfx-orbit/src/cli/canister/claim.rs index 92896a56b..160a405b8 100644 --- a/tools/dfx-orbit/src/cli/canister/claim.rs +++ b/tools/dfx-orbit/src/cli/canister/claim.rs @@ -4,12 +4,13 @@ use anyhow::anyhow; use crate::{args::canister::Claim, dfx_extension_api, local_config}; /// Puts a canister controlled by the user under Orbit control. +// TODO: Need to be able to specify which Orbit to use, e.g. as a global flag. +// TODO: Implement this without calling the `dfx` executable. pub fn exec(args: Claim) -> anyhow::Result<()> { let Claim { canister, exclusive, } = args; - // TODO: Need to be able to specify which Orbit to use, e.g. as a global flag. let orbit_principal = &local_config::default_station()? .ok_or_else(|| anyhow!("No default station specified"))? .canister_id; From db40c8748a5c05acc54c0f0839ee3a0a41441d88 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 19 Jun 2024 17:00:11 +0200 Subject: [PATCH 089/156] Cleanup --- Cargo.lock | 1 - Cargo.toml | 1 - tools/dfx-orbit/Cargo.toml | 1 - tools/dfx-orbit/src/cli/request.rs | 21 +-------------------- 4 files changed, 1 insertion(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dc6ac0dc9..90fcb13fd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1008,7 +1008,6 @@ dependencies = [ "slog-async", "slog-term", "station-api", - "tempfile", "tokio", ] diff --git a/Cargo.toml b/Cargo.toml index 84ce72002..03fed1054 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,7 +70,6 @@ slog = "2.5.2" slog-async = "2.4.0" slog-term = "2.9.0" syn = { version = "2.0", features = ["extra-traits", "full"] } -tempfile = "3.10.1" thiserror = "1.0.48" time = { version = "0.3", features = ["formatting", "parsing"] } tokio = { version = "1.33.0" } diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 48e3d6663..7a1a53b91 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -18,7 +18,6 @@ serde.workspace = true serde_json.workspace = true cap-std.workspace = true dfx-core.workspace = true -tempfile.workspace = true ic-agent.workspace = true slog.workspace = true slog-term.workspace = true diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 1e666dcfc..3f7a73782 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -2,11 +2,8 @@ use crate::args::request::{Args, CreateRequestArgs}; use anyhow::anyhow; -use candid::{CandidType, IDLArgs, Principal}; +use candid::Principal; use orbit_station_api::{ApiErrorDTO, CreateRequestResponse}; -use std::fs::File; -use std::io::Write; -use tempfile::tempdir; /// The main entry point for the `dfx orbit` CLI. pub async fn exec(args: Args) -> anyhow::Result> { @@ -14,13 +11,6 @@ pub async fn exec(args: Args) -> anyhow::Result anyhow::Result(value: &T) -> anyhow::Result { - // Afaik there still is no better way of doing this than serializing to binary candid, then converting the binary candid to text-type candid. If true this is really unfortunate. - let bytes = candid::encode_one(value)?; - let decoded: IDLArgs = IDLArgs::from_bytes(&bytes)?; - let text = decoded.to_string(); - Ok(text) -} From d8082de979a4fe5f56fe0240ab8fdb8230a89a35 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 17:50:09 +0200 Subject: [PATCH 090/156] Step towards an asset upload function --- tools/dfx-orbit/src/args/canister.rs | 13 +++++++++++++ tools/dfx-orbit/src/cli.rs | 2 +- tools/dfx-orbit/src/cli/canister.rs | 6 +++++- tools/dfx-orbit/src/orbit_station_agent.rs | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index 68d0ea4fb..86f04d7c3 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -9,6 +9,8 @@ use std::fmt::Debug; pub enum Args { /// Puts a canister controlled by the user under Orbit control. Claim(Claim), + /// Uplods assets to an HTTP asset canister. + UploadHttpAssets(UploadHttpAssets), } /// Puts a canister controlled by the user under Orbit control. @@ -21,3 +23,14 @@ pub struct Claim { #[clap(long, short, action)] pub exclusive: bool, } + +/// Uploads assets to an HTTP asset canister. +#[derive(Debug, Parser)] +pub struct UploadHttpAssets { + /// The canister name or `canister_id`. + #[structopt(long)] + pub canister: String, + /// The path to the assets to upload. + #[structopt(long)] + pub path: String, +} diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 2865cfe7e..b5ed1241c 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -27,7 +27,7 @@ pub async fn exec(args: DfxOrbitArgs) -> anyhow::Result<()> { DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { dfx_extension_cli::exec(dfx_extension_args) } - DfxOrbitSubcommands::Canister(canister_args) => canister::exec(canister_args), + DfxOrbitSubcommands::Canister(canister_args) => canister::exec(canister_args).await, DfxOrbitSubcommands::Request(request_args) => match request::exec(request_args).await { Ok(Ok(_response)) => Ok(()), Ok(Err(e)) => Err(anyhow!("Error response from the station: {e:?}")), diff --git a/tools/dfx-orbit/src/cli/canister.rs b/tools/dfx-orbit/src/cli/canister.rs index 8a5173406..8cfc0c5df 100644 --- a/tools/dfx-orbit/src/cli/canister.rs +++ b/tools/dfx-orbit/src/cli/canister.rs @@ -1,11 +1,15 @@ //! Implements the `dfx-orbit canister *` CLI commands. mod claim; +mod upload_http_assets; use crate::args::canister::Args; /// The main entry point for the `dfx orbit` CLI. -pub fn exec(args: Args) -> anyhow::Result<()> { +pub async fn exec(args: Args) -> anyhow::Result<()> { match args { Args::Claim(claim_args) => claim::exec(claim_args), + Args::UploadHttpAssets(upload_http_assets_args) => { + upload_http_assets::exec(upload_http_assets_args).await + } } } diff --git a/tools/dfx-orbit/src/orbit_station_agent.rs b/tools/dfx-orbit/src/orbit_station_agent.rs index 0af641c17..9a13c1810 100644 --- a/tools/dfx-orbit/src/orbit_station_agent.rs +++ b/tools/dfx-orbit/src/orbit_station_agent.rs @@ -29,4 +29,10 @@ impl StationAgent { let network = &self.station.network; self.dfx.canister_id(canister_name, network) } + + /// Makes a canister update call on the network used by the station. + pub async fn update(&mut self) { + let _agent = self.dfx.agent(); + todo!() + } } From 1fa6226094354c63434225470376674e9b224887 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 18:02:49 +0200 Subject: [PATCH 091/156] step --- .../dfx-orbit/src/cli/canister/upload_http_assets.rs | 12 ++++++++++++ tools/dfx-orbit/src/orbit_station_agent.rs | 6 +++--- 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 tools/dfx-orbit/src/cli/canister/upload_http_assets.rs diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs new file mode 100644 index 000000000..de02f6b79 --- /dev/null +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -0,0 +1,12 @@ +//! Implements the `dfx-orbit canister upload-http-assets` CLI command. +use crate::args::canister::UploadHttpAssets as Args; + +/// The main entry point for the `dfx orbit` CLI. +pub async fn exec(args: Args) -> anyhow::Result<()> { + let Args { + canister: _canister, + path: _path, + } = args; + let _station_agent = crate::orbit_station_agent::StationAgent::new()?; + todo!() +} diff --git a/tools/dfx-orbit/src/orbit_station_agent.rs b/tools/dfx-orbit/src/orbit_station_agent.rs index 9a13c1810..aa0411426 100644 --- a/tools/dfx-orbit/src/orbit_station_agent.rs +++ b/tools/dfx-orbit/src/orbit_station_agent.rs @@ -1,6 +1,7 @@ //! A dfx and IC agent for communicating with an Orbit station. use candid::Principal; +use ic_agent::agent::UpdateBuilder; use crate::{ dfx_extension_api::DfxExtensionAgent, @@ -31,8 +32,7 @@ impl StationAgent { } /// Makes a canister update call on the network used by the station. - pub async fn update(&mut self) { - let _agent = self.dfx.agent(); - todo!() + pub async fn update(&mut self, canister_id: &Principal, method_name: &str) -> anyhow::Result { + Ok(self.dfx.agent().await?.update(canister_id, method_name)) } } From ce58a52b76259b207090518842bbe9b356f6da51 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 19:19:21 +0200 Subject: [PATCH 092/156] Add the ic-asset crate --- Cargo.lock | 194 +++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + tools/dfx-orbit/Cargo.toml | 1 + 3 files changed, 190 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 90fcb13fd..7357f806b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -247,9 +247,12 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" dependencies = [ + "futures-core", "getrandom", "instant", + "pin-project-lite", "rand", + "tokio", ] [[package]] @@ -443,6 +446,16 @@ dependencies = [ "sha2 0.9.9", ] +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -992,6 +1005,47 @@ dependencies = [ "url", ] +[[package]] +name = "dfx-core" +version = "0.0.1" +source = "git+https://github.com/dfinity/sdk.git?rev=66f2b87e94f2fde67f64ba8e38ee2ea9047a909e#66f2b87e94f2fde67f64ba8e38ee2ea9047a909e" +dependencies = [ + "aes-gcm", + "argon2", + "bip32", + "byte-unit", + "bytes", + "candid", + "clap", + "dialoguer", + "directories-next", + "dunce", + "flate2", + "handlebars", + "hex", + "humantime-serde", + "ic-agent", + "ic-identity-hsm", + "ic-utils", + "k256 0.11.6", + "keyring", + "lazy_static", + "reqwest", + "ring 0.16.20", + "schemars", + "sec1 0.3.0", + "semver", + "serde", + "serde_json", + "slog", + "tar", + "tempfile", + "thiserror", + "time", + "tiny-bip39", + "url", +] + [[package]] name = "dfx-orbit" version = "0.1.0" @@ -1000,8 +1054,9 @@ dependencies = [ "candid", "cap-std", "clap", - "dfx-core", + "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?tag=0.20.2-beta.0)", "ic-agent", + "ic-asset", "serde", "serde_json", "slog", @@ -1408,6 +1463,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + [[package]] name = "futures-io" version = "0.3.30" @@ -1520,6 +1586,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + [[package]] name = "group" version = "0.12.1" @@ -1800,6 +1879,36 @@ dependencies = [ "url", ] +[[package]] +name = "ic-asset" +version = "0.20.0" +source = "git+https://github.com/dfinity/sdk.git?rev=66f2b87e94f2fde67f64ba8e38ee2ea9047a909e#66f2b87e94f2fde67f64ba8e38ee2ea9047a909e" +dependencies = [ + "backoff", + "candid", + "derivative", + "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?rev=66f2b87e94f2fde67f64ba8e38ee2ea9047a909e)", + "flate2", + "futures", + "futures-intrusive", + "globset", + "hex", + "ic-agent", + "ic-utils", + "itertools 0.10.5", + "json5", + "mime", + "mime_guess", + "serde", + "serde_bytes", + "serde_json", + "sha2 0.10.8", + "slog", + "thiserror", + "tokio", + "walkdir", +] + [[package]] name = "ic-cdk" version = "0.12.1" @@ -2109,6 +2218,15 @@ version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + [[package]] name = "itertools" version = "0.11.0" @@ -2133,6 +2251,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "json5" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1" +dependencies = [ + "pest", + "pest_derive", + "serde", +] + [[package]] name = "k256" version = "0.11.6" @@ -2190,7 +2319,7 @@ dependencies = [ "ascii-canvas", "bit-set", "ena", - "itertools", + "itertools 0.11.0", "lalrpop-util", "petgraph", "pico-args", @@ -2356,6 +2485,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -2648,6 +2787,17 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + [[package]] name = "parking_lot" version = "0.12.2" @@ -2655,7 +2805,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e4af0ca4f6caed20e900d564c242b8e5d4903fdacf31d3daf527b66fe6f42fb" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", ] [[package]] @@ -3014,7 +3178,7 @@ dependencies = [ "fnv", "lazy_static", "memchr", - "parking_lot", + "parking_lot 0.12.2", "protobuf", "thiserror", ] @@ -3079,6 +3243,15 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60fcc7d6849342eff22c4350c8b9a989ee8ceabc4b481253e8946b9fe83d684" +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -3922,7 +4095,7 @@ checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b" dependencies = [ "new_debug_unreachable", "once_cell", - "parking_lot", + "parking_lot 0.12.2", "phf_shared", "precomputed-hash", ] @@ -4162,7 +4335,7 @@ dependencies = [ "libc", "mio", "num_cpus", - "parking_lot", + "parking_lot 0.12.2", "pin-project-lite", "signal-hook-registry", "socket2 0.5.7", @@ -4383,6 +4556,15 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "unicase" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" +dependencies = [ + "version_check", +] + [[package]] name = "unicode-bidi" version = "0.3.15" diff --git a/Cargo.toml b/Cargo.toml index 03fed1054..e0d1cd99e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ getrandom = { version = "0.2", features = ["custom"] } hex = "0.4" # The ic-agent matches the one sed by bthe ic-agent = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } +ic-asset = { git = "https://github.com/dfinity/sdk.git", rev = "66f2b87e94f2fde67f64ba8e38ee2ea9047a909e" } ic-cdk = "0.13.2" ic-cdk-macros = "0.9" ic-cdk-timers = "0.7.0" diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 7a1a53b91..df68048ab 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -19,6 +19,7 @@ serde_json.workspace = true cap-std.workspace = true dfx-core.workspace = true ic-agent.workspace = true +ic-asset.workspace = true slog.workspace = true slog-term.workspace = true slog-async.workspace = true From 2015991cde8e8167807b737543b911c5cc8f08f1 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 19:23:37 +0200 Subject: [PATCH 093/156] fmt --- tools/dfx-orbit/src/orbit_station_agent.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/orbit_station_agent.rs b/tools/dfx-orbit/src/orbit_station_agent.rs index aa0411426..74adb353f 100644 --- a/tools/dfx-orbit/src/orbit_station_agent.rs +++ b/tools/dfx-orbit/src/orbit_station_agent.rs @@ -32,7 +32,11 @@ impl StationAgent { } /// Makes a canister update call on the network used by the station. - pub async fn update(&mut self, canister_id: &Principal, method_name: &str) -> anyhow::Result { + pub async fn update( + &mut self, + canister_id: &Principal, + method_name: &str, + ) -> anyhow::Result { Ok(self.dfx.agent().await?.update(canister_id, method_name)) } } From a3771626c72c4c5969bb5006dde3024a3cbe5800 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 19:28:52 +0200 Subject: [PATCH 094/156] Add a logger --- tools/dfx-orbit/src/dfx_extension_api.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 3ed6675ce..4615cf83b 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -8,6 +8,7 @@ use anyhow::Context; use candid::Principal; use dfx_core::interface::dfx::DfxInterface; use ic_agent::Agent; +use slog::{o, Drain, Logger}; /// Calls the dfx cli. /// @@ -43,21 +44,36 @@ pub struct DfxExtensionAgent { name: String, /// The directory where all extension configuration files are stored, including those of other extensions. extensions_dir: cap_std::fs::Dir, - /// The dfx interface. + /// An interface including an ic-agent. dfx_interface: Option, + /// A logger; some public `sdk` repository methods require a specific type of logger so this is a compatible logger. + logger: Logger, } impl DfxExtensionAgent { /// Creates a new DfxExtensionAgent for the extension with the given name. pub fn new(name: &str) -> Self { + let logger = { + let decorator = slog_term::TermDecorator::new().build(); + let drain = slog_term::FullFormat::new(decorator).build().fuse(); + let drain = slog_async::Async::new(drain).build().fuse(); + + slog::Logger::root(drain, o!()) + }; Self { name: name.to_string(), extensions_dir: Self::extensions_dir() .expect("Could not get the dfx extensions directory"), dfx_interface: None, + logger, } } + /// A logger; some public `sdk` repository methods require a specific type of logger so this is a compatible logger. + pub fn logger(&self) -> &Logger { + &self.logger + } + /// Gets the extensions directory, typically at `~/.config/dfx/extensions` fn extensions_dir() -> anyhow::Result { let user_config_dir = dfx_core::config::directories::get_user_dfx_config_dir() From f3c41819f91b24a2c7644f4d7c664a578037c801 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 19:37:44 +0200 Subject: [PATCH 095/156] Import ic-utils --- Cargo.lock | 1 + Cargo.toml | 1 + tools/dfx-orbit/Cargo.toml | 1 + 3 files changed, 3 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 7357f806b..8d5782db3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1057,6 +1057,7 @@ dependencies = [ "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?tag=0.20.2-beta.0)", "ic-agent", "ic-asset", + "ic-utils", "serde", "serde_json", "slog", diff --git a/Cargo.toml b/Cargo.toml index e0d1cd99e..c52b324b6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ ic-cdk-macros = "0.9" ic-cdk-timers = "0.7.0" ic-ledger-types = "0.10.0" ic-stable-structures = "0.6.4" +ic-utils = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } lazy_static = "1.4.0" mockall = "0.12.1" num-bigint = "0.4" diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index df68048ab..f09fc6eb1 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -20,6 +20,7 @@ cap-std.workspace = true dfx-core.workspace = true ic-agent.workspace = true ic-asset.workspace = true +ic-utils.workspace = true slog.workspace = true slog-term.workspace = true slog-async.workspace = true From a2d1f006eee4c202e19673b2f5f9477d748d9953 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 19:39:30 +0200 Subject: [PATCH 096/156] Look up canister id --- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index de02f6b79..3528454c5 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -4,9 +4,10 @@ use crate::args::canister::UploadHttpAssets as Args; /// The main entry point for the `dfx orbit` CLI. pub async fn exec(args: Args) -> anyhow::Result<()> { let Args { - canister: _canister, + canister, path: _path, } = args; - let _station_agent = crate::orbit_station_agent::StationAgent::new()?; + let station_agent = crate::orbit_station_agent::StationAgent::new()?; + let _canister_id = station_agent.canister_id(&canister)?; todo!() } From 570696386a2b27c4fdbe3ad68982937fb4c21713 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 20 Jun 2024 19:43:55 +0200 Subject: [PATCH 097/156] Create a canister agent --- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 3528454c5..add9b2943 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -1,4 +1,6 @@ //! Implements the `dfx-orbit canister upload-http-assets` CLI command. +use ic_utils::canister::CanisterBuilder; + use crate::args::canister::UploadHttpAssets as Args; /// The main entry point for the `dfx orbit` CLI. @@ -7,7 +9,11 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { canister, path: _path, } = args; - let station_agent = crate::orbit_station_agent::StationAgent::new()?; - let _canister_id = station_agent.canister_id(&canister)?; + let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + let canister_id = station_agent.canister_id(&canister)?; + let _canister_agent = CanisterBuilder::new() + .with_agent(station_agent.dfx.agent().await?) + .with_canister_id(canister_id) + .build()?; todo!() } From 44c5ee5e93bba56e00c3d00a06820d6f4b6187ed Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 12:58:59 +0200 Subject: [PATCH 098/156] Add verbose flag --- tools/dfx-orbit/src/args/canister.rs | 3 +++ tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index 86f04d7c3..93e6ed263 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -33,4 +33,7 @@ pub struct UploadHttpAssets { /// The path to the assets to upload. #[structopt(long)] pub path: String, + /// Provide a running commentary. + #[arg(short, long, default_value_t = false)] + pub verbose: bool, } diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index add9b2943..c3ab33659 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -8,7 +8,11 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let Args { canister, path: _path, + verbose, } = args; + if verbose { + println!("Uploading assets to canister: {}", canister); + } let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let canister_id = station_agent.canister_id(&canister)?; let _canister_agent = CanisterBuilder::new() From f7b2cd2d54bd2d5856124401774c7ed774eb223a Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 13:54:49 +0200 Subject: [PATCH 099/156] List assets --- Cargo.lock | 1 + tools/dfx-orbit/Cargo.toml | 1 + .../src/cli/canister/upload_http_assets.rs | 28 +++++++++++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8d5782db3..d1de10609 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1065,6 +1065,7 @@ dependencies = [ "slog-term", "station-api", "tokio", + "walkdir", ] [[package]] diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index f09fc6eb1..21e210948 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -27,3 +27,4 @@ slog-async.workspace = true tokio.workspace = true orbit-station-api = { path = "../../core/station/api", package = "station-api" } +walkdir = "2.5.0" diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index c3ab33659..5dfe9a296 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -1,5 +1,8 @@ //! Implements the `dfx-orbit canister upload-http-assets` CLI command. +use std::path::PathBuf; + use ic_utils::canister::CanisterBuilder; +use walkdir::WalkDir; use crate::args::canister::UploadHttpAssets as Args; @@ -7,11 +10,14 @@ use crate::args::canister::UploadHttpAssets as Args; pub async fn exec(args: Args) -> anyhow::Result<()> { let Args { canister, - path: _path, + path, verbose, } = args; if verbose { println!("Uploading assets to canister: {}", canister); + for asset in list_assets(&path){ + println!("Uploading asset: {}", asset.display()); + } } let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let canister_id = station_agent.canister_id(&canister)?; @@ -19,5 +25,23 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { .with_agent(station_agent.dfx.agent().await?) .with_canister_id(canister_id) .build()?; - todo!() + todo!("Still need to upload the assets") +} + +/// Lists all the files at the given path. +/// +/// - Links are followed. +/// - Only files are returned. +/// - The files are sorted by name. +/// - Any files that cannot be read are ignored. +/// - The path includes the prefix. +fn list_assets(path: &str) -> Vec { + WalkDir::new(path) + .sort_by_file_name() + .follow_links(true) + .into_iter() + .filter_map(|e| e.ok()) + .filter(|entry| entry.file_type().is_file()) + .map(|entry| entry.into_path()) + .collect() } From 4fdb39f5db3ce5871128af2b05859fdc6788ff86 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 15:06:35 +0200 Subject: [PATCH 100/156] Upload assets without committing them --- .../src/cli/canister/upload_http_assets.rs | 37 ++++++++++++++----- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 5dfe9a296..dac71050a 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -1,5 +1,5 @@ //! Implements the `dfx-orbit canister upload-http-assets` CLI command. -use std::path::PathBuf; +use std::{collections::HashMap, path::PathBuf}; use ic_utils::canister::CanisterBuilder; use walkdir::WalkDir; @@ -11,21 +11,18 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let Args { canister, path, - verbose, + verbose: _verbose, } = args; - if verbose { - println!("Uploading assets to canister: {}", canister); - for asset in list_assets(&path){ - println!("Uploading asset: {}", asset.display()); - } - } let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let canister_id = station_agent.canister_id(&canister)?; - let _canister_agent = CanisterBuilder::new() + let logger = station_agent.dfx.logger().clone(); + let canister_agent = CanisterBuilder::new() .with_agent(station_agent.dfx.agent().await?) .with_canister_id(canister_id) .build()?; - todo!("Still need to upload the assets") + let assets = assets_as_hash_map(&path); + ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; + Ok(()) } /// Lists all the files at the given path. @@ -45,3 +42,23 @@ fn list_assets(path: &str) -> Vec { .map(|entry| entry.into_path()) .collect() } + +/// A hash map of all assets. +/// +/// Note: Given that ordering in a HashMap is not deterministic, is this really the best API? +fn assets_as_hash_map(asset_dir: &str) -> HashMap { + list_assets(asset_dir) + .into_iter() + .map(|asset_path| { + let relative_path = asset_path.strip_prefix(asset_dir).expect( + "Internal error: list_assets should have returned only files in the asset_dir", + ); + let key = relative_path + .file_name() + .expect("Internal error: File has no name") // TODO: This can probably be eliminated by the filter_map above. + .to_string_lossy() + .to_string(); + (key, asset_path) + }) + .collect() +} From 03102c64472161a57a755d42a601b7d610bb5ca8 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 16:20:10 +0200 Subject: [PATCH 101/156] ++ --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1de10609..307f54949 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1008,7 +1008,7 @@ dependencies = [ [[package]] name = "dfx-core" version = "0.0.1" -source = "git+https://github.com/dfinity/sdk.git?rev=66f2b87e94f2fde67f64ba8e38ee2ea9047a909e#66f2b87e94f2fde67f64ba8e38ee2ea9047a909e" +source = "git+https://github.com/dfinity/sdk.git?rev=dc587bf24206686a8be2c7f6d57e01a300bda5ad#dc587bf24206686a8be2c7f6d57e01a300bda5ad" dependencies = [ "aes-gcm", "argon2", @@ -1884,12 +1884,12 @@ dependencies = [ [[package]] name = "ic-asset" version = "0.20.0" -source = "git+https://github.com/dfinity/sdk.git?rev=66f2b87e94f2fde67f64ba8e38ee2ea9047a909e#66f2b87e94f2fde67f64ba8e38ee2ea9047a909e" +source = "git+https://github.com/dfinity/sdk.git?rev=dc587bf24206686a8be2c7f6d57e01a300bda5ad#dc587bf24206686a8be2c7f6d57e01a300bda5ad" dependencies = [ "backoff", "candid", "derivative", - "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?rev=66f2b87e94f2fde67f64ba8e38ee2ea9047a909e)", + "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?rev=dc587bf24206686a8be2c7f6d57e01a300bda5ad)", "flate2", "futures", "futures-intrusive", diff --git a/Cargo.toml b/Cargo.toml index c52b324b6..0e22308a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,7 @@ getrandom = { version = "0.2", features = ["custom"] } hex = "0.4" # The ic-agent matches the one sed by bthe ic-agent = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } -ic-asset = { git = "https://github.com/dfinity/sdk.git", rev = "66f2b87e94f2fde67f64ba8e38ee2ea9047a909e" } +ic-asset = { git = "https://github.com/dfinity/sdk.git", rev = "dc587bf24206686a8be2c7f6d57e01a300bda5ad" } ic-cdk = "0.13.2" ic-cdk-macros = "0.9" ic-cdk-timers = "0.7.0" diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index dac71050a..f18cd4139 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -1,7 +1,6 @@ //! Implements the `dfx-orbit canister upload-http-assets` CLI command. -use std::{collections::HashMap, path::PathBuf}; - use ic_utils::canister::CanisterBuilder; +use std::{collections::HashMap, path::PathBuf}; use walkdir::WalkDir; use crate::args::canister::UploadHttpAssets as Args; @@ -21,7 +20,8 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { .with_canister_id(canister_id) .build()?; let assets = assets_as_hash_map(&path); - ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; + let batch_id = ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; + println!("Proposed batch_id: {}", batch_id); Ok(()) } From e75ec8fb581647fcac7d370bec162ef5e42a5c44 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 16:28:01 +0200 Subject: [PATCH 102/156] Fix http path --- .../dfx-orbit/src/cli/canister/upload_http_assets.rs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index f18cd4139..88d4fccc4 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -53,12 +53,11 @@ fn assets_as_hash_map(asset_dir: &str) -> HashMap { let relative_path = asset_path.strip_prefix(asset_dir).expect( "Internal error: list_assets should have returned only files in the asset_dir", ); - let key = relative_path - .file_name() - .expect("Internal error: File has no name") // TODO: This can probably be eliminated by the filter_map above. - .to_string_lossy() - .to_string(); - (key, asset_path) + let http_path = format!( + "/{relative_path}", + relative_path = relative_path.to_string_lossy() + ); + (http_path, asset_path) }) .collect() } From e8700b12cff5347b607cebc6c9018a67e241c198 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 17:24:10 +0200 Subject: [PATCH 103/156] Wait for the remote evidence to be computed --- Cargo.lock | 247 +++++++++++++++++- Cargo.toml | 3 +- tools/dfx-orbit/Cargo.toml | 1 + .../src/cli/canister/upload_http_assets.rs | 19 ++ 4 files changed, 256 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 307f54949..a6765fbc7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -497,6 +497,39 @@ dependencies = [ "thiserror", ] +[[package]] +name = "cached" +version = "0.47.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69b0116662497bc24e4b177c90eaf8870e39e2714c3fcfa296327a93f593fc21" +dependencies = [ + "ahash", + "cached_proc_macro", + "cached_proc_macro_types", + "hashbrown", + "instant", + "once_cell", + "thiserror", +] + +[[package]] +name = "cached_proc_macro" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c878c71c2821aa2058722038a59a67583a4240524687c6028571c9b395ded61f" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cached_proc_macro_types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade8366b8bd5ba243f0a58f036cc0ca8a2f069cff1a2351ef1cac6b083e16fc0" + [[package]] name = "canbench-rs" version = "0.1.1" @@ -668,7 +701,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -910,6 +943,41 @@ dependencies = [ "zeroize", ] +[[package]] +name = "darling" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 1.0.109", +] + +[[package]] +name = "darling_macro" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +dependencies = [ + "darling_core", + "quote", + "syn 1.0.109", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -1008,7 +1076,7 @@ dependencies = [ [[package]] name = "dfx-core" version = "0.0.1" -source = "git+https://github.com/dfinity/sdk.git?rev=dc587bf24206686a8be2c7f6d57e01a300bda5ad#dc587bf24206686a8be2c7f6d57e01a300bda5ad" +source = "git+https://github.com/dfinity/sdk.git?rev=ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e#ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e" dependencies = [ "aes-gcm", "argon2", @@ -1057,6 +1125,7 @@ dependencies = [ "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?tag=0.20.2-beta.0)", "ic-agent", "ic-asset", + "ic-certified-assets", "ic-utils", "serde", "serde_json", @@ -1634,7 +1703,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1728,6 +1797,17 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.1.0" @@ -1746,7 +1826,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" dependencies = [ "bytes", - "http", + "http 1.1.0", ] [[package]] @@ -1757,7 +1837,7 @@ checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" dependencies = [ "bytes", "futures-core", - "http", + "http 1.1.0", "http-body", "pin-project-lite", ] @@ -1794,7 +1874,7 @@ dependencies = [ "futures-channel", "futures-util", "h2", - "http", + "http 1.1.0", "http-body", "httparse", "itoa", @@ -1811,7 +1891,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c" dependencies = [ "futures-util", - "http", + "http 1.1.0", "hyper", "hyper-util", "rustls", @@ -1830,7 +1910,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", + "http 1.1.0", "http-body", "hyper", "pin-project-lite", @@ -1848,12 +1928,12 @@ source = "git+https://github.com/dfinity/agent-rs.git?rev=8273d321e9a09fd8373bd4 dependencies = [ "async-lock 3.4.0", "backoff", - "cached", + "cached 0.46.1", "candid", "ed25519-consensus", "futures-util", "hex", - "http", + "http 1.1.0", "http-body", "ic-certification", "ic-transport-types", @@ -1884,12 +1964,12 @@ dependencies = [ [[package]] name = "ic-asset" version = "0.20.0" -source = "git+https://github.com/dfinity/sdk.git?rev=dc587bf24206686a8be2c7f6d57e01a300bda5ad#dc587bf24206686a8be2c7f6d57e01a300bda5ad" +source = "git+https://github.com/dfinity/sdk.git?rev=ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e#ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e" dependencies = [ "backoff", "candid", "derivative", - "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?rev=dc587bf24206686a8be2c7f6d57e01a300bda5ad)", + "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?rev=ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e)", "flate2", "futures", "futures-intrusive", @@ -1911,6 +1991,19 @@ dependencies = [ "walkdir", ] +[[package]] +name = "ic-cbor" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bc917070b8fc4bd88e3199746372e44d507f54c93a9b191787e1caefca1eba" +dependencies = [ + "candid", + "ic-certification", + "leb128", + "nom", + "thiserror", +] + [[package]] name = "ic-cdk" version = "0.12.1" @@ -1993,6 +2086,25 @@ dependencies = [ "slotmap", ] +[[package]] +name = "ic-certificate-verification" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "769142849e241e6cf7f5611f9b04983e958729495ea67d2de95e5d9a9c687d9b" +dependencies = [ + "cached 0.47.0", + "candid", + "ic-cbor", + "ic-certification", + "lazy_static", + "leb128", + "miracl_core_bls12381", + "nom", + "parking_lot 0.12.2", + "sha2 0.10.8", + "thiserror", +] + [[package]] name = "ic-certification" version = "2.5.0" @@ -2005,6 +2117,41 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "ic-certified-assets" +version = "0.2.5" +source = "git+https://github.com/dfinity/sdk.git?rev=ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e#ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e" +dependencies = [ + "base64 0.13.1", + "candid", + "hex", + "ic-cdk 0.13.2", + "ic-certification", + "ic-representation-independent-hash", + "ic-response-verification", + "itertools 0.10.5", + "num-traits", + "serde", + "serde_bytes", + "serde_cbor", + "sha2 0.10.8", +] + +[[package]] +name = "ic-http-certification" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ddb96501529c2380e087fa9f4552fd0d416f5784bb1e48142d746e9b3d6ae13" +dependencies = [ + "candid", + "http 0.2.12", + "ic-certification", + "ic-representation-independent-hash", + "serde", + "thiserror", + "urlencoding", +] + [[package]] name = "ic-identity-hsm" version = "0.35.0" @@ -2033,6 +2180,40 @@ dependencies = [ "sha2 0.10.8", ] +[[package]] +name = "ic-representation-independent-hash" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4d9c969c80e9b445255341da79772680f503ef856b95b3ddf162b41d096df1f" +dependencies = [ + "leb128", + "sha2 0.10.8", +] + +[[package]] +name = "ic-response-verification" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ce81210d3747a4e334a86851c57725a5ec4d2d0c40b05b5dc4f9114c19c78a" +dependencies = [ + "base64 0.21.7", + "candid", + "flate2", + "hex", + "http 0.2.12", + "ic-cbor", + "ic-certificate-verification", + "ic-certification", + "ic-http-certification", + "ic-representation-independent-hash", + "leb128", + "log", + "nom", + "sha2 0.10.8", + "thiserror", + "urlencoding", +] + [[package]] name = "ic-stable-structures" version = "0.6.4" @@ -2111,6 +2292,12 @@ dependencies = [ "thiserror", ] +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -2497,6 +2684,12 @@ dependencies = [ "unicase", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.7.2" @@ -2517,6 +2710,12 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "miracl_core_bls12381" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07cbe42e2a8dd41df582fb8e00fc24d920b5561cc301fcb6d14e2e0434b500f" + [[package]] name = "mockall" version = "0.12.1" @@ -2573,6 +2772,16 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -3345,7 +3554,7 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", + "http 1.1.0", "http-body", "http-body-util", "hyper", @@ -4102,6 +4311,12 @@ dependencies = [ "precomputed-hash", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" @@ -4671,6 +4886,12 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf8-width" version = "0.1.7" diff --git a/Cargo.toml b/Cargo.toml index 0e22308a9..618fe8b2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,7 +44,8 @@ getrandom = { version = "0.2", features = ["custom"] } hex = "0.4" # The ic-agent matches the one sed by bthe ic-agent = { git = "https://github.com/dfinity/agent-rs.git", rev = "8273d321e9a09fd8373bd4e38b0676ec6ad9c260" } -ic-asset = { git = "https://github.com/dfinity/sdk.git", rev = "dc587bf24206686a8be2c7f6d57e01a300bda5ad" } +ic-asset = { git = "https://github.com/dfinity/sdk.git", rev = "ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e" } +ic-certified-assets = { git = "https://github.com/dfinity/sdk.git", rev = "ae10a96b381cfce3d8ac5a6cb940d19224ea6d2e" } ic-cdk = "0.13.2" ic-cdk-macros = "0.9" ic-cdk-timers = "0.7.0" diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 21e210948..3520177ef 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -20,6 +20,7 @@ cap-std.workspace = true dfx-core.workspace = true ic-agent.workspace = true ic-asset.workspace = true +ic-certified-assets.workspace = true ic-utils.workspace = true slog.workspace = true slog-term.workspace = true diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 88d4fccc4..6f703c738 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -1,5 +1,9 @@ //! Implements the `dfx-orbit canister upload-http-assets` CLI command. +use ic_asset::canister_api::{ + methods::batch::compute_evidence, types::batch_upload::common::ComputeEvidenceArguments, +}; use ic_utils::canister::CanisterBuilder; +use slog::info; use std::{collections::HashMap, path::PathBuf}; use walkdir::WalkDir; @@ -15,6 +19,7 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let canister_id = station_agent.canister_id(&canister)?; let logger = station_agent.dfx.logger().clone(); + // Upload assets let canister_agent = CanisterBuilder::new() .with_agent(station_agent.dfx.agent().await?) .with_canister_id(canister_id) @@ -22,6 +27,20 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let assets = assets_as_hash_map(&path); let batch_id = ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; println!("Proposed batch_id: {}", batch_id); + // Wait for the evidence to be computed. + // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. + + let compute_evidence_arg = ComputeEvidenceArguments { + batch_id: batch_id.clone(), + max_iterations: Some(97), // 75% of max(130) = 97.5 + }; + info!(logger, "Computing evidence."); + let evidence = loop { + if let Some(evidence) = compute_evidence(&canister_agent, &compute_evidence_arg).await? { + break evidence; + } + }; + println!("Evidence computed: {:#?}", evidence); Ok(()) } From a749e3c8566aec7d7b015bce56f3eec6ad147861 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 17:32:00 +0200 Subject: [PATCH 104/156] ++ --- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 6f703c738..cdb1d67c2 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -27,8 +27,9 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let assets = assets_as_hash_map(&path); let batch_id = ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; println!("Proposed batch_id: {}", batch_id); - // Wait for the evidence to be computed. + // Wait for the canister to compute the evidence: // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. + // The docs explicitly include waiting for the evidence so this should really be made easier! See: https://github.com/dfinity/sdk/blob/2509e81e11e71dce4045c679686c952809525470/docs/design/asset-canister-interface.md?plain=1#L85 let compute_evidence_arg = ComputeEvidenceArguments { batch_id: batch_id.clone(), @@ -39,8 +40,10 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { if let Some(evidence) = compute_evidence(&canister_agent, &compute_evidence_arg).await? { break evidence; } - }; - println!("Evidence computed: {:#?}", evidence); + }; + println!("Canister computed evidence: {evidence:?}"); + + // Maybe compute evidence locally and then compare? Ok(()) } From 79e7a1b1a836555d7ee4027777c437e0b1e253ee Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 17:37:46 +0200 Subject: [PATCH 105/156] ++ --- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index cdb1d67c2..10ad1de45 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -4,7 +4,7 @@ use ic_asset::canister_api::{ }; use ic_utils::canister::CanisterBuilder; use slog::info; -use std::{collections::HashMap, path::PathBuf}; +use std::{collections::HashMap, path::{Path, PathBuf}}; use walkdir::WalkDir; use crate::args::canister::UploadHttpAssets as Args; @@ -16,6 +16,10 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { path, verbose: _verbose, } = args; + // The path is needed in various forms. If dirs is plural, maybe we should accept multiple dirs? + let dir: PathBuf = PathBuf::from(&path); + let dirs: Vec<&Path> = vec![dir.as_path()]; + let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let canister_id = station_agent.canister_id(&canister)?; let logger = station_agent.dfx.logger().clone(); @@ -27,6 +31,8 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let assets = assets_as_hash_map(&path); let batch_id = ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; println!("Proposed batch_id: {}", batch_id); + // Compute evidence locally: + let _local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; // Wait for the canister to compute the evidence: // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. // The docs explicitly include waiting for the evidence so this should really be made easier! See: https://github.com/dfinity/sdk/blob/2509e81e11e71dce4045c679686c952809525470/docs/design/asset-canister-interface.md?plain=1#L85 @@ -40,7 +46,7 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { if let Some(evidence) = compute_evidence(&canister_agent, &compute_evidence_arg).await? { break evidence; } - }; + }; println!("Canister computed evidence: {evidence:?}"); // Maybe compute evidence locally and then compare? From 1489283bd5e1278f1b3ac97aedf4bc700d9c7d46 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 17:38:40 +0200 Subject: [PATCH 106/156] ++ --- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 10ad1de45..17edc3e03 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -4,7 +4,10 @@ use ic_asset::canister_api::{ }; use ic_utils::canister::CanisterBuilder; use slog::info; -use std::{collections::HashMap, path::{Path, PathBuf}}; +use std::{ + collections::HashMap, + path::{Path, PathBuf}, +}; use walkdir::WalkDir; use crate::args::canister::UploadHttpAssets as Args; @@ -32,7 +35,7 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let batch_id = ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; println!("Proposed batch_id: {}", batch_id); // Compute evidence locally: - let _local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; + let local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; // Wait for the canister to compute the evidence: // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. // The docs explicitly include waiting for the evidence so this should really be made easier! See: https://github.com/dfinity/sdk/blob/2509e81e11e71dce4045c679686c952809525470/docs/design/asset-canister-interface.md?plain=1#L85 @@ -47,6 +50,7 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { break evidence; } }; + println!("Local evidence: {local_evidence}"); println!("Canister computed evidence: {evidence:?}"); // Maybe compute evidence locally and then compare? From 52f73dd6a6aec5dc3e8ff50db30861878f40e0ac Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 17:59:26 +0200 Subject: [PATCH 107/156] ++ --- .../src/cli/canister/upload_http_assets.rs | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 17edc3e03..3c6c8ff03 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -50,8 +50,10 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { break evidence; } }; - println!("Local evidence: {local_evidence}"); - println!("Canister computed evidence: {evidence:?}"); + println!("Proposed batch_id: {}", batch_id); + println!("Local evidence: \"{}\"", escape_hex_string(&local_evidence)); + println!("Canister computed evidence: {}", blob_from_bytes(&evidence)); + // TODO: The local evidence doesn't match the canister evidence. // Maybe compute evidence locally and then compare? Ok(()) @@ -93,3 +95,25 @@ fn assets_as_hash_map(asset_dir: &str) -> HashMap { }) .collect() } + +/// Converts a hex string into one escaped as in a candid blob. +fn escape_hex_string(s: &str) -> String { + let mut ans = String::with_capacity(s.len() + s.len() / 2); + for chunk in s.chars().collect::>()[..].chunks(2) { + ans.push('\\'); + for char in chunk { + ans.push(*char); + } + } + ans +} + +/// Converts a byte array into one escaped as a candid blob +fn blob_from_bytes(bytes: &[u8]) -> String { + let mut ans = String::with_capacity(bytes.len() + bytes.len() / 2); + for byte in bytes { + ans.push('\\'); + ans.push_str(&format!("{:02x}", byte)); + } + ans +} From 5b656b476e416de29d90646277aa63e811396a7c Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 18:03:09 +0200 Subject: [PATCH 108/156] docs --- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 2 ++ tools/dfx-orbit/src/cli/request.rs | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 3c6c8ff03..86f9a0657 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -56,6 +56,8 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { // TODO: The local evidence doesn't match the canister evidence. // Maybe compute evidence locally and then compare? + + // TODO: Get Orbit to make the API call to commit the changes. Ok(()) } diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 3f7a73782..109c62540 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -5,7 +5,7 @@ use anyhow::anyhow; use candid::Principal; use orbit_station_api::{ApiErrorDTO, CreateRequestResponse}; -/// The main entry point for the `dfx orbit` CLI. +/// The main entry point for the `dfx orbit request` CLI. pub async fn exec(args: Args) -> anyhow::Result> { // Converts the CLI arg type into the equivalent Orbit API type. let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; From b8add8f6ff5d2925edd1999c45ab319582b0d0e9 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 18:09:37 +0200 Subject: [PATCH 109/156] Move change to a dedicated file --- tools/dfx-orbit/src/args/request/canister.rs | 95 +------------------ .../src/args/request/canister/change.rs | 93 ++++++++++++++++++ 2 files changed, 97 insertions(+), 91 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index 20ad15b6c..3438fb76e 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -1,15 +1,17 @@ //! Makes requests to do things to canisters. Such as update the Wasm, deploy frontend assets or make API calls to them. +pub mod change; + use super::CreateRequestArgs; use crate::orbit_station_agent::StationAgent; -use clap::{Parser, Subcommand, ValueEnum}; +use clap::Subcommand; /// Request canister changes. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { /// Request to update the canister. - Change(ChangeExternalCanister), + Change(change::ChangeExternalCanister), } impl CreateRequestArgs for Args { @@ -23,92 +25,3 @@ impl CreateRequestArgs for Args { } } } - -/// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. -#[derive(Debug, Parser)] -pub struct ChangeExternalCanister { - // TODO: Poll, waiting for the request to be accepted. - /// The canister ID to install or update. - // TODO: Canister by name - #[clap(short, long)] - canister: String, - /// The installation mode. - #[clap(long, value_enum, rename_all = "kebab-case")] - mode: CanisterInstallMode, - /// The path to the Wasm file to install. - #[clap(short, long)] - wasm: String, - /// The argument to pass to the canister. - #[clap(short, long)] - arg: Option, - // TODO: exclusive OR - /// The path to a file containing the argument to pass to the canister. - #[clap(short = 'f', long)] - arg_file: Option, -} - -impl CreateRequestArgs for ChangeExternalCanister { - /// Converts the CLI arg type into the equivalent Orbit API type. - fn into_create_request_input( - self, - station_agent: &StationAgent, - ) -> anyhow::Result { - let ChangeExternalCanister { - canister, - mode, - wasm, - arg, - arg_file, - } = self; - let canister_id = station_agent.canister_id(&canister)?; - let operation = { - let module = std::fs::read(wasm) - .expect("Could not read Wasm file") - .to_vec(); - let arg = if let Some(file) = arg_file { - Some( - std::fs::read(file) - .expect("Could not read argument file") - .to_vec(), - ) - } else { - arg.map(|arg| arg.as_bytes().to_vec()) - }; - let mode = mode.into(); - orbit_station_api::ChangeExternalCanisterOperationInput { - canister_id, - mode, - module, - arg, - } - }; - let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); - Ok(orbit_station_api::CreateRequestInput { - operation, - title: None, - summary: None, - execution_plan: None, - }) - } -} - -/// Canister installation mode equivalent to `dfx canister install --mode XXX` and `orbit_station_api::CanisterInstallMode`. -#[derive(Copy, Clone, Eq, PartialEq, Debug, ValueEnum)] -pub enum CanisterInstallMode { - /// Corresponds to `dfx canister install` - Install, - /// Corresponds to `dfx canister reinstall` - Reinstall, - /// Corresponds to `dfx canister upgrade` - Upgrade, -} - -impl From for orbit_station_api::CanisterInstallMode { - fn from(mode: CanisterInstallMode) -> Self { - match mode { - CanisterInstallMode::Install => orbit_station_api::CanisterInstallMode::Install, - CanisterInstallMode::Reinstall => orbit_station_api::CanisterInstallMode::Reinstall, - CanisterInstallMode::Upgrade => orbit_station_api::CanisterInstallMode::Upgrade, - } - } -} diff --git a/tools/dfx-orbit/src/args/request/canister/change.rs b/tools/dfx-orbit/src/args/request/canister/change.rs index e69de29bb..627af69c0 100644 --- a/tools/dfx-orbit/src/args/request/canister/change.rs +++ b/tools/dfx-orbit/src/args/request/canister/change.rs @@ -0,0 +1,93 @@ +//! Arguments for updating an external canister Wasm. + +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; +use clap::{Parser, ValueEnum}; + +/// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. +#[derive(Debug, Parser)] +pub struct ChangeExternalCanister { + // TODO: Poll, waiting for the request to be accepted. + /// The canister ID to install or update. + // TODO: Canister by name + #[clap(short, long)] + canister: String, + /// The installation mode. + #[clap(long, value_enum, rename_all = "kebab-case")] + mode: CanisterInstallMode, + /// The path to the Wasm file to install. + #[clap(short, long)] + wasm: String, + /// The argument to pass to the canister. + #[clap(short, long)] + arg: Option, + // TODO: exclusive OR + /// The path to a file containing the argument to pass to the canister. + #[clap(short = 'f', long)] + arg_file: Option, +} + +impl CreateRequestArgs for ChangeExternalCanister { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { + let ChangeExternalCanister { + canister, + mode, + wasm, + arg, + arg_file, + } = self; + let canister_id = station_agent.canister_id(&canister)?; + let operation = { + let module = std::fs::read(wasm) + .expect("Could not read Wasm file") + .to_vec(); + let arg = if let Some(file) = arg_file { + Some( + std::fs::read(file) + .expect("Could not read argument file") + .to_vec(), + ) + } else { + arg.map(|arg| arg.as_bytes().to_vec()) + }; + let mode = mode.into(); + orbit_station_api::ChangeExternalCanisterOperationInput { + canister_id, + mode, + module, + arg, + } + }; + let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); + Ok(orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + }) + } +} + +/// Canister installation mode equivalent to `dfx canister install --mode XXX` and `orbit_station_api::CanisterInstallMode`. +#[derive(Copy, Clone, Eq, PartialEq, Debug, ValueEnum)] +pub enum CanisterInstallMode { + /// Corresponds to `dfx canister install` + Install, + /// Corresponds to `dfx canister reinstall` + Reinstall, + /// Corresponds to `dfx canister upgrade` + Upgrade, +} + +impl From for orbit_station_api::CanisterInstallMode { + fn from(mode: CanisterInstallMode) -> Self { + match mode { + CanisterInstallMode::Install => orbit_station_api::CanisterInstallMode::Install, + CanisterInstallMode::Reinstall => orbit_station_api::CanisterInstallMode::Reinstall, + CanisterInstallMode::Upgrade => orbit_station_api::CanisterInstallMode::Upgrade, + } + } +} From 7d5381e047403d18dcc246400fe7d3693d3cdf50 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 26 Jun 2024 18:16:45 +0200 Subject: [PATCH 110/156] Placeholder subcommand for requesting canister calls --- tools/dfx-orbit/src/args/request/canister.rs | 8 ++++++-- .../src/args/request/canister/call.rs | 19 +++++++++++++++++++ .../src/args/request/canister/change.rs | 8 ++++---- 3 files changed, 29 insertions(+), 6 deletions(-) create mode 100644 tools/dfx-orbit/src/args/request/canister/call.rs diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index 3438fb76e..5c2dd0595 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -1,5 +1,6 @@ -//! Makes requests to do things to canisters. Such as update the Wasm, deploy frontend assets or make API calls to them. +//! CLI arguments for `dfx-orbit canister`. +pub mod call; pub mod change; use super::CreateRequestArgs; @@ -11,7 +12,9 @@ use clap::Subcommand; #[command(version, about, long_about = None)] pub enum Args { /// Request to update the canister. - Change(change::ChangeExternalCanister), + Change(change::Args), + /// Request to call a canister method. + Call(call::Args), } impl CreateRequestArgs for Args { @@ -22,6 +25,7 @@ impl CreateRequestArgs for Args { ) -> anyhow::Result { match self { Args::Change(change_args) => change_args.into_create_request_input(station_agent), + Args::Call(call_args) => call_args.into_create_request_input(station_agent), } } } diff --git a/tools/dfx-orbit/src/args/request/canister/call.rs b/tools/dfx-orbit/src/args/request/canister/call.rs new file mode 100644 index 000000000..52f8e0714 --- /dev/null +++ b/tools/dfx-orbit/src/args/request/canister/call.rs @@ -0,0 +1,19 @@ +//! CLI arguments for `dfx-orbit canister call`. + +use clap::Parser; + +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; + +/// Requests that a call be made to a canister. +#[derive(Debug, Parser)] +pub struct Args {} + +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + _station_agent: &StationAgent, + ) -> anyhow::Result { + todo!("Need to convert CLI args into Orbit API args for canister call.") + } +} \ No newline at end of file diff --git a/tools/dfx-orbit/src/args/request/canister/change.rs b/tools/dfx-orbit/src/args/request/canister/change.rs index 627af69c0..287898082 100644 --- a/tools/dfx-orbit/src/args/request/canister/change.rs +++ b/tools/dfx-orbit/src/args/request/canister/change.rs @@ -1,11 +1,11 @@ -//! Arguments for updating an external canister Wasm. +//! Arguments for `dfx orbit canister change`. use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; use clap::{Parser, ValueEnum}; /// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. #[derive(Debug, Parser)] -pub struct ChangeExternalCanister { +pub struct Args { // TODO: Poll, waiting for the request to be accepted. /// The canister ID to install or update. // TODO: Canister by name @@ -26,13 +26,13 @@ pub struct ChangeExternalCanister { arg_file: Option, } -impl CreateRequestArgs for ChangeExternalCanister { +impl CreateRequestArgs for Args { /// Converts the CLI arg type into the equivalent Orbit API type. fn into_create_request_input( self, station_agent: &StationAgent, ) -> anyhow::Result { - let ChangeExternalCanister { + let Args { canister, mode, wasm, From f7ae7c15ab404af54026161bb31e1dece9947f05 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 11:42:00 +0200 Subject: [PATCH 111/156] fmt --- tools/dfx-orbit/src/args/request/canister/call.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/request/canister/call.rs b/tools/dfx-orbit/src/args/request/canister/call.rs index 52f8e0714..2605a3fa1 100644 --- a/tools/dfx-orbit/src/args/request/canister/call.rs +++ b/tools/dfx-orbit/src/args/request/canister/call.rs @@ -16,4 +16,4 @@ impl CreateRequestArgs for Args { ) -> anyhow::Result { todo!("Need to convert CLI args into Orbit API args for canister call.") } -} \ No newline at end of file +} From 46eba54bf5c810baa5b0aac1a8ad81c35c3b3ea9 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 17:05:49 +0200 Subject: [PATCH 112/156] Add url as string --- tools/dfx-orbit/src/args/station.rs | 3 +++ tools/dfx-orbit/src/local_config.rs | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index b8ef77c73..eed4e2dcd 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -36,6 +36,9 @@ pub struct Add { /// The dfx network name. #[structopt(long)] pub network: String, + /// The Obit user interface URL. + #[structopt(long)] + pub url: String, } /// Lists Orbit station in the local dfx configuration. diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 67831af3c..6e9f0dd88 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -21,6 +21,8 @@ pub struct StationConfig { pub canister_id: String, /// The dfx network name. pub network: String, + /// The Orbit user interface URL. + pub url: String, } /// The directoy in the orbit dfx config directory where stations are stored. @@ -108,11 +110,13 @@ pub fn add_station(args: &Add) -> anyhow::Result<()> { name, canister_id, network, + url, } = args; let station = StationConfig { name: name.to_string(), canister_id: canister_id.to_string(), network: network.to_string(), + url: url.to_string(), }; let station_file = create_station_file(name)?; station_file.set_len(0)?; From cfec7398fb73ffc4b6e85e33c2cc3ea3c4aefc9f Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 17:22:11 +0200 Subject: [PATCH 113/156] Consider using the Url type --- tools/dfx-orbit/src/local_config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 6e9f0dd88..6c9a20b27 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -22,6 +22,7 @@ pub struct StationConfig { /// The dfx network name. pub network: String, /// The Orbit user interface URL. + // TODO: This would be better as URL. That requires serde to be implemented for URL. Consider: https://docs.rs/url_serde/latest/url_serde/ pub url: String, } From 63da40684d7b965855574bcfa2d33c6a69a9fd73 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 17:32:52 +0200 Subject: [PATCH 114/156] Rename arg for clarity --- tools/dfx-orbit/src/args/station.rs | 4 ++-- tools/dfx-orbit/src/cli.rs | 2 +- tools/dfx-orbit/src/cli/canister/claim.rs | 2 +- tools/dfx-orbit/src/cli/request.rs | 2 +- tools/dfx-orbit/src/local_config.rs | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index eed4e2dcd..d4421d62e 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -30,9 +30,9 @@ pub struct Add { /// Wallet name. #[structopt(long)] pub name: String, - /// Wallet canister ID. + /// Station canister ID, called "Wallet ID" in the Orbit UI. #[structopt(long)] - pub canister_id: Principal, + pub station_id: Principal, /// The dfx network name. #[structopt(long)] pub network: String, diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index b5ed1241c..4ae2eb171 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -13,7 +13,7 @@ pub async fn exec(args: DfxOrbitArgs) -> anyhow::Result<()> { DfxOrbitSubcommands::Me => { let station_principal = &crate::local_config::default_station()? .ok_or_else(|| anyhow!("No default station specified"))? - .canister_id; + .station_id; let ans = crate::dfx_extension_api::call_dfx_cli(vec![ "canister", "call", diff --git a/tools/dfx-orbit/src/cli/canister/claim.rs b/tools/dfx-orbit/src/cli/canister/claim.rs index 160a405b8..b556786bc 100644 --- a/tools/dfx-orbit/src/cli/canister/claim.rs +++ b/tools/dfx-orbit/src/cli/canister/claim.rs @@ -13,7 +13,7 @@ pub fn exec(args: Claim) -> anyhow::Result<()> { } = args; let orbit_principal = &local_config::default_station()? .ok_or_else(|| anyhow!("No default station specified"))? - .canister_id; + .station_id; let claim_type = if exclusive { "--set-controller" } else { diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 109c62540..d2231df97 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -13,7 +13,7 @@ pub async fn exec(args: Args) -> anyhow::Result Vec { pub fn add_station(args: &Add) -> anyhow::Result<()> { let Add { name, - canister_id, + station_id, network, url, } = args; let station = StationConfig { name: name.to_string(), - canister_id: canister_id.to_string(), + station_id: station_id.to_string(), network: network.to_string(), url: url.to_string(), }; From e031c5e4f91bd6d4f491f1940d4c979795388df0 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 17:42:47 +0200 Subject: [PATCH 115/156] Add TODO --- tools/dfx-orbit/src/local_config.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 34e3f81db..7762df52d 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -106,6 +106,7 @@ pub fn list_stations() -> Vec { /// Adds a new Orbit station to the local dfx configuration. /// /// If there is no default station, the new station is set as the default. +// TODO: Check that the URL works & is the root URL. pub fn add_station(args: &Add) -> anyhow::Result<()> { let Add { name, From 3e3ef3d58749e23d93f94fe99b2a4aab8fe19c3c Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 18:05:07 +0200 Subject: [PATCH 116/156] Print URL to request --- tools/dfx-orbit/src/cli/request.rs | 9 ++++++++- tools/dfx-orbit/src/orbit_station_agent.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index d2231df97..15319f44e 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -22,6 +22,13 @@ pub async fn exec(args: Args) -> anyhow::Result = candid::decode_one(&bytes)?; - println!("{ans:#?}"); + if let Ok(response) = &ans { + let request_id = &response.request.id; + let request_url = station_agent.request_url(request_id); + println!("Created request: {request_id}"); + println!("Request URL: {request_url}"); + } else { + println!("{ans:#?}"); + } Ok(ans) } diff --git a/tools/dfx-orbit/src/orbit_station_agent.rs b/tools/dfx-orbit/src/orbit_station_agent.rs index 74adb353f..e4e2eafba 100644 --- a/tools/dfx-orbit/src/orbit_station_agent.rs +++ b/tools/dfx-orbit/src/orbit_station_agent.rs @@ -39,4 +39,12 @@ impl StationAgent { ) -> anyhow::Result { Ok(self.dfx.agent().await?.update(canister_id, method_name)) } + + /// The URL for a request in the Orbit UI. + pub fn request_url(&self, request_id: &str) -> String { + format!( + "{}/en/settings/requests?reqid={}", + self.station.url, request_id + ) + } } From 2a01b6fbbcbc290272dfba45abb251f4c7b517ac Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 18:42:27 +0200 Subject: [PATCH 117/156] Fix text --- tools/dfx-orbit/src/args/request.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/request.rs b/tools/dfx-orbit/src/args/request.rs index d447e13d8..a2b32f251 100644 --- a/tools/dfx-orbit/src/args/request.rs +++ b/tools/dfx-orbit/src/args/request.rs @@ -17,7 +17,7 @@ pub enum Args { /// Request changes to a canister. #[command(subcommand)] Canister(canister::Args), - /// Request changes to a canister. + /// Request permissions. #[command(subcommand)] Permission(permission::Args), } From 2fd9ac45d064e26e86d7e57addca5bdd1b933a27 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 19:02:42 +0200 Subject: [PATCH 118/156] Define arguments for reviewing the next proposal --- tools/dfx-orbit/src/args.rs | 4 ++++ tools/dfx-orbit/src/cli.rs | 2 ++ 2 files changed, 6 insertions(+) diff --git a/tools/dfx-orbit/src/args.rs b/tools/dfx-orbit/src/args.rs index 137f5c77c..6d41c532f 100644 --- a/tools/dfx-orbit/src/args.rs +++ b/tools/dfx-orbit/src/args.rs @@ -2,6 +2,7 @@ pub mod canister; pub mod dfx_extension_api; pub mod request; +pub mod review; pub mod station; use clap::{Parser, Subcommand}; @@ -29,6 +30,9 @@ pub enum DfxOrbitSubcommands { /// Make requests to Orbit #[command(subcommand)] Request(request::Args), + /// View and decide on requests. + #[command(subcommand)] + Review(review::Args), /// Exercises the experimental DFX extension API. /// /// As the API is brand new and prototypical, this is exposed as a subcommand. Once stable it can be removed. diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 4ae2eb171..9d108f22b 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -2,6 +2,7 @@ pub mod canister; pub mod dfx_extension_cli; pub mod request; +pub mod review; pub mod station; use crate::args::{DfxOrbitArgs, DfxOrbitSubcommands}; @@ -33,5 +34,6 @@ pub async fn exec(args: DfxOrbitArgs) -> anyhow::Result<()> { Ok(Err(e)) => Err(anyhow!("Error response from the station: {e:?}")), Err(e) => Err(e), }, + DfxOrbitSubcommands::Review(review_args) => review::exec(review_args).await, } } From 6de7644969afee9bfb68a575aa98777ea5aaa9bd Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 19:10:04 +0200 Subject: [PATCH 119/156] Placeholder implementation for review next --- tools/dfx-orbit/src/args/review.rs | 12 ++++++++++++ tools/dfx-orbit/src/args/review/next.rs | 7 +++++++ tools/dfx-orbit/src/cli/review.rs | 11 +++++++++++ tools/dfx-orbit/src/cli/review/next.rs | 8 ++++++++ 4 files changed, 38 insertions(+) create mode 100644 tools/dfx-orbit/src/args/review.rs create mode 100644 tools/dfx-orbit/src/args/review/next.rs create mode 100644 tools/dfx-orbit/src/cli/review.rs create mode 100644 tools/dfx-orbit/src/cli/review/next.rs diff --git a/tools/dfx-orbit/src/args/review.rs b/tools/dfx-orbit/src/args/review.rs new file mode 100644 index 000000000..ea543ff3f --- /dev/null +++ b/tools/dfx-orbit/src/args/review.rs @@ -0,0 +1,12 @@ +//! Defines the command line arguments for `dfx-orbit review`. These correspond to Orbit station `get_request`, `submit_request_approval` and related API calls. + +use clap::Subcommand; +pub mod next; + +/// Station management commands. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Review the next request. + Next(next::Args), +} diff --git a/tools/dfx-orbit/src/args/review/next.rs b/tools/dfx-orbit/src/args/review/next.rs new file mode 100644 index 000000000..0c8d02a4b --- /dev/null +++ b/tools/dfx-orbit/src/args/review/next.rs @@ -0,0 +1,7 @@ +//! CLI arguments for `dfx-orbit review next`. + +use clap::Parser; + +/// Reviews the next request. +#[derive(Debug, Parser)] +pub struct Args {} diff --git a/tools/dfx-orbit/src/cli/review.rs b/tools/dfx-orbit/src/cli/review.rs new file mode 100644 index 000000000..ae1804157 --- /dev/null +++ b/tools/dfx-orbit/src/cli/review.rs @@ -0,0 +1,11 @@ +//! Implements `dfx review` commands. These correspond to Orbit station `get_request`, approve and related API calls. +pub mod next; + +use crate::args::review::Args; + +/// The main entry point for the `dfx orbit review` CLI. +pub async fn exec(args: Args) -> anyhow::Result<()> { + match args { + Args::Next(next_args) => next::exec(next_args).await, + } +} diff --git a/tools/dfx-orbit/src/cli/review/next.rs b/tools/dfx-orbit/src/cli/review/next.rs new file mode 100644 index 000000000..9a90d4467 --- /dev/null +++ b/tools/dfx-orbit/src/cli/review/next.rs @@ -0,0 +1,8 @@ +//! Implements `dfx review next` command. These correspond to Orbit station `get_next_approvable_request` API call. + +use crate::args::review::next::Args; + +/// The main entry point for the `dfx orbit review next` CLI. +pub async fn exec(_args: Args) -> anyhow::Result<()> { + unimplemented!("Review next request") +} From 63fbc9ac4602f05dac107e7dc878b23ee3a7e692 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 19:15:14 +0200 Subject: [PATCH 120/156] Comments --- tools/dfx-orbit/src/args/canister.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index 93e6ed263..3c57ecabd 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -9,7 +9,7 @@ use std::fmt::Debug; pub enum Args { /// Puts a canister controlled by the user under Orbit control. Claim(Claim), - /// Uplods assets to an HTTP asset canister. + /// Uploads assets to an HTTP asset canister and requests that the assets be used. UploadHttpAssets(UploadHttpAssets), } From facda611db360a0157bba163f765d51a99f85b3c Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 19:50:43 +0200 Subject: [PATCH 121/156] Complete the next request review function --- tools/dfx-orbit/src/args/review/next.rs | 9 +++++++++ tools/dfx-orbit/src/cli/request.rs | 4 ++-- tools/dfx-orbit/src/cli/review/next.rs | 26 +++++++++++++++++++++++-- 3 files changed, 35 insertions(+), 4 deletions(-) diff --git a/tools/dfx-orbit/src/args/review/next.rs b/tools/dfx-orbit/src/args/review/next.rs index 0c8d02a4b..a623294c2 100644 --- a/tools/dfx-orbit/src/args/review/next.rs +++ b/tools/dfx-orbit/src/args/review/next.rs @@ -5,3 +5,12 @@ use clap::Parser; /// Reviews the next request. #[derive(Debug, Parser)] pub struct Args {} + +impl From for orbit_station_api::GetNextApprovableRequestInput { + fn from(_: Args) -> Self { + Self { + excluded_request_ids: vec![], + operation_types: None, + } + } +} diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 15319f44e..a8509ef13 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -16,12 +16,12 @@ pub async fn exec(args: Args) -> anyhow::Result = candid::decode_one(&bytes)?; + let ans: Result = candid::decode_one(&response_bytes)?; if let Ok(response) = &ans { let request_id = &response.request.id; let request_url = station_agent.request_url(request_id); diff --git a/tools/dfx-orbit/src/cli/review/next.rs b/tools/dfx-orbit/src/cli/review/next.rs index 9a90d4467..e004ab729 100644 --- a/tools/dfx-orbit/src/cli/review/next.rs +++ b/tools/dfx-orbit/src/cli/review/next.rs @@ -1,8 +1,30 @@ //! Implements `dfx review next` command. These correspond to Orbit station `get_next_approvable_request` API call. +use anyhow::anyhow; +use candid::Principal; +use orbit_station_api::{ + ApiErrorDTO, GetNextApprovableRequestInput, GetNextApprovableRequestResponse, +}; + use crate::args::review::next::Args; /// The main entry point for the `dfx orbit review next` CLI. -pub async fn exec(_args: Args) -> anyhow::Result<()> { - unimplemented!("Review next request") +pub async fn exec(args: Args) -> anyhow::Result<()> { + let args = GetNextApprovableRequestInput::from(args); + let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + let ic_agent = station_agent.dfx.agent().await?; + // The station canister ID to which we will make the API call. + let orbit_canister_id = crate::local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .station_id; + let canister_id = Principal::from_text(&orbit_canister_id)?; + let response_bytes = ic_agent + .update(&canister_id, "get_next_approvable_request") + .with_arg(candid::encode_one(args)?) + .call_and_wait() + .await?; + let ans: Result = + candid::decode_one(&response_bytes)?; + println!("{ans:#?}"); + Ok(()) } From 66d8a8c7541bbf9899a3a59b35a7f0f40a88e282 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 20:09:43 +0200 Subject: [PATCH 122/156] Tell the user how to see the request --- tools/dfx-orbit/src/args/review.rs | 5 ++++- tools/dfx-orbit/src/args/review/id.rs | 18 ++++++++++++++++++ tools/dfx-orbit/src/cli/request.rs | 1 + tools/dfx-orbit/src/cli/review.rs | 2 ++ tools/dfx-orbit/src/cli/review/id.rs | 27 +++++++++++++++++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tools/dfx-orbit/src/args/review/id.rs create mode 100644 tools/dfx-orbit/src/cli/review/id.rs diff --git a/tools/dfx-orbit/src/args/review.rs b/tools/dfx-orbit/src/args/review.rs index ea543ff3f..d6987557f 100644 --- a/tools/dfx-orbit/src/args/review.rs +++ b/tools/dfx-orbit/src/args/review.rs @@ -1,7 +1,8 @@ //! Defines the command line arguments for `dfx-orbit review`. These correspond to Orbit station `get_request`, `submit_request_approval` and related API calls. +pub mod id; +pub mod next; use clap::Subcommand; -pub mod next; /// Station management commands. #[derive(Debug, Subcommand)] @@ -9,4 +10,6 @@ pub mod next; pub enum Args { /// Review the next request. Next(next::Args), + /// Review a specific request. + Id(id::Args), } diff --git a/tools/dfx-orbit/src/args/review/id.rs b/tools/dfx-orbit/src/args/review/id.rs new file mode 100644 index 000000000..059de5282 --- /dev/null +++ b/tools/dfx-orbit/src/args/review/id.rs @@ -0,0 +1,18 @@ +//! CLI arguments for `dfx-orbit review next`. + +use clap::Parser; +use orbit_station_api::GetRequestInput; + +/// Reviews the next request. +#[derive(Debug, Parser)] +pub struct Args { + /// The ID of the request to review. + request_id: String, +} + +impl From for GetRequestInput { + fn from(args: Args) -> Self { + let Args { request_id } = args; + GetRequestInput { request_id } + } +} diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index a8509ef13..06cee92c9 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -27,6 +27,7 @@ pub async fn exec(args: Args) -> anyhow::Result anyhow::Result<()> { match args { + Args::Id(id_args) => id::exec(id_args).await, Args::Next(next_args) => next::exec(next_args).await, } } diff --git a/tools/dfx-orbit/src/cli/review/id.rs b/tools/dfx-orbit/src/cli/review/id.rs new file mode 100644 index 000000000..3f68eb815 --- /dev/null +++ b/tools/dfx-orbit/src/cli/review/id.rs @@ -0,0 +1,27 @@ +//! Implements `dfx review id XXXX` command. This corresponds to Orbit station `get_request` API call. + +use anyhow::anyhow; +use candid::Principal; +use orbit_station_api::{ApiErrorDTO, GetRequestInput, GetRequestResponse}; + +use crate::args::review::id::Args; + +/// The main entry point for the `dfx orbit review next` CLI. +pub async fn exec(args: Args) -> anyhow::Result<()> { + let args = GetRequestInput::from(args); + let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + let ic_agent = station_agent.dfx.agent().await?; + // The station canister ID to which we will make the API call. + let orbit_canister_id = crate::local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .station_id; + let canister_id = Principal::from_text(&orbit_canister_id)?; + let response_bytes = ic_agent + .update(&canister_id, "get_request") + .with_arg(candid::encode_one(args)?) + .call_and_wait() + .await?; + let ans: Result = candid::decode_one(&response_bytes)?; + println!("{ans:#?}"); + Ok(()) +} From 3ac0dd7039827bec43fcf3411801d12b25d61ba5 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 20:32:45 +0200 Subject: [PATCH 123/156] Argument for request canister call --- .../src/args/request/canister/call.rs | 45 ++++++++++++++++++- .../src/args/request/canister/change.rs | 3 +- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister/call.rs b/tools/dfx-orbit/src/args/request/canister/call.rs index 2605a3fa1..6d42d1649 100644 --- a/tools/dfx-orbit/src/args/request/canister/call.rs +++ b/tools/dfx-orbit/src/args/request/canister/call.rs @@ -6,7 +6,14 @@ use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent} /// Requests that a call be made to a canister. #[derive(Debug, Parser)] -pub struct Args {} +pub struct Args { + /// The canister name or ID. + canister: String, + /// The name of the method to call. + method: String, + /// The argument to pass to the canister. + argument: Option, +} impl CreateRequestArgs for Args { /// Converts the CLI arg type into the equivalent Orbit API type. @@ -14,6 +21,40 @@ impl CreateRequestArgs for Args { self, _station_agent: &StationAgent, ) -> anyhow::Result { - todo!("Need to convert CLI args into Orbit API args for canister call.") + /* + let Args { + canister,method,argument + } = self; + let canister_id = station_agent.canister_id(&canister)?; + let operation = { + let module = std::fs::read(wasm) + .expect("Could not read Wasm file") + .to_vec(); + let arg = if let Some(file) = arg_file { + Some( + std::fs::read(file) + .expect("Could not read argument file") + .to_vec(), + ) + } else { + arg.map(|arg| arg.as_bytes().to_vec()) + }; + let mode = mode.into(); + orbit_station_api::ChangeExternalCanisterOperationInput { + canister_id, + mode, + module, + arg, + } + }; + let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); + Ok(orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + }) + */ + unimplemented!("Argument conversion not implemented yet") } } diff --git a/tools/dfx-orbit/src/args/request/canister/change.rs b/tools/dfx-orbit/src/args/request/canister/change.rs index 287898082..835ee5a4a 100644 --- a/tools/dfx-orbit/src/args/request/canister/change.rs +++ b/tools/dfx-orbit/src/args/request/canister/change.rs @@ -7,8 +7,7 @@ use clap::{Parser, ValueEnum}; #[derive(Debug, Parser)] pub struct Args { // TODO: Poll, waiting for the request to be accepted. - /// The canister ID to install or update. - // TODO: Canister by name + /// The canister name or ID. #[clap(short, long)] canister: String, /// The installation mode. From 9b0cbe81072dbd1b7155b24eb1ae1a9f2aabbca8 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 20:53:02 +0200 Subject: [PATCH 124/156] Basic cli arg conversion --- .../src/args/request/canister/call.rs | 54 +++++++++---------- 1 file changed, 24 insertions(+), 30 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister/call.rs b/tools/dfx-orbit/src/args/request/canister/call.rs index 6d42d1649..f2fa99a14 100644 --- a/tools/dfx-orbit/src/args/request/canister/call.rs +++ b/tools/dfx-orbit/src/args/request/canister/call.rs @@ -1,6 +1,7 @@ //! CLI arguments for `dfx-orbit canister call`. use clap::Parser; +use orbit_station_api::{CallExternalCanisterOperationInput, CanisterMethodDTO}; use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; @@ -10,51 +11,44 @@ pub struct Args { /// The canister name or ID. canister: String, /// The name of the method to call. - method: String, - /// The argument to pass to the canister. - argument: Option, + method_name: String, + // TODO: + // /// The argument to pass to the canister. + // argument: Option, + // TODO: + // /// The format of the argument. + // #[clap(short, long)] + // r#type: Option, + // TODO: Read argument from a file } impl CreateRequestArgs for Args { /// Converts the CLI arg type into the equivalent Orbit API type. fn into_create_request_input( self, - _station_agent: &StationAgent, + station_agent: &StationAgent, ) -> anyhow::Result { - /* let Args { - canister,method,argument + canister, + method_name, } = self; let canister_id = station_agent.canister_id(&canister)?; - let operation = { - let module = std::fs::read(wasm) - .expect("Could not read Wasm file") - .to_vec(); - let arg = if let Some(file) = arg_file { - Some( - std::fs::read(file) - .expect("Could not read argument file") - .to_vec(), - ) - } else { - arg.map(|arg| arg.as_bytes().to_vec()) - }; - let mode = mode.into(); - orbit_station_api::ChangeExternalCanisterOperationInput { - canister_id, - mode, - module, - arg, - } - }; - let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); + let operation = orbit_station_api::RequestOperationInput::CallExternalCanister( + CallExternalCanisterOperationInput { + validation_method: None, + execution_method: CanisterMethodDTO { + canister_id, + method_name, + }, + arg: None, + execution_method_cycles: None, // TODO: Add this to the CLI + }, + ); Ok(orbit_station_api::CreateRequestInput { operation, title: None, summary: None, execution_plan: None, }) - */ - unimplemented!("Argument conversion not implemented yet") } } From b1baa54004a344ad8524e1f4da9ffdd8ec69fa62 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 20:58:02 +0200 Subject: [PATCH 125/156] Support cycles --- tools/dfx-orbit/src/args/request/canister/call.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/args/request/canister/call.rs b/tools/dfx-orbit/src/args/request/canister/call.rs index f2fa99a14..494e51d9a 100644 --- a/tools/dfx-orbit/src/args/request/canister/call.rs +++ b/tools/dfx-orbit/src/args/request/canister/call.rs @@ -20,6 +20,9 @@ pub struct Args { // #[clap(short, long)] // r#type: Option, // TODO: Read argument from a file + /// Specifies the amount of cycles to send on the call. + #[clap(short, long)] + with_cycles: Option, } impl CreateRequestArgs for Args { @@ -31,6 +34,7 @@ impl CreateRequestArgs for Args { let Args { canister, method_name, + with_cycles, } = self; let canister_id = station_agent.canister_id(&canister)?; let operation = orbit_station_api::RequestOperationInput::CallExternalCanister( @@ -41,7 +45,7 @@ impl CreateRequestArgs for Args { method_name, }, arg: None, - execution_method_cycles: None, // TODO: Add this to the CLI + execution_method_cycles: with_cycles, }, ); Ok(orbit_station_api::CreateRequestInput { From fce029271f8847db0485a7123fbdb8d05955507d Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Tue, 2 Jul 2024 21:26:34 +0200 Subject: [PATCH 126/156] ++ --- Cargo.lock | 1 + tools/dfx-orbit/Cargo.toml | 1 + .../src/args/request/canister/call.rs | 19 +++++++++++++++---- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a6765fbc7..07b229744 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1120,6 +1120,7 @@ version = "0.1.0" dependencies = [ "anyhow", "candid", + "candid_parser", "cap-std", "clap", "dfx-core 0.0.1 (git+https://github.com/dfinity/sdk.git?tag=0.20.2-beta.0)", diff --git a/tools/dfx-orbit/Cargo.toml b/tools/dfx-orbit/Cargo.toml index 3520177ef..e8241f772 100644 --- a/tools/dfx-orbit/Cargo.toml +++ b/tools/dfx-orbit/Cargo.toml @@ -13,6 +13,7 @@ license.workspace = true [dependencies] anyhow.workspace = true candid.workspace = true +candid_parser.workspace = true clap.workspace = true serde.workspace = true serde_json.workspace = true diff --git a/tools/dfx-orbit/src/args/request/canister/call.rs b/tools/dfx-orbit/src/args/request/canister/call.rs index 494e51d9a..e759b68f6 100644 --- a/tools/dfx-orbit/src/args/request/canister/call.rs +++ b/tools/dfx-orbit/src/args/request/canister/call.rs @@ -1,5 +1,6 @@ //! CLI arguments for `dfx-orbit canister call`. +use anyhow::Context; use clap::Parser; use orbit_station_api::{CallExternalCanisterOperationInput, CanisterMethodDTO}; @@ -12,9 +13,8 @@ pub struct Args { canister: String, /// The name of the method to call. method_name: String, - // TODO: - // /// The argument to pass to the canister. - // argument: Option, + /// The argument to pass to the method. + argument: Option, // TODO: // /// The format of the argument. // #[clap(short, long)] @@ -35,8 +35,19 @@ impl CreateRequestArgs for Args { canister, method_name, with_cycles, + argument, } = self; let canister_id = station_agent.canister_id(&canister)?; + // TODO: It would be really nice to be able to use `blob_from_arguments(..)` here, as in dfx, to geta ll the nice things such as help composing the argument. + let arg = if let Some(argument) = argument { + Some( + candid_parser::parse_idl_args(&argument) + .with_context(|| "Invalid Candid values".to_string())? + .to_bytes()?, + ) + } else { + None + }; let operation = orbit_station_api::RequestOperationInput::CallExternalCanister( CallExternalCanisterOperationInput { validation_method: None, @@ -44,7 +55,7 @@ impl CreateRequestArgs for Args { canister_id, method_name, }, - arg: None, + arg, execution_method_cycles: with_cycles, }, ); From 47587b66417df39c5cf1e3981f4edba24dde1f5f Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 10:07:38 +0200 Subject: [PATCH 127/156] Move canister upgrade toa subcommand --- CLI.md | 4 +- tools/dfx-orbit/src/args/request/canister.rs | 1 + .../src/args/request/canister/change.rs | 90 +++--------------- .../src/args/request/canister/change/wasm.rs | 91 +++++++++++++++++++ 4 files changed, 106 insertions(+), 80 deletions(-) create mode 100644 tools/dfx-orbit/src/args/request/canister/change/wasm.rs diff --git a/CLI.md b/CLI.md index a4d3dea9c..e9b548eba 100644 --- a/CLI.md +++ b/CLI.md @@ -74,7 +74,7 @@ Add Orbit as a controller while keeping existing controllers: This will allow you to propose upgrades to `MY_CANISTER`: ``` -dfx-orbit request permission canister change --canister MY_CANISTER +dfx-orbit request permission canister change wasm --canister MY_CANISTER ``` This will create an Orbit request. Once approved you will be able to propose canister upgrades. @@ -83,5 +83,5 @@ This will create an Orbit request. Once approved you will be able to propose ca ### Upgrade a canister Suppose that you have built a new Wasm and put a copy at `./MY-CANISTER.wasm.gz`. To upgrade your canister to the new Wasm: ``` -dfx-orbit request canister change --canister MY_CANISTER --mode upgrade --wasm ./MY-CANISTER.wasm.gz +dfx-orbit request canister change wasm --canister MY_CANISTER --mode upgrade --wasm ./MY-CANISTER.wasm.gz ``` \ No newline at end of file diff --git a/tools/dfx-orbit/src/args/request/canister.rs b/tools/dfx-orbit/src/args/request/canister.rs index 5c2dd0595..682247c85 100644 --- a/tools/dfx-orbit/src/args/request/canister.rs +++ b/tools/dfx-orbit/src/args/request/canister.rs @@ -12,6 +12,7 @@ use clap::Subcommand; #[command(version, about, long_about = None)] pub enum Args { /// Request to update the canister. + #[command(subcommand)] Change(change::Args), /// Request to call a canister method. Call(call::Args), diff --git a/tools/dfx-orbit/src/args/request/canister/change.rs b/tools/dfx-orbit/src/args/request/canister/change.rs index 835ee5a4a..74a4f70bc 100644 --- a/tools/dfx-orbit/src/args/request/canister/change.rs +++ b/tools/dfx-orbit/src/args/request/canister/change.rs @@ -1,28 +1,16 @@ //! Arguments for `dfx orbit canister change`. +pub mod wasm; + +use clap::Subcommand; use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; -use clap::{Parser, ValueEnum}; -/// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. -#[derive(Debug, Parser)] -pub struct Args { - // TODO: Poll, waiting for the request to be accepted. - /// The canister name or ID. - #[clap(short, long)] - canister: String, - /// The installation mode. - #[clap(long, value_enum, rename_all = "kebab-case")] - mode: CanisterInstallMode, - /// The path to the Wasm file to install. - #[clap(short, long)] - wasm: String, - /// The argument to pass to the canister. - #[clap(short, long)] - arg: Option, - // TODO: exclusive OR - /// The path to a file containing the argument to pass to the canister. - #[clap(short = 'f', long)] - arg_file: Option, +/// Request permission. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Request changes to the canister Wasm. + Wasm(wasm::Args), } impl CreateRequestArgs for Args { @@ -31,62 +19,8 @@ impl CreateRequestArgs for Args { self, station_agent: &StationAgent, ) -> anyhow::Result { - let Args { - canister, - mode, - wasm, - arg, - arg_file, - } = self; - let canister_id = station_agent.canister_id(&canister)?; - let operation = { - let module = std::fs::read(wasm) - .expect("Could not read Wasm file") - .to_vec(); - let arg = if let Some(file) = arg_file { - Some( - std::fs::read(file) - .expect("Could not read argument file") - .to_vec(), - ) - } else { - arg.map(|arg| arg.as_bytes().to_vec()) - }; - let mode = mode.into(); - orbit_station_api::ChangeExternalCanisterOperationInput { - canister_id, - mode, - module, - arg, - } - }; - let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); - Ok(orbit_station_api::CreateRequestInput { - operation, - title: None, - summary: None, - execution_plan: None, - }) - } -} - -/// Canister installation mode equivalent to `dfx canister install --mode XXX` and `orbit_station_api::CanisterInstallMode`. -#[derive(Copy, Clone, Eq, PartialEq, Debug, ValueEnum)] -pub enum CanisterInstallMode { - /// Corresponds to `dfx canister install` - Install, - /// Corresponds to `dfx canister reinstall` - Reinstall, - /// Corresponds to `dfx canister upgrade` - Upgrade, -} - -impl From for orbit_station_api::CanisterInstallMode { - fn from(mode: CanisterInstallMode) -> Self { - match mode { - CanisterInstallMode::Install => orbit_station_api::CanisterInstallMode::Install, - CanisterInstallMode::Reinstall => orbit_station_api::CanisterInstallMode::Reinstall, - CanisterInstallMode::Upgrade => orbit_station_api::CanisterInstallMode::Upgrade, + match self { + Args::Wasm(wasm_args) => wasm_args.into_create_request_input(station_agent), } } -} +} \ No newline at end of file diff --git a/tools/dfx-orbit/src/args/request/canister/change/wasm.rs b/tools/dfx-orbit/src/args/request/canister/change/wasm.rs new file mode 100644 index 000000000..878d051ed --- /dev/null +++ b/tools/dfx-orbit/src/args/request/canister/change/wasm.rs @@ -0,0 +1,91 @@ +//! Arguments for `dfx orbit canister change wasm`. +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; +use clap::{Parser, ValueEnum}; + +/// Requests that a canister be installed or updated. Equivalent to `orbit_station_api::CanisterInstallMode`. +#[derive(Debug, Parser)] +pub struct Args { + // TODO: Poll, waiting for the request to be accepted. + /// The canister name or ID. + #[clap(short, long)] + canister: String, + /// The installation mode. + #[clap(long, value_enum, rename_all = "kebab-case")] + mode: CanisterInstallMode, + /// The path to the Wasm file to install. + #[clap(short, long)] + wasm: String, + /// The argument to pass to the canister. + #[clap(short, long)] + arg: Option, + // TODO: exclusive OR + /// The path to a file containing the argument to pass to the canister. + #[clap(short = 'f', long)] + arg_file: Option, +} + +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { + let Args { + canister, + mode, + wasm, + arg, + arg_file, + } = self; + let canister_id = station_agent.canister_id(&canister)?; + let operation = { + let module = std::fs::read(wasm) + .expect("Could not read Wasm file") + .to_vec(); + let arg = if let Some(file) = arg_file { + Some( + std::fs::read(file) + .expect("Could not read argument file") + .to_vec(), + ) + } else { + arg.map(|arg| arg.as_bytes().to_vec()) + }; + let mode = mode.into(); + orbit_station_api::ChangeExternalCanisterOperationInput { + canister_id, + mode, + module, + arg, + } + }; + let operation = orbit_station_api::RequestOperationInput::ChangeExternalCanister(operation); + Ok(orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + }) + } +} + +/// Canister installation mode equivalent to `dfx canister install --mode XXX` and `orbit_station_api::CanisterInstallMode`. +#[derive(Copy, Clone, Eq, PartialEq, Debug, ValueEnum)] +pub enum CanisterInstallMode { + /// Corresponds to `dfx canister install` + Install, + /// Corresponds to `dfx canister reinstall` + Reinstall, + /// Corresponds to `dfx canister upgrade` + Upgrade, +} + +impl From for orbit_station_api::CanisterInstallMode { + fn from(mode: CanisterInstallMode) -> Self { + match mode { + CanisterInstallMode::Install => orbit_station_api::CanisterInstallMode::Install, + CanisterInstallMode::Reinstall => orbit_station_api::CanisterInstallMode::Reinstall, + CanisterInstallMode::Upgrade => orbit_station_api::CanisterInstallMode::Upgrade, + } + } +} From 07085937c2b42851bd43ddae79fd84e952389d37 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 10:34:06 +0200 Subject: [PATCH 128/156] Provide command for committing changes --- .../src/args/request/canister/change.rs | 2 +- .../src/cli/canister/upload_http_assets.rs | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/dfx-orbit/src/args/request/canister/change.rs b/tools/dfx-orbit/src/args/request/canister/change.rs index 74a4f70bc..bcffc78ba 100644 --- a/tools/dfx-orbit/src/args/request/canister/change.rs +++ b/tools/dfx-orbit/src/args/request/canister/change.rs @@ -23,4 +23,4 @@ impl CreateRequestArgs for Args { Args::Wasm(wasm_args) => wasm_args.into_create_request_input(station_agent), } } -} \ No newline at end of file +} diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 86f9a0657..34d9eb2d7 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -36,23 +36,30 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { println!("Proposed batch_id: {}", batch_id); // Compute evidence locally: let local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; + let local_evidence_blob = escape_hex_string(&local_evidence); + // Wait for the canister to compute the evidence: // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. // The docs explicitly include waiting for the evidence so this should really be made easier! See: https://github.com/dfinity/sdk/blob/2509e81e11e71dce4045c679686c952809525470/docs/design/asset-canister-interface.md?plain=1#L85 - let compute_evidence_arg = ComputeEvidenceArguments { batch_id: batch_id.clone(), max_iterations: Some(97), // 75% of max(130) = 97.5 }; info!(logger, "Computing evidence."); - let evidence = loop { + let canister_evidence = loop { if let Some(evidence) = compute_evidence(&canister_agent, &compute_evidence_arg).await? { break evidence; } }; - println!("Proposed batch_id: {}", batch_id); - println!("Local evidence: \"{}\"", escape_hex_string(&local_evidence)); - println!("Canister computed evidence: {}", blob_from_bytes(&evidence)); + let canister_evidence_blob = blob_from_bytes(&canister_evidence); + + println!(r#"Proposed batch_id: {batch_id}"#); + println!(r#"Local evidence: "{local_evidence_blob}""#); + println!(r#"Canister computed evidence: {canister_evidence_blob}"#); + println!(r#"Assets have been uploaded. For the changes to take effect, run:"#); + println!( + r#"dfx-orbit request canister call {canister} commit_proposed_batch '(record {{ batch_id = {batch_id} : nat; evidence = blob "{canister_evidence_blob}" }})'"# + ); // TODO: The local evidence doesn't match the canister evidence. // Maybe compute evidence locally and then compare? From 1fa380dc119b3694d63baa2ba8d12a38d32a930c Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 10:41:18 +0200 Subject: [PATCH 129/156] Tighten scope --- .../src/cli/canister/upload_http_assets.rs | 40 ++++++++++--------- 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index 34d9eb2d7..f0232a8ac 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -35,30 +35,34 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let batch_id = ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; println!("Proposed batch_id: {}", batch_id); // Compute evidence locally: - let local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; - let local_evidence_blob = escape_hex_string(&local_evidence); - - // Wait for the canister to compute the evidence: - // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. - // The docs explicitly include waiting for the evidence so this should really be made easier! See: https://github.com/dfinity/sdk/blob/2509e81e11e71dce4045c679686c952809525470/docs/design/asset-canister-interface.md?plain=1#L85 - let compute_evidence_arg = ComputeEvidenceArguments { - batch_id: batch_id.clone(), - max_iterations: Some(97), // 75% of max(130) = 97.5 + let local_evidence = { + let local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; + escape_hex_string(&local_evidence) }; - info!(logger, "Computing evidence."); - let canister_evidence = loop { - if let Some(evidence) = compute_evidence(&canister_agent, &compute_evidence_arg).await? { - break evidence; - } + // Wait for the canister to compute the evidence: + let canister_evidence = { + // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. + // The docs explicitly include waiting for the evidence so this should really be made easier! See: https://github.com/dfinity/sdk/blob/2509e81e11e71dce4045c679686c952809525470/docs/design/asset-canister-interface.md?plain=1#L85 + let compute_evidence_arg = ComputeEvidenceArguments { + batch_id: batch_id.clone(), + max_iterations: Some(97), // 75% of max(130) = 97.5 + }; + info!(logger, "Computing evidence."); + let canister_evidence = loop { + if let Some(evidence) = compute_evidence(&canister_agent, &compute_evidence_arg).await? + { + break evidence; + } + }; + blob_from_bytes(&canister_evidence) }; - let canister_evidence_blob = blob_from_bytes(&canister_evidence); println!(r#"Proposed batch_id: {batch_id}"#); - println!(r#"Local evidence: "{local_evidence_blob}""#); - println!(r#"Canister computed evidence: {canister_evidence_blob}"#); + println!(r#"Local evidence: "{local_evidence}""#); + println!(r#"Canister computed evidence: {canister_evidence}"#); println!(r#"Assets have been uploaded. For the changes to take effect, run:"#); println!( - r#"dfx-orbit request canister call {canister} commit_proposed_batch '(record {{ batch_id = {batch_id} : nat; evidence = blob "{canister_evidence_blob}" }})'"# + r#"dfx-orbit request canister call {canister} commit_proposed_batch '(record {{ batch_id = {batch_id} : nat; evidence = blob "{canister_evidence}" }})'"# ); // TODO: The local evidence doesn't match the canister evidence. From 1a6088fd274d6eada80812ef194761ffe4485c5c Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 10:45:40 +0200 Subject: [PATCH 130/156] Cleanup --- .../src/cli/canister/upload_http_assets.rs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index f0232a8ac..f41d0192c 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -3,7 +3,7 @@ use ic_asset::canister_api::{ methods::batch::compute_evidence, types::batch_upload::common::ComputeEvidenceArguments, }; use ic_utils::canister::CanisterBuilder; -use slog::info; +use slog::{info, warn}; use std::{ collections::HashMap, path::{Path, PathBuf}, @@ -12,7 +12,7 @@ use walkdir::WalkDir; use crate::args::canister::UploadHttpAssets as Args; -/// The main entry point for the `dfx orbit` CLI. +/// The main entry point for the `dfx orbit canister upload-http-assets` CLI. pub async fn exec(args: Args) -> anyhow::Result<()> { let Args { canister, @@ -26,7 +26,7 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let canister_id = station_agent.canister_id(&canister)?; let logger = station_agent.dfx.logger().clone(); - // Upload assets + // Upload assets: let canister_agent = CanisterBuilder::new() .with_agent(station_agent.dfx.agent().await?) .with_canister_id(canister_id) @@ -39,7 +39,7 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { let local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; escape_hex_string(&local_evidence) }; - // Wait for the canister to compute the evidence: + // Wait for the canister to compute evidence: let canister_evidence = { // This part is stolen from ic_asset::sync::prepare_sync_for_proposal. Unfortunately the relevant functions are private. // The docs explicitly include waiting for the evidence so this should really be made easier! See: https://github.com/dfinity/sdk/blob/2509e81e11e71dce4045c679686c952809525470/docs/design/asset-canister-interface.md?plain=1#L85 @@ -58,17 +58,15 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { }; println!(r#"Proposed batch_id: {batch_id}"#); - println!(r#"Local evidence: "{local_evidence}""#); - println!(r#"Canister computed evidence: {canister_evidence}"#); + if local_evidence == canister_evidence { + info!(logger, "Local evidence matches canister evidence."); + } else { + warn!(logger, "Local evidence does not match canister evidence:\n local: {local_evidence}\n canister:{canister_evidence}"); + } println!(r#"Assets have been uploaded. For the changes to take effect, run:"#); println!( r#"dfx-orbit request canister call {canister} commit_proposed_batch '(record {{ batch_id = {batch_id} : nat; evidence = blob "{canister_evidence}" }})'"# ); - // TODO: The local evidence doesn't match the canister evidence. - - // Maybe compute evidence locally and then compare? - - // TODO: Get Orbit to make the API call to commit the changes. Ok(()) } From e1769895766a9d6d5d8d6098a52272bc4f9749a5 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 10:50:40 +0200 Subject: [PATCH 131/156] Match terminology with dfx.json --- tools/dfx-orbit/src/args/canister.rs | 4 ++-- tools/dfx-orbit/src/cli/canister/upload_http_assets.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index 3c57ecabd..a44386311 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -30,9 +30,9 @@ pub struct UploadHttpAssets { /// The canister name or `canister_id`. #[structopt(long)] pub canister: String, - /// The path to the assets to upload. + /// A directory of assets to upload. #[structopt(long)] - pub path: String, + pub source: String, /// Provide a running commentary. #[arg(short, long, default_value_t = false)] pub verbose: bool, diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index f41d0192c..bdd75e55d 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -16,11 +16,11 @@ use crate::args::canister::UploadHttpAssets as Args; pub async fn exec(args: Args) -> anyhow::Result<()> { let Args { canister, - path, + source, verbose: _verbose, } = args; // The path is needed in various forms. If dirs is plural, maybe we should accept multiple dirs? - let dir: PathBuf = PathBuf::from(&path); + let dir: PathBuf = PathBuf::from(&source); let dirs: Vec<&Path> = vec![dir.as_path()]; let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; @@ -31,7 +31,7 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { .with_agent(station_agent.dfx.agent().await?) .with_canister_id(canister_id) .build()?; - let assets = assets_as_hash_map(&path); + let assets = assets_as_hash_map(&source); let batch_id = ic_asset::upload_and_propose(&canister_agent, assets, &logger).await?; println!("Proposed batch_id: {}", batch_id); // Compute evidence locally: From 44b86be17a1f656b471e0ec273c00499fd18fc48 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 11:09:17 +0200 Subject: [PATCH 132/156] Support multiple asset dirs --- tools/dfx-orbit/src/args/canister.rs | 2 +- .../src/cli/canister/upload_http_assets.rs | 39 +++++++++++-------- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index a44386311..8976e6bf8 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -32,7 +32,7 @@ pub struct UploadHttpAssets { pub canister: String, /// A directory of assets to upload. #[structopt(long)] - pub source: String, + pub source: Vec, /// Provide a running commentary. #[arg(short, long, default_value_t = false)] pub verbose: bool, diff --git a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs index bdd75e55d..8fb6219ea 100644 --- a/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs +++ b/tools/dfx-orbit/src/cli/canister/upload_http_assets.rs @@ -19,9 +19,13 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { source, verbose: _verbose, } = args; - // The path is needed in various forms. If dirs is plural, maybe we should accept multiple dirs? - let dir: PathBuf = PathBuf::from(&source); - let dirs: Vec<&Path> = vec![dir.as_path()]; + // The path is needed in various forms. + let source_pathbufs: Vec = + source.iter().map(|source| PathBuf::from(&source)).collect(); + let source_paths: Vec<&Path> = source_pathbufs + .iter() + .map(|pathbuf| pathbuf.as_path()) + .collect(); let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; let canister_id = station_agent.canister_id(&canister)?; @@ -36,7 +40,8 @@ pub async fn exec(args: Args) -> anyhow::Result<()> { println!("Proposed batch_id: {}", batch_id); // Compute evidence locally: let local_evidence = { - let local_evidence = ic_asset::compute_evidence(&canister_agent, &dirs, &logger).await?; + let local_evidence = + ic_asset::compute_evidence(&canister_agent, &source_paths, &logger).await?; escape_hex_string(&local_evidence) }; // Wait for the canister to compute evidence: @@ -91,18 +96,20 @@ fn list_assets(path: &str) -> Vec { /// A hash map of all assets. /// /// Note: Given that ordering in a HashMap is not deterministic, is this really the best API? -fn assets_as_hash_map(asset_dir: &str) -> HashMap { - list_assets(asset_dir) - .into_iter() - .map(|asset_path| { - let relative_path = asset_path.strip_prefix(asset_dir).expect( - "Internal error: list_assets should have returned only files in the asset_dir", - ); - let http_path = format!( - "/{relative_path}", - relative_path = relative_path.to_string_lossy() - ); - (http_path, asset_path) +fn assets_as_hash_map(asset_dirs: &[String]) -> HashMap { + asset_dirs + .iter() + .flat_map(|asset_dir| { + list_assets(asset_dir).into_iter().map(move |asset_path| { + let relative_path = asset_path.strip_prefix(asset_dir).expect( + "Internal error: list_assets should have returned only files in the asset_dir", + ); + let http_path = format!( + "/{relative_path}", + relative_path = relative_path.to_string_lossy() + ); + (http_path, asset_path) + }) }) .collect() } From bfaac73e209352e6d7a7f9fdeb338c9eb41b911f Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 11:38:57 +0200 Subject: [PATCH 133/156] Update documentation --- CLI.md | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/CLI.md b/CLI.md index e9b548eba..797ec7d7c 100644 --- a/CLI.md +++ b/CLI.md @@ -84,4 +84,50 @@ This will create an Orbit request. Once approved you will be able to propose ca Suppose that you have built a new Wasm and put a copy at `./MY-CANISTER.wasm.gz`. To upgrade your canister to the new Wasm: ``` dfx-orbit request canister change wasm --canister MY_CANISTER --mode upgrade --wasm ./MY-CANISTER.wasm.gz -``` \ No newline at end of file +``` + +## Upload assets to a canister +We will assume that Orbit is a controller of the asset canister. If not, please adapt the following commands by using `dfx canister call` instead of `dfx-orbit request canister call`. + +### Authorize the developer to upload assets +Note: Uploaded assets are not published. They are only prepared for release. +``` +developer_principal="$(dfx identity get-principal)" +dfx-orbit request canister call frontend grant_permission " +( + record { + permission = variant { Prepare }; + to_principal = principal \"$developer_principal\"; + }, +) +" +``` + +### Authorize the orbit station to commit assets +Note: Committing uploaded assets causes them to be published on the asset canister web site. +``` +station_principal="$(dfx-orbit station show | jq -r .station_id)" +dfx-orbit request canister call frontend grant_permission " +( + record { + permission = variant { Commit }; + to_principal = principal \"$station_principal\"; + }, +) +" +``` + +### Upload assets +A developer may upload one or more directories of HTTP assets with: +``` +dfx-orbit canister upload-http-assets --canister CANISTER_NAME --source SOME_DIR/ --source OTHER_DIR/ +``` +The developer may now request that the assets be published. The command for this is printed at the end of the upload command. Example: +``` +... +Jul 03 09:36:42.148 INFO Computing evidence. +Proposed batch_id: 5 +Assets have been uploaded. For the changes to take effect, run: +dfx-orbit request canister call frontend commit_proposed_batch '(record { batch_id = 5 : nat; evidence = blob "\e3\b0\c4\42\98\fc\1c\14\9a\fb\f4\c8\99\6f\b9\24\27\ae\41\e4\64\9b\93\4c\a4\95\99\1b\78\52\b8\55" })' +``` +Once the request has been approved, the changes will take effect. \ No newline at end of file From 222060a8405173d635f30de56a1648254a0ea098 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Wed, 3 Jul 2024 11:46:00 +0200 Subject: [PATCH 134/156] docs++ --- CLI.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CLI.md b/CLI.md index 797ec7d7c..2628e5c16 100644 --- a/CLI.md +++ b/CLI.md @@ -102,6 +102,10 @@ dfx-orbit request canister call frontend grant_permission " ) " ``` +When the request has been approved, check the list of principals permitted to prepare assets: +``` +dfx canister call frontend list_permitted '(record { permission = variant { Prepare } })' +``` ### Authorize the orbit station to commit assets Note: Committing uploaded assets causes them to be published on the asset canister web site. @@ -116,6 +120,10 @@ dfx-orbit request canister call frontend grant_permission " ) " ``` +When the request has been approved, check the list of principals permitted to commit assets: +``` +dfx canister call frontend list_permitted '(record { permission = variant { Commit } })' +``` ### Upload assets A developer may upload one or more directories of HTTP assets with: From ac0a6273373cdde8e31a2589197f732d807a216b Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 03:40:10 +0200 Subject: [PATCH 135/156] docs --- CLI.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CLI.md b/CLI.md index 2628e5c16..2338f38e4 100644 --- a/CLI.md +++ b/CLI.md @@ -42,7 +42,7 @@ Tell the command line tool where to find the orbit station: * Copy the wallet ID * Store the station details locally. If your wallet is called `shiny` and is running locally, the command is: ``` - dfx-orbit station add --name shiny --canister-id "$WALLET_ID" --network local + dfx-orbit station add --name shiny --station-id "$WALLET_ID" --network local ``` * Verify that the station is in your list of stations: ``` @@ -57,6 +57,8 @@ Tell the command line tool where to find the orbit station: dfx-orbit me ``` +TODO: The Oisy canister ID is also called the wallet ID and the station ID. Consistent nomenclature that doesn't conflict with established terminology would be nice. + ## Control a canister with Orbit ### Grant Orbit control of the canister From 203fe6e7cfb4a4bf803e868da5128e3e16c16651 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 03:50:47 +0200 Subject: [PATCH 136/156] doc --- CLI.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CLI.md b/CLI.md index 2338f38e4..4227098a9 100644 --- a/CLI.md +++ b/CLI.md @@ -42,7 +42,7 @@ Tell the command line tool where to find the orbit station: * Copy the wallet ID * Store the station details locally. If your wallet is called `shiny` and is running locally, the command is: ``` - dfx-orbit station add --name shiny --station-id "$WALLET_ID" --network local + dfx-orbit station add --name shiny --station-id "$WALLET_ID" --network local --url https://orbitwallet.io ``` * Verify that the station is in your list of stations: ``` @@ -52,6 +52,10 @@ Tell the command line tool where to find the orbit station: ``` dfx-orbit station use --name shiny ``` +* In the orbit web UI, create a user with your local dfx principal: + ``` + dfx identity get-principal + ``` * Verify that you can get your profile on the Orbit station: ``` dfx-orbit me From 9185671d0717b39288a26c44fdd8828c18cad72d Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 04:08:41 +0200 Subject: [PATCH 137/156] Make station ID a positional arg --- CLI.md | 8 ++++++-- tools/dfx-orbit/src/args/station.rs | 2 -- tools/dfx-orbit/src/cli.rs | 15 ++------------- tools/dfx-orbit/src/cli/me.rs | 14 ++++++++++++++ 4 files changed, 22 insertions(+), 17 deletions(-) create mode 100644 tools/dfx-orbit/src/cli/me.rs diff --git a/CLI.md b/CLI.md index 4227098a9..373da5cc5 100644 --- a/CLI.md +++ b/CLI.md @@ -42,7 +42,7 @@ Tell the command line tool where to find the orbit station: * Copy the wallet ID * Store the station details locally. If your wallet is called `shiny` and is running locally, the command is: ``` - dfx-orbit station add --name shiny --station-id "$WALLET_ID" --network local --url https://orbitwallet.io + dfx-orbit station add shiny --station-id "$WALLET_ID" --network local --url https://orbitwallet.io ``` * Verify that the station is in your list of stations: ``` @@ -50,7 +50,11 @@ Tell the command line tool where to find the orbit station: ``` * If you have multiple stations, set this as your default: ``` - dfx-orbit station use --name shiny + dfx-orbit station use shiny + ``` +* Show the station details + ``` + dfx-orbit station show ``` * In the orbit web UI, create a user with your local dfx principal: ``` diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index d4421d62e..1ea5921e3 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -28,7 +28,6 @@ pub enum StationArgs { #[derive(Debug, Parser)] pub struct Add { /// Wallet name. - #[structopt(long)] pub name: String, /// Station canister ID, called "Wallet ID" in the Orbit UI. #[structopt(long)] @@ -91,6 +90,5 @@ pub struct Remove { #[derive(Debug, Parser)] pub struct Use { /// Station name. - #[structopt(long)] pub name: String, } diff --git a/tools/dfx-orbit/src/cli.rs b/tools/dfx-orbit/src/cli.rs index 9d108f22b..7a8615138 100644 --- a/tools/dfx-orbit/src/cli.rs +++ b/tools/dfx-orbit/src/cli.rs @@ -1,6 +1,7 @@ //! Implementation of the `dfx-orbit` commands. pub mod canister; pub mod dfx_extension_cli; +pub mod me; pub mod request; pub mod review; pub mod station; @@ -11,19 +12,7 @@ use anyhow::anyhow; /// A command line tool for interacting with Orbit on the Internet Computer. pub async fn exec(args: DfxOrbitArgs) -> anyhow::Result<()> { match args.command { - DfxOrbitSubcommands::Me => { - let station_principal = &crate::local_config::default_station()? - .ok_or_else(|| anyhow!("No default station specified"))? - .station_id; - let ans = crate::dfx_extension_api::call_dfx_cli(vec![ - "canister", - "call", - station_principal, - "me", - ])?; - print!("{ans}"); - Ok(()) - } + DfxOrbitSubcommands::Me => me::exec().await, DfxOrbitSubcommands::Station(station_args) => station::exec(station_args), DfxOrbitSubcommands::DfxExtension(dfx_extension_args) => { dfx_extension_cli::exec(dfx_extension_args) diff --git a/tools/dfx-orbit/src/cli/me.rs b/tools/dfx-orbit/src/cli/me.rs new file mode 100644 index 000000000..2b93e6d13 --- /dev/null +++ b/tools/dfx-orbit/src/cli/me.rs @@ -0,0 +1,14 @@ +//! Implementation of the `dfx-orbit me` command. + +use anyhow::anyhow; + +/// A command line tool for interacting with Orbit on the Internet Computer. +pub async fn exec() -> anyhow::Result<()> { + let station_principal = &crate::local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .station_id; + let ans = + crate::dfx_extension_api::call_dfx_cli(vec!["canister", "call", station_principal, "me"])?; + print!("{ans}"); + Ok(()) +} From 74173c24462e39caa996e87885b58e84600bc7b0 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 04:26:13 +0200 Subject: [PATCH 138/156] Add orbit agent methods --- tools/dfx-orbit/src/orbit_station_agent.rs | 44 +++++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/orbit_station_agent.rs b/tools/dfx-orbit/src/orbit_station_agent.rs index e4e2eafba..fc9c21161 100644 --- a/tools/dfx-orbit/src/orbit_station_agent.rs +++ b/tools/dfx-orbit/src/orbit_station_agent.rs @@ -1,5 +1,6 @@ //! A dfx and IC agent for communicating with an Orbit station. +use anyhow::anyhow; use candid::Principal; use ic_agent::agent::UpdateBuilder; @@ -31,8 +32,16 @@ impl StationAgent { self.dfx.canister_id(canister_name, network) } - /// Makes a canister update call on the network used by the station. - pub async fn update( + /// Builds a canister update call on the network used by the station. + /// + /// # Example + /// ``` + /// let response_bytes = station_agent.update_canister(&canister_id, "method_name") + /// .with_arg(candid::encode_one(args)?) + /// .call_and_wait() + /// .await?; + /// ``` + pub async fn update_canister_id( &mut self, canister_id: &Principal, method_name: &str, @@ -40,6 +49,37 @@ impl StationAgent { Ok(self.dfx.agent().await?.update(canister_id, method_name)) } + /// Builds a canister update call to a named canister on the network used by the station. + /// + /// # Example + /// ``` + /// let response_bytes = station_agent.update_canister("mycanister", "method_name") + /// .with_arg(candid::encode_one(args)?) + /// .call_and_wait() + /// .await?; + /// ``` + pub async fn update_canister( + &mut self, + canister: &str, + method_name: &str, + ) -> anyhow::Result { + let canister_id = self.canister_id(canister)?; + Ok(self.dfx.agent().await?.update(&canister_id, method_name)) + } + + /// Makes an update call to the station. + pub async fn update_orbit(&mut self, method_name: &str) -> anyhow::Result { + let orbit_canister_id = crate::local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .station_id; + let orbit_canister_id = Principal::from_text(&orbit_canister_id)?; + Ok(self + .dfx + .agent() + .await? + .update(&orbit_canister_id, method_name)) + } + /// The URL for a request in the Orbit UI. pub fn request_url(&self, request_id: &str) -> String { format!( From e8c7d02e5cbbaebd9262792df6a25b8c5fffd7a4 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 04:50:14 +0200 Subject: [PATCH 139/156] refactor (cli/request): Use orbit agent --- tools/dfx-orbit/src/cli/request.rs | 13 +++---------- tools/dfx-orbit/src/orbit_station_agent.rs | 12 ++++++++++-- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 06cee92c9..3f68ab8cd 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -1,8 +1,6 @@ //! Implements `dfx request` commands. These correspond to Orbit station `create_request` API calls. use crate::args::request::{Args, CreateRequestArgs}; -use anyhow::anyhow; -use candid::Principal; use orbit_station_api::{ApiErrorDTO, CreateRequestResponse}; /// The main entry point for the `dfx orbit request` CLI. @@ -10,14 +8,9 @@ pub async fn exec(args: Args) -> anyhow::Result anyhow::Result { let orbit_canister_id = crate::local_config::default_station()? .ok_or_else(|| anyhow!("No default station specified"))? From d53e3ee568e0ffabc8973b0ef3c4c8129d8dd5f8 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 04:53:43 +0200 Subject: [PATCH 140/156] comments --- tools/dfx-orbit/src/cli/request.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/cli/request.rs b/tools/dfx-orbit/src/cli/request.rs index 3f68ab8cd..f56f2b160 100644 --- a/tools/dfx-orbit/src/cli/request.rs +++ b/tools/dfx-orbit/src/cli/request.rs @@ -5,15 +5,17 @@ use orbit_station_api::{ApiErrorDTO, CreateRequestResponse}; /// The main entry point for the `dfx orbit request` CLI. pub async fn exec(args: Args) -> anyhow::Result> { - // Converts the CLI arg type into the equivalent Orbit API type. let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + // Converts the CLI arg type into the equivalent Orbit API type. let args = args.into_create_request_input(&station_agent)?; + // Makes an update call to the station. let response_bytes = station_agent .update_orbit("create_request") .await? .with_arg(candid::encode_one(args)?) .call_and_wait() .await?; + // Decodes the response from the station. let ans: Result = candid::decode_one(&response_bytes)?; if let Ok(response) = &ans { let request_id = &response.request.id; From dcb8daf51c2a31752f5e50e8eae4f264fda33117 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 05:28:36 +0200 Subject: [PATCH 141/156] Use the station agent for me --- tools/dfx-orbit/src/cli/me.rs | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/tools/dfx-orbit/src/cli/me.rs b/tools/dfx-orbit/src/cli/me.rs index 2b93e6d13..725366a75 100644 --- a/tools/dfx-orbit/src/cli/me.rs +++ b/tools/dfx-orbit/src/cli/me.rs @@ -1,14 +1,30 @@ //! Implementation of the `dfx-orbit me` command. -use anyhow::anyhow; +use anyhow::Context; +use candid::encode_args; +use orbit_station_api::{ApiErrorDTO, MeResponse}; /// A command line tool for interacting with Orbit on the Internet Computer. pub async fn exec() -> anyhow::Result<()> { - let station_principal = &crate::local_config::default_station()? - .ok_or_else(|| anyhow!("No default station specified"))? - .station_id; - let ans = - crate::dfx_extension_api::call_dfx_cli(vec!["canister", "call", station_principal, "me"])?; - print!("{ans}"); + let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + let ans = station_agent + .update_orbit("me") + .await? + .with_arg(empty_args()) + .call_and_wait() + .await + .with_context(|| "Failed to make API call")?; + let ans: Result = + candid::decode_one(&ans).with_context(|| "Failed to decode response")?; + println!( + "{}", + serde_json::to_string_pretty(&ans) + .with_context(|| "Failed to serialize response as JSON")? + ); Ok(()) } + +/// Encodes an empty tuple as Candid. This is used for methods with no arguments. +pub fn empty_args() -> Vec { + encode_args(()).expect("Failed to candid encode empty tuple") +} From c5344a6bc0a14ec6b609a36b5438647b8740ea50 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 05:53:42 +0200 Subject: [PATCH 142/156] Set teh network and get the root key, if needed --- tools/dfx-orbit/src/dfx_extension_api.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 4615cf83b..f91cc9467 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -139,10 +139,15 @@ impl DfxExtensionAgent { call_dfx_cli(vec!["identity", "whoami"]) } - /// Gets the dfx interface + /// Gets the dfx_core interface pub async fn dfx_interface(&mut self) -> anyhow::Result<&DfxInterface> { if self.dfx_interface.is_none() { - self.dfx_interface = Some(DfxInterface::builder().build().await?); + let interface_builder = DfxInterface::builder().with_network_named("local"); + let interface = interface_builder.build().await?; + if !interface.network_descriptor().is_ic { + interface.agent().fetch_root_key().await?; + } + self.dfx_interface = Some(interface); } Ok(self .dfx_interface From 4a966a167616e41152314f4ca7967c025a95ca76 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 06:29:05 +0200 Subject: [PATCH 143/156] Me works on mainnet --- tools/dfx-orbit/src/dfx_extension_api.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index f91cc9467..9640fee4a 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -10,6 +10,8 @@ use dfx_core::interface::dfx::DfxInterface; use ic_agent::Agent; use slog::{o, Drain, Logger}; +use crate::local_config; + /// Calls the dfx cli. /// /// Some methods are implemented as calls to the dfx cli until a library is available. @@ -142,7 +144,11 @@ impl DfxExtensionAgent { /// Gets the dfx_core interface pub async fn dfx_interface(&mut self) -> anyhow::Result<&DfxInterface> { if self.dfx_interface.is_none() { - let interface_builder = DfxInterface::builder().with_network_named("local"); + let network_name = local_config::station_or_default(None) + .with_context(|| "Failed to get station")? + .network; + println!("Network name: {}", network_name); + let interface_builder = DfxInterface::builder().with_network_named(&network_name); let interface = interface_builder.build().await?; if !interface.network_descriptor().is_ic { interface.agent().fetch_root_key().await?; From da23cd831636fd7ef23b78645fefe2b7dd2d4129 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 06:35:41 +0200 Subject: [PATCH 144/156] Small refactor --- tools/dfx-orbit/src/args/station.rs | 13 +++++++++++++ tools/dfx-orbit/src/cli/station.rs | 3 +-- tools/dfx-orbit/src/local_config.rs | 24 ++++++++---------------- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/tools/dfx-orbit/src/args/station.rs b/tools/dfx-orbit/src/args/station.rs index 1ea5921e3..bdfc43432 100644 --- a/tools/dfx-orbit/src/args/station.rs +++ b/tools/dfx-orbit/src/args/station.rs @@ -4,6 +4,8 @@ use std::fmt::{self, Display, Formatter}; use candid::Principal; use clap::{Parser, Subcommand}; +use crate::local_config::StationConfig; + /// Station management commands. #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] @@ -40,6 +42,17 @@ pub struct Add { pub url: String, } +impl From for StationConfig { + fn from(add: Add) -> Self { + Self { + name: add.name, + station_id: add.station_id.to_text(), + network: add.network, + url: add.url, + } + } +} + /// Lists Orbit station in the local dfx configuration. #[derive(Debug, Parser)] pub struct List {} diff --git a/tools/dfx-orbit/src/cli/station.rs b/tools/dfx-orbit/src/cli/station.rs index b93dece53..506fb3489 100644 --- a/tools/dfx-orbit/src/cli/station.rs +++ b/tools/dfx-orbit/src/cli/station.rs @@ -6,8 +6,7 @@ use crate::local_config; pub fn exec(args: StationArgs) -> anyhow::Result<()> { match args { StationArgs::Add(add_args) => { - local_config::add_station(&add_args) - .expect("Failed to add station to local dfx config"); + local_config::add_station(add_args).expect("Failed to add station to local dfx config"); } StationArgs::List(_list_args) => { let stations = local_config::list_stations(); diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 7762df52d..7a8f03d68 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -2,7 +2,7 @@ use anyhow::Context; use serde::{Deserialize, Serialize}; -use crate::{args::station::Add, dfx_extension_api::DfxExtensionAgent}; +use crate::dfx_extension_api::DfxExtensionAgent; /// Configuration that lives in e.g. ~/.config/dfx/orbit.json #[derive(Debug, Default, Serialize, Deserialize)] @@ -107,25 +107,17 @@ pub fn list_stations() -> Vec { /// /// If there is no default station, the new station is set as the default. // TODO: Check that the URL works & is the root URL. -pub fn add_station(args: &Add) -> anyhow::Result<()> { - let Add { - name, - station_id, - network, - url, - } = args; - let station = StationConfig { - name: name.to_string(), - station_id: station_id.to_string(), - network: network.to_string(), - url: url.to_string(), - }; - let station_file = create_station_file(name)?; +pub fn add_station(args: T) -> anyhow::Result<()> +where + T: Into, +{ + let station: StationConfig = args.into(); + let station_file = create_station_file(&station.name)?; station_file.set_len(0)?; serde_json::to_writer_pretty(station_file, &station).expect("Failed to write station file"); if default_station_name()?.is_none() { - set_default_station(Some(name.to_string()))?; + set_default_station(Some(station.name.to_owned()))?; } Ok(()) From 53c3d3800224e97c9a30912118f21e450d79a582 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 06:49:19 +0200 Subject: [PATCH 145/156] Fix rename defaults --- tools/dfx-orbit/src/local_config.rs | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/tools/dfx-orbit/src/local_config.rs b/tools/dfx-orbit/src/local_config.rs index 7a8f03d68..02a89d152 100644 --- a/tools/dfx-orbit/src/local_config.rs +++ b/tools/dfx-orbit/src/local_config.rs @@ -161,17 +161,12 @@ pub fn remove_station(name: &str) -> anyhow::Result<()> { /// /// If the station being renamed is the default station, the default is updated to reflect the new name. pub fn rename_station(name: &str, new_name: &str) -> anyhow::Result<()> { - let dir = stations_dir()?; - let old_path = station_file_name(name); - let new_path = station_file_name(new_name); - dir.rename(old_path, &dir, new_path).with_context(|| { - format!( - "Failed to rename dfx config file for station {} to {}", - name, new_name - ) - })?; - - if default_station_name()? == Some(name.to_string()) { + let default_station_name = default_station_name()?; + let mut station = station(name)?; + station.name = new_name.to_string(); + add_station(station)?; + remove_station(name)?; + if default_station_name == Some(name.to_string()) { set_default_station(Some(new_name.to_string()))?; } Ok(()) From 7268de35341bff8cb51efa96e5f7790d9f5ad49a Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 07:03:51 +0200 Subject: [PATCH 146/156] Supply network to canister claim --- CLI.md | 5 +---- tools/dfx-orbit/src/args/canister.rs | 1 - tools/dfx-orbit/src/cli/canister/claim.rs | 5 +++++ 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CLI.md b/CLI.md index 373da5cc5..77b00c49d 100644 --- a/CLI.md +++ b/CLI.md @@ -74,10 +74,7 @@ Assume that you have a canister called `MY_CANISTER` in `dfx`. You may also ref Add Orbit as a controller while keeping existing controllers: ``` -( - orbit_station="$(dfx-orbit station show | jq -r .canister_id)" - dfx canister update-settings --add-controller "$orbit_station" MY_CANISTER -) +dfx-orbit canister claim MY_CANISTER ``` ### Register yourself as a developer for your canister diff --git a/tools/dfx-orbit/src/args/canister.rs b/tools/dfx-orbit/src/args/canister.rs index 8976e6bf8..ea9b3f4f3 100644 --- a/tools/dfx-orbit/src/args/canister.rs +++ b/tools/dfx-orbit/src/args/canister.rs @@ -17,7 +17,6 @@ pub enum Args { #[derive(Debug, Parser)] pub struct Claim { /// The canister name or `canister_id`. - #[structopt(long)] pub canister: String, /// Make Orbit the exclusive controller of the canister. #[clap(long, short, action)] diff --git a/tools/dfx-orbit/src/cli/canister/claim.rs b/tools/dfx-orbit/src/cli/canister/claim.rs index b556786bc..933cbf79e 100644 --- a/tools/dfx-orbit/src/cli/canister/claim.rs +++ b/tools/dfx-orbit/src/cli/canister/claim.rs @@ -19,9 +19,14 @@ pub fn exec(args: Claim) -> anyhow::Result<()> { } else { "--add-controller" }; + let network = local_config::default_station()? + .ok_or_else(|| anyhow!("No default station specified"))? + .network; dfx_extension_api::call_dfx_cli(vec![ "canister", "update-settings", + "--network", + &network, claim_type, orbit_principal, &canister, From 8d173062d45b5e2700451980695640fc5a1a42b6 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 10:53:05 +0200 Subject: [PATCH 147/156] docs --- CLI.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CLI.md b/CLI.md index 77b00c49d..0cc768094 100644 --- a/CLI.md +++ b/CLI.md @@ -72,10 +72,19 @@ TODO: The Oisy canister ID is also called the wallet ID and the station ID. Con ### Grant Orbit control of the canister Assume that you have a canister called `MY_CANISTER` in `dfx`. You may also refer to your canister by canister ID. -Add Orbit as a controller while keeping existing controllers: +Check the current controllers of the canister: +``` +dfx canister info MY_CANISTER --network MY_CANISTER_NETWORK +``` + +Add Orbit as a controller of the canister: ``` dfx-orbit canister claim MY_CANISTER ``` +Verify that Orbit has been added as a controller: +``` +dfx canister info MY_CANISTER --network MY_CANISTER_NETWORK +``` ### Register yourself as a developer for your canister This will allow you to propose upgrades to `MY_CANISTER`: From 940cc7e7b523f4effeaa87d86f23e0abb18536ed Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 11:05:35 +0200 Subject: [PATCH 148/156] Printless --- tools/dfx-orbit/src/dfx_extension_api.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tools/dfx-orbit/src/dfx_extension_api.rs b/tools/dfx-orbit/src/dfx_extension_api.rs index 9640fee4a..6672dfa2a 100644 --- a/tools/dfx-orbit/src/dfx_extension_api.rs +++ b/tools/dfx-orbit/src/dfx_extension_api.rs @@ -147,7 +147,6 @@ impl DfxExtensionAgent { let network_name = local_config::station_or_default(None) .with_context(|| "Failed to get station")? .network; - println!("Network name: {}", network_name); let interface_builder = DfxInterface::builder().with_network_named(&network_name); let interface = interface_builder.build().await?; if !interface.network_descriptor().is_ic { From 0bc35a2cbf7aeb434250320247bc67780dce63a5 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 11:46:41 +0200 Subject: [PATCH 149/156] docs --- CLI.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CLI.md b/CLI.md index 0cc768094..c28107a02 100644 --- a/CLI.md +++ b/CLI.md @@ -67,6 +67,35 @@ Tell the command line tool where to find the orbit station: TODO: The Oisy canister ID is also called the wallet ID and the station ID. Consistent nomenclature that doesn't conflict with established terminology would be nice. +### Grant permission to make requests +You can check which permissions you have with: +``` +dfx-orbit me | jq .Ok.privileges +``` +Initially you are likely to have only permission to see your own profile: +``` +[ + "Capabilities" +] +``` + +Without permission to make requests, `request permission` commands, like this meaningless request to update a non-existent canister, will fail with `Unauthorized access to resources: Permission(Update)`. +``` +dfx-orbit request permission canister change --canister tmlz3-yjbfg-j2wfb-745ni-omr52-4tga6-rbk3r-wjryr-l3xk7-oziho-wae +``` + +In the UI the permission that needs to be granted is: + +| Permission | [Name in UI](https://orbitwallet.io/en/settings/user-groups/permissions) | Privilige | Used for | +| --- | --- | --- | -- | +| `Request(List)` | Request/List | `ListRequests` | `dfx-orbit review next` | + +TODO: It would be nice to be able to link directly to a permission. E.g. this could open the permissions page and focus on one specific permission: https://orbitwallet.io/en/settings/user-groups/permissions#Request/List + + +## Make canister calls with Orbit + + ## Control a canister with Orbit ### Grant Orbit control of the canister From 7ab0fc21e954b5777e6ae64655351af71e930f26 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 12:07:13 +0200 Subject: [PATCH 150/156] Add request list command --- tools/dfx-orbit/src/args/review.rs | 3 +++ tools/dfx-orbit/src/args/review/list.rs | 31 +++++++++++++++++++++++++ tools/dfx-orbit/src/cli/review.rs | 2 ++ tools/dfx-orbit/src/cli/review/list.rs | 20 ++++++++++++++++ 4 files changed, 56 insertions(+) create mode 100644 tools/dfx-orbit/src/args/review/list.rs create mode 100644 tools/dfx-orbit/src/cli/review/list.rs diff --git a/tools/dfx-orbit/src/args/review.rs b/tools/dfx-orbit/src/args/review.rs index d6987557f..fc9c947e6 100644 --- a/tools/dfx-orbit/src/args/review.rs +++ b/tools/dfx-orbit/src/args/review.rs @@ -1,5 +1,6 @@ //! Defines the command line arguments for `dfx-orbit review`. These correspond to Orbit station `get_request`, `submit_request_approval` and related API calls. pub mod id; +pub mod list; pub mod next; use clap::Subcommand; @@ -8,6 +9,8 @@ use clap::Subcommand; #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { + /// List requests + List(list::Args), /// Review the next request. Next(next::Args), /// Review a specific request. diff --git a/tools/dfx-orbit/src/args/review/list.rs b/tools/dfx-orbit/src/args/review/list.rs new file mode 100644 index 000000000..e77c2da01 --- /dev/null +++ b/tools/dfx-orbit/src/args/review/list.rs @@ -0,0 +1,31 @@ +//! CLI arguments for `dfx-orbit review list`. + +use clap::Parser; + +/// Reviews the next request. +#[derive(Debug, Parser)] +pub struct Args { + /// Show only approvable requests. + #[clap(short, long)] + pub only_approvable: bool, +} + +impl From for orbit_station_api::ListRequestsInput { + fn from(args: Args) -> Self { + let Args { only_approvable } = args; + Self { + requester_ids: None, + approver_ids: None, + statuses: None, + operation_types: None, + expiration_from_dt: None, + expiration_to_dt: None, + created_from_dt: None, + created_to_dt: None, + paginate: None, + sort_by: None, + only_approvable, + with_evaluation_results: true, + } + } +} diff --git a/tools/dfx-orbit/src/cli/review.rs b/tools/dfx-orbit/src/cli/review.rs index 224da8177..e8ee0d2e3 100644 --- a/tools/dfx-orbit/src/cli/review.rs +++ b/tools/dfx-orbit/src/cli/review.rs @@ -1,5 +1,6 @@ //! Implements `dfx review` commands. These correspond to Orbit station `get_request`, approve and related API calls. pub mod id; +pub mod list; pub mod next; use crate::args::review::Args; @@ -8,6 +9,7 @@ use crate::args::review::Args; pub async fn exec(args: Args) -> anyhow::Result<()> { match args { Args::Id(id_args) => id::exec(id_args).await, + Args::List(list_args) => list::exec(list_args).await, Args::Next(next_args) => next::exec(next_args).await, } } diff --git a/tools/dfx-orbit/src/cli/review/list.rs b/tools/dfx-orbit/src/cli/review/list.rs new file mode 100644 index 000000000..33e861d1f --- /dev/null +++ b/tools/dfx-orbit/src/cli/review/list.rs @@ -0,0 +1,20 @@ +//! Implements `dfx review list` command. These correspond to Orbit station `list_requests` API call. + +use orbit_station_api::{ApiErrorDTO, ListRequestsInput, ListRequestsResponse}; + +use crate::args::review::list::Args; + +/// The main entry point for the `dfx orbit review next` CLI. +pub async fn exec(args: Args) -> anyhow::Result<()> { + let args = ListRequestsInput::from(args); + let mut station_agent = crate::orbit_station_agent::StationAgent::new()?; + let response_bytes = station_agent + .update_orbit("list_requests") + .await? + .with_arg(candid::encode_one(args)?) + .call_and_wait() + .await?; + let ans: Result = candid::decode_one(&response_bytes)?; + println!("{}", serde_json::to_string_pretty(&ans)?); + Ok(()) +} From b2448bf804d2b73f4162f8244652ce574ac51b52 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 12:12:00 +0200 Subject: [PATCH 151/156] doc++ --- CLI.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/CLI.md b/CLI.md index c28107a02..f284b21cd 100644 --- a/CLI.md +++ b/CLI.md @@ -79,16 +79,13 @@ Initially you are likely to have only permission to see your own profile: ] ``` -Without permission to make requests, `request permission` commands, like this meaningless request to update a non-existent canister, will fail with `Unauthorized access to resources: Permission(Update)`. -``` -dfx-orbit request permission canister change --canister tmlz3-yjbfg-j2wfb-745ni-omr52-4tga6-rbk3r-wjryr-l3xk7-oziho-wae -``` +Without permission to make and view requests, you will not be able to do much. The following permissions are recommended for anyone entitled to make requests: In the UI the permission that needs to be granted is: -| Permission | [Name in UI](https://orbitwallet.io/en/settings/user-groups/permissions) | Privilige | Used for | +| Privilege | [Name in UI](https://orbitwallet.io/en/settings/user-groups/permissions) | Name in error messages | Used for | | --- | --- | --- | -- | -| `Request(List)` | Request/List | `ListRequests` | `dfx-orbit review next` | +| `ListRequests` | Request/List | `Request(List)` | `dfx-orbit review list` | TODO: It would be nice to be able to link directly to a permission. E.g. this could open the permissions page and focus on one specific permission: https://orbitwallet.io/en/settings/user-groups/permissions#Request/List From dab11451bc96a991f07afcd8f477a71d682b1adb Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 12:19:42 +0200 Subject: [PATCH 152/156] doc++ --- CLI.md | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/CLI.md b/CLI.md index f284b21cd..bee68e535 100644 --- a/CLI.md +++ b/CLI.md @@ -79,13 +79,12 @@ Initially you are likely to have only permission to see your own profile: ] ``` -Without permission to make and view requests, you will not be able to do much. The following permissions are recommended for anyone entitled to make requests: +Without permission to make and view requests, you will not be able to do much. It is recommended to make a `Developer` group with the following permissions: -In the UI the permission that needs to be granted is: - -| Privilege | [Name in UI](https://orbitwallet.io/en/settings/user-groups/permissions) | Name in error messages | Used for | +| [Name in UI](https://orbitwallet.io/en/settings/user-groups/permissions) | Privilege in `dfx-orbit me` | Name in error messages | Used for | | --- | --- | --- | -- | -| `ListRequests` | Request/List | `Request(List)` | `dfx-orbit review list` | +| Request/List | `ListRequests` | `Request(List)` | `dfx-orbit review list` | +| Request/Read | Not Shown | `Request(Read(Id` | `dfx-orbit review id REQUEST_ID` | TODO: It would be nice to be able to link directly to a permission. E.g. this could open the permissions page and focus on one specific permission: https://orbitwallet.io/en/settings/user-groups/permissions#Request/List From a65848588e3971b12629e436ec72e13f0a485d06 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 12:24:37 +0200 Subject: [PATCH 153/156] fmt --- CLI.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CLI.md b/CLI.md index bee68e535..412c2ae0e 100644 --- a/CLI.md +++ b/CLI.md @@ -81,10 +81,10 @@ Initially you are likely to have only permission to see your own profile: Without permission to make and view requests, you will not be able to do much. It is recommended to make a `Developer` group with the following permissions: -| [Name in UI](https://orbitwallet.io/en/settings/user-groups/permissions) | Privilege in `dfx-orbit me` | Name in error messages | Used for | -| --- | --- | --- | -- | -| Request/List | `ListRequests` | `Request(List)` | `dfx-orbit review list` | -| Request/Read | Not Shown | `Request(Read(Id` | `dfx-orbit review id REQUEST_ID` | +| Name in UI | Privilege in `dfx-orbit me` | Name in error messages | Used for | +|--------------|-----------------------------|------------------------|----------------------------------| +| Request/List | `ListRequests` | `Request(List)` | `dfx-orbit review list` | +| Request/Read | Not Shown | `Request(Read(Id` | `dfx-orbit review id REQUEST_ID` | TODO: It would be nice to be able to link directly to a permission. E.g. this could open the permissions page and focus on one specific permission: https://orbitwallet.io/en/settings/user-groups/permissions#Request/List From 92e61e4c73520eb4ab9398b25deaae3ff1b2a8e7 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 12:35:17 +0200 Subject: [PATCH 154/156] refactor (cli): canister change into a separate file --- .../src/args/request/permission/canister.rs | 53 ++----------------- .../request/permission/canister/change.rs | 49 +++++++++++++++++ 2 files changed, 54 insertions(+), 48 deletions(-) create mode 100644 tools/dfx-orbit/src/args/request/permission/canister/change.rs diff --git a/tools/dfx-orbit/src/args/request/permission/canister.rs b/tools/dfx-orbit/src/args/request/permission/canister.rs index 8fcade636..931abb245 100644 --- a/tools/dfx-orbit/src/args/request/permission/canister.rs +++ b/tools/dfx-orbit/src/args/request/permission/canister.rs @@ -1,5 +1,7 @@ -//! Makes `EditPermission` requests regarding `ExternalCanister` to Orbit. -use clap::{Parser, Subcommand}; +//! Arguments for `dfx-orbit request permission canister`. +pub mod change; + +use clap::Subcommand; use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; @@ -8,7 +10,7 @@ use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent} #[command(version, about, long_about = None)] pub enum Args { /// Request changes to canister permissions. - Change(ChangeCanister), + Change(change::Args), } impl CreateRequestArgs for Args { @@ -22,48 +24,3 @@ impl CreateRequestArgs for Args { } } } - -/// Requests the privilige of proposing canister upgrades. -#[derive(Debug, Parser)] -pub struct ChangeCanister { - /// Canister name or ID. - // TODO: If a canister is not specified, require --all. - #[structopt(long)] - pub canister: Option, -} - -impl CreateRequestArgs for ChangeCanister { - /// Converts the CLI arg type into the equivalent Orbit API type. - fn into_create_request_input( - self, - station_agent: &StationAgent, - ) -> anyhow::Result { - let canisters: anyhow::Result = - if let Some(canister_name_or_id) = self.canister { - station_agent - .canister_id(&canister_name_or_id) - .map(orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister) - } else { - Ok(orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Any) - }; - - let resource = orbit_station_api::ResourceDTO::ExternalCanister( - orbit_station_api::ExternalCanisterResourceActionDTO::Change(canisters?), - ); - - let operation = orbit_station_api::RequestOperationInput::EditPermission( - orbit_station_api::EditPermissionOperationInput { - resource, - auth_scope: None, - users: None, - user_groups: None, - }, - ); - Ok(orbit_station_api::CreateRequestInput { - operation, - title: None, - summary: None, - execution_plan: None, - }) - } -} diff --git a/tools/dfx-orbit/src/args/request/permission/canister/change.rs b/tools/dfx-orbit/src/args/request/permission/canister/change.rs new file mode 100644 index 000000000..0d1557ede --- /dev/null +++ b/tools/dfx-orbit/src/args/request/permission/canister/change.rs @@ -0,0 +1,49 @@ +//! Arguments for `dfx-orbit request permission canister change`. +use clap::Parser; + +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; + +/// Requests the privilige of proposing canister upgrades. +#[derive(Debug, Parser)] +pub struct Args { + /// Canister name or ID. + // TODO: If a canister is not specified, require --all. + #[structopt(long)] + pub canister: Option, +} + +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { + let canisters: anyhow::Result = + if let Some(canister_name_or_id) = self.canister { + station_agent + .canister_id(&canister_name_or_id) + .map(orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Canister) + } else { + Ok(orbit_station_api::ChangeExternalCanisterResourceTargetDTO::Any) + }; + + let resource = orbit_station_api::ResourceDTO::ExternalCanister( + orbit_station_api::ExternalCanisterResourceActionDTO::Change(canisters?), + ); + + let operation = orbit_station_api::RequestOperationInput::EditPermission( + orbit_station_api::EditPermissionOperationInput { + resource, + auth_scope: None, + users: None, + user_groups: None, + }, + ); + Ok(orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + }) + } +} From 727b8db34aeb6599c979cdc13e06c9a9ff496bce Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 15:14:09 +0200 Subject: [PATCH 155/156] More commands to manage permissions --- .../dfx-orbit/src/args/request/permission.rs | 8 ++++ .../src/args/request/permission/permission.rs | 33 +++++++++++++ .../request/permission/permission/read.rs | 46 +++++++++++++++++++ .../request/permission/permission/update.rs | 46 +++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 tools/dfx-orbit/src/args/request/permission/permission.rs create mode 100644 tools/dfx-orbit/src/args/request/permission/permission/read.rs create mode 100644 tools/dfx-orbit/src/args/request/permission/permission/update.rs diff --git a/tools/dfx-orbit/src/args/request/permission.rs b/tools/dfx-orbit/src/args/request/permission.rs index 25918970b..a1caa0516 100644 --- a/tools/dfx-orbit/src/args/request/permission.rs +++ b/tools/dfx-orbit/src/args/request/permission.rs @@ -1,5 +1,7 @@ //! Makes `EditPermission` requests to Orbit. pub mod canister; +#[allow(clippy::module_inception)] +pub mod permission; use clap::Subcommand; @@ -11,6 +13,9 @@ use super::CreateRequestArgs; #[derive(Debug, Subcommand)] #[command(version, about, long_about = None)] pub enum Args { + /// Request permission to create requests. + #[command(subcommand)] + Permission(permission::Args), /// Request changes to canister permissions. #[command(subcommand)] Canister(canister::Args), @@ -24,6 +29,9 @@ impl CreateRequestArgs for Args { ) -> anyhow::Result { match self { Args::Canister(canister_args) => canister_args.into_create_request_input(station_agent), + Args::Permission(permission_args) => { + permission_args.into_create_request_input(station_agent) + } } } } diff --git a/tools/dfx-orbit/src/args/request/permission/permission.rs b/tools/dfx-orbit/src/args/request/permission/permission.rs new file mode 100644 index 000000000..5ad3db917 --- /dev/null +++ b/tools/dfx-orbit/src/args/request/permission/permission.rs @@ -0,0 +1,33 @@ +//! Arguments for `dfx-orbit request permission permission`. +pub mod read; +pub mod update; + +use clap::Subcommand; +use orbit_station_api::CreateRequestInput; + +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; + +/// Request canister changes. +/// +// TODO: Add flags for --title, --summary, and --execution-plan. +// Note: I have looked at the docs and the anwer for how to do this really doesn't jump out at me. Google foo failed as well. Maybe the sdk repo has some examples. +#[derive(Debug, Subcommand)] +#[command(version, about, long_about = None)] +pub enum Args { + /// Request permission to update permissions. + Update(update::Args), + /// Request permission to read permissions. + Read(read::Args), +} + +impl CreateRequestArgs for Args { + fn into_create_request_input( + self, + station_agent: &StationAgent, + ) -> anyhow::Result { + match self { + Args::Read(read_args) => read_args.into_create_request_input(station_agent), + Args::Update(update_args) => update_args.into_create_request_input(station_agent), + } + } +} diff --git a/tools/dfx-orbit/src/args/request/permission/permission/read.rs b/tools/dfx-orbit/src/args/request/permission/permission/read.rs new file mode 100644 index 000000000..a3ec19952 --- /dev/null +++ b/tools/dfx-orbit/src/args/request/permission/permission/read.rs @@ -0,0 +1,46 @@ +//! Arguments for `dfx-orbit request permission permission read`. +use clap::Parser; +use orbit_station_api::PermissionResourceActionDTO; + +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; + +/// Requests the privilige of proposing canister upgrades. +#[derive(Debug, Parser)] +pub struct Args { + /// A users that should be permitted to change permissions. WARNING: Any user that is not listed will lose the ability to change permissions. + #[structopt(long)] + pub user: Vec, + /// A groups that should be permitted to change permissions. WARNING: Any group that is not listed will lose the ability to change permissions. + #[structopt(long)] + pub group: Vec, +} + +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + _station_agent: &StationAgent, + ) -> anyhow::Result { + let Args { + user: users, + group: user_groups, + } = self; + + let operation = orbit_station_api::RequestOperationInput::EditPermission( + orbit_station_api::EditPermissionOperationInput { + resource: orbit_station_api::ResourceDTO::Permission( + PermissionResourceActionDTO::Read, + ), + auth_scope: None, + users: Some(users), + user_groups: Some(user_groups), + }, + ); + Ok(orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + }) + } +} diff --git a/tools/dfx-orbit/src/args/request/permission/permission/update.rs b/tools/dfx-orbit/src/args/request/permission/permission/update.rs new file mode 100644 index 000000000..977c949b6 --- /dev/null +++ b/tools/dfx-orbit/src/args/request/permission/permission/update.rs @@ -0,0 +1,46 @@ +//! Arguments for `dfx-orbit request permission permission update`. +use clap::Parser; +use orbit_station_api::PermissionResourceActionDTO; + +use crate::{args::request::CreateRequestArgs, orbit_station_agent::StationAgent}; + +/// Requests the privilige of proposing canister upgrades. +#[derive(Debug, Parser)] +pub struct Args { + /// A users that should be permitted to change permissions. WARNING: Any user that is not listed will lose the ability to change permissions. + #[structopt(long)] + pub user: Vec, + /// A groups that should be permitted to change permissions. WARNING: Any group that is not listed will lose the ability to change permissions. + #[structopt(long)] + pub group: Vec, +} + +impl CreateRequestArgs for Args { + /// Converts the CLI arg type into the equivalent Orbit API type. + fn into_create_request_input( + self, + _station_agent: &StationAgent, + ) -> anyhow::Result { + let Args { + user: users, + group: user_groups, + } = self; + + let operation = orbit_station_api::RequestOperationInput::EditPermission( + orbit_station_api::EditPermissionOperationInput { + resource: orbit_station_api::ResourceDTO::Permission( + PermissionResourceActionDTO::Update, + ), + auth_scope: None, + users: Some(users), + user_groups: Some(user_groups), + }, + ); + Ok(orbit_station_api::CreateRequestInput { + operation, + title: None, + summary: None, + execution_plan: None, + }) + } +} From 6805b524bc869394456a5c2efc545497cb8e5043 Mon Sep 17 00:00:00 2001 From: Max Murphy Date: Thu, 4 Jul 2024 15:24:59 +0200 Subject: [PATCH 156/156] docs++ --- CLI.md | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/CLI.md b/CLI.md index 412c2ae0e..9fe47e529 100644 --- a/CLI.md +++ b/CLI.md @@ -90,6 +90,13 @@ TODO: It would be nice to be able to link directly to a permission. E.g. this ## Make canister calls with Orbit +Instead of using `dfx canister call CANISTER METHOD ARGUMENTS` use `dfx-orbit request canister call CANISTER METHOD ARGUMENTS`. + +For example, asset canisters have the methods `list_authorized` and `list_permitted`. You should be able to make these canister calls directly or via Orbit: +``` +dfx canister call frontend list_authorized +dfx-orbit request canister call frontend list_authorized +``` ## Control a canister with Orbit @@ -111,7 +118,8 @@ Verify that Orbit has been added as a controller: dfx canister info MY_CANISTER --network MY_CANISTER_NETWORK ``` -### Register yourself as a developer for your canister +### Upgrade canisters +#### Request permission to make upgrade requests This will allow you to propose upgrades to `MY_CANISTER`: ``` @@ -121,16 +129,16 @@ This will create an Orbit request. Once approved you will be able to propose ca > :warning: **The Orbit GUI does not currently show this proposal unless you enter the proposal URL directly, under /en/settings/requests?reqid=THE_ID** -### Upgrade a canister +#### Request a canister upgrade Suppose that you have built a new Wasm and put a copy at `./MY-CANISTER.wasm.gz`. To upgrade your canister to the new Wasm: ``` dfx-orbit request canister change wasm --canister MY_CANISTER --mode upgrade --wasm ./MY-CANISTER.wasm.gz ``` -## Upload assets to a canister +### Upload assets to a canister We will assume that Orbit is a controller of the asset canister. If not, please adapt the following commands by using `dfx canister call` instead of `dfx-orbit request canister call`. -### Authorize the developer to upload assets +#### Authorize the developer to upload assets Note: Uploaded assets are not published. They are only prepared for release. ``` developer_principal="$(dfx identity get-principal)" @@ -148,7 +156,7 @@ When the request has been approved, check the list of principals permitted to pr dfx canister call frontend list_permitted '(record { permission = variant { Prepare } })' ``` -### Authorize the orbit station to commit assets +#### Authorize the orbit station to commit assets Note: Committing uploaded assets causes them to be published on the asset canister web site. ``` station_principal="$(dfx-orbit station show | jq -r .station_id)" @@ -166,7 +174,7 @@ When the request has been approved, check the list of principals permitted to co dfx canister call frontend list_permitted '(record { permission = variant { Commit } })' ``` -### Upload assets +#### Request an asset update A developer may upload one or more directories of HTTP assets with: ``` dfx-orbit canister upload-http-assets --canister CANISTER_NAME --source SOME_DIR/ --source OTHER_DIR/