From 89228ae1e11261329ea6d00aa9803470499cd2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C8=99u?= Date: Tue, 5 Sep 2023 22:16:03 +0300 Subject: [PATCH] Catch and emit event in backend for URL opening The JS part of listening to that event is still not working, probably due to some window init race. Needs to be investigated more. --- .../commands/src/coconut/issue_credentials.rs | 6 +- nym-connect/desktop/Cargo.lock | 424 +++++++++++++++++- nym-connect/desktop/src-tauri/Cargo.toml | 3 + nym-connect/desktop/src-tauri/Info.plist | 20 + .../desktop/src-tauri/src/deep_links.rs | 39 ++ nym-connect/desktop/src-tauri/src/error.rs | 21 + nym-connect/desktop/src-tauri/src/main.rs | 25 +- .../src/operations/connection/connect.rs | 3 +- nym-connect/desktop/src/context/main.tsx | 34 +- nym-connect/desktop/src/hooks/events.ts | 9 + .../desktop/src/pages/connection/index.tsx | 2 +- 11 files changed, 553 insertions(+), 33 deletions(-) create mode 100644 nym-connect/desktop/src-tauri/Info.plist create mode 100644 nym-connect/desktop/src-tauri/src/deep_links.rs diff --git a/common/commands/src/coconut/issue_credentials.rs b/common/commands/src/coconut/issue_credentials.rs index cd8a9b5f36..9897d44ab7 100644 --- a/common/commands/src/coconut/issue_credentials.rs +++ b/common/commands/src/coconut/issue_credentials.rs @@ -14,15 +14,15 @@ use std::path::PathBuf; pub struct Args { /// Config file of the client that is supposed to use the credential. #[clap(long)] - pub(crate) client_config: PathBuf, + pub client_config: PathBuf, /// The amount of utokens the credential will hold. #[clap(long, default_value = "0")] - pub(crate) amount: u64, + pub amount: u64, /// Path to a directory used to store recovery files for unconsumed deposits #[clap(long)] - pub(crate) recovery_dir: PathBuf, + pub recovery_dir: PathBuf, } pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index e7c60df056..845fba9979 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -242,7 +242,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" dependencies = [ "async-lock", - "autocfg", + "autocfg 1.1.0", "blocking", "futures-lite", ] @@ -254,7 +254,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" dependencies = [ "async-lock", - "autocfg", + "autocfg 1.1.0", "cfg-if", "concurrent-queue", "futures-lite", @@ -284,7 +284,7 @@ checksum = "7a9d28b1d97e08915212e2e45310d47854eafa69600756fc735fb788f75199c9" dependencies = [ "async-io", "async-lock", - "autocfg", + "autocfg 1.1.0", "blocking", "cfg-if", "event-listener", @@ -381,6 +381,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.1.0", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -894,6 +903,15 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2da6da31387c7e4ef160ffab6d5e7f00c42626fe39aea70a7b0f1773f7dd6c1b" +[[package]] +name = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "cocoa" version = "0.24.1" @@ -969,6 +987,18 @@ dependencies = [ "memchr", ] +[[package]] +name = "comfy-table" +version = "6.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e959d788268e3bf9d35ace83e81b124190378e4c91c9067524675e33394b8ba" +dependencies = [ + "crossterm", + "strum 0.24.1", + "strum_macros 0.24.3", + "unicode-width", +] + [[package]] name = "concurrent-queue" version = "2.2.0" @@ -1209,7 +1239,7 @@ version = "0.9.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae211234986c545741a7dc064309f67ee1e5ad243d0e48335adc0484d960bcc7" dependencies = [ - "autocfg", + "autocfg 1.1.0", "cfg-if", "crossbeam-utils", "memoffset 0.9.0", @@ -1235,6 +1265,31 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossterm" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84cda67535339806297f1b331d6dd6320470d2a0fe65381e79ee9e156dd3d13" +dependencies = [ + "bitflags 1.3.2", + "crossterm_winapi", + "libc", + "mio", + "parking_lot 0.12.1", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + [[package]] name = "crypto-bigint" version = "0.4.9" @@ -2166,6 +2221,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" +[[package]] +name = "fuchsia-cprng" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" + [[package]] name = "funty" version = "2.0.0" @@ -3143,7 +3204,7 @@ version = "1.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ - "autocfg", + "autocfg 1.1.0", "hashbrown 0.12.3", "serde", ] @@ -3195,6 +3256,19 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "interprocess" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81f2533f3be42fffe3b5e63b71aeca416c1c3bc33e4e27be018521e76b1f38fb" +dependencies = [ + "cfg-if", + "libc", + "rustc_version", + "to_method", + "winapi", +] + [[package]] name = "io-lifetimes" version = "1.0.11" @@ -3493,7 +3567,7 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16" dependencies = [ - "autocfg", + "autocfg 1.1.0", "scopeguard", ] @@ -3596,7 +3670,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -3605,7 +3679,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -3643,6 +3717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", + "log", "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] @@ -3768,7 +3843,7 @@ version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" dependencies = [ - "autocfg", + "autocfg 1.1.0", "num-traits", ] @@ -3778,7 +3853,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" dependencies = [ - "autocfg", + "autocfg 1.1.0", "num-integer", "num-traits", ] @@ -3789,7 +3864,7 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" dependencies = [ - "autocfg", + "autocfg 1.1.0", "libm", ] @@ -3875,9 +3950,59 @@ dependencies = [ "pretty_env_logger", "semver 0.11.0", "serde", + "serde_json", "vergen", ] +[[package]] +name = "nym-cli-commands" +version = "1.0.0" +dependencies = [ + "anyhow", + "base64 0.13.1", + "bip39", + "bs58 0.4.0", + "cfg-if", + "clap", + "comfy-table", + "cosmrs", + "cosmwasm-std", + "cw-utils", + "handlebars", + "humantime-serde", + "k256 0.13.1", + "log", + "nym-bandwidth-controller", + "nym-bin-common", + "nym-client-core", + "nym-coconut-bandwidth-contract-common", + "nym-coconut-dkg-common", + "nym-config", + "nym-contracts-common", + "nym-credential-storage", + "nym-credential-utils", + "nym-credentials", + "nym-crypto", + "nym-mixnet-contract-common", + "nym-multisig-contract-common", + "nym-name-service-common", + "nym-network-defaults", + "nym-pemstore", + "nym-service-provider-directory-common", + "nym-sphinx", + "nym-types", + "nym-validator-client", + "nym-vesting-contract-common", + "rand 0.6.5", + "serde", + "serde_json", + "tap", + "thiserror", + "time", + "toml 0.5.11", + "url", +] + [[package]] name = "nym-client-core" version = "1.1.15" @@ -3996,6 +4121,7 @@ version = "1.1.19" dependencies = [ "anyhow", "bip39", + "bs58 0.4.0", "dirs 4.0.0", "dotenvy", "eyre", @@ -4006,6 +4132,7 @@ dependencies = [ "log", "nym-api-requests", "nym-bin-common", + "nym-cli-commands", "nym-client-core", "nym-config", "nym-contracts-common", @@ -4031,6 +4158,7 @@ dependencies = [ "tauri-build", "tauri-codegen", "tauri-macros", + "tauri-plugin-deep-link", "tempfile", "thiserror", "time", @@ -4064,6 +4192,21 @@ dependencies = [ "tokio", ] +[[package]] +name = "nym-credential-utils" +version = "0.1.0" +dependencies = [ + "log", + "nym-bandwidth-controller", + "nym-client-core", + "nym-config", + "nym-credential-storage", + "nym-credentials", + "nym-validator-client", + "thiserror", + "tokio", +] + [[package]] name = "nym-credentials" version = "0.1.0" @@ -4578,6 +4721,30 @@ dependencies = [ "thiserror", ] +[[package]] +name = "nym-types" +version = "1.0.0" +dependencies = [ + "cosmrs", + "cosmwasm-std", + "eyre", + "itertools", + "log", + "nym-coconut-interface", + "nym-config", + "nym-mixnet-contract-common", + "nym-validator-client", + "nym-vesting-contract-common", + "reqwest", + "schemars", + "serde", + "serde_json", + "strum 0.23.0", + "thiserror", + "ts-rs", + "url", +] + [[package]] name = "nym-validator-client" version = "0.1.0" @@ -4659,6 +4826,28 @@ dependencies = [ "objc_id", ] +[[package]] +name = "objc-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e1d07c6eab1ce8b6382b8e3c7246fe117ff3f8b34be065f5ebace6749fe845" + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + [[package]] name = "objc_exception" version = "0.1.2" @@ -5197,7 +5386,7 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ - "autocfg", + "autocfg 1.1.0", "bitflags 1.3.2", "cfg-if", "concurrent-queue", @@ -5366,6 +5555,25 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" +[[package]] +name = "rand" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" +dependencies = [ + "autocfg 0.1.8", + "libc", + "rand_chacha 0.1.1", + "rand_core 0.4.2", + "rand_hc 0.1.0", + "rand_isaac", + "rand_jitter", + "rand_os", + "rand_pcg 0.1.2", + "rand_xorshift", + "winapi", +] + [[package]] name = "rand" version = "0.7.3" @@ -5376,8 +5584,8 @@ dependencies = [ "libc", "rand_chacha 0.2.2", "rand_core 0.5.1", - "rand_hc", - "rand_pcg", + "rand_hc 0.2.0", + "rand_pcg 0.2.1", ] [[package]] @@ -5391,6 +5599,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.3.1", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -5411,6 +5629,21 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_core" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" +dependencies = [ + "rand_core 0.4.2", +] + +[[package]] +name = "rand_core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" + [[package]] name = "rand_core" version = "0.5.1" @@ -5439,6 +5672,15 @@ dependencies = [ "rand 0.7.3", ] +[[package]] +name = "rand_hc" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -5448,6 +5690,50 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_isaac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" +dependencies = [ + "rand_core 0.3.1", +] + +[[package]] +name = "rand_jitter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" +dependencies = [ + "libc", + "rand_core 0.4.2", + "winapi", +] + +[[package]] +name = "rand_os" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" +dependencies = [ + "cloudabi", + "fuchsia-cprng", + "libc", + "rand_core 0.4.2", + "rdrand", + "winapi", +] + +[[package]] +name = "rand_pcg" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" +dependencies = [ + "autocfg 0.1.8", + "rand_core 0.4.2", +] + [[package]] name = "rand_pcg" version = "0.2.1" @@ -5457,6 +5743,15 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "rand_xorshift" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "raw-window-handle" version = "0.5.2" @@ -5485,6 +5780,15 @@ dependencies = [ "num_cpus", ] +[[package]] +name = "rdrand" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" +dependencies = [ + "rand_core 0.3.1", +] + [[package]] name = "redox_syscall" version = "0.2.16" @@ -6331,6 +6635,17 @@ dependencies = [ "signal-hook-registry", ] +[[package]] +name = "signal-hook-mio" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -6378,7 +6693,7 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6528351c9bc8ab22353f9d776db39a20288e8d6c37ef8cfe3317cf875eecfc2d" dependencies = [ - "autocfg", + "autocfg 1.1.0", ] [[package]] @@ -6759,6 +7074,47 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "strum" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cae14b91c7d11c9a851d3fbc80a963198998c2a64eec840477fa92d8ce9b70bb" +dependencies = [ + "strum_macros 0.23.1", +] + +[[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.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb0dc7ee9c15cea6199cde9a127fa16a4c5819af85395457ad72d68edc85a38" +dependencies = [ + "heck 0.3.3", + "proc-macro2", + "quote", + "rustversion", + "syn 1.0.109", +] + +[[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 = "1.0.0" @@ -7029,6 +7385,22 @@ dependencies = [ "tauri-utils", ] +[[package]] +name = "tauri-plugin-deep-link" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4536f5f6602e8fdfaa7b3b185076c2a0704f8eb7015f4e58461eb483ec3ed1f8" +dependencies = [ + "dirs 5.0.1", + "interprocess", + "log", + "objc2", + "once_cell", + "tauri-utils", + "windows-sys 0.48.0", + "winreg 0.50.0", +] + [[package]] name = "tauri-runtime" version = "0.14.0" @@ -7332,6 +7704,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "to_method" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" + [[package]] name = "tokio" version = "1.31.0" @@ -7672,6 +8050,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + [[package]] name = "unicode_categories" version = "0.1.1" @@ -8421,6 +8805,16 @@ dependencies = [ "winapi", ] +[[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 = "wry" version = "0.24.3" diff --git a/nym-connect/desktop/src-tauri/Cargo.toml b/nym-connect/desktop/src-tauri/Cargo.toml index 133b94a921..e15bec079e 100644 --- a/nym-connect/desktop/src-tauri/Cargo.toml +++ b/nym-connect/desktop/src-tauri/Cargo.toml @@ -21,6 +21,7 @@ tauri-macros = "^1.2.1" [dependencies] anyhow = "1.0" bip39 = { version = "2.0.0", features = ["zeroize"] } +bs58 = "0.4" dirs = "4.0" eyre = "0.6.5" fix-path-env = { git = "https://github.com/tauri-apps/fix-path-env-rs", branch = "release"} @@ -38,6 +39,7 @@ serde_json = "1.0" serde_repr = "0.1" tap = "1.0.1" tauri = { version = "^1.2.2", features = ["clipboard-write-text", "macos-private-api", "notification-all", "shell-open", "system-tray", "updater", "window-close", "window-minimize", "window-start-dragging"] } +tauri-plugin-deep-link = "0.1.1" #tendermint-rpc = "0.23.0" thiserror = "1.0" time = { version = "0.3.17", features = ["local-offset"] } @@ -51,6 +53,7 @@ dotenvy = "0.15.7" nym-client-core = { path = "../../../common/client-core" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } +nym-cli-commands = { path = "../../../common/commands" } nym-contracts-common = { path = "../../../common/cosmwasm-smart-contracts/contracts-common"} nym-config = { path = "../../../common/config" } nym-crypto = { path = "../../../common/crypto" } diff --git a/nym-connect/desktop/src-tauri/Info.plist b/nym-connect/desktop/src-tauri/Info.plist new file mode 100644 index 0000000000..30c5d757da --- /dev/null +++ b/nym-connect/desktop/src-tauri/Info.plist @@ -0,0 +1,20 @@ + + + + + + CFBundleURLTypes + + + CFBundleURLName + + net.nymtech.connect + CFBundleURLSchemes + + + nym-connect + + + + + diff --git a/nym-connect/desktop/src-tauri/src/deep_links.rs b/nym-connect/desktop/src-tauri/src/deep_links.rs new file mode 100644 index 0000000000..0308cd2631 --- /dev/null +++ b/nym-connect/desktop/src-tauri/src/deep_links.rs @@ -0,0 +1,39 @@ +// Copyright 2023 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::{BackendError, Result}; +use bip39::Mnemonic; +use nym_cli_commands::coconut::issue_credentials::Args as CoconutArgs; +use nym_cli_commands::context::{create_signing_client, get_network_details, ClientArgs}; +use std::path::PathBuf; +use url::Url; + +pub async fn handle_url(url: &str) -> Result<()> { + let url = Url::parse(url)?; + if url.scheme() != env!("CARGO_PKG_NAME") { + return Err(BackendError::InvalidURLScheme { + scheme: url.scheme().to_string(), + }); + } + let bytes = bs58::decode(url.path()).into_vec()?; + let mnemonic = Mnemonic::from_entropy(&bytes)?; + + let args = ClientArgs { + config_env_file: None, + nyxd_url: None, + nym_api_url: None, + mnemonic: Some(mnemonic), + mixnet_contract_address: None, + vesting_contract_address: None, + }; + let network_details = get_network_details(&args)?; + let client = create_signing_client(args, &network_details)?; + let coconut_args = CoconutArgs { + client_config: Default::default(), + amount: 10, + recovery_dir: PathBuf::default(), + }; + nym_cli_commands::coconut::issue_credentials::execute(coconut_args, client).await?; + + Ok(()) +} diff --git a/nym-connect/desktop/src-tauri/src/error.rs b/nym-connect/desktop/src-tauri/src/error.rs index a6290280c3..68458e0a38 100644 --- a/nym-connect/desktop/src-tauri/src/error.rs +++ b/nym-connect/desktop/src-tauri/src/error.rs @@ -111,6 +111,27 @@ pub enum BackendError { url: reqwest::Url, status_code: reqwest::StatusCode, }, + + #[error("the URL provided has an unrecognized scheme: {scheme}")] + InvalidURLScheme { scheme: String }, + + #[error("{source}")] + BS58DecodeError { + #[from] + source: bs58::decode::Error, + }, + + #[error("{source}")] + Bip39Error { + #[from] + source: bip39::Error, + }, + + #[error("{source}")] + ContextError { + #[from] + source: nym_cli_commands::context::errors::ContextError, + }, } impl Serialize for BackendError { diff --git a/nym-connect/desktop/src-tauri/src/main.rs b/nym-connect/desktop/src-tauri/src/main.rs index 684c641446..29ccf42a46 100644 --- a/nym-connect/desktop/src-tauri/src/main.rs +++ b/nym-connect/desktop/src-tauri/src/main.rs @@ -18,6 +18,7 @@ use crate::window::window_toggle; mod config; mod constants; +// mod deep_links; mod error; mod events; mod logging; @@ -30,6 +31,7 @@ mod tasks; mod window; fn main() { + tauri_plugin_deep_link::prepare("nym-connect"); dotenvy::dotenv().ok(); setup_env(env::args().nth(1).map(PathBuf::from).as_ref()); @@ -112,7 +114,28 @@ fn main() { ); } }) - .setup(move |app| Ok(crate::logging::setup_logging(app.app_handle(), monitoring)?)) + .setup(move |app| { + let handle = app.handle(); + tauri_plugin_deep_link::register(env!("CARGO_PKG_NAME"), move |request| { + let window = handle.windows(); + log::info!("Windows: {:?}", window.keys()); + if let Err(err) = window.emit("scheme-request-received", request) { + log::error!("Failed to emit tauri event: {err}"); + } + }) + .unwrap(); + + // If you also need the url when the primary instance was started by the custom scheme, you currently have to read it yourself + #[cfg(not(target_os = "macos"))] + // on macos the plugin handles this (macos doesn't use cli args for the url) + if let Some(arg) = env::args().nth(1) { + if let Err(e) = deep_links::handle_url(&arg) { + log::error!("Could not handle URL {}: {:?}", request, e); + } + } + + Ok(crate::logging::setup_logging(app.app_handle(), monitoring)?) + }) .system_tray(create_tray_menu()) .on_system_tray_event(tray_menu_event_handler) .run(context) diff --git a/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs b/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs index 95a125fa30..2589085fae 100644 --- a/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs +++ b/nym-connect/desktop/src-tauri/src/operations/connection/connect.rs @@ -8,10 +8,11 @@ use tokio::sync::RwLock; #[tauri::command] pub async fn start_connecting( + coconut_enabled: bool, state: tauri::State<'_, Arc>>, window: tauri::Window, ) -> Result { - log::trace!("Start connecting"); + log::info!("Start connecting with coconut enabled: {}", coconut_enabled); let (msg_receiver, exit_status_receiver) = { let mut state_w = state.write().await; diff --git a/nym-connect/desktop/src/context/main.tsx b/nym-connect/desktop/src/context/main.tsx index 2f553b5153..bb6a45a80a 100644 --- a/nym-connect/desktop/src/context/main.tsx +++ b/nym-connect/desktop/src/context/main.tsx @@ -38,7 +38,7 @@ export type TClientContext = { setShowInfoModal: (show: boolean) => void; setServiceProvider: () => void; setGateway: () => void; - startConnecting: () => Promise; + startConnecting: (coconut_enabled: boolean) => Promise; startDisconnecting: () => Promise; setUserDefinedGateway: React.Dispatch>; setUserDefinedSPAddress: React.Dispatch>; @@ -139,15 +139,6 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { setGateways(fetchedGateways); }; - useEvents({ - onError: (e) => { - setError(e); - Sentry.captureException(e); - }, - onGatewayPerformanceChange: (performance) => setGatewayPerformance(performance), - onStatusChange: (status) => setConnectionStatus(status), - }); - useEffect(() => { initialiseApp(); }, []); @@ -160,9 +151,9 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { })(); }, []); - const startConnecting = useCallback(async () => { + const startConnecting = useCallback(async (value: boolean) => { try { - await invoke('start_connecting'); + await invoke('start_connecting', { coconutEnabled: value }); } catch (e) { setError({ title: 'Could not connect', message: e as string }); console.log(e); @@ -243,6 +234,25 @@ export const ClientContextProvider: FCWithChildren = ({ children }) => { await getUserData(); }; + const handleSchemeRequest = async () => { + if (connectionStatus === 'disconnected') { + await setServiceProvider(); + await setGateway(); + await startConnecting(true); + setConnectedSince(DateTime.now()); + } + }; + + useEvents({ + onError: (e) => { + setError(e); + Sentry.captureException(e); + }, + onGatewayPerformanceChange: (performance) => setGatewayPerformance(performance), + onStatusChange: (status) => setConnectionStatus(status), + onSchemeRequest: handleSchemeRequest, + }); + const contextValue = useMemo( () => ({ mode, diff --git a/nym-connect/desktop/src/hooks/events.ts b/nym-connect/desktop/src/hooks/events.ts index 0b15e5347d..9dc5250f94 100644 --- a/nym-connect/desktop/src/hooks/events.ts +++ b/nym-connect/desktop/src/hooks/events.ts @@ -11,10 +11,12 @@ export const useEvents = ({ onError, onStatusChange, onGatewayPerformanceChange, + onSchemeRequest, }: { onError: (error: Error) => void; onStatusChange: (status: ConnectionStatusKind) => void; onGatewayPerformanceChange: (status: GatewayPerformance) => void; + onSchemeRequest: () => Promise; }) => { const timerId = useRef(); @@ -65,6 +67,13 @@ export const useEvents = ({ unlisten.push(result); }); + listen('scheme-request-received', (e: TauriEvent) => { + console.log(e); + onSchemeRequest(); + }).then((result) => { + unlisten.push(result); + }); + return () => { unlisten.forEach((unsubscribe) => unsubscribe()); }; diff --git a/nym-connect/desktop/src/pages/connection/index.tsx b/nym-connect/desktop/src/pages/connection/index.tsx index 725bfb23de..7bf7cd7144 100644 --- a/nym-connect/desktop/src/pages/connection/index.tsx +++ b/nym-connect/desktop/src/pages/connection/index.tsx @@ -19,7 +19,7 @@ export const ConnectionPage = () => { Sentry.captureMessage('start connect', 'info'); await context.setServiceProvider(); await context.setGateway(); - await context.startConnecting(); + await context.startConnecting(false); context.setConnectedSince(DateTime.now()); context.setShowInfoModal(true); break;