From 9100780122d3497e372f30cecf11e6c952e4f64d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 9 Sep 2024 11:55:28 +0100 Subject: [PATCH 001/125] init, start walletconnect client impl --- .cargo/config.toml | 4 +- Cargo.lock | 928 +++++++++++++------- Cargo.toml | 1 + mm2src/coins/Cargo.toml | 30 +- mm2src/crypto/Cargo.toml | 3 + mm2src/kdf_walletconnect/Cargo.toml | 24 + mm2src/kdf_walletconnect/src/handler.rs | 58 ++ mm2src/kdf_walletconnect/src/lib.rs | 60 ++ mm2src/kdf_walletconnect/src/session_key.rs | 73 ++ mm2src/mm2_main/Cargo.toml | 27 +- mm2src/mm2_number/Cargo.toml | 2 +- 11 files changed, 886 insertions(+), 324 deletions(-) create mode 100644 mm2src/kdf_walletconnect/Cargo.toml create mode 100644 mm2src/kdf_walletconnect/src/handler.rs create mode 100644 mm2src/kdf_walletconnect/src/lib.rs create mode 100644 mm2src/kdf_walletconnect/src/session_key.rs diff --git a/.cargo/config.toml b/.cargo/config.toml index 5704896780..1bbbfea3c5 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,7 +2,7 @@ JEMALLOC_SYS_WITH_MALLOC_CONF = "background_thread:true,narenas:1,tcache:false,dirty_decay_ms:0,muzzy_decay_ms:0,metadata_thp:auto" [target.'cfg(all())'] -rustflags = [ "-Zshare-generics=y" ] +rustflags = ["-Zshare-generics=y", '--cfg=curve25519_dalek_backend="fiat"'] # # Install lld using package manager # [target.x86_64-unknown-linux-gnu] @@ -24,4 +24,4 @@ rustflags = [ "-Zshare-generics=y" ] [target.wasm32-unknown-unknown] runner = 'wasm-bindgen-test-runner' -rustflags = [ "--cfg=web_sys_unstable_apis" ] +rustflags = ["--cfg=web_sys_unstable_apis"] diff --git a/Cargo.lock b/Cargo.lock index 431959e5c5..47667aea98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -35,25 +35,14 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" [[package]] name = "aead" -version = "0.4.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "922b33332f54fc0ad13fa3e514601e8d30fb54e1f3eadc36643f6526db645621" +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 1.0.0", - "cipher 0.3.0", - "cpufeatures 0.2.11", - "opaque-debug", -] - [[package]] name = "aes" version = "0.8.3" @@ -61,19 +50,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" dependencies = [ "cfg-if 1.0.0", - "cipher 0.4.4", - "cpufeatures 0.2.11", + "cipher", + "cpufeatures", ] [[package]] name = "aes-gcm" -version = "0.9.2" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc3be92e19a7ef47457b8e6f90707e12b6ac5d20c6f3866584fa3be0787d839f" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", - "aes 0.7.5", - "cipher 0.3.0", + "aes", + "cipher", "ctr", "ghash", "subtle", @@ -145,9 +134,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.42" +version = "1.0.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "595d3cfa7a60d4555cb5067b99f07142a08ea778de5cf993f7b75c7d8fabc486" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" [[package]] name = "argon2" @@ -157,7 +146,7 @@ checksum = "17ba4cac0a46bc1d2912652a751c47f2a9f3a7fe89bcae2275d418f5270402f9" dependencies = [ "base64ct", "blake2", - "cpufeatures 0.2.11", + "cpufeatures", "password-hash", "zeroize", ] @@ -261,8 +250,8 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -278,9 +267,9 @@ version = "0.1.76" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -327,7 +316,7 @@ checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" dependencies = [ "async-trait", "axum-core", - "bitflags", + "bitflags 1.3.2", "bytes 1.4.0", "futures-util", "http 0.2.12", @@ -533,7 +522,7 @@ dependencies = [ "ripemd160", "serialization", "sha-1", - "sha2 0.10.7", + "sha2 0.10.8", "sha3 0.9.1", "siphasher", ] @@ -544,6 +533,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + [[package]] name = "bitvec" version = "0.18.5" @@ -714,7 +709,7 @@ dependencies = [ "borsh-derive-internal", "borsh-schema-derive-internal", "proc-macro-crate 0.1.5", - "proc-macro2 1.0.69", + "proc-macro2 1.0.86", "syn 1.0.95", ] @@ -724,8 +719,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5449c28a7b352f2d1e592a8a28bf139bc71afb0764a14f3c02500935d8c44065" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -735,8 +730,8 @@ version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdbd5696d8bfa21d53d9fe39a714a18538bad11492a42d066dbbc395fb1951c0" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -795,8 +790,8 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -869,7 +864,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" dependencies = [ - "cipher 0.4.4", + "cipher", ] [[package]] @@ -895,25 +890,24 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" -version = "0.8.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c80e5460aa66fe3b91d40bcbdab953a597b60053e34d684ac6903f863b680a6" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if 1.0.0", - "cipher 0.3.0", - "cpufeatures 0.2.11", - "zeroize", + "cipher", + "cpufeatures", ] [[package]] name = "chacha20poly1305" -version = "0.9.1" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a18446b09be63d457bbec447509e85f662f32952b035ce892290396bc0b0cff5" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", "chacha20", - "cipher 0.3.0", + "cipher", "poly1305", "zeroize", ] @@ -946,15 +940,6 @@ dependencies = [ "winapi", ] -[[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" @@ -963,6 +948,7 @@ checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ "crypto-common", "inout", + "zeroize", ] [[package]] @@ -973,7 +959,7 @@ checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" dependencies = [ "ansi_term", "atty", - "bitflags", + "bitflags 1.3.2", "strsim 0.8.0", "textwrap", "unicode-width", @@ -986,7 +972,7 @@ version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -995,7 +981,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -1034,7 +1020,7 @@ dependencies = [ "db_common", "derive_more", "dirs", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "ed25519-dalek-bip32 0.2.0", "enum_derives", "ethabi", @@ -1107,7 +1093,7 @@ dependencies = [ "serde_with", "serialization", "serialization_derive", - "sha2 0.10.7", + "sha2 0.10.8", "sha3 0.9.1", "sia-rust", "solana-client", @@ -1120,7 +1106,7 @@ dependencies = [ "time 0.3.20", "tokio", "tokio-rustls 0.24.1", - "tokio-tungstenite-wasm", + "tokio-tungstenite-wasm 0.1.1-alpha.0 (git+https://github.com/KomodoPlatform/tokio-tungstenite-wasm?rev=d20abdb)", "tonic", "tonic-build", "tower-service", @@ -1221,7 +1207,7 @@ dependencies = [ "serde_derive", "serde_json", "serde_repr", - "sha2 0.10.7", + "sha2 0.10.8", "shared_ref_counter", "tokio", "uuid 1.2.2", @@ -1352,15 +1338,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cpufeatures" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed00c67cb5d0a7d64a44f6ad2668db7e7530311dd53ea79bcd4fb022c64911c8" -dependencies = [ - "libc", -] - [[package]] name = "cpufeatures" version = "0.2.11" @@ -1528,7 +1505,7 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" name = "crypto" version = "1.0.0" dependencies = [ - "aes 0.8.3", + "aes", "argon2", "arrayref", "async-trait", @@ -1539,7 +1516,7 @@ dependencies = [ "bs58 0.4.0", "cbc", "cfg-if 1.0.0", - "cipher 0.4.4", + "cipher", "common", "derive_more", "enum-primitive-derive", @@ -1567,7 +1544,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", "tokio", "trezor", "wasm-bindgen-test", @@ -1594,6 +1571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", + "rand_core 0.6.4", "typenum", ] @@ -1644,11 +1622,11 @@ dependencies = [ [[package]] name = "ctr" -version = "0.7.0" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a232f92a03f37dd7d7dd2adc67166c77e9cd88de5b019b9a9eecfaeaf7bfd481" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher 0.3.0", + "cipher", ] [[package]] @@ -1677,18 +1655,31 @@ dependencies = [ [[package]] name = "curve25519-dalek" -version = "4.0.0-rc.1" +version = "4.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d4ba9852b42210c7538b75484f9daa0655e9a3ac04f693747bb0f02cf3cfe16" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if 1.0.0", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", "fiat-crypto", - "packed_simd_2", - "platforms", + "rustc_version 0.4.0", "subtle", "zeroize", ] +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "curve25519-dalek-ng" version = "4.1.1" @@ -1723,8 +1714,8 @@ dependencies = [ "cc", "codespan-reporting", "lazy_static", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "scratch", "syn 1.0.95", ] @@ -1741,8 +1732,8 @@ version = "1.0.81" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -1764,8 +1755,8 @@ checksum = "859d65a907b6852c9361e3185c862aae7fafd2887876799fa55f5f99dc40d610" dependencies = [ "fnv", "ident_case", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "strsim 0.10.0", "syn 1.0.95", ] @@ -1777,7 +1768,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c972679f83bdf9c42bd905396b6c3588a843a17f0f16dfcfa3e2c5d57441835" dependencies = [ "darling_core", - "quote 1.0.33", + "quote 1.0.37", "syn 1.0.95", ] @@ -1864,8 +1855,8 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -1875,8 +1866,8 @@ version = "0.99.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -2019,12 +2010,12 @@ dependencies = [ [[package]] name = "ed25519" -version = "1.5.2" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ "serde", - "signature 1.4.0", + "signature 1.6.4", ] [[package]] @@ -2057,7 +2048,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" dependencies = [ "curve25519-dalek 3.2.0", - "ed25519 1.5.2", + "ed25519 1.5.3", "rand 0.7.3", "serde", "serde_bytes", @@ -2065,6 +2056,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519 2.2.3", + "rand_core 0.6.4", + "serde", + "sha2 0.10.8", + "subtle", + "zeroize", +] + [[package]] name = "ed25519-dalek-bip32" version = "0.1.1" @@ -2072,7 +2078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "057f328f31294b5ab432e6c39642f54afd1531677d6d4ba2905932844cc242f3" dependencies = [ "derivation-path 0.1.3", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "failure", "hmac 0.9.0", "sha2 0.9.9", @@ -2085,9 +2091,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d2be62a4061b872c8c0873ee4fc6f101ce7b889d039f019c5fa2af471a59908" dependencies = [ "derivation-path 0.2.0", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "hmac 0.12.1", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -2148,9 +2154,9 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ - "heck", - "proc-macro2 1.0.69", - "quote 1.0.33", + "heck 0.4.0", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -2161,7 +2167,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" dependencies = [ "num-traits", - "quote 1.0.33", + "quote 1.0.37", "syn 1.0.95", ] @@ -2170,8 +2176,8 @@ name = "enum_derives" version = "0.1.0" dependencies = [ "itertools", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -2342,8 +2348,8 @@ version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", "synstructure", ] @@ -2398,9 +2404,9 @@ dependencies = [ [[package]] name = "fiat-crypto" -version = "0.1.20" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e825f6987101665dea6ec934c09ec6d721de7bc1bf92248e1d5810c8cd636b77" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" [[package]] name = "filetime" @@ -2470,6 +2476,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "form_urlencoded" version = "1.0.1" @@ -2487,8 +2508,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26c4b37de5ae15812a764c958297cfc50f5c010438f60c6ce75d11b802abd404" dependencies = [ "cbc", - "cipher 0.4.4", - "libm 0.2.7", + "cipher", + "libm", "num-bigint", "num-integer", "num-traits", @@ -2604,9 +2625,9 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -2731,9 +2752,9 @@ dependencies = [ [[package]] name = "ghash" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7bbd60caa311237d508927dbba7594b483db3ef05faa55172fcf89b1bcda7853" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" dependencies = [ "opaque-debug", "polyval", @@ -2902,12 +2923,27 @@ dependencies = [ "http 0.2.12", ] +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "heck" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" +[[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.1.14" @@ -2952,6 +2988,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + [[package]] name = "hmac" version = "0.8.1" @@ -3035,6 +3080,17 @@ dependencies = [ "itoa 1.0.10", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes 1.4.0", + "fnv", + "itoa 1.0.10", +] + [[package]] name = "http-body" version = "0.1.0" @@ -3264,8 +3320,8 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5dacb10c5b3bb92d46ba347505a9041e676bb20ad220101326bffb0c93031ee" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -3447,6 +3503,20 @@ dependencies = [ "serde_json", ] +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + [[package]] name = "jubjub" version = "0.5.1" @@ -3471,10 +3541,28 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.7", + "sha2 0.10.8", "signature 2.2.0", ] +[[package]] +name = "kdf_walletconnect" +version = "0.1.0" +dependencies = [ + "common", + "futures 0.3.28", + "hex", + "hkdf", + "mm2_err_handle", + "pairing_api", + "rand 0.8.4", + "relay_client", + "relay_rpc", + "sha2 0.10.8", + "thiserror", + "x25519-dalek 2.0.1", +] + [[package]] name = "keccak" version = "0.1.0" @@ -3530,7 +3618,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" dependencies = [ "arrayvec 0.5.1", - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "ryu", "static_assertions", @@ -3552,12 +3640,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "libm" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fc7aa29613bd6a620df431842069224d8bc9011086b1db4c0e0cd47fa03ec9a" - [[package]] name = "libm" version = "0.2.7" @@ -3704,7 +3786,7 @@ dependencies = [ "quick-protobuf-codec", "rand 0.8.4", "regex", - "sha2 0.10.7", + "sha2 0.10.8", "smallvec 1.6.1", "unsigned-varint", "void", @@ -3739,13 +3821,13 @@ checksum = "d2874d9c6575f1d7a151022af5c42bb0ffdcdfbafe0a6fd039de870b384835a2" dependencies = [ "asn1_der", "bs58 0.5.0", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "libsecp256k1 0.7.0", "log", "multihash", "quick-protobuf", "rand 0.8.4", - "sha2 0.10.7", + "sha2 0.10.8", "thiserror", "zeroize", ] @@ -3802,11 +3884,11 @@ dependencies = [ "once_cell", "quick-protobuf", "rand 0.8.4", - "sha2 0.10.7", + "sha2 0.10.8", "snow", "static_assertions", "thiserror", - "x25519-dalek", + "x25519-dalek 1.1.0", "zeroize", ] @@ -3871,11 +3953,11 @@ name = "libp2p-swarm-derive" version = "0.33.0" source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" dependencies = [ - "heck", + "heck 0.4.0", "proc-macro-warning", - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -4303,9 +4385,9 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddece26afd34c31585c74a4db0630c376df271c285d682d1e55012197830b6df" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -4765,9 +4847,9 @@ dependencies = [ "secp256k1 0.20.3", "serde", "serde_bytes", - "sha2 0.10.7", + "sha2 0.10.8", "smallvec 1.6.1", - "syn 2.0.38", + "syn 2.0.77", "tokio", "void", ] @@ -4844,8 +4926,8 @@ version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3048ef3680533a27f9f8e7d6a0bce44dc61e4895ea0f42709337fa1c8616fefe" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -4908,6 +4990,23 @@ dependencies = [ "unsigned-varint", ] +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + [[package]] name = "netlink-packet-core" version = "0.4.2" @@ -4927,7 +5026,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" dependencies = [ "anyhow", - "bitflags", + "bitflags 1.3.2", "byteorder", "libc", "netlink-packet-core", @@ -4989,7 +5088,7 @@ version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cc", "cfg-if 1.0.0", "libc", @@ -5002,7 +5101,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" dependencies = [ - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "libc", ] @@ -5044,8 +5143,8 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -5108,8 +5207,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" dependencies = [ "proc-macro-crate 1.1.3", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -5140,12 +5239,50 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" +[[package]] +name = "openssl" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "ordered-float" version = "3.7.0" @@ -5174,21 +5311,11 @@ checksum = "44a0b52c2cbaef7dffa5fec1a43274afe8bd2a644fa9fc50a9ef4ff0269b1257" dependencies = [ "Inflector", "proc-macro-error", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] -[[package]] -name = "packed_simd_2" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1914cd452d8fccd6f9db48147b29fd4ae05bea9dc5d9ad578509f72415de282" -dependencies = [ - "cfg-if 1.0.0", - "libm 0.1.4", -] - [[package]] name = "pairing" version = "0.18.0" @@ -5199,6 +5326,27 @@ dependencies = [ "group 0.8.0", ] +[[package]] +name = "pairing_api" +version = "0.1.0" +dependencies = [ + "anyhow", + "hex", + "lazy_static", + "paste", + "rand 0.8.4", + "regex", + "relay_client", + "relay_rpc", + "serde", + "serde_json", + "structopt", + "thiserror", + "tokio", + "url", + "wc_common", +] + [[package]] name = "parity-scale-codec" version = "3.1.2" @@ -5220,8 +5368,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c45ed1f39709f5a89338fab50e59816b2e8815f5bb58276e7ddf9afd495f73f8" dependencies = [ "proc-macro-crate 1.1.3", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -5249,7 +5397,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f557c32c6d268a07c921471619c0295f5efad3a0e76d4f97a05c091a51d110b2" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.86", "syn 1.0.95", "synstructure", ] @@ -5343,9 +5491,9 @@ dependencies = [ [[package]] name = "paste" -version = "1.0.7" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c520e05135d6e763148b6426a837e239041653ba7becd2e538c076c738025fc" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pbkdf2" @@ -5382,8 +5530,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" dependencies = [ "peg-runtime", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", ] [[package]] @@ -5432,9 +5580,9 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -5471,12 +5619,6 @@ version = "0.3.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" -[[package]] -name = "platforms" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d7ddaed09e0eb771a79ab0fd64609ba0afb0a8366421957936ad14cbd13630" - [[package]] name = "polling" version = "2.8.0" @@ -5484,7 +5626,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" dependencies = [ "autocfg 1.1.0", - "bitflags", + "bitflags 1.3.2", "cfg-if 1.0.0", "concurrent-queue 2.2.0", "libc", @@ -5495,23 +5637,23 @@ dependencies = [ [[package]] name = "poly1305" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fe800695325da85083cd23b56826fccb2e2dc29b218e7811a6f33bc93f414be" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures 0.1.4", + "cpufeatures", "opaque-debug", "universal-hash", ] [[package]] name = "polyval" -version = "0.5.1" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e597450cbf209787f0e6de80bf3795c6b2356a380ee87837b545aded8dbc1823" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if 1.0.0", - "cpufeatures 0.1.4", + "cpufeatures", "opaque-debug", "universal-hash", ] @@ -5534,7 +5676,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f28f53e8b192565862cf99343194579a022eb9c7dd3a8d03134734803c7b3125" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.86", "syn 1.0.95", ] @@ -5588,8 +5730,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" dependencies = [ "proc-macro-error-attr", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", "version_check", ] @@ -5600,8 +5742,8 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "version_check", ] @@ -5611,9 +5753,9 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70550716265d1ec349c41f70dd4f964b4fd88394efe4405f0c1da679c4799a07" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -5627,9 +5769,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] @@ -5652,8 +5794,8 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b6a5217beb0ad503ee7fa752d451c905113d70721b937126158f3106a48cc1" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -5674,7 +5816,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes 1.4.0", - "heck", + "heck 0.4.0", "itertools", "lazy_static", "log", @@ -5697,8 +5839,8 @@ checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" dependencies = [ "anyhow", "itertools", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -5828,11 +5970,11 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ - "proc-macro2 1.0.69", + "proc-macro2 1.0.86", ] [[package]] @@ -6067,7 +6209,7 @@ version = "10.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c49596760fce12ca21550ac21dc5a9617b2ea4b6e0aa7d8dab8ff2824fc2bba" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -6128,7 +6270,7 @@ version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" dependencies = [ - "bitflags", + "bitflags 1.3.2", ] [[package]] @@ -6167,8 +6309,8 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c523ccaed8ac4b0288948849a350b37d3035827413c458b6a40ddb614bb4f72" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -6189,6 +6331,58 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "relay_client" +version = "0.1.0" +dependencies = [ + "chrono", + "data-encoding", + "futures-util", + "getrandom 0.2.9", + "http 1.1.0", + "js-sys", + "pin-project", + "rand 0.7.3", + "relay_rpc", + "serde", + "serde_json", + "serde_qs", + "thiserror", + "tokio", + "tokio-tungstenite-wasm 0.1.1-alpha.0 (git+https://github.com/KomodoPlatform/tokio-tungstenite-wasm.git?rev=8fc7e2f)", + "tokio-util", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "relay_rpc" +version = "0.1.0" +dependencies = [ + "anyhow", + "bs58 0.4.0", + "chrono", + "data-encoding", + "derive_more", + "ed25519-dalek 2.1.1", + "hex", + "jsonwebtoken", + "once_cell", + "paste", + "rand 0.8.4", + "regex", + "serde", + "serde-aux", + "serde_json", + "sha2 0.10.8", + "strum", + "thiserror", + "url", +] + [[package]] name = "reqwest" version = "0.11.9" @@ -6401,7 +6595,7 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" dependencies = [ - "bitflags", + "bitflags 1.3.2", "fallible-iterator", "fallible-streaming-iterator", "hashlink", @@ -6470,7 +6664,7 @@ version = "0.36.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd5c6ff11fecd55b40746d1995a02f2eb375bf8c00d192d521ee09f42bef37bc" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.2.8", "io-lifetimes", "libc", @@ -6484,7 +6678,7 @@ version = "0.37.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d" dependencies = [ - "bitflags", + "bitflags 1.3.2", "errno 0.3.1", "io-lifetimes", "libc", @@ -6624,8 +6818,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50e334bb10a245e28e5fd755cabcafd96cfcd167c99ae63a46924ca8d8703a3c" dependencies = [ "proc-macro-crate 1.1.3", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -6747,7 +6941,7 @@ version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "core-foundation-sys", "libc", @@ -6808,21 +7002,31 @@ dependencies = [ name = "ser_error_derive" version = "0.1.0" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "ser_error", "syn 1.0.95", ] [[package]] name = "serde" -version = "1.0.189" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] +[[package]] +name = "serde-aux" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" +dependencies = [ + "serde", + "serde_json", +] + [[package]] name = "serde-wasm-bindgen" version = "0.4.3" @@ -6845,35 +7049,47 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] name = "serde_json" -version = "1.0.79" +version = "1.0.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" dependencies = [ - "indexmap 1.9.3", + "indexmap 2.2.3", "itoa 1.0.10", + "memchr", "ryu", "serde", ] +[[package]] +name = "serde_qs" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cac3f1e2ca2fe333923a1ae72caca910b98ed0630bb35ef6f8c8517d6e81afa" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + [[package]] name = "serde_repr" version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dc6b7951b17b051f3210b063f12cc17320e2fe30ae05b0fe2a3abb068551c76" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -6906,8 +7122,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082" dependencies = [ "darling", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -6950,7 +7166,7 @@ checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpufeatures 0.2.11", + "cpufeatures", "digest 0.9.0", "opaque-debug", ] @@ -6962,7 +7178,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if 1.0.0", - "cpufeatures 0.2.11", + "cpufeatures", "digest 0.10.7", ] @@ -6974,19 +7190,19 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if 1.0.0", - "cpufeatures 0.2.11", + "cpufeatures", "digest 0.9.0", "opaque-debug", ] [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if 1.0.0", - "cpufeatures 0.2.11", + "cpufeatures", "digest 0.10.7", ] @@ -7028,7 +7244,7 @@ dependencies = [ "blake2b_simd", "chrono", "derive_more", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "hex", "nom", "reqwest", @@ -7050,9 +7266,9 @@ dependencies = [ [[package]] name = "signature" -version = "1.4.0" +version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02658e48d89f2bec991f9a78e69cfa4c316f8d6a6c4ec12fae1aeb263d486788" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" [[package]] name = "signature" @@ -7064,6 +7280,18 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time 0.3.20", +] + [[package]] name = "siphasher" version = "0.1.3" @@ -7123,18 +7351,18 @@ dependencies = [ [[package]] name = "snow" -version = "0.9.2" +version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ccba027ba85743e09d15c03296797cad56395089b832b48b5a5217880f57733" +checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" dependencies = [ "aes-gcm", "blake2", "chacha20poly1305", - "curve25519-dalek 4.0.0-rc.1", + "curve25519-dalek 4.1.3", "rand_core 0.6.4", - "ring 0.16.20", + "ring 0.17.3", "rustc_version 0.4.0", - "sha2 0.10.7", + "sha2 0.10.8", "subtle", ] @@ -7402,8 +7630,8 @@ version = "1.9.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "402fffb54bf5d335e6df26fc1719feecfbd7a22fafdf6649fe78380de3c47384" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "rustc_version 0.4.0", "syn 1.0.95", ] @@ -7501,7 +7729,7 @@ checksum = "0a463f546a2f5842d35974bd4691ae5ceded6785ec24db440f773723f6ce4e11" dependencies = [ "base64 0.13.0", "bincode", - "bitflags", + "bitflags 1.3.2", "blake3", "borsh", "borsh-derive", @@ -7655,7 +7883,7 @@ dependencies = [ "assert_matches", "base64 0.13.0", "bincode", - "bitflags", + "bitflags 1.3.2", "borsh", "bs58 0.4.0", "bytemuck", @@ -7663,7 +7891,7 @@ dependencies = [ "chrono", "derivation-path 0.1.3", "digest 0.9.0", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "ed25519-dalek-bip32 0.1.1", "generic-array", "hmac 0.11.0", @@ -7704,8 +7932,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c834b4e02ac911b13c13aed08b3f847e722f6be79d31b1c660c1dbd2dee83cdb" dependencies = [ "bs58 0.4.0", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "rustversion", "syn 1.0.95", ] @@ -7803,7 +8031,7 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77963e2aa8fadb589118c3aede2e78b6c4bcf1c01d588fbf33e915b390825fbd" dependencies = [ - "bitflags", + "bitflags 1.3.2", "byteorder", "hash-db", "hash256-std-hasher", @@ -7828,8 +8056,8 @@ version = "4.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d676664972e22a0796176e81e7bec41df461d1edf52090955cdab55f2c956ff2" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -7858,8 +8086,8 @@ checksum = "22ecb916b9664ed9f90abef0ff5a3e61454c1efea5861b2997e03f39b59b955f" dependencies = [ "Inflector", "proc-macro-crate 1.1.3", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", ] @@ -7991,7 +8219,7 @@ dependencies = [ "serde", "serde_json", "serialization", - "sha2 0.10.7", + "sha2 0.10.8", "test_helpers", ] @@ -8012,8 +8240,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f9799e6d412271cb2414597581128b03f3285f260ea49f5363d07df6a332b3e" dependencies = [ "Inflector", - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "serde", "serde_json", "unicode-xid 0.2.0", @@ -8043,6 +8271,52 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 1.0.95", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2 1.0.86", + "quote 1.0.37", + "rustversion", + "syn 2.0.77", +] + [[package]] name = "subtle" version = "2.4.0" @@ -8098,19 +8372,19 @@ version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fbaf6116ab8924f39d52792136fb74fd60a80194cf1b1c6ffa6453eef1c3f942" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "unicode-ident", ] [[package]] name = "syn" -version = "2.0.38" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "unicode-ident", ] @@ -8135,8 +8409,8 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b834f2d66f734cb897113e34aaff2f1ab4719ca946f9a7358dba8f8064148701" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", "unicode-xid 0.2.0", ] @@ -8147,7 +8421,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ - "bitflags", + "bitflags 1.3.2", "core-foundation", "system-configuration-sys", ] @@ -8214,7 +8488,7 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.7", + "sha2 0.10.8", "signature 2.2.0", "subtle", "subtle-encoding", @@ -8323,7 +8597,7 @@ dependencies = [ "rand 0.8.4", "serde", "serde_json", - "sha2 0.10.7", + "sha2 0.10.8", ] [[package]] @@ -8350,9 +8624,9 @@ version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f9456a42c5b0d803c8cd86e73dd7cc9edd429499f37a3550d286d5e86720569f" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -8490,9 +8764,19 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", ] [[package]] @@ -8535,14 +8819,33 @@ checksum = "e80b39df6afcc12cdf752398ade96a6b9e99c903dfdc36e53ad10b9c366bca72" dependencies = [ "futures-util", "log", + "native-tls", "rustls 0.20.4", "rustls-native-certs", "tokio", + "tokio-native-tls", "tokio-rustls 0.23.2", "tungstenite", "webpki", ] +[[package]] +name = "tokio-tungstenite-wasm" +version = "0.1.1-alpha.0" +source = "git+https://github.com/KomodoPlatform/tokio-tungstenite-wasm.git?rev=8fc7e2f#8fc7e2ff4c970bee0c0867399cb9a941881ea183" +dependencies = [ + "futures-channel", + "futures-util", + "http 0.2.12", + "httparse", + "js-sys", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "tokio-tungstenite-wasm" version = "0.1.1-alpha.0" @@ -8623,9 +8926,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a6fdaae4c2c638bb70fe42803a26fbd6fc6ac8c72f5c59f67ecc2a2dcabf4b07" dependencies = [ "prettyplease", - "proc-macro2 1.0.69", + "proc-macro2 1.0.86", "prost-build", - "quote 1.0.33", + "quote 1.0.37", "syn 1.0.95", ] @@ -8679,9 +8982,9 @@ version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", ] [[package]] @@ -8816,6 +9119,7 @@ dependencies = [ "http 0.2.12", "httparse", "log", + "native-tls", "rand 0.8.4", "rustls 0.20.4", "sha-1", @@ -8828,9 +9132,9 @@ dependencies = [ [[package]] name = "typenum" -version = "1.15.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" [[package]] name = "uint" @@ -8873,6 +9177,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + [[package]] name = "unicode-width" version = "0.1.9" @@ -8899,11 +9209,11 @@ checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" [[package]] name = "universal-hash" -version = "0.4.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8326b2c654932e3e4f9196e69d08fdf7cfd718e1dc6f66b347e6024a0c961402" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "generic-array", + "crypto-common", "subtle", ] @@ -8941,13 +9251,12 @@ dependencies = [ [[package]] name = "url" -version = "2.2.2" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +checksum = "22fe195a4f217c25b25cb5058ced57059824a678474874038dc88d211bf508d3" dependencies = [ "form_urlencoded", "idna", - "matches", "percent-encoding", "serde", ] @@ -9131,9 +9440,9 @@ dependencies = [ "bumpalo", "log", "once_cell", - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", "wasm-bindgen-shared", ] @@ -9155,7 +9464,7 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d" dependencies = [ - "quote 1.0.33", + "quote 1.0.37", "wasm-bindgen-macro-support", ] @@ -9165,9 +9474,9 @@ version = "0.2.87" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", - "syn 2.0.38", + "proc-macro2 1.0.86", + "quote 1.0.37", + "syn 2.0.77", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -9198,8 +9507,17 @@ version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c2e18093f11c19ca4e188c177fecc7c372304c311189f12c2f9bea5b7324ac7" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", +] + +[[package]] +name = "wc_common" +version = "0.1.0" +dependencies = [ + "base64 0.21.7", + "chacha20poly1305", + "thiserror", ] [[package]] @@ -9604,6 +9922,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek 4.1.3", + "rand_core 0.6.4", + "serde", + "zeroize", +] + [[package]] name = "xattr" version = "0.2.2" @@ -9750,7 +10080,7 @@ name = "zcash_primitives" version = "0.5.0" source = "git+https://github.com/KomodoPlatform/librustzcash.git?tag=k-1.4.1#e92443a7bbd1c5e92e00e6deb45b5a33af14cea4" dependencies = [ - "aes 0.8.3", + "aes", "bitvec 0.18.5", "blake2b_simd", "blake2s_simd", @@ -9808,8 +10138,8 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" dependencies = [ - "proc-macro2 1.0.69", - "quote 1.0.33", + "proc-macro2 1.0.86", + "quote 1.0.37", "syn 1.0.95", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index deec6b843f..32e69774ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ members = [ "mm2src/derives/ser_error_derive", "mm2src/derives/ser_error", "mm2src/hw_common", + "mm2src/kdf_walletconnect", "mm2src/mm2_bin_lib", "mm2src/mm2_bitcoin/chain", "mm2src/mm2_bitcoin/crypto", diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index c870e9baf0..db9414def1 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -7,19 +7,19 @@ edition = "2018" zhtlc-native-tests = [] # TODO enable-solana = [ - "dep:bincode", - "dep:ed25519-dalek-bip32", - "dep:solana-client", - "dep:solana-sdk", - "dep:solana-transaction-status", - "dep:spl-token", - "dep:spl-associated-token-account", - "dep:satomic-swap" + "dep:bincode", + "dep:ed25519-dalek-bip32", + "dep:solana-client", + "dep:solana-sdk", + "dep:solana-transaction-status", + "dep:spl-token", + "dep:spl-associated-token-account", + "dep:satomic-swap" ] enable-sia = [ - "dep:reqwest", - "dep:blake2b_simd", - "dep:sia-rust" + "dep:reqwest", + "dep:blake2b_simd", + "dep:sia-rust" ] default = [] run-docker-tests = [] @@ -79,7 +79,7 @@ mm2_git = { path = "../mm2_git" } mm2_io = { path = "../mm2_io" } mm2_metrics = { path = "../mm2_metrics" } mm2_net = { path = "../mm2_net", features = ["p2p"] } -mm2_number = { path = "../mm2_number"} +mm2_number = { path = "../mm2_number" } mm2_rpc = { path = "../mm2_rpc" } mm2_state_machine = { path = "../mm2_state_machine" } mocktopus = "0.8.0" @@ -101,7 +101,7 @@ script = { path = "../mm2_bitcoin/script" } secp256k1 = { version = "0.20" } ser_error = { path = "../derives/ser_error" } ser_error_derive = { path = "../derives/ser_error_derive" } -serde = "1.0" +serde = { version = "1.0", features = ["derive"] } serde_derive = "1.0" serde_json = { version = "1", features = ["preserve_order", "raw_value"] } serde_with = "1.14.0" @@ -114,7 +114,7 @@ sha3 = "0.9" utxo_signer = { path = "utxo_signer" } # using the same version as cosmrs tendermint-rpc = { version = "0.32.0", default-features = false } -tokio-tungstenite-wasm = { git = "https://github.com/KomodoPlatform/tokio-tungstenite-wasm", rev = "d20abdb", features = ["rustls-tls-native-roots"]} +tokio-tungstenite-wasm = { git = "https://github.com/KomodoPlatform/tokio-tungstenite-wasm", rev = "d20abdb", features = ["rustls-tls-native-roots"] } url = { version = "2.2.2", features = ["serde"] } uuid = { version = "1.2.2", features = ["fast-rng", "serde", "v4"] } # One of web3 dependencies is the old `tokio-uds 0.1.7` which fails cross-compiling to ARM. @@ -123,7 +123,7 @@ web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.20.0", d zbase32 = "0.1.2" zcash_client_backend = { git = "https://github.com/KomodoPlatform/librustzcash.git", tag = "k-1.4.1" } zcash_extras = { git = "https://github.com/KomodoPlatform/librustzcash.git", tag = "k-1.4.1" } -zcash_primitives = {features = ["transparent-inputs"], git = "https://github.com/KomodoPlatform/librustzcash.git", tag = "k-1.4.1" } +zcash_primitives = { features = ["transparent-inputs"], git = "https://github.com/KomodoPlatform/librustzcash.git", tag = "k-1.4.1" } [target.'cfg(all(not(target_os = "ios"), not(target_os = "android"), not(target_arch = "wasm32")))'.dependencies] bincode = { version = "1.3.3", default-features = false, optional = true } diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index dd3bbec752..68e49a531a 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -60,3 +60,6 @@ tokio = { version = "1.20", default-features = false } [features] trezor-udp = ["trezor/trezor-udp"] + +[patch.crates-io] +rand_core = "=0.6.4" \ No newline at end of file diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml new file mode 100644 index 0000000000..211d655a3e --- /dev/null +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "kdf_walletconnect" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# chacha20poly1305 = "0.10" +common = { path = "../common" } +futures = { version = "0.3", package = "futures", features = [ + "compat", + "async-await", +] } +hex = "0.4.2" +hkdf = "0.12.4" +mm2_err_handle = { path = "../mm2_err_handle" } +pairing_api = { path = "../../../kdf-wc/pairing_api" } +rand = "0.8" +relay_client = { path = "../../../kdf-wc/relay_client" } +relay_rpc = { path = "../../../kdf-wc/relay_rpc" } +sha2 = "0.10.8" +thiserror = "1.0.40" +x25519-dalek = { version = "2.0", features = ["static_secrets"] } diff --git a/mm2src/kdf_walletconnect/src/handler.rs b/mm2src/kdf_walletconnect/src/handler.rs new file mode 100644 index 0000000000..cdd69d0910 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/handler.rs @@ -0,0 +1,58 @@ +use std::time::Duration; + +use futures::channel::mpsc::UnboundedSender; +use relay_client::{error::ClientError, websocket::{CloseFrame, ConnectionHandler, PublishedMessage}, ConnectionOptions}; +use common::log::info; +use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; + +pub struct Handler { + name: &'static str, + sender: UnboundedSender, +} + +impl Handler { + pub fn new(name: &'static str, sender: UnboundedSender) -> Self { + Self { name, sender } + } +} + +impl ConnectionHandler for Handler { + fn connected(&mut self) { + info!("\n[{}] connection open", self.name); + } + + fn disconnected(&mut self, frame: Option>) { + info!("\n[{}] connection closed: frame={frame:?}", self.name); + } + + fn message_received(&mut self, message: PublishedMessage) { + info!( + "\n[{}] inbound message: message_id={} topic={} tag={} message={}", + self.name, message.message_id, message.topic, message.tag, message.message, + ); + + if let Err(e) = self.sender.start_send(message) { + info!("\n[{}] failed to send the to the receiver: {e}", self.name); + } + } + + fn inbound_error(&mut self, error: ClientError) { + info!("\n[{}] inbound error: {error}", self.name); + } + + fn outbound_error(&mut self, error: ClientError) { + info!("\n[{}] outbound error: {error}", self.name); + } +} + +fn create_conn_opts(relay_address: &str, project_id: &str) -> ConnectionOptions { + let key = SigningKey::generate(&mut rand::thread_rng()); + + let auth = AuthToken::new("https://komodefi.com") + .aud(relay_address) + .ttl(Duration::from_secs(60 * 60)) + .as_jwt(&key) + .unwrap(); + + ConnectionOptions::new(project_id, auth).with_address(relay_address) +} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs new file mode 100644 index 0000000000..823e4eae54 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -0,0 +1,60 @@ +use std::{collections::HashMap, sync::Arc}; + +use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex}; +use handler::Handler; +use mm2_err_handle::prelude::MmResult; +use pairing_api::PairingClient; +use relay_client::{error::ClientError, websocket::{Client, PublishedMessage}, ConnectionOptions}; +use relay_rpc::domain::{SubscriptionId, Topic}; +use session_key::SessionKey; +use mm2_err_handle::prelude::*; + +mod session_key; +mod handler; + +pub const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com"; +pub const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b"; + +#[derive(Debug)] +pub struct Session { + /// Pairing subscription id. + pub subscription_id: SubscriptionId, + /// Session symmetric key. + pub session_key: SessionKey, +} + +#[derive(Debug)] +pub struct WalletConnectClient { + pub client: Arc, + pub pairing: Arc, + pub sessions: HashMap, + pub handler: Arc>> +} + +impl Default for WalletConnectClient { + fn default() -> Self { + Self::new() + } +} + +impl WalletConnectClient { + pub fn new() -> Self { + let (sender, receiver) = unbounded(); + + let pairing = PairingClient::new(); + let client = Arc::new(Client::new(Handler::new("Komodefi", sender))); + + Self { + client, + pairing, + sessions: HashMap::new(), + handler: Arc::new(Mutex::new(receiver)) + } + } + + pub async fn connect(&self, opts: &ConnectionOptions) -> MmResult<(), ClientError>{ + self.client.connect(opts).await.map_to_mm(|err|err) + } + + +} diff --git a/mm2src/kdf_walletconnect/src/session_key.rs b/mm2src/kdf_walletconnect/src/session_key.rs new file mode 100644 index 0000000000..84e7958bee --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session_key.rs @@ -0,0 +1,73 @@ +use { + hkdf::Hkdf, + rand::{rngs::OsRng, CryptoRng, RngCore}, + sha2::{Digest, Sha256}, + std::fmt::Debug, + x25519_dalek::{EphemeralSecret, PublicKey}, +}; + +/// Session key and topic derivation errors. +#[derive(Debug, thiserror::Error)] +pub enum SessionError { + #[error("Failed to generate symmetric session key: {0}")] + SymKeyGeneration(String), +} + +pub struct SessionKey { + sym_key: [u8; 32], + public_key: PublicKey, +} + +impl std::fmt::Debug for SessionKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SessionKey") + .field("sym_key", &"*******") + .field("public_key", &self.public_key) + .finish() + } +} + +impl SessionKey { + /// Creates new session key from `osrng`. + pub fn from_osrng(sender_public_key: &[u8; 32]) -> Result { + SessionKey::diffie_hellman(OsRng, sender_public_key) + } + + /// Performs Diffie-Hellman symmetric key derivation. + pub fn diffie_hellman(csprng: T, sender_public_key: &[u8; 32]) -> Result + where + T: RngCore + CryptoRng, + { + let single_use_private_key = EphemeralSecret::random_from_rng(csprng); + let public_key = PublicKey::from(&single_use_private_key); + + let ikm = single_use_private_key.diffie_hellman(&PublicKey::from(*sender_public_key)); + + let mut session_sym_key = Self { + sym_key: [0u8; 32], + public_key, + }; + let hk = Hkdf::::new(None, ikm.as_bytes()); + hk.expand(&[], &mut session_sym_key.sym_key) + .map_err(|e| SessionError::SymKeyGeneration(e.to_string()))?; + + Ok(session_sym_key) + } + + /// Gets symmetic key reference. + pub fn symmetric_key(&self) -> &[u8; 32] { + &self.sym_key + } + + /// Gets "our" public key used in symmetric key derivation. + pub fn diffie_public_key(&self) -> &[u8; 32] { + self.public_key.as_bytes() + } + + /// Generates new session topic. + pub fn generate_topic(&self) -> String { + let mut hasher = Sha256::new(); + hasher.update(self.sym_key); + hex::encode(hasher.finalize()) + } +} diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index 60c3e9aa62..9cf79be15d 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -13,7 +13,8 @@ path = "src/mm2.rs" doctest = false [features] -custom-swap-locktime = [] # only for testing purposes, should never be activated on release builds. +custom-swap-locktime = [ +] # only for testing purposes, should never be activated on release builds. native = [] # Deprecated track-ctx-pointer = ["common/track-ctx-pointer"] zhtlc-native-tests = ["coins/zhtlc-native-tests"] @@ -21,7 +22,9 @@ run-docker-tests = ["coins/run-docker-tests"] # TODO enable-solana = ["coins/enable-solana", "coins_activation/enable-solana"] default = [] -trezor-udp = ["crypto/trezor-udp"] # use for tests to connect to trezor emulator over udp +trezor-udp = [ + "crypto/trezor-udp", +] # use for tests to connect to trezor emulator over udp run-device-tests = [] enable-sia = ["coins/enable-sia", "coins_activation/enable-sia"] @@ -42,11 +45,17 @@ crypto = { path = "../crypto" } db_common = { path = "../db_common" } derive_more = "0.99" either = "1.6" -ethereum-types = { version = "0.13", default-features = false, features = ["std", "serialize"] } +ethereum-types = { version = "0.13", default-features = false, features = [ + "std", + "serialize", +] } enum_derives = { path = "../derives/enum_derives" } enum-primitive-derive = "0.2" futures01 = { version = "0.1", package = "futures" } -futures = { version = "0.3.1", package = "futures", features = ["compat", "async-await"] } +futures = { version = "0.3.1", package = "futures", features = [ + "compat", + "async-await", +] } gstuff = { version = "0.7", features = ["nightly"] } hash256-std-hasher = "0.15.2" hash-db = "0.15.2" @@ -68,7 +77,7 @@ mm2-libp2p = { path = "../mm2_p2p", package = "mm2_p2p" } mm2_metrics = { path = "../mm2_metrics" } mm2_net = { path = "../mm2_net", features = ["event-stream", "p2p"] } mm2_number = { path = "../mm2_number" } -mm2_rpc = { path = "../mm2_rpc", features = ["rpc_facilities"]} +mm2_rpc = { path = "../mm2_rpc", features = ["rpc_facilities"] } mm2_state_machine = { path = "../mm2_state_machine" } num-traits = "0.2" parity-util-mem = "0.11" @@ -93,7 +102,9 @@ ser_error_derive = { path = "../derives/ser_error_derive" } serialization = { path = "../mm2_bitcoin/serialization" } serialization_derive = { path = "../mm2_bitcoin/serialization_derive" } spv_validation = { path = "../mm2_bitcoin/spv_validation" } -sp-runtime-interface = { version = "6.0.0", default-features = false, features = ["disable_target_static_assertions"] } +sp-runtime-interface = { version = "6.0.0", default-features = false, features = [ + "disable_target_static_assertions", +] } sp-trie = { version = "6.0", default-features = false } trie-db = { version = "0.23.1", default-features = false } trie-root = "0.16.0" @@ -127,7 +138,9 @@ coins_activation = { path = "../coins_activation", features = ["for-tests"] } mm2_test_helpers = { path = "../mm2_test_helpers" } mocktopus = "0.8.0" testcontainers = "0.15.0" -web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.20.0", default-features = false, features = ["http-rustls-tls"] } +web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.20.0", default-features = false, features = [ + "http-rustls-tls", +] } ethabi = { version = "17.0.0" } rlp = { version = "0.5" } ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } diff --git a/mm2src/mm2_number/Cargo.toml b/mm2src/mm2_number/Cargo.toml index 0303fd20d8..2449ca3360 100644 --- a/mm2src/mm2_number/Cargo.toml +++ b/mm2src/mm2_number/Cargo.toml @@ -11,6 +11,6 @@ bigdecimal = { version = "0.3", features = ["serde"] } num-bigint = { version = "0.4", features = ["serde", "std"] } num-rational = { version = "0.4", features = ["serde"] } num-traits = "0.2" -paste = "1.0" +paste = "1.0.7" serde = { version = "1", features = ["serde_derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } From ca3f558990e86d3299ae9822670e5525b58bd65e Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 9 Sep 2024 15:38:28 +0100 Subject: [PATCH 002/125] save dev state - walletconnect client impl --- Cargo.lock | 4 + mm2src/kdf_walletconnect/Cargo.toml | 4 + mm2src/kdf_walletconnect/src/error.rs | 25 ++++++ mm2src/kdf_walletconnect/src/lib.rs | 123 +++++++++++++++++++++++--- 4 files changed, 146 insertions(+), 10 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/error.rs diff --git a/Cargo.lock b/Cargo.lock index 47667aea98..42a5e0ae52 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3550,6 +3550,7 @@ name = "kdf_walletconnect" version = "0.1.0" dependencies = [ "common", + "derive_more", "futures 0.3.28", "hex", "hkdf", @@ -3558,8 +3559,11 @@ dependencies = [ "rand 0.8.4", "relay_client", "relay_rpc", + "serde", + "serde_json", "sha2 0.10.8", "thiserror", + "wc_common", "x25519-dalek 2.0.1", ] diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 211d655a3e..f8198bbb3c 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] # chacha20poly1305 = "0.10" common = { path = "../common" } +derive_more = "0.99" futures = { version = "0.3", package = "futures", features = [ "compat", "async-await", @@ -21,4 +22,7 @@ relay_client = { path = "../../../kdf-wc/relay_client" } relay_rpc = { path = "../../../kdf-wc/relay_rpc" } sha2 = "0.10.8" thiserror = "1.0.40" +wc_common = { path = "../../../kdf-wc/wc_common" } x25519-dalek = { version = "2.0", features = ["static_secrets"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = { version = "1", features = ["preserve_order", "raw_value"] } diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs new file mode 100644 index 0000000000..67761fe678 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -0,0 +1,25 @@ +use derive_more::Display; +use pairing_api::PairingClientError; +use relay_client::error::{ClientError, Error}; +use relay_rpc::rpc::PublishError; + +#[derive(Debug, Display)] +pub enum WalletConnectClientError { + PairingError(PairingClientError), + EncodeError(String), + PublishError(Error), + ClientError(ClientError), + PairingNotFound(String) +} + +impl From for WalletConnectClientError { + fn from(value: PairingClientError) -> Self { + WalletConnectClientError::PairingError(value) + } +} + +impl From for WalletConnectClientError { + fn from(value: ClientError) -> Self { + WalletConnectClientError::ClientError(value) + } +} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 823e4eae54..bc984785f3 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,16 +1,21 @@ -use std::{collections::HashMap, sync::Arc}; +use std::{collections::HashMap, sync::Arc, time::Duration}; -use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex}; +use error::WalletConnectClientError; +use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex, StreamExt}; use handler::Handler; use mm2_err_handle::prelude::MmResult; -use pairing_api::PairingClient; -use relay_client::{error::ClientError, websocket::{Client, PublishedMessage}, ConnectionOptions}; -use relay_rpc::domain::{SubscriptionId, Topic}; +use pairing_api::{Methods, PairingClient}; +use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; +use relay_rpc::{domain::{MessageId, SubscriptionId, Topic}, rpc::{params::{IrnMetadata, Metadata}, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; use session_key::SessionKey; use mm2_err_handle::prelude::*; +use wc_common::{encrypt_and_encode, EnvelopeType}; +use common::log::info; + mod session_key; mod handler; +mod error; pub const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com"; pub const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b"; @@ -39,22 +44,120 @@ impl Default for WalletConnectClient { impl WalletConnectClient { pub fn new() -> Self { - let (sender, receiver) = unbounded(); + let (msg_sender, msg_receiver) = unbounded(); let pairing = PairingClient::new(); - let client = Arc::new(Client::new(Handler::new("Komodefi", sender))); + let client = Arc::new(Client::new(Handler::new("Komodefi", msg_sender))); Self { client, pairing, sessions: HashMap::new(), - handler: Arc::new(Mutex::new(receiver)) + handler: Arc::new(Mutex::new(msg_receiver)) } } - pub async fn connect(&self, opts: &ConnectionOptions) -> MmResult<(), ClientError>{ - self.client.connect(opts).await.map_to_mm(|err|err) + pub async fn create_pairing(&self, metadata: Metadata, methods: Option) -> MmResult<(Topic, String), WalletConnectClientError> { + Ok(self.pairing.create(metadata, methods, &self.client).await?) + } + + pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { + Ok(self.pairing.pair(url, activate, &self.client).await?) + } + + pub async fn connect(&self, opts: &ConnectionOptions) -> MmResult<(), WalletConnectClientError> { + Ok(self.client.connect(opts).await?) } + /// Private function to publish a request. + async fn publish_request( + &self, + topic: &str, + params: Params, + irn_metadata: IrnMetadata + ) -> MmResult<(), WalletConnectClientError> { + let message_id = MessageIdGenerator::new().next(); + let request = Request::new(message_id, params); + // Publish the encrypted message + self.publish_payload(topic, irn_metadata, Payload::Request(request)) + .await?; + + info!("Otbound request sent!\n"); + + Ok(()) + } + + /// Private function to publish a request response. + async fn publish_response( + &self, + topic: &str, + params: Params, + irn_metadata: IrnMetadata, + message_id: MessageId, + ) -> MmResult<(), WalletConnectClientError> { + let response = Response::Success(SuccessfulResponse { + id: message_id, + jsonrpc: JSON_RPC_VERSION_STR.into(), + result: serde_json::to_value(params) + .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?, + }); + + // Publish the encrypted message + self.publish_payload(topic, irn_metadata, Payload::Response(response)) + .await?; + + println!("\nOutbound request sent!"); + + Ok(()) + } + + + /// Private function to publish a payload. + async fn publish_payload( + &self, + topic: &str, + irn_metadata: IrnMetadata, + payload: Payload, + ) -> MmResult<(), WalletConnectClientError> { + // try to extend session before updating local store. + let sym_key = { + let pairings = self.pairing.pairings.lock().await; + let pairing = pairings + .get(topic) + .ok_or_else(|| WalletConnectClientError::PairingNotFound(format!("Pariring not found for topic:{topic}")))?; + hex::decode(pairing.sym_key.clone()).map_to_mm(|err| { + WalletConnectClientError::EncodeError(format!("Failed to decode sym_key: {:?}", err)) + })? + }; + + let payload = serde_json::to_string(&payload) + .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; + let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key) + .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; + + // Publish the encrypted message + { + self.client + .publish( + topic.into(), + message, + None, + irn_metadata.tag, + Duration::from_secs(irn_metadata.ttl), + irn_metadata.prompt, + ) + .await + .map_to_mm(WalletConnectClientError::PublishError)?; + }; + + Ok(()) + } +} + +pub async fn published_message_event_loop(client: Arc) { + let mut recv = client.handler.lock().await; + while let Some(data) = recv.next().await { + todo!() + } } From c3dc6c64cd8c8c7458fdc2ffe487889cd4c2076e Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 9 Sep 2024 16:34:54 +0100 Subject: [PATCH 003/125] save dev state - WalletConnect client impl --- Cargo.lock | 1 + mm2src/kdf_walletconnect/src/error.rs | 23 +- mm2src/kdf_walletconnect/src/handler.rs | 10 +- mm2src/kdf_walletconnect/src/lib.rs | 249 +++++++++++--------- mm2src/kdf_walletconnect/src/session_key.rs | 24 +- mm2src/mm2_core/Cargo.toml | 3 +- mm2src/mm2_core/src/mm_ctx.rs | 9 +- mm2src/mm2_main/src/rpc.rs | 2 +- 8 files changed, 174 insertions(+), 147 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42a5e0ae52..233c319211 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4486,6 +4486,7 @@ dependencies = [ "gstuff", "hex", "instant", + "kdf_walletconnect", "lazy_static", "mm2_err_handle", "mm2_event_stream", diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 67761fe678..5c369ab7d8 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -2,24 +2,25 @@ use derive_more::Display; use pairing_api::PairingClientError; use relay_client::error::{ClientError, Error}; use relay_rpc::rpc::PublishError; +use serde::{Deserialize, Serialize}; -#[derive(Debug, Display)] +#[derive(Debug, Display, Serialize, Deserialize)] pub enum WalletConnectClientError { - PairingError(PairingClientError), + PairingError(String), EncodeError(String), - PublishError(Error), - ClientError(ClientError), - PairingNotFound(String) + PublishError(String), + ClientError(String), + PairingNotFound(String), } impl From for WalletConnectClientError { - fn from(value: PairingClientError) -> Self { - WalletConnectClientError::PairingError(value) - } + fn from(error: PairingClientError) -> Self { WalletConnectClientError::PairingError(error.to_string()) } } impl From for WalletConnectClientError { - fn from(value: ClientError) -> Self { - WalletConnectClientError::ClientError(value) - } + fn from(error: ClientError) -> Self { WalletConnectClientError::ClientError(error.to_string()) } +} + +impl From> for WalletConnectClientError { + fn from(error: Error) -> Self { WalletConnectClientError::PublishError(format!("{error:?}")) } } diff --git a/mm2src/kdf_walletconnect/src/handler.rs b/mm2src/kdf_walletconnect/src/handler.rs index cdd69d0910..3288bed03c 100644 --- a/mm2src/kdf_walletconnect/src/handler.rs +++ b/mm2src/kdf_walletconnect/src/handler.rs @@ -1,8 +1,10 @@ use std::time::Duration; -use futures::channel::mpsc::UnboundedSender; -use relay_client::{error::ClientError, websocket::{CloseFrame, ConnectionHandler, PublishedMessage}, ConnectionOptions}; use common::log::info; +use futures::channel::mpsc::UnboundedSender; +use relay_client::{error::ClientError, + websocket::{CloseFrame, ConnectionHandler, PublishedMessage}, + ConnectionOptions}; use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; pub struct Handler { @@ -11,9 +13,7 @@ pub struct Handler { } impl Handler { - pub fn new(name: &'static str, sender: UnboundedSender) -> Self { - Self { name, sender } - } + pub fn new(name: &'static str, sender: UnboundedSender) -> Self { Self { name, sender } } } impl ConnectionHandler for Handler { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index bc984785f3..f83811824e 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,24 +1,39 @@ -use std::{collections::HashMap, sync::Arc, time::Duration}; +mod error; +mod handler; +mod session_key; +use common::log::info; use error::WalletConnectClientError; -use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex, StreamExt}; +use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, + lock::Mutex, + StreamExt}; use handler::Handler; use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::*; use pairing_api::{Methods, PairingClient}; -use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; -use relay_rpc::{domain::{MessageId, SubscriptionId, Topic}, rpc::{params::{IrnMetadata, Metadata}, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; +use relay_client::{websocket::{Client, PublishedMessage}, + ConnectionOptions, MessageIdGenerator}; +use relay_rpc::{domain::{MessageId, SubscriptionId, Topic}, + rpc::{params::{IrnMetadata, Metadata}, + Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; use session_key::SessionKey; -use mm2_err_handle::prelude::*; +use std::{collections::HashMap, sync::Arc, time::Duration}; use wc_common::{encrypt_and_encode, EnvelopeType}; -use common::log::info; - - -mod session_key; -mod handler; -mod error; -pub const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com"; -pub const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b"; +const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com"; +const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b"; +const SUPPORTED_PROTOCOL: &str = "irn"; +const SUPPORTED_METHODS: &[&str] = &[ + "eth_sendTransaction", + "eth_signTransaction", + "eth_sign", + "personal_sign", + "eth_signTypedData", + "eth_signTypedData_v4", +]; +const SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5"]; +const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; +const SUPPORTED_ACCOUNTS: &[&str] = &["eip155:5:0xBA5BA3955463ADcc7aa3E33bbdfb8A68e0933dD8"]; #[derive(Debug)] pub struct Session { @@ -28,136 +43,148 @@ pub struct Session { pub session_key: SessionKey, } -#[derive(Debug)] pub struct WalletConnectClient { - pub client: Arc, - pub pairing: Arc, - pub sessions: HashMap, - pub handler: Arc>> + pub client: Client, + pub pairing: PairingClient, + pub sessions: Arc>>, + pub handler: Arc>>, + pub rpc_handler: Arc>>, + pub rpc_sender: UnboundedSender, } impl Default for WalletConnectClient { - fn default() -> Self { - Self::new() - } + fn default() -> Self { Self::new() } } impl WalletConnectClient { pub fn new() -> Self { let (msg_sender, msg_receiver) = unbounded(); + let (rpc_sender, rpc_receiver) = unbounded::(); let pairing = PairingClient::new(); - let client = Arc::new(Client::new(Handler::new("Komodefi", msg_sender))); + let client = Client::new(Handler::new("Komodefi", msg_sender)); Self { client, pairing, - sessions: HashMap::new(), - handler: Arc::new(Mutex::new(msg_receiver)) + rpc_sender, + sessions: Arc::new(Mutex::new(HashMap::new())), + handler: Arc::new(Mutex::new(msg_receiver)), + rpc_handler: Arc::new(Mutex::new(rpc_receiver)), } } - pub async fn create_pairing(&self, metadata: Metadata, methods: Option) -> MmResult<(Topic, String), WalletConnectClientError> { - Ok(self.pairing.create(metadata, methods, &self.client).await?) + pub async fn create_pairing( + &self, + metadata: Metadata, + methods: Option, + ) -> MmResult<(Topic, String), WalletConnectClientError> { + Ok(self.pairing.create(metadata, methods, &self.client).await?) } pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { - Ok(self.pairing.pair(url, activate, &self.client).await?) + Ok(self.pairing.pair(url, activate, &self.client).await?) } pub async fn connect(&self, opts: &ConnectionOptions) -> MmResult<(), WalletConnectClientError> { Ok(self.client.connect(opts).await?) } - /// Private function to publish a request. - async fn publish_request( - &self, - topic: &str, - params: Params, - irn_metadata: IrnMetadata - ) -> MmResult<(), WalletConnectClientError> { - let message_id = MessageIdGenerator::new().next(); - let request = Request::new(message_id, params); - // Publish the encrypted message - self.publish_payload(topic, irn_metadata, Payload::Request(request)) - .await?; - - info!("Otbound request sent!\n"); - - Ok(()) - } - - /// Private function to publish a request response. - async fn publish_response( - &self, - topic: &str, - params: Params, - irn_metadata: IrnMetadata, - message_id: MessageId, - ) -> MmResult<(), WalletConnectClientError> { - let response = Response::Success(SuccessfulResponse { - id: message_id, - jsonrpc: JSON_RPC_VERSION_STR.into(), - result: serde_json::to_value(params) - .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?, - }); - - // Publish the encrypted message - self.publish_payload(topic, irn_metadata, Payload::Response(response)) - .await?; - - println!("\nOutbound request sent!"); - - Ok(()) - } - - - /// Private function to publish a payload. - async fn publish_payload( - &self, - topic: &str, - irn_metadata: IrnMetadata, - payload: Payload, - ) -> MmResult<(), WalletConnectClientError> { - // try to extend session before updating local store. - let sym_key = { - let pairings = self.pairing.pairings.lock().await; - let pairing = pairings - .get(topic) - .ok_or_else(|| WalletConnectClientError::PairingNotFound(format!("Pariring not found for topic:{topic}")))?; - hex::decode(pairing.sym_key.clone()).map_to_mm(|err| { - WalletConnectClientError::EncodeError(format!("Failed to decode sym_key: {:?}", err)) - })? - }; - - let payload = serde_json::to_string(&payload) - .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; - let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key) - .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; - - // Publish the encrypted message - { - self.client - .publish( - topic.into(), - message, - None, - irn_metadata.tag, - Duration::from_secs(irn_metadata.ttl), - irn_metadata.prompt, - ) - .await - .map_to_mm(WalletConnectClientError::PublishError)?; - }; - - Ok(()) - } + async fn publish_request( + &self, + topic: &str, + params: Params, + irn_metadata: IrnMetadata, + ) -> MmResult<(), WalletConnectClientError> { + let message_id = MessageIdGenerator::new().next(); + let request = Request::new(message_id, params); + // Publish the encrypted message + self.publish_payload(topic, irn_metadata, Payload::Request(request)) + .await?; + + info!("Otbound request sent!\n"); + + Ok(()) + } + + /// Private function to publish a request response. + async fn publish_response( + &self, + topic: &str, + params: Params, + irn_metadata: IrnMetadata, + message_id: MessageId, + ) -> MmResult<(), WalletConnectClientError> { + let response = Response::Success(SuccessfulResponse { + id: message_id, + jsonrpc: JSON_RPC_VERSION_STR.into(), + result: serde_json::to_value(params) + .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?, + }); + + // Publish the encrypted message + self.publish_payload(topic, irn_metadata, Payload::Response(response)) + .await?; + + println!("\nOutbound request sent!"); + + Ok(()) + } + + /// Private function to publish a payload. + async fn publish_payload( + &self, + topic: &str, + irn_metadata: IrnMetadata, + payload: Payload, + ) -> MmResult<(), WalletConnectClientError> { + // try to extend session before updating local store. + let sym_key = { + let pairings = self.pairing.pairings.lock().await; + let pairing = pairings.get(topic).ok_or_else(|| { + WalletConnectClientError::PairingNotFound(format!("Pariring not found for topic:{topic}")) + })?; + hex::decode(pairing.sym_key.clone()).map_to_mm(|err| { + WalletConnectClientError::EncodeError(format!("Failed to decode sym_key: {:?}", err)) + })? + }; + + let payload = + serde_json::to_string(&payload).map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; + let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key) + .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; + + // Publish the encrypted message + { + self.client + .publish( + topic.into(), + message, + None, + irn_metadata.tag, + Duration::from_secs(irn_metadata.ttl), + irn_metadata.prompt, + ) + .await?; + }; + + Ok(()) + } } pub async fn published_message_event_loop(client: Arc) { let mut recv = client.handler.lock().await; - while let Some(data) = recv.next().await { + while let Some(msg) = recv.next().await { + info!("Pulished Message: {msg:?}"); + todo!() + } +} + +pub async fn wc_rpc_event_loop(receiver: Arc>>) { + let mut recv = receiver.lock().await; + while let Some(param) = recv.next().await { + info!("Params: {param:?}"); todo!() } } diff --git a/mm2src/kdf_walletconnect/src/session_key.rs b/mm2src/kdf_walletconnect/src/session_key.rs index 84e7958bee..ecab541f6f 100644 --- a/mm2src/kdf_walletconnect/src/session_key.rs +++ b/mm2src/kdf_walletconnect/src/session_key.rs @@ -1,10 +1,8 @@ -use { - hkdf::Hkdf, - rand::{rngs::OsRng, CryptoRng, RngCore}, - sha2::{Digest, Sha256}, - std::fmt::Debug, - x25519_dalek::{EphemeralSecret, PublicKey}, -}; +use {hkdf::Hkdf, + rand::{rngs::OsRng, CryptoRng, RngCore}, + sha2::{Digest, Sha256}, + std::fmt::Debug, + x25519_dalek::{EphemeralSecret, PublicKey}}; /// Session key and topic derivation errors. #[derive(Debug, thiserror::Error)] @@ -35,8 +33,8 @@ impl SessionKey { /// Performs Diffie-Hellman symmetric key derivation. pub fn diffie_hellman(csprng: T, sender_public_key: &[u8; 32]) -> Result - where - T: RngCore + CryptoRng, + where + T: RngCore + CryptoRng, { let single_use_private_key = EphemeralSecret::random_from_rng(csprng); let public_key = PublicKey::from(&single_use_private_key); @@ -55,14 +53,10 @@ impl SessionKey { } /// Gets symmetic key reference. - pub fn symmetric_key(&self) -> &[u8; 32] { - &self.sym_key - } + pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } /// Gets "our" public key used in symmetric key derivation. - pub fn diffie_public_key(&self) -> &[u8; 32] { - self.public_key.as_bytes() - } + pub fn diffie_public_key(&self) -> &[u8; 32] { self.public_key.as_bytes() } /// Generates new session topic. pub fn generate_topic(&self) -> String { diff --git a/mm2src/mm2_core/Cargo.toml b/mm2src/mm2_core/Cargo.toml index 943dcac280..47c9d4270f 100644 --- a/mm2src/mm2_core/Cargo.toml +++ b/mm2src/mm2_core/Cargo.toml @@ -16,6 +16,7 @@ db_common = { path = "../db_common" } derive_more = "0.99" futures = { version = "0.3", package = "futures", features = ["compat", "async-await", "thread-pool"] } hex = "0.4.2" +kdf_walletconnect = { path = "../kdf_walletconnect" } lazy_static = "1.4" mm2_err_handle = { path = "../mm2_err_handle" } mm2_event_stream = { path = "../mm2_event_stream" } @@ -32,7 +33,7 @@ uuid = { version = "1.2.2", features = ["fast-rng", "serde", "v4"] } [target.'cfg(target_arch = "wasm32")'.dependencies] gstuff = { version = "0.7", features = ["nightly"] } instant = { version = "0.1.12", features = ["wasm-bindgen"] } -mm2_rpc = { path = "../mm2_rpc", features = [ "rpc_facilities" ] } +mm2_rpc = { path = "../mm2_rpc", features = ["rpc_facilities"] } wasm-bindgen-test = { version = "0.3.2" } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs index e891f0b649..8b95f8bf0d 100644 --- a/mm2src/mm2_core/src/mm_ctx.rs +++ b/mm2src/mm2_core/src/mm_ctx.rs @@ -5,6 +5,7 @@ use common::executor::{abortable_queue::{AbortableQueue, WeakSpawner}, use common::log::{self, LogLevel, LogOnError, LogState}; use common::{cfg_native, cfg_wasm32, small_rng}; use gstuff::{try_s, Constructible, ERR, ERRL}; +use kdf_walletconnect::WalletConnectClient; use lazy_static::lazy_static; use mm2_event_stream::{controller::Controller, Event, EventStreamConfiguration}; use mm2_metrics::{MetricsArc, MetricsOps}; @@ -84,7 +85,7 @@ pub struct MmCtx { pub event_stream_configuration: Option, /// True if the MarketMaker instance needs to stop. pub stop: Constructible, - /// Unique context identifier, allowing us to more easily pass the context through the FFI boundaries. + /// Unique context identifier, allowing us to more easily pass the context through the FFI boundaries. /// 0 if the handler ID is allocated yet. pub ffi_handle: Constructible, /// The context belonging to the `ordermatch` mod: `OrdermatchContext`. @@ -142,6 +143,7 @@ pub struct MmCtx { /// asynchronous handle for rusqlite connection. #[cfg(not(target_arch = "wasm32"))] pub async_sqlite_connection: Constructible>>, + pub wallect_connect: Arc, } impl MmCtx { @@ -191,6 +193,7 @@ impl MmCtx { nft_ctx: Mutex::new(None), #[cfg(not(target_arch = "wasm32"))] async_sqlite_connection: Constructible::default(), + wallect_connect: Arc::new(WalletConnectClient::default()), } } @@ -293,7 +296,7 @@ impl MmCtx { db_root.join(wallet_name.to_string() + ".dat") } - /// MM database path. + /// MM database path. /// Defaults to a relative "DB". /// /// Can be changed via the "dbdir" configuration field, for example: @@ -565,7 +568,7 @@ impl MmArc { } } - /// Tries getting access to the MM context. + /// Tries getting access to the MM context. /// Fails if an invalid MM context handler is passed (no such context or dropped context). #[track_caller] pub fn from_ffi_handle(ffi_handle: u32) -> Result { diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index 2709d76f32..6003f9f6c2 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -51,7 +51,7 @@ mod dispatcher_legacy; pub mod lp_commands_legacy; mod rate_limiter; -/// Lists the RPC method not requiring the "userpass" authentication. +/// Lists the RPC method not requiring the "userpass" authentication. /// None is also public to skip auth and display proper error in case of method is missing const PUBLIC_METHODS: &[Option<&str>] = &[ // Sorted alphanumerically (on the first letter) for readability. From 0eea639f359c7aefa22e947f8b00479a94606826 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 11 Sep 2024 15:19:35 +0100 Subject: [PATCH 004/125] rough implementations --- mm2src/crypto/src/walletconnect.rs | 0 mm2src/kdf_walletconnect/Cargo.toml | 1 + mm2src/kdf_walletconnect/src/error.rs | 28 +- mm2src/kdf_walletconnect/src/handler.rs | 18 +- mm2src/kdf_walletconnect/src/lib.rs | 241 ++++++++++----- mm2src/kdf_walletconnect/src/pairing.rs | 50 ++++ mm2src/kdf_walletconnect/src/session.rs | 281 ++++++++++++++++++ mm2src/kdf_walletconnect/src/session_key.rs | 3 +- mm2src/mm2_core/src/mm_ctx.rs | 6 +- mm2src/mm2_main/src/lp_native_dex.rs | 8 + mm2src/mm2_main/src/rpc.rs | 2 +- .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 2 + .../src/rpc/lp_commands/lp_commands.rs | 28 ++ 13 files changed, 564 insertions(+), 104 deletions(-) create mode 100644 mm2src/crypto/src/walletconnect.rs create mode 100644 mm2src/kdf_walletconnect/src/pairing.rs create mode 100644 mm2src/kdf_walletconnect/src/session.rs diff --git a/mm2src/crypto/src/walletconnect.rs b/mm2src/crypto/src/walletconnect.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index f8198bbb3c..8292020592 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] # chacha20poly1305 = "0.10" +chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } derive_more = "0.99" futures = { version = "0.3", package = "futures", features = [ diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 5c369ab7d8..6968182711 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -1,26 +1,38 @@ use derive_more::Display; use pairing_api::PairingClientError; use relay_client::error::{ClientError, Error}; -use relay_rpc::rpc::PublishError; +use relay_rpc::rpc::{PublishError, SubscriptionError}; use serde::{Deserialize, Serialize}; #[derive(Debug, Display, Serialize, Deserialize)] -pub enum WalletConnectClientError { +pub enum WalletConnectCtxError { PairingError(String), EncodeError(String), PublishError(String), ClientError(String), PairingNotFound(String), + SubscriptionError(String), + InternalError(String), + SerdeError(String), + UnsuccessfulResponse(String) } -impl From for WalletConnectClientError { - fn from(error: PairingClientError) -> Self { WalletConnectClientError::PairingError(error.to_string()) } +impl From for WalletConnectCtxError { + fn from(error: PairingClientError) -> Self { WalletConnectCtxError::PairingError(error.to_string()) } } -impl From for WalletConnectClientError { - fn from(error: ClientError) -> Self { WalletConnectClientError::ClientError(error.to_string()) } +impl From for WalletConnectCtxError { + fn from(error: ClientError) -> Self { WalletConnectCtxError::ClientError(error.to_string()) } } -impl From> for WalletConnectClientError { - fn from(error: Error) -> Self { WalletConnectClientError::PublishError(format!("{error:?}")) } +impl From> for WalletConnectCtxError { + fn from(error: Error) -> Self { WalletConnectCtxError::PublishError(format!("{error:?}")) } +} + +impl From> for WalletConnectCtxError { + fn from(error: Error) -> Self { WalletConnectCtxError::SubscriptionError(format!("{error:?}")) } +} + +impl From for WalletConnectCtxError { + fn from(value: serde_json::Error) -> Self { WalletConnectCtxError::SerdeError(value.to_string()) } } diff --git a/mm2src/kdf_walletconnect/src/handler.rs b/mm2src/kdf_walletconnect/src/handler.rs index 3288bed03c..5c92d42998 100644 --- a/mm2src/kdf_walletconnect/src/handler.rs +++ b/mm2src/kdf_walletconnect/src/handler.rs @@ -1,11 +1,7 @@ -use std::time::Duration; - use common::log::info; use futures::channel::mpsc::UnboundedSender; use relay_client::{error::ClientError, - websocket::{CloseFrame, ConnectionHandler, PublishedMessage}, - ConnectionOptions}; -use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; + websocket::{CloseFrame, ConnectionHandler, PublishedMessage}}; pub struct Handler { name: &'static str, @@ -44,15 +40,3 @@ impl ConnectionHandler for Handler { info!("\n[{}] outbound error: {error}", self.name); } } - -fn create_conn_opts(relay_address: &str, project_id: &str) -> ConnectionOptions { - let key = SigningKey::generate(&mut rand::thread_rng()); - - let auth = AuthToken::new("https://komodefi.com") - .aud(relay_address) - .ttl(Duration::from_secs(60 * 60)) - .as_jwt(&key) - .unwrap(); - - ConnectionOptions::new(project_id, auth).with_address(relay_address) -} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index f83811824e..fd9c164149 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,27 +1,33 @@ mod error; mod handler; +mod pairing; +mod session; mod session_key; use common::log::info; -use error::WalletConnectClientError; -use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, +use error::WalletConnectCtxError; +use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex, StreamExt}; use handler::Handler; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; +use pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}; use pairing_api::{Methods, PairingClient}; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; -use relay_rpc::{domain::{MessageId, SubscriptionId, Topic}, - rpc::{params::{IrnMetadata, Metadata}, +use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, + domain::{MessageId, Topic}, + rpc::{params::{IrnMetadata, Metadata, ResponseParamsSuccess}, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; -use session_key::SessionKey; -use std::{collections::HashMap, sync::Arc, time::Duration}; -use wc_common::{encrypt_and_encode, EnvelopeType}; +use session::{Session, APP_DESCRIPTION, APP_NAME}; +use std::{sync::Arc, time::Duration}; +use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com"; const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b"; +const AUTH_TOKEN_SUB: &str = "http://127.0.0.1:8000"; + const SUPPORTED_PROTOCOL: &str = "irn"; const SUPPORTED_METHODS: &[&str] = &[ "eth_sendTransaction", @@ -35,31 +41,20 @@ const SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5"]; const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; const SUPPORTED_ACCOUNTS: &[&str] = &["eip155:5:0xBA5BA3955463ADcc7aa3E33bbdfb8A68e0933dD8"]; -#[derive(Debug)] -pub struct Session { - /// Pairing subscription id. - pub subscription_id: SubscriptionId, - /// Session symmetric key. - pub session_key: SessionKey, -} - -pub struct WalletConnectClient { +pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, - pub sessions: Arc>>, + pub session: Session, pub handler: Arc>>, - pub rpc_handler: Arc>>, - pub rpc_sender: UnboundedSender, } -impl Default for WalletConnectClient { +impl Default for WalletConnectCtx { fn default() -> Self { Self::new() } } -impl WalletConnectClient { +impl WalletConnectCtx { pub fn new() -> Self { let (msg_sender, msg_receiver) = unbounded(); - let (rpc_sender, rpc_receiver) = unbounded::(); let pairing = PairingClient::new(); let client = Client::new(Handler::new("Komodefi", msg_sender)); @@ -67,39 +62,78 @@ impl WalletConnectClient { Self { client, pairing, - rpc_sender, - sessions: Arc::new(Mutex::new(HashMap::new())), + session: Session::new(), handler: Arc::new(Mutex::new(msg_receiver)), - rpc_handler: Arc::new(Mutex::new(rpc_receiver)), } } - pub async fn create_pairing( - &self, - metadata: Metadata, - methods: Option, - ) -> MmResult<(Topic, String), WalletConnectClientError> { - Ok(self.pairing.create(metadata, methods, &self.client).await?) + pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { + let auth = { + let key = SigningKey::generate(&mut rand::thread_rng()); + AuthToken::new(AUTH_TOKEN_SUB) + .aud(RELAY_ADDRESS) + .ttl(Duration::from_secs(60 * 60)) + .as_jwt(&key) + .unwrap() + }; + let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); + self.client.connect(&opts).await?; + + info!("WC connected"); + + Ok(()) } - pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { - Ok(self.pairing.pair(url, activate, &self.client).await?) + // todo: return slice + async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { + println!("sym topic: {topic:?}"); + { + let sessions = self.session.lock().await; + if let Some(sesssion) = sessions.get(topic) { + return Ok(sesssion.session_key.symmetric_key().to_vec()); + } + } + + { + let pairings = self.pairing.pairings.lock().await; + if let Some(pairing) = pairings.get(topic.as_ref()) { + let key = hex::decode(pairing.sym_key.clone()) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + return Ok(key); + } + } + + MmError::err(WalletConnectCtxError::PairingNotFound("Topic not found".to_owned())) } - pub async fn connect(&self, opts: &ConnectionOptions) -> MmResult<(), WalletConnectClientError> { - Ok(self.client.connect(opts).await?) + pub async fn create_pairing(&self) -> MmResult<(Topic, String), WalletConnectCtxError> { + let metadata = Metadata { + description: APP_DESCRIPTION.to_owned(), + url: "127.0.0.1:3000".to_owned(), + icons: vec![], + name: APP_NAME.to_owned(), + }; + let methods = Methods(vec![SUPPORTED_METHODS + .iter() + .map(|m| m.to_string()) + .collect::>()]); + + Ok(self.pairing.create(metadata, Some(methods), &self.client).await?) + } + + pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { + Ok(self.pairing.pair(url, activate, &self.client).await?) } /// Private function to publish a request. async fn publish_request( &self, - topic: &str, + topic: &Topic, params: Params, irn_metadata: IrnMetadata, - ) -> MmResult<(), WalletConnectClientError> { + ) -> MmResult<(), WalletConnectCtxError> { let message_id = MessageIdGenerator::new().next(); let request = Request::new(message_id, params); - // Publish the encrypted message self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; @@ -111,55 +145,42 @@ impl WalletConnectClient { /// Private function to publish a request response. async fn publish_response( &self, - topic: &str, - params: Params, + topic: &Topic, + params: serde_json::Value, irn_metadata: IrnMetadata, message_id: MessageId, - ) -> MmResult<(), WalletConnectClientError> { + ) -> MmResult<(), WalletConnectCtxError> { let response = Response::Success(SuccessfulResponse { id: message_id, jsonrpc: JSON_RPC_VERSION_STR.into(), - result: serde_json::to_value(params) - .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?, + result: params, }); - // Publish the encrypted message self.publish_payload(topic, irn_metadata, Payload::Response(response)) .await?; - println!("\nOutbound request sent!"); - Ok(()) } /// Private function to publish a payload. async fn publish_payload( &self, - topic: &str, + topic: &Topic, irn_metadata: IrnMetadata, payload: Payload, - ) -> MmResult<(), WalletConnectClientError> { - // try to extend session before updating local store. - let sym_key = { - let pairings = self.pairing.pairings.lock().await; - let pairing = pairings.get(topic).ok_or_else(|| { - WalletConnectClientError::PairingNotFound(format!("Pariring not found for topic:{topic}")) - })?; - hex::decode(pairing.sym_key.clone()).map_to_mm(|err| { - WalletConnectClientError::EncodeError(format!("Failed to decode sym_key: {:?}", err)) - })? - }; + ) -> MmResult<(), WalletConnectCtxError> { + let sym_key = self.sym_key(topic).await?; let payload = - serde_json::to_string(&payload).map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; - let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key) - .map_to_mm(|err| WalletConnectClientError::EncodeError(err.to_string()))?; + serde_json::to_string(&payload).map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + info!("\n Sending Outbound request: {payload}!"); - // Publish the encrypted message + let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; { self.client .publish( - topic.into(), + topic.clone(), message, None, irn_metadata.tag, @@ -171,20 +192,92 @@ impl WalletConnectClient { Ok(()) } -} -pub async fn published_message_event_loop(client: Arc) { - let mut recv = client.handler.lock().await; - while let Some(msg) = recv.next().await { - info!("Pulished Message: {msg:?}"); - todo!() + pub async fn published_message_event_loop(self: Arc) { + let mut recv = self.handler.lock().await; + while let Some(msg) = recv.next().await { + let message = { + let key = self.sym_key(&msg.topic).await.unwrap(); + decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() + }; + + println!("\nInbound message payload={message}"); + + let response = serde_json::from_str::(&message).unwrap(); + let result = match response { + Payload::Request(request) => process_inbound_request(self.clone(), request, &msg.topic).await, + Payload::Response(response) => process_inbound_response(self.clone(), response).await, + }; + + match result { + Ok(()) => info!("Inbound message was handled succesfully"), + Err(err) => info!("Error while handling inbound message: {err:?}"), + }; + } } } -pub async fn wc_rpc_event_loop(receiver: Arc>>) { - let mut recv = receiver.lock().await; - while let Some(param) = recv.next().await { - info!("Params: {param:?}"); - todo!() +async fn process_inbound_request( + ctx: Arc, + request: Request, + topic: &Topic, +) -> MmResult<(), WalletConnectCtxError> { + let response = match request.params { + Params::SessionPropose(proposal) => ctx.session.process_proposal_request(&ctx, proposal).await, + Params::SessionExtend(param) => ctx.session.process_session_extend_request(topic, param).await, + Params::SessionDelete(param) => ctx.session.process_session_delete_request(param), + Params::SessionPing(()) => ctx.session.process_session_ping_request(), + Params::SessionSettle(param) => ctx.session.process_session_settle_request(topic, param).await, + Params::SessionUpdate(param) => ctx.session.process_session_update_request(topic, param).await, + Params::SessionRequest(_) => todo!(), + Params::SessionEvent(_) => todo!(), + + Params::PairingPing(_param) => process_pairing_ping_response().await, + Params::PairingDelete(param) => process_pairing_delete_response(&ctx, topic, param).await, + Params::PairingExtend(param) => process_pairing_extend_response(&ctx, topic, param).await, + _ => todo!(), + }?; + + info!("Publishing reponse"); + ctx.publish_response(topic, response.0, response.1, request.id).await?; + + // todo + // ctx.session.session_delete_cleanup(ctx.clone(), topic).await? + + Ok(()) +} + +async fn process_inbound_response( + _ctx: Arc, + response: Response, +) -> MmResult<(), WalletConnectCtxError> { + match response { + Response::Success(value) => { + let params = serde_json::from_value::(value.result)?; + match params { + ResponseParamsSuccess::SessionPropose(param) => { + info!("Session Propose Response: {param:?}"); + todo!() + }, + ResponseParamsSuccess::SessionSettle(success) | ResponseParamsSuccess::SessionUpdate(success) |ResponseParamsSuccess::SessionExtend(success) + | ResponseParamsSuccess::SessionRequest(success) + | ResponseParamsSuccess::SessionEvent(success) + | ResponseParamsSuccess::SessionDelete(success) + | ResponseParamsSuccess::SessionPing(success) + | ResponseParamsSuccess::PairingExtend(success) + | ResponseParamsSuccess::PairingDelete(success) + | ResponseParamsSuccess::PairingPing(success) => { + if !success { + return MmError::err(WalletConnectCtxError::UnsuccessfulResponse(format!("Unsuccessful response={params:?}"))); + } + + Ok(()) + }, + } + }, + Response::Error(err) => { + println!("Error: {err:?}"); + todo!() + }, } } diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs new file mode 100644 index 0000000000..a781722e90 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -0,0 +1,50 @@ +use crate::{error::WalletConnectCtxError, session::WcRequestResult, WalletConnectCtx}; + +use relay_rpc::rpc::params::RelayProtocolMetadata; +use relay_rpc::{domain::Topic, + rpc::params::{pairing_delete::PairingDeleteRequest, pairing_extend::PairingExtendRequest, + ResponseParamsSuccess}}; + +pub(crate) async fn process_pairing_ping_response() -> WcRequestResult { + let response = ResponseParamsSuccess::PairingPing(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) +} + +pub(crate) async fn process_pairing_extend_response( + ctx: &WalletConnectCtx, + topic: &Topic, + extend: PairingExtendRequest, +) -> WcRequestResult { + { + let mut pairings = ctx.pairing.pairings.lock().await; + if let Some(pairing) = pairings.get_mut(topic.as_ref()) { + pairing.pairing.expiry = extend.expiry; + pairing.pairing.active = true; + }; + } + + let response = ResponseParamsSuccess::PairingPing(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) +} + +pub(crate) async fn process_pairing_delete_response( + ctx: &WalletConnectCtx, + topic: &Topic, + _delete: PairingDeleteRequest, +) -> WcRequestResult { + { + ctx.pairing.disconnect(topic.as_ref(), &ctx.client).await?; + } + + let response = ResponseParamsSuccess::PairingDelete(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) +} diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs new file mode 100644 index 0000000000..67f2ece7ab --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -0,0 +1,281 @@ +use crate::{error::WalletConnectCtxError, session_key::SessionKey, WalletConnectCtx, SUPPORTED_ACCOUNTS, + SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; +use chrono::Utc; +use common::log::info; +use futures::lock::Mutex; +use mm2_err_handle::prelude::{MapToMmResult, MmResult}; +use relay_rpc::rpc::params::session_delete::SessionDeleteRequest; +use relay_rpc::rpc::params::session_extend::SessionExtendRequest; +use relay_rpc::rpc::params::session_update::SessionUpdateRequest; +use relay_rpc::rpc::params::{IrnMetadata, RelayProtocolMetadata}; +use relay_rpc::{domain::{SubscriptionId, Topic}, + rpc::params::{session::{ProposeNamespace, ProposeNamespaces, SettleNamespace, SettleNamespaces}, + session_propose::{SessionProposeRequest, SessionProposeResponse}, + session_settle::{Controller, SessionSettleRequest}, + Metadata, Relay, RequestParams, ResponseParamsSuccess}}; +use serde_json::Value; +use std::collections::HashMap; +use std::ops::Deref; +use std::{collections::BTreeMap, sync::Arc}; + +pub(crate) const APP_NAME: &str = "Komodefi Framework"; +pub(crate) const APP_DESCRIPTION: &str = "WallectConnect Komodefi Framework Playground"; + +pub(crate) type WcRequestResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; + +#[derive(Debug, Clone)] +pub struct SessionInfo { + /// Pairing subscription id. + pub subscription_id: SubscriptionId, + /// Session symmetric key + pub session_key: SessionKey, + pub controller: Controller, + pub relay: Relay, + pub namespaces: ProposeNamespaces, + pub settled_namespaces: SettleNamespaces, + pub expiry: u64, +} + +impl SessionInfo { + fn new(subscription_id: SubscriptionId, session_key: SessionKey, responder_public_key: String) -> Self { + let mut namespaces = BTreeMap::::new(); + namespaces.insert("eip155".to_string(), ProposeNamespace { + chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + }); + let mut settled_namespaces = BTreeMap::::new(); + settled_namespaces.insert("eip155".to_string(), SettleNamespace { + accounts: SUPPORTED_ACCOUNTS.iter().map(|a| a.to_string()).collect(), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + }); + let relay = Relay { + protocol: SUPPORTED_PROTOCOL.to_string(), + data: None, + }; + let controller = Controller { + public_key: responder_public_key, + metadata: Metadata { + name: APP_NAME.to_owned(), + description: APP_DESCRIPTION.to_owned(), + icons: vec!["https://www.rust-lang.org/static/images/rust-logo-blk.svg".to_string()], + ..Default::default() + }, + }; + + Self { + subscription_id, + session_key, + controller, + namespaces: ProposeNamespaces(namespaces), + settled_namespaces: SettleNamespaces(settled_namespaces), + relay, + expiry: Utc::now().timestamp() as u64 + 300, + } + } + + fn supported_propose_namespaces(&self) -> &ProposeNamespaces { &self.namespaces } + fn supported_settle_namespaces(&self) -> &SettleNamespaces { &self.settled_namespaces } + fn create_settle_request(&self) -> RequestParams { + RequestParams::SessionSettle(SessionSettleRequest { + relay: self.relay.clone(), + controller: self.controller.clone(), + namespaces: self.supported_settle_namespaces().clone(), + expiry: Utc::now().timestamp() as u64 + 300, // 5 min TTL + }) + } + fn create_proposal_response(&self) -> Result<(Value, IrnMetadata), WalletConnectCtxError> { + let response = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { + relay: self.relay.clone(), + responder_public_key: self.controller.public_key.clone(), + }); + let irn_metadata = response.irn_metadata(); + let value = + serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) + } +} + +#[derive(Debug, Clone)] +pub struct Session { + session: Arc>>, +} + +impl Deref for Session { + type Target = Arc>>; + fn deref(&self) -> &Self::Target { &self.session } +} + +impl Default for Session { + fn default() -> Self { Self::new() } +} + +impl Session { + pub fn new() -> Self { + Self { + session: Default::default(), + } + } + + pub fn from_session_info(topic: Topic, session_info: SessionInfo) -> Self { + Self { + session: Arc::new(Mutex::new(HashMap::from([(topic, session_info)]))), + } + } + + pub(crate) async fn process_session_extend_request( + &self, + topic: &Topic, + extend: SessionExtendRequest, + ) -> WcRequestResult { + let mut sessions = self.session.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.expiry = extend.expiry; + info!("Updated extended, info: {:?}", session); + } + + let response = ResponseParamsSuccess::SessionExtend(true); + let irn_metadata = response.irn_metadata(); + let value = + serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) + } + + /// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal + pub async fn process_proposal_request( + &self, + ctx: &WalletConnectCtx, + proposal: SessionProposeRequest, + ) -> WcRequestResult { + let sender_public_key = hex::decode(&proposal.proposer.public_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? + .as_slice() + .try_into() + .unwrap(); + + let session_key = SessionKey::from_osrng(&sender_public_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let responder_public_key = hex::encode(session_key.diffie_public_key()); + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + + let session = SessionInfo::new(subscription_id, session_key, responder_public_key); + session + .supported_propose_namespaces() + .supported(&proposal.required_namespaces) + .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; + + { + let mut sessions = ctx.session.deref().lock().await; + _ = sessions.insert(session_topic.clone(), session.clone()); + } + + let settle_params = session.create_settle_request(); + let irn_metadata = settle_params.irn_metadata(); + ctx.publish_request(&session_topic, settle_params.into(), irn_metadata) + .await?; + + Ok(session.create_proposal_response()?) + } + + pub(crate) async fn process_session_settle_request( + &self, + topic: &Topic, + settle: SessionSettleRequest, + ) -> WcRequestResult { + { + let mut sessions = self.session.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.settled_namespaces = settle.namespaces.clone(); + session.controller = settle.controller.clone(); + session.relay = settle.relay.clone(); + session.expiry = settle.expiry; + + info!("Session successfully settled for topic: {:?}", topic); + info!("Updated session info: {:?}", session); + } + } + + let response = ResponseParamsSuccess::SessionSettle(true); + let irn_metadata = response.irn_metadata(); + let value = + serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) + } + + pub(crate) fn process_session_ping_request(&self) -> WcRequestResult { + let response = ResponseParamsSuccess::SessionPing(true); + let irn_metadata = response.irn_metadata(); + let value = + serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) + } + + pub(crate) fn process_session_delete_request(&self, delete_params: SessionDeleteRequest) -> WcRequestResult { + info!( + "\nSession is being terminated reason={}, code={}", + delete_params.message, delete_params.code, + ); + + let response = ResponseParamsSuccess::SessionDelete(true); + let irn_metadata = response.irn_metadata(); + let value = + serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) + } + + pub(crate) async fn session_delete_cleanup( + &self, + ctx: Arc, + topic: &Topic, + ) -> MmResult<(), WalletConnectCtxError> { + let mut sessions = ctx.session.lock().await; + sessions.remove(topic).ok_or_else(|| { + WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()) + })?; + + ctx.client.unsubscribe(topic.clone()).await?; + + // Check if there are no active sessions remaining + if sessions.is_empty() { + info!("\nNo active sessions left, disconnecting the pairing"); + + // Attempt to disconnect and remove the pairing associated with the topic + ctx.pairing + .disconnect(topic.as_ref(), &ctx.client) + .await + .map_err(|e| WalletConnectCtxError::InternalError(format!("Failed to disconnect pairing: {}", e)))?; + } + + Ok(()) + } + + pub(crate) async fn process_session_update_request( + &self, + topic: &Topic, + update: SessionUpdateRequest, + ) -> WcRequestResult { + let mut sessions = self.session.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.settled_namespaces = update.namespaces.clone(); + info!("Updated extended, info: {:?}", session); + } + + let response = ResponseParamsSuccess::SessionUpdate(true); + let irn_metadata = response.irn_metadata(); + let value = + serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + + Ok((value, irn_metadata)) + } +} diff --git a/mm2src/kdf_walletconnect/src/session_key.rs b/mm2src/kdf_walletconnect/src/session_key.rs index ecab541f6f..b1b1f7a89f 100644 --- a/mm2src/kdf_walletconnect/src/session_key.rs +++ b/mm2src/kdf_walletconnect/src/session_key.rs @@ -5,12 +5,13 @@ use {hkdf::Hkdf, x25519_dalek::{EphemeralSecret, PublicKey}}; /// Session key and topic derivation errors. -#[derive(Debug, thiserror::Error)] +#[derive(Debug, Clone, thiserror::Error)] pub enum SessionError { #[error("Failed to generate symmetric session key: {0}")] SymKeyGeneration(String), } +#[derive(Clone)] pub struct SessionKey { sym_key: [u8; 32], public_key: PublicKey, diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs index 8b95f8bf0d..f6ee573e6d 100644 --- a/mm2src/mm2_core/src/mm_ctx.rs +++ b/mm2src/mm2_core/src/mm_ctx.rs @@ -5,7 +5,7 @@ use common::executor::{abortable_queue::{AbortableQueue, WeakSpawner}, use common::log::{self, LogLevel, LogOnError, LogState}; use common::{cfg_native, cfg_wasm32, small_rng}; use gstuff::{try_s, Constructible, ERR, ERRL}; -use kdf_walletconnect::WalletConnectClient; +use kdf_walletconnect::WalletConnectCtx; use lazy_static::lazy_static; use mm2_event_stream::{controller::Controller, Event, EventStreamConfiguration}; use mm2_metrics::{MetricsArc, MetricsOps}; @@ -143,7 +143,7 @@ pub struct MmCtx { /// asynchronous handle for rusqlite connection. #[cfg(not(target_arch = "wasm32"))] pub async_sqlite_connection: Constructible>>, - pub wallect_connect: Arc, + pub wallect_connect: Arc, } impl MmCtx { @@ -193,7 +193,7 @@ impl MmCtx { nft_ctx: Mutex::new(None), #[cfg(not(target_arch = "wasm32"))] async_sqlite_connection: Constructible::default(), - wallect_connect: Arc::new(WalletConnectClient::default()), + wallect_connect: Arc::new(WalletConnectCtx::default()), } } diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index 3b73947ffb..286d0d0e02 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -472,6 +472,14 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { init_message_service(&ctx).await?; + // connect walletconnect + ctx.wallect_connect + .connect_client() + .await + .map_err(|err| MmInitError::WalletInitError(err.to_string()))?; + ctx.spawner() + .spawn(ctx.wallect_connect.clone().published_message_event_loop()); + let balance_update_ordermatch_handler = BalanceUpdateOrdermatchHandler::new(ctx.clone()); register_balance_update_handler(ctx.clone(), Box::new(balance_update_ordermatch_handler)).await; diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index 6003f9f6c2..bb07a3ef88 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -236,7 +236,7 @@ async fn process_single_request(ctx: MmArc, req: Json, client: SocketAddr) -> Re #[cfg(not(target_arch = "wasm32"))] async fn rpc_service(req: Request, ctx_h: u32, client: SocketAddr) -> Response { - const NON_ALLOWED_CHARS: &[char] = &['<', '>', '&']; + const NON_ALLOWED_CHARS: &[char] = &['Ã’']; /// Unwraps a result or propagates its error 500 response with the specified headers (if they are present). macro_rules! try_sf { diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index b9066bf540..f9fb65d111 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -1,3 +1,4 @@ +use super::lp_commands::connect_to_peer; use super::{DispatcherError, DispatcherResult, PUBLIC_METHODS}; use crate::lp_native_dex::init_hw::{cancel_init_trezor, init_trezor, init_trezor_status, init_trezor_user_action}; #[cfg(target_arch = "wasm32")] @@ -167,6 +168,7 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, add_node_to_version_stat).await, "best_orders" => handle_mmrpc(ctx, request, best_orders_rpc_v2).await, "clear_nft_db" => handle_mmrpc(ctx, request, clear_nft_db).await, + "wc_connect_to_peer" => handle_mmrpc(ctx, request, connect_to_peer).await, "enable_bch_with_tokens" => handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await, "enable_slp" => handle_mmrpc(ctx, request, enable_token::).await, "enable_eth_with_tokens" => handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await, diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs index ae992c6d3e..f206fe6c41 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs @@ -114,3 +114,31 @@ pub async fn trezor_connection_status( status: hw_ctx.trezor_connection_status().await, }) } + +use serde::Serialize; + +#[derive(Deserialize)] +pub struct CreatePairingRequest { + url: String, +} + +#[derive(Debug, PartialEq, Serialize)] +pub struct CreatePairingResponse { + pub topic: String, +} + +/// `connect_to_peer` RPC command implementation. +pub async fn connect_to_peer( + ctx: MmArc, + req: CreatePairingRequest, +) -> MmResult { + let topic = ctx + .wallect_connect + .connect_to_pairing(&req.url, true) + .await + .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; + + Ok(CreatePairingResponse { + topic: topic.to_string(), + }) +} From 588316fc66a7b342f6fbabbe6ee14ca824c5bb83 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 11 Sep 2024 15:19:46 +0100 Subject: [PATCH 005/125] commit lock file --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index 233c319211..c257e389c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3549,6 +3549,7 @@ dependencies = [ name = "kdf_walletconnect" version = "0.1.0" dependencies = [ + "chrono", "common", "derive_more", "futures 0.3.28", From 60a2fc5a2fffed4fc4d4f81dbce14a8f2dbbc0e0 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 12 Sep 2024 17:04:53 +0100 Subject: [PATCH 006/125] save dev state - handle connection close, session improvements, etc --- Cargo.lock | 2 + mm2src/coins/Cargo.toml | 2 + mm2src/kdf_walletconnect/Cargo.toml | 3 +- mm2src/kdf_walletconnect/src/error.rs | 2 +- mm2src/kdf_walletconnect/src/handler.rs | 21 +++- mm2src/kdf_walletconnect/src/lib.rs | 103 +++++++++++++++--- mm2src/kdf_walletconnect/src/session.rs | 76 +++++++++++-- mm2src/mm2_main/src/lp_native_dex.rs | 2 + .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 5 +- .../src/rpc/lp_commands/lp_commands.rs | 32 +++++- 10 files changed, 208 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c257e389c5..e1767f2209 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3560,6 +3560,7 @@ dependencies = [ "rand 0.8.4", "relay_client", "relay_rpc", + "secp256k1 0.20.3", "serde", "serde_json", "sha2 0.10.8", @@ -5337,6 +5338,7 @@ name = "pairing_api" version = "0.1.0" dependencies = [ "anyhow", + "chrono", "hex", "lazy_static", "paste", diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index db9414def1..732a6df7e2 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -187,3 +187,5 @@ wagyu-zcash-parameters = { version = "0.2" } [build-dependencies] prost-build = { version = "0.11", default-features = false } tonic-build = { version = "0.9", default-features = false, features = ["prost"] } + + diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 8292020592..343f7ea511 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -24,6 +24,7 @@ relay_rpc = { path = "../../../kdf-wc/relay_rpc" } sha2 = "0.10.8" thiserror = "1.0.40" wc_common = { path = "../../../kdf-wc/wc_common" } -x25519-dalek = { version = "2.0", features = ["static_secrets"] } +secp256k1 = { version = "0.20" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } +x25519-dalek = { version = "2.0", features = ["static_secrets"] } diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 6968182711..35f496fd61 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -14,7 +14,7 @@ pub enum WalletConnectCtxError { SubscriptionError(String), InternalError(String), SerdeError(String), - UnsuccessfulResponse(String) + UnsuccessfulResponse(String), } impl From for WalletConnectCtxError { diff --git a/mm2src/kdf_walletconnect/src/handler.rs b/mm2src/kdf_walletconnect/src/handler.rs index 5c92d42998..e4fbb5b164 100644 --- a/mm2src/kdf_walletconnect/src/handler.rs +++ b/mm2src/kdf_walletconnect/src/handler.rs @@ -5,11 +5,22 @@ use relay_client::{error::ClientError, pub struct Handler { name: &'static str, - sender: UnboundedSender, + msg_sender: UnboundedSender, + conn_live_sender: UnboundedSender<()>, } impl Handler { - pub fn new(name: &'static str, sender: UnboundedSender) -> Self { Self { name, sender } } + pub fn new( + name: &'static str, + msg_sender: UnboundedSender, + conn_live_sender: UnboundedSender<()>, + ) -> Self { + Self { + name, + msg_sender, + conn_live_sender, + } + } } impl ConnectionHandler for Handler { @@ -19,6 +30,10 @@ impl ConnectionHandler for Handler { fn disconnected(&mut self, frame: Option>) { info!("\n[{}] connection closed: frame={frame:?}", self.name); + + if let Err(e) = self.conn_live_sender.start_send(()) { + info!("\n[{}] failed to send the to the receiver: {e}", self.name); + } } fn message_received(&mut self, message: PublishedMessage) { @@ -27,7 +42,7 @@ impl ConnectionHandler for Handler { self.name, message.message_id, message.topic, message.tag, message.message, ); - if let Err(e) = self.sender.start_send(message) { + if let Err(e) = self.msg_sender.start_send(message) { info!("\n[{}] failed to send the to the receiver: {e}", self.name); } } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index fd9c164149..d082098572 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -14,13 +14,17 @@ use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; use pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}; use pairing_api::{Methods, PairingClient}; +use rand::rngs::OsRng; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; +use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, - rpc::{params::{IrnMetadata, Metadata, ResponseParamsSuccess}, + rpc::{params::{session_propose::SessionProposeRequest, IrnMetadata, Metadata, RequestParams, + ResponseParamsSuccess}, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; -use session::{Session, APP_DESCRIPTION, APP_NAME}; +use session::{Session, SessionInfo, SessionUserType, APP_DESCRIPTION, APP_NAME}; +use session_key::SessionKey; use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; @@ -45,7 +49,8 @@ pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, pub session: Session, - pub handler: Arc>>, + pub msg_handler: Arc>>, + pub connection_live_handler: Arc>>, } impl Default for WalletConnectCtx { @@ -55,15 +60,17 @@ impl Default for WalletConnectCtx { impl WalletConnectCtx { pub fn new() -> Self { let (msg_sender, msg_receiver) = unbounded(); + let (conn_live_sender, conn_live_receiver) = unbounded(); let pairing = PairingClient::new(); - let client = Client::new(Handler::new("Komodefi", msg_sender)); + let client = Client::new(Handler::new("Komodefi", msg_sender, conn_live_sender)); Self { client, pairing, session: Session::new(), - handler: Arc::new(Mutex::new(msg_receiver)), + msg_handler: Arc::new(Mutex::new(msg_receiver)), + connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), } } @@ -79,6 +86,7 @@ impl WalletConnectCtx { let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); self.client.connect(&opts).await?; + // let is_connected = self.client.; info!("WC connected"); Ok(()) @@ -86,7 +94,6 @@ impl WalletConnectCtx { // todo: return slice async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { - println!("sym topic: {topic:?}"); { let sessions = self.session.lock().await; if let Some(sesssion) = sessions.get(topic) { @@ -103,10 +110,12 @@ impl WalletConnectCtx { } } - MmError::err(WalletConnectCtxError::PairingNotFound("Topic not found".to_owned())) + MmError::err(WalletConnectCtxError::PairingNotFound(format!( + "Topic not found:{topic}" + ))) } - pub async fn create_pairing(&self) -> MmResult<(Topic, String), WalletConnectCtxError> { + pub async fn create_pairing(&self) -> MmResult { let metadata = Metadata { description: APP_DESCRIPTION.to_owned(), url: "127.0.0.1:3000".to_owned(), @@ -117,8 +126,47 @@ impl WalletConnectCtx { .iter() .map(|m| m.to_string()) .collect::>()]); + let (topic, url) = self + .pairing + .create(metadata.clone(), Some(methods), &self.client) + .await?; + + let signing_key = SigningKey::generate(&mut OsRng); + let public_key = signing_key.verifying_key(); + let session_key = SessionKey::from_osrng(public_key.as_bytes()) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = self + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + let session = SessionInfo::new( + subscription_id, + session_key, + topic.clone(), + metadata, + SessionUserType::Proposer, + ); + + let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { + relays: vec![session.relay.clone()], + proposer: session.proposer.clone(), + required_namespaces: session.namespaces.clone(), + }); + + // Store the session information in your session manager (self.sessions or similar) + { + let mut sessions = self.session.lock().await; + sessions.insert(session_topic.clone(), session); + } + + let irn_metadata = session_proposal.irn_metadata(); + self.publish_request(&topic, session_proposal.into(), irn_metadata) + .await?; - Ok(self.pairing.create(metadata, Some(methods), &self.client).await?) + let clean_url = url.replace("&", "&"); + Ok(clean_url) } pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { @@ -194,7 +242,7 @@ impl WalletConnectCtx { } pub async fn published_message_event_loop(self: Arc) { - let mut recv = self.handler.lock().await; + let mut recv = self.msg_handler.lock().await; while let Some(msg) = recv.next().await { let message = { let key = self.sym_key(&msg.topic).await.unwrap(); @@ -206,7 +254,7 @@ impl WalletConnectCtx { let response = serde_json::from_str::(&message).unwrap(); let result = match response { Payload::Request(request) => process_inbound_request(self.clone(), request, &msg.topic).await, - Payload::Response(response) => process_inbound_response(self.clone(), response).await, + Payload::Response(response) => process_inbound_response(self.clone(), response, &msg.topic).await, }; match result { @@ -215,6 +263,18 @@ impl WalletConnectCtx { }; } } + + pub async fn spawn_connection_live_watcher(self: Arc) { + let mut recv = self.connection_live_handler.lock().await; + while let Some(_msg) = recv.next().await { + info!("connection disconnected, reconnecting"); + if let Err(err) = self.connect_client().await { + common::log::error!("{err:?}"); + continue; + }; + info!("reconnecting success!"); + } + } } async fn process_inbound_request( @@ -223,7 +283,11 @@ async fn process_inbound_request( topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { let response = match request.params { - Params::SessionPropose(proposal) => ctx.session.process_proposal_request(&ctx, proposal).await, + Params::SessionPropose(proposal) => { + ctx.session + .process_proposal_request(&ctx, proposal, topic.clone()) + .await + }, Params::SessionExtend(param) => ctx.session.process_session_extend_request(topic, param).await, Params::SessionDelete(param) => ctx.session.process_session_delete_request(param), Params::SessionPing(()) => ctx.session.process_session_ping_request(), @@ -248,18 +312,21 @@ async fn process_inbound_request( } async fn process_inbound_response( - _ctx: Arc, + ctx: Arc, response: Response, + topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { match response { Response::Success(value) => { let params = serde_json::from_value::(value.result)?; match params { ResponseParamsSuccess::SessionPropose(param) => { - info!("Session Propose Response: {param:?}"); - todo!() + ctx.session.handle_session_propose_response(topic, param).await; + Ok(()) }, - ResponseParamsSuccess::SessionSettle(success) | ResponseParamsSuccess::SessionUpdate(success) |ResponseParamsSuccess::SessionExtend(success) + ResponseParamsSuccess::SessionSettle(success) + | ResponseParamsSuccess::SessionUpdate(success) + | ResponseParamsSuccess::SessionExtend(success) | ResponseParamsSuccess::SessionRequest(success) | ResponseParamsSuccess::SessionEvent(success) | ResponseParamsSuccess::SessionDelete(success) @@ -268,7 +335,9 @@ async fn process_inbound_response( | ResponseParamsSuccess::PairingDelete(success) | ResponseParamsSuccess::PairingPing(success) => { if !success { - return MmError::err(WalletConnectCtxError::UnsuccessfulResponse(format!("Unsuccessful response={params:?}"))); + return MmError::err(WalletConnectCtxError::UnsuccessfulResponse(format!( + "Unsuccessful response={params:?}" + ))); } Ok(()) diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 67f2ece7ab..fb96c65acc 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -6,6 +6,7 @@ use futures::lock::Mutex; use mm2_err_handle::prelude::{MapToMmResult, MmResult}; use relay_rpc::rpc::params::session_delete::SessionDeleteRequest; use relay_rpc::rpc::params::session_extend::SessionExtendRequest; +use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::session_update::SessionUpdateRequest; use relay_rpc::rpc::params::{IrnMetadata, RelayProtocolMetadata}; use relay_rpc::{domain::{SubscriptionId, Topic}, @@ -23,6 +24,12 @@ pub(crate) const APP_DESCRIPTION: &str = "WallectConnect Komodefi Framework Play pub(crate) type WcRequestResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; +#[derive(Debug, Clone)] +pub enum SessionUserType { + Controller, + Proposer, +} + #[derive(Debug, Clone)] pub struct SessionInfo { /// Pairing subscription id. @@ -30,48 +37,70 @@ pub struct SessionInfo { /// Session symmetric key pub session_key: SessionKey, pub controller: Controller, + pub proposer: Proposer, pub relay: Relay, pub namespaces: ProposeNamespaces, pub settled_namespaces: SettleNamespaces, pub expiry: u64, + pub pairing_topic: Topic, + pub session_type: SessionUserType, } impl SessionInfo { - fn new(subscription_id: SubscriptionId, session_key: SessionKey, responder_public_key: String) -> Self { + pub fn new( + subscription_id: SubscriptionId, + session_key: SessionKey, + pairing_topic: Topic, + metadata: Metadata, + session_type: SessionUserType, + ) -> Self { + // Initialize the namespaces for both proposer and controller let mut namespaces = BTreeMap::::new(); namespaces.insert("eip155".to_string(), ProposeNamespace { chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), }); + let mut settled_namespaces = BTreeMap::::new(); settled_namespaces.insert("eip155".to_string(), SettleNamespace { accounts: SUPPORTED_ACCOUNTS.iter().map(|a| a.to_string()).collect(), methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), }); + + // Initialize relay let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), data: None, }; - let controller = Controller { - public_key: responder_public_key, - metadata: Metadata { - name: APP_NAME.to_owned(), - description: APP_DESCRIPTION.to_owned(), - icons: vec!["https://www.rust-lang.org/static/images/rust-logo-blk.svg".to_string()], - ..Default::default() - }, + + // Conditional logic to handle proposer or controller + let (proposer, controller) = match session_type { + SessionUserType::Proposer => ( + Proposer { + public_key: hex::encode(session_key.diffie_public_key()), + metadata, + }, + Controller::default(), + ), + SessionUserType::Controller => (Proposer::default(), Controller { + public_key: hex::encode(session_key.diffie_public_key()), + metadata, + }), }; Self { subscription_id, session_key, controller, + proposer, namespaces: ProposeNamespaces(namespaces), settled_namespaces: SettleNamespaces(settled_namespaces), relay, expiry: Utc::now().timestamp() as u64 + 300, + pairing_topic, + session_type, } } @@ -125,6 +154,19 @@ impl Session { } } + pub(crate) async fn handle_session_propose_response( + &self, + session_topic: &Topic, + response: SessionProposeResponse, + ) { + let mut sessions = self.lock().await; + if let Some(session) = sessions.get_mut(session_topic) { + info!("session found!"); + session.proposer.public_key = response.responder_public_key; + session.relay = response.relay; + }; + } + pub(crate) async fn process_session_extend_request( &self, topic: &Topic, @@ -149,6 +191,7 @@ impl Session { &self, ctx: &WalletConnectCtx, proposal: SessionProposeRequest, + pairing_topic: Topic, ) -> WcRequestResult { let sender_public_key = hex::decode(&proposal.proposer.public_key) .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? @@ -158,7 +201,6 @@ impl Session { let session_key = SessionKey::from_osrng(&sender_public_key) .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; - let responder_public_key = hex::encode(session_key.diffie_public_key()); let session_topic: Topic = session_key.generate_topic().into(); let subscription_id = ctx .client @@ -166,7 +208,19 @@ impl Session { .await .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - let session = SessionInfo::new(subscription_id, session_key, responder_public_key); + let metadata = Metadata { + description: APP_DESCRIPTION.to_owned(), + url: "127.0.0.1:3000".to_owned(), + icons: vec![], + name: APP_NAME.to_owned(), + }; + let session = SessionInfo::new( + subscription_id, + session_key, + pairing_topic, + metadata, + SessionUserType::Controller, + ); session .supported_propose_namespaces() .supported(&proposal.required_namespaces) diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index 286d0d0e02..cb2d5e91e4 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -479,6 +479,8 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { .map_err(|err| MmInitError::WalletInitError(err.to_string()))?; ctx.spawner() .spawn(ctx.wallect_connect.clone().published_message_event_loop()); + ctx.spawner() + .spawn(ctx.wallect_connect.clone().spawn_connection_live_watcher()); let balance_update_ordermatch_handler = BalanceUpdateOrdermatchHandler::new(ctx.clone()); register_balance_update_handler(ctx.clone(), Box::new(balance_update_ordermatch_handler)).await; diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index f9fb65d111..ece20f9eda 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -1,4 +1,4 @@ -use super::lp_commands::connect_to_peer; +use super::lp_commands::{connect_to_peer, create_new_pairing}; use super::{DispatcherError, DispatcherResult, PUBLIC_METHODS}; use crate::lp_native_dex::init_hw::{cancel_init_trezor, init_trezor, init_trezor_status, init_trezor_user_action}; #[cfg(target_arch = "wasm32")] @@ -168,7 +168,8 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, add_node_to_version_stat).await, "best_orders" => handle_mmrpc(ctx, request, best_orders_rpc_v2).await, "clear_nft_db" => handle_mmrpc(ctx, request, clear_nft_db).await, - "wc_connect_to_peer" => handle_mmrpc(ctx, request, connect_to_peer).await, + "wc_connect_pairing" => handle_mmrpc(ctx, request, connect_to_peer).await, + "wc_create_pairing" => handle_mmrpc(ctx, request, create_new_pairing).await, "enable_bch_with_tokens" => handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await, "enable_slp" => handle_mmrpc(ctx, request, enable_token::).await, "enable_eth_with_tokens" => handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await, diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs index f206fe6c41..fdaaac19a5 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs @@ -118,27 +118,49 @@ pub async fn trezor_connection_status( use serde::Serialize; #[derive(Deserialize)] -pub struct CreatePairingRequest { +pub struct ConnectPairingRequest { url: String, } #[derive(Debug, PartialEq, Serialize)] -pub struct CreatePairingResponse { +pub struct ConnectPairingResponse { pub topic: String, } /// `connect_to_peer` RPC command implementation. pub async fn connect_to_peer( ctx: MmArc, - req: CreatePairingRequest, -) -> MmResult { + req: ConnectPairingRequest, +) -> MmResult { let topic = ctx .wallect_connect .connect_to_pairing(&req.url, true) .await .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; - Ok(CreatePairingResponse { + Ok(ConnectPairingResponse { topic: topic.to_string(), }) } + +#[derive(Debug, PartialEq, Serialize)] +pub struct CreatePairingResponse { + pub url: String, +} + +#[derive(Deserialize)] +pub struct CreatePairingRequest {} + +/// `create_new_pairing` RPC command implementation. +pub async fn create_new_pairing( + ctx: MmArc, + _req: CreatePairingRequest, +) -> MmResult { + let url = ctx + .wallect_connect + .create_pairing() + .await + .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; + + Ok(CreatePairingResponse { url }) +} From fd8797cca85338662cce082912db686ce7f1b350 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 12 Sep 2024 21:57:04 +0100 Subject: [PATCH 007/125] minor changes --- .../kdf_walletconnect/src/inbound_message.rs | 81 +++++++++++++++++ mm2src/kdf_walletconnect/src/lib.rs | 89 ++----------------- mm2src/kdf_walletconnect/src/session.rs | 10 ++- mm2src/mm2_test_helpers/src/for_tests.rs | 14 +-- 4 files changed, 103 insertions(+), 91 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/inbound_message.rs diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs new file mode 100644 index 0000000000..1c783f9cc5 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -0,0 +1,81 @@ +use std::sync::Arc; + +use mm2_err_handle::prelude::{MmError, MmResult}; +use relay_rpc::{domain::Topic, + rpc::{params::ResponseParamsSuccess, Params, Request, Response}}; + +use crate::{error::WalletConnectCtxError, + pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}, + WalletConnectCtx}; + +pub(crate) async fn process_inbound_request( + ctx: Arc, + request: Request, + topic: &Topic, +) -> MmResult<(), WalletConnectCtxError> { + let response = match request.params { + Params::SessionPropose(proposal) => { + ctx.session + .process_proposal_request(&ctx, proposal, topic.clone()) + .await + }, + Params::SessionExtend(param) => ctx.session.process_session_extend_request(topic, param).await, + Params::SessionDelete(param) => ctx.session.process_session_delete_request(param), + Params::SessionPing(()) => ctx.session.process_session_ping_request(), + Params::SessionSettle(param) => ctx.session.process_session_settle_request(topic, param).await, + Params::SessionUpdate(param) => ctx.session.process_session_update_request(topic, param).await, + Params::SessionRequest(_) => todo!(), + Params::SessionEvent(_) => todo!(), + + Params::PairingPing(_param) => process_pairing_ping_response().await, + Params::PairingDelete(param) => process_pairing_delete_response(&ctx, topic, param).await, + Params::PairingExtend(param) => process_pairing_extend_response(&ctx, topic, param).await, + _ => todo!(), + }?; + + ctx.publish_response(topic, response.0, response.1, request.id).await?; + + // ctx.session.session_delete_cleanup(ctx.clone(), topic).await? + + Ok(()) +} + +pub(crate) async fn process_inbound_response( + ctx: Arc, + response: Response, + topic: &Topic, +) -> MmResult<(), WalletConnectCtxError> { + match response { + Response::Success(value) => { + let params = serde_json::from_value::(value.result)?; + match params { + ResponseParamsSuccess::SessionPropose(param) => { + ctx.session.handle_session_propose_response(topic, param).await; + Ok(()) + }, + ResponseParamsSuccess::SessionSettle(success) + | ResponseParamsSuccess::SessionUpdate(success) + | ResponseParamsSuccess::SessionExtend(success) + | ResponseParamsSuccess::SessionRequest(success) + | ResponseParamsSuccess::SessionEvent(success) + | ResponseParamsSuccess::SessionDelete(success) + | ResponseParamsSuccess::SessionPing(success) + | ResponseParamsSuccess::PairingExtend(success) + | ResponseParamsSuccess::PairingDelete(success) + | ResponseParamsSuccess::PairingPing(success) => { + if !success { + return MmError::err(WalletConnectCtxError::UnsuccessfulResponse(format!( + "Unsuccessful response={params:?}" + ))); + } + + Ok(()) + }, + } + }, + Response::Error(err) => { + println!("Error: {err:?}"); + todo!() + }, + } +} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d082098572..00139e3e82 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,18 +1,19 @@ mod error; mod handler; +mod inbound_message; mod pairing; mod session; mod session_key; -use common::log::info; +use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex, StreamExt}; use handler::Handler; +use inbound_message::{process_inbound_request, process_inbound_response}; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; -use pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}; use pairing_api::{Methods, PairingClient}; use rand::rngs::OsRng; use relay_client::{websocket::{Client, PublishedMessage}, @@ -20,8 +21,7 @@ use relay_client::{websocket::{Client, PublishedMessage}, use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, - rpc::{params::{session_propose::SessionProposeRequest, IrnMetadata, Metadata, RequestParams, - ResponseParamsSuccess}, + rpc::{params::{session_propose::SessionProposeRequest, IrnMetadata, Metadata, RequestParams}, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; use session::{Session, SessionInfo, SessionUserType, APP_DESCRIPTION, APP_NAME}; use session_key::SessionKey; @@ -86,13 +86,11 @@ impl WalletConnectCtx { let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); self.client.connect(&opts).await?; - // let is_connected = self.client.; info!("WC connected"); Ok(()) } - // todo: return slice async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { { let sessions = self.session.lock().await; @@ -126,6 +124,7 @@ impl WalletConnectCtx { .iter() .map(|m| m.to_string()) .collect::>()]); + let (topic, url) = self .pairing .create(metadata.clone(), Some(methods), &self.client) @@ -155,7 +154,6 @@ impl WalletConnectCtx { required_namespaces: session.namespaces.clone(), }); - // Store the session information in your session manager (self.sessions or similar) { let mut sessions = self.session.lock().await; sessions.insert(session_topic.clone(), session); @@ -249,7 +247,7 @@ impl WalletConnectCtx { decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() }; - println!("\nInbound message payload={message}"); + info!("\nInbound message payload={message}"); let response = serde_json::from_str::(&message).unwrap(); let result = match response { @@ -270,83 +268,10 @@ impl WalletConnectCtx { info!("connection disconnected, reconnecting"); if let Err(err) = self.connect_client().await { common::log::error!("{err:?}"); + Timer::sleep(5.).await; continue; }; info!("reconnecting success!"); } } } - -async fn process_inbound_request( - ctx: Arc, - request: Request, - topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { - let response = match request.params { - Params::SessionPropose(proposal) => { - ctx.session - .process_proposal_request(&ctx, proposal, topic.clone()) - .await - }, - Params::SessionExtend(param) => ctx.session.process_session_extend_request(topic, param).await, - Params::SessionDelete(param) => ctx.session.process_session_delete_request(param), - Params::SessionPing(()) => ctx.session.process_session_ping_request(), - Params::SessionSettle(param) => ctx.session.process_session_settle_request(topic, param).await, - Params::SessionUpdate(param) => ctx.session.process_session_update_request(topic, param).await, - Params::SessionRequest(_) => todo!(), - Params::SessionEvent(_) => todo!(), - - Params::PairingPing(_param) => process_pairing_ping_response().await, - Params::PairingDelete(param) => process_pairing_delete_response(&ctx, topic, param).await, - Params::PairingExtend(param) => process_pairing_extend_response(&ctx, topic, param).await, - _ => todo!(), - }?; - - info!("Publishing reponse"); - ctx.publish_response(topic, response.0, response.1, request.id).await?; - - // todo - // ctx.session.session_delete_cleanup(ctx.clone(), topic).await? - - Ok(()) -} - -async fn process_inbound_response( - ctx: Arc, - response: Response, - topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { - match response { - Response::Success(value) => { - let params = serde_json::from_value::(value.result)?; - match params { - ResponseParamsSuccess::SessionPropose(param) => { - ctx.session.handle_session_propose_response(topic, param).await; - Ok(()) - }, - ResponseParamsSuccess::SessionSettle(success) - | ResponseParamsSuccess::SessionUpdate(success) - | ResponseParamsSuccess::SessionExtend(success) - | ResponseParamsSuccess::SessionRequest(success) - | ResponseParamsSuccess::SessionEvent(success) - | ResponseParamsSuccess::SessionDelete(success) - | ResponseParamsSuccess::SessionPing(success) - | ResponseParamsSuccess::PairingExtend(success) - | ResponseParamsSuccess::PairingDelete(success) - | ResponseParamsSuccess::PairingPing(success) => { - if !success { - return MmError::err(WalletConnectCtxError::UnsuccessfulResponse(format!( - "Unsuccessful response={params:?}" - ))); - } - - Ok(()) - }, - } - }, - Response::Error(err) => { - println!("Error: {err:?}"); - todo!() - }, - } -} diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index fb96c65acc..174e858b9b 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -21,6 +21,8 @@ use std::{collections::BTreeMap, sync::Arc}; pub(crate) const APP_NAME: &str = "Komodefi Framework"; pub(crate) const APP_DESCRIPTION: &str = "WallectConnect Komodefi Framework Playground"; +const FIVE_MINUTES: u64 = 300; +const THIRTY_DAYS: u64 = 60 * 60 * 30; pub(crate) type WcRequestResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; @@ -69,13 +71,12 @@ impl SessionInfo { events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), }); - // Initialize relay let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), data: None, }; - // Conditional logic to handle proposer or controller + // handle proposer or controller let (proposer, controller) = match session_type { SessionUserType::Proposer => ( Proposer { @@ -98,7 +99,7 @@ impl SessionInfo { namespaces: ProposeNamespaces(namespaces), settled_namespaces: SettleNamespaces(settled_namespaces), relay, - expiry: Utc::now().timestamp() as u64 + 300, + expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, pairing_topic, session_type, } @@ -111,7 +112,7 @@ impl SessionInfo { relay: self.relay.clone(), controller: self.controller.clone(), namespaces: self.supported_settle_namespaces().clone(), - expiry: Utc::now().timestamp() as u64 + 300, // 5 min TTL + expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, }) } fn create_proposal_response(&self) -> Result<(Value, IrnMetadata), WalletConnectCtxError> { @@ -164,6 +165,7 @@ impl Session { info!("session found!"); session.proposer.public_key = response.responder_public_key; session.relay = response.relay; + session.expiry = Utc::now().timestamp() + THIRTY_DAYS; }; } diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index 57084a72e2..56fa519ccc 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -853,9 +853,7 @@ pub fn nft_dev_conf() -> Json { }) } -fn set_chain_id(conf: &mut Json, chain_id: u64) { - conf["chain_id"] = json!(chain_id); -} +fn set_chain_id(conf: &mut Json, chain_id: u64) { conf["chain_id"] = json!(chain_id); } pub fn eth_sepolia_conf() -> Json { json!({ @@ -2903,7 +2901,10 @@ pub async fn enable_tendermint( tx_history: bool, ) -> Json { let ibc_requests: Vec<_> = ibc_assets.iter().map(|ticker| json!({ "ticker": ticker })).collect(); - let nodes: Vec = rpc_urls.iter().map(|u| json!({"url": u, "komodo_proxy": false })).collect(); + let nodes: Vec = rpc_urls + .iter() + .map(|u| json!({"url": u, "komodo_proxy": false })) + .collect(); let request = json!({ "userpass": mm.userpass, @@ -2940,7 +2941,10 @@ pub async fn enable_tendermint_without_balance( tx_history: bool, ) -> Json { let ibc_requests: Vec<_> = ibc_assets.iter().map(|ticker| json!({ "ticker": ticker })).collect(); - let nodes: Vec = rpc_urls.iter().map(|u| json!({"url": u, "komodo_proxy": false })).collect(); + let nodes: Vec = rpc_urls + .iter() + .map(|u| json!({"url": u, "komodo_proxy": false })) + .collect(); let request = json!({ "userpass": mm.userpass, From 437767bb63832c51ba464c9b8f5b77ef43776802 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 13 Sep 2024 01:28:04 +0100 Subject: [PATCH 008/125] fix wasm compilation --- mm2src/kdf_walletconnect/src/session.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 174e858b9b..b6bb696da5 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -165,7 +165,7 @@ impl Session { info!("session found!"); session.proposer.public_key = response.responder_public_key; session.relay = response.relay; - session.expiry = Utc::now().timestamp() + THIRTY_DAYS; + session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; }; } From 6374da321f9b9e90795f2238c1b648bec3ef0ece Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 13 Sep 2024 01:45:18 +0100 Subject: [PATCH 009/125] minor changes - create metadata mod --- mm2src/kdf_walletconnect/src/lib.rs | 19 ++++++------------ mm2src/kdf_walletconnect/src/metadata.rs | 16 +++++++++++++++ mm2src/kdf_walletconnect/src/session.rs | 25 ++++++++++-------------- 3 files changed, 32 insertions(+), 28 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/metadata.rs diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 00139e3e82..b81d7f27c2 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,6 +1,7 @@ mod error; mod handler; mod inbound_message; +mod metadata; mod pairing; mod session; mod session_key; @@ -12,6 +13,7 @@ use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, StreamExt}; use handler::Handler; use inbound_message::{process_inbound_request, process_inbound_response}; +use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; use pairing_api::{Methods, PairingClient}; @@ -21,17 +23,13 @@ use relay_client::{websocket::{Client, PublishedMessage}, use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, - rpc::{params::{session_propose::SessionProposeRequest, IrnMetadata, Metadata, RequestParams}, + rpc::{params::{session_propose::SessionProposeRequest, IrnMetadata, RequestParams}, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; -use session::{Session, SessionInfo, SessionUserType, APP_DESCRIPTION, APP_NAME}; +use session::{Session, SessionInfo, SessionType}; use session_key::SessionKey; use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; -const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com"; -const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b"; -const AUTH_TOKEN_SUB: &str = "http://127.0.0.1:8000"; - const SUPPORTED_PROTOCOL: &str = "irn"; const SUPPORTED_METHODS: &[&str] = &[ "eth_sendTransaction", @@ -114,12 +112,7 @@ impl WalletConnectCtx { } pub async fn create_pairing(&self) -> MmResult { - let metadata = Metadata { - description: APP_DESCRIPTION.to_owned(), - url: "127.0.0.1:3000".to_owned(), - icons: vec![], - name: APP_NAME.to_owned(), - }; + let metadata = generate_metadata(); let methods = Methods(vec![SUPPORTED_METHODS .iter() .map(|m| m.to_string()) @@ -145,7 +138,7 @@ impl WalletConnectCtx { session_key, topic.clone(), metadata, - SessionUserType::Proposer, + SessionType::Proposer, ); let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { diff --git a/mm2src/kdf_walletconnect/src/metadata.rs b/mm2src/kdf_walletconnect/src/metadata.rs new file mode 100644 index 0000000000..777bbd6148 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/metadata.rs @@ -0,0 +1,16 @@ +use relay_rpc::rpc::params::Metadata; + +pub(crate) const RELAY_ADDRESS: &str = "wss://relay.walletconnect.com"; +pub(crate) const PROJECT_ID: &str = "86e916bcbacee7f98225dde86b697f5b"; +pub(crate) const AUTH_TOKEN_SUB: &str = "http://127.0.0.1:8000"; +pub(crate) const APP_NAME: &str = "Komodefi Framework"; +pub(crate) const APP_DESCRIPTION: &str = "WallectConnect Komodefi Framework Playground"; + +pub(crate) fn generate_metadata() -> Metadata { + Metadata { + description: APP_DESCRIPTION.to_owned(), + url: AUTH_TOKEN_SUB.to_owned(), + icons: vec![], + name: APP_NAME.to_owned(), + } +} diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index b6bb696da5..cc30867946 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -19,15 +19,13 @@ use std::collections::HashMap; use std::ops::Deref; use std::{collections::BTreeMap, sync::Arc}; -pub(crate) const APP_NAME: &str = "Komodefi Framework"; -pub(crate) const APP_DESCRIPTION: &str = "WallectConnect Komodefi Framework Playground"; const FIVE_MINUTES: u64 = 300; const THIRTY_DAYS: u64 = 60 * 60 * 30; pub(crate) type WcRequestResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; #[derive(Debug, Clone)] -pub enum SessionUserType { +pub enum SessionType { Controller, Proposer, } @@ -45,7 +43,7 @@ pub struct SessionInfo { pub settled_namespaces: SettleNamespaces, pub expiry: u64, pub pairing_topic: Topic, - pub session_type: SessionUserType, + pub session_type: SessionType, } impl SessionInfo { @@ -54,7 +52,7 @@ impl SessionInfo { session_key: SessionKey, pairing_topic: Topic, metadata: Metadata, - session_type: SessionUserType, + session_type: SessionType, ) -> Self { // Initialize the namespaces for both proposer and controller let mut namespaces = BTreeMap::::new(); @@ -78,14 +76,14 @@ impl SessionInfo { // handle proposer or controller let (proposer, controller) = match session_type { - SessionUserType::Proposer => ( + SessionType::Proposer => ( Proposer { public_key: hex::encode(session_key.diffie_public_key()), metadata, }, Controller::default(), ), - SessionUserType::Controller => (Proposer::default(), Controller { + SessionType::Controller => (Proposer::default(), Controller { public_key: hex::encode(session_key.diffie_public_key()), metadata, }), @@ -106,7 +104,9 @@ impl SessionInfo { } fn supported_propose_namespaces(&self) -> &ProposeNamespaces { &self.namespaces } + fn supported_settle_namespaces(&self) -> &SettleNamespaces { &self.settled_namespaces } + fn create_settle_request(&self) -> RequestParams { RequestParams::SessionSettle(SessionSettleRequest { relay: self.relay.clone(), @@ -115,6 +115,7 @@ impl SessionInfo { expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, }) } + fn create_proposal_response(&self) -> Result<(Value, IrnMetadata), WalletConnectCtxError> { let response = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { relay: self.relay.clone(), @@ -210,18 +211,12 @@ impl Session { .await .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - let metadata = Metadata { - description: APP_DESCRIPTION.to_owned(), - url: "127.0.0.1:3000".to_owned(), - icons: vec![], - name: APP_NAME.to_owned(), - }; let session = SessionInfo::new( subscription_id, session_key, pairing_topic, - metadata, - SessionUserType::Controller, + proposal.proposer.metadata, + SessionType::Controller, ); session .supported_propose_namespaces() From 1c9cfe085a82bf34ad4e7c10d4296a2c53dfd5c1 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 14 Sep 2024 16:56:58 +0100 Subject: [PATCH 010/125] minor changes and code organization --- mm2src/kdf_walletconnect/src/error.rs | 7 +++ mm2src/kdf_walletconnect/src/lib.rs | 50 +++--------------- mm2src/kdf_walletconnect/src/pairing.rs | 46 ++++++++++++++--- mm2src/kdf_walletconnect/src/session.rs | 67 ++++++++++++++++++++++--- 4 files changed, 113 insertions(+), 57 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 35f496fd61..7e7679e504 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -4,6 +4,8 @@ use relay_client::error::{ClientError, Error}; use relay_rpc::rpc::{PublishError, SubscriptionError}; use serde::{Deserialize, Serialize}; +use crate::session_key::SessionError; + #[derive(Debug, Display, Serialize, Deserialize)] pub enum WalletConnectCtxError { PairingError(String), @@ -15,6 +17,7 @@ pub enum WalletConnectCtxError { InternalError(String), SerdeError(String), UnsuccessfulResponse(String), + SessionError(String), } impl From for WalletConnectCtxError { @@ -36,3 +39,7 @@ impl From> for WalletConnectCtxError { impl From for WalletConnectCtxError { fn from(value: serde_json::Error) -> Self { WalletConnectCtxError::SerdeError(value.to_string()) } } + +impl From for WalletConnectCtxError { + fn from(value: SessionError) -> Self { WalletConnectCtxError::SessionError(value.to_string()) } +} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index b81d7f27c2..1a3fd9cd60 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -2,8 +2,8 @@ mod error; mod handler; mod inbound_message; mod metadata; -mod pairing; -mod session; +#[allow(unused)] mod pairing; +#[allow(unused)] mod session; mod session_key; use common::{executor::Timer, log::info}; @@ -17,16 +17,13 @@ use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; use pairing_api::{Methods, PairingClient}; -use rand::rngs::OsRng; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; -use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, - rpc::{params::{session_propose::SessionProposeRequest, IrnMetadata, RequestParams}, - Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; -use session::{Session, SessionInfo, SessionType}; -use session_key::SessionKey; + rpc::{params::IrnMetadata, Params, Payload, Request, Response, SuccessfulResponse, + JSON_RPC_VERSION_STR}}; +use session::Session; use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; @@ -123,41 +120,9 @@ impl WalletConnectCtx { .create(metadata.clone(), Some(methods), &self.client) .await?; - let signing_key = SigningKey::generate(&mut OsRng); - let public_key = signing_key.verifying_key(); - let session_key = SessionKey::from_osrng(public_key.as_bytes()) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; - let session_topic: Topic = session_key.generate_topic().into(); - let subscription_id = self - .client - .subscribe(session_topic.clone()) - .await - .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - let session = SessionInfo::new( - subscription_id, - session_key, - topic.clone(), - metadata, - SessionType::Proposer, - ); - - let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { - relays: vec![session.relay.clone()], - proposer: session.proposer.clone(), - required_namespaces: session.namespaces.clone(), - }); - - { - let mut sessions = self.session.lock().await; - sessions.insert(session_topic.clone(), session); - } - - let irn_metadata = session_proposal.irn_metadata(); - self.publish_request(&topic, session_proposal.into(), irn_metadata) - .await?; + Session::create_proposal_session(self, topic, metadata).await?; - let clean_url = url.replace("&", "&"); - Ok(clean_url) + Ok(url) } pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { @@ -248,6 +213,7 @@ impl WalletConnectCtx { Payload::Response(response) => process_inbound_response(self.clone(), response, &msg.topic).await, }; + // TODO: Handle errors. match result { Ok(()) => info!("Inbound message was handled succesfully"), Err(err) => info!("Error while handling inbound message: {err:?}"), diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index a781722e90..ee637c7169 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -1,11 +1,14 @@ -use crate::{error::WalletConnectCtxError, session::WcRequestResult, WalletConnectCtx}; +use crate::session::{WcRequestResponseResult, THIRTY_DAYS}; +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; -use relay_rpc::rpc::params::RelayProtocolMetadata; +use chrono::Utc; +use relay_rpc::rpc::params::pairing_ping::PairingPingRequest; +use relay_rpc::rpc::params::{RelayProtocolMetadata, RequestParams}; use relay_rpc::{domain::Topic, rpc::params::{pairing_delete::PairingDeleteRequest, pairing_extend::PairingExtendRequest, ResponseParamsSuccess}}; -pub(crate) async fn process_pairing_ping_response() -> WcRequestResult { +pub(crate) async fn process_pairing_ping_response() -> WcRequestResponseResult { let response = ResponseParamsSuccess::PairingPing(true); let irn_metadata = response.irn_metadata(); let value = serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; @@ -17,7 +20,7 @@ pub(crate) async fn process_pairing_extend_response( ctx: &WalletConnectCtx, topic: &Topic, extend: PairingExtendRequest, -) -> WcRequestResult { +) -> WcRequestResponseResult { { let mut pairings = ctx.pairing.pairings.lock().await; if let Some(pairing) = pairings.get_mut(topic.as_ref()) { @@ -28,7 +31,7 @@ pub(crate) async fn process_pairing_extend_response( let response = ResponseParamsSuccess::PairingPing(true); let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let value = serde_json::to_value(response)?; Ok((value, irn_metadata)) } @@ -37,14 +40,43 @@ pub(crate) async fn process_pairing_delete_response( ctx: &WalletConnectCtx, topic: &Topic, _delete: PairingDeleteRequest, -) -> WcRequestResult { +) -> WcRequestResponseResult { { ctx.pairing.disconnect(topic.as_ref(), &ctx.client).await?; } let response = ResponseParamsSuccess::PairingDelete(true); let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let value = serde_json::to_value(response)?; + + Ok((value, irn_metadata)) +} + +pub(crate) async fn pairing_ping_request() -> WcRequestResponseResult { + let request = RequestParams::PairingPing(PairingPingRequest {}); + let irn_metadata = request.irn_metadata(); + let value = serde_json::to_value(request)?; + + Ok((value, irn_metadata)) +} + +pub(crate) async fn pairing_delete_request() -> WcRequestResponseResult { + let request = RequestParams::PairingDelete(PairingDeleteRequest { + code: 6000, + message: "Delete my pairing".to_string(), + }); + let irn_metadata = request.irn_metadata(); + let value = serde_json::to_value(request)?; + + Ok((value, irn_metadata)) +} + +pub(crate) async fn pairing_extend_request() -> WcRequestResponseResult { + let request = RequestParams::PairingExtend(PairingExtendRequest { + expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, + }); + let irn_metadata = request.irn_metadata(); + let value = serde_json::to_value(request)?; Ok((value, irn_metadata)) } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index cc30867946..fdaedc353e 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -4,6 +4,8 @@ use chrono::Utc; use common::log::info; use futures::lock::Mutex; use mm2_err_handle::prelude::{MapToMmResult, MmResult}; +use rand::rngs::OsRng; +use relay_rpc::auth::ed25519_dalek::SigningKey; use relay_rpc::rpc::params::session_delete::SessionDeleteRequest; use relay_rpc::rpc::params::session_extend::SessionExtendRequest; use relay_rpc::rpc::params::session_propose::Proposer; @@ -20,9 +22,9 @@ use std::ops::Deref; use std::{collections::BTreeMap, sync::Arc}; const FIVE_MINUTES: u64 = 300; -const THIRTY_DAYS: u64 = 60 * 60 * 30; +pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; -pub(crate) type WcRequestResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; +pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; #[derive(Debug, Clone)] pub enum SessionType { @@ -156,6 +158,52 @@ impl Session { } } + pub(crate) async fn create_proposal_session( + ctx: &WalletConnectCtx, + topic: Topic, + metadata: Metadata, + ) -> MmResult<(), WalletConnectCtxError> { + let (session, session_topic) = { + let signing_key = SigningKey::generate(&mut OsRng); + let public_key = signing_key.verifying_key(); + let session_key = SessionKey::from_osrng(public_key.as_bytes())?; + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + + ( + SessionInfo::new( + subscription_id, + session_key, + topic.clone(), + metadata, + SessionType::Proposer, + ), + session_topic, + ) + }; + + { + let mut sessions = ctx.session.lock().await; + sessions.insert(session_topic.clone(), session.clone()); + } + + let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { + relays: vec![session.relay], + proposer: session.proposer, + required_namespaces: session.namespaces, + }); + let irn_metadata = session_proposal.irn_metadata(); + + ctx.publish_request(&topic, session_proposal.into(), irn_metadata) + .await?; + + Ok(()) + } + pub(crate) async fn handle_session_propose_response( &self, session_topic: &Topic, @@ -174,7 +222,7 @@ impl Session { &self, topic: &Topic, extend: SessionExtendRequest, - ) -> WcRequestResult { + ) -> WcRequestResponseResult { let mut sessions = self.session.lock().await; if let Some(session) = sessions.get_mut(topic) { session.expiry = extend.expiry; @@ -195,7 +243,7 @@ impl Session { ctx: &WalletConnectCtx, proposal: SessionProposeRequest, pairing_topic: Topic, - ) -> WcRequestResult { + ) -> WcRequestResponseResult { let sender_public_key = hex::decode(&proposal.proposer.public_key) .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? .as_slice() @@ -240,7 +288,7 @@ impl Session { &self, topic: &Topic, settle: SessionSettleRequest, - ) -> WcRequestResult { + ) -> WcRequestResponseResult { { let mut sessions = self.session.lock().await; if let Some(session) = sessions.get_mut(topic) { @@ -262,7 +310,7 @@ impl Session { Ok((value, irn_metadata)) } - pub(crate) fn process_session_ping_request(&self) -> WcRequestResult { + pub(crate) fn process_session_ping_request(&self) -> WcRequestResponseResult { let response = ResponseParamsSuccess::SessionPing(true); let irn_metadata = response.irn_metadata(); let value = @@ -271,7 +319,10 @@ impl Session { Ok((value, irn_metadata)) } - pub(crate) fn process_session_delete_request(&self, delete_params: SessionDeleteRequest) -> WcRequestResult { + pub(crate) fn process_session_delete_request( + &self, + delete_params: SessionDeleteRequest, + ) -> WcRequestResponseResult { info!( "\nSession is being terminated reason={}, code={}", delete_params.message, delete_params.code, @@ -315,7 +366,7 @@ impl Session { &self, topic: &Topic, update: SessionUpdateRequest, - ) -> WcRequestResult { + ) -> WcRequestResponseResult { let mut sessions = self.session.lock().await; if let Some(session) = sessions.get_mut(topic) { session.settled_namespaces = update.namespaces.clone(); From f7987dd6beb1b400bcdb0dbc42ce4e46fa82a489 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 14 Sep 2024 17:30:20 +0100 Subject: [PATCH 011/125] minor changes + merge session and session_key mod --- mm2src/kdf_walletconnect/src/error.rs | 9 ++- mm2src/kdf_walletconnect/src/lib.rs | 1 - mm2src/kdf_walletconnect/src/session.rs | 73 ++++++++++++++++++--- mm2src/kdf_walletconnect/src/session_key.rs | 68 ------------------- 4 files changed, 71 insertions(+), 80 deletions(-) delete mode 100644 mm2src/kdf_walletconnect/src/session_key.rs diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 7e7679e504..c11fd3cc38 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -4,8 +4,6 @@ use relay_client::error::{ClientError, Error}; use relay_rpc::rpc::{PublishError, SubscriptionError}; use serde::{Deserialize, Serialize}; -use crate::session_key::SessionError; - #[derive(Debug, Display, Serialize, Deserialize)] pub enum WalletConnectCtxError { PairingError(String), @@ -43,3 +41,10 @@ impl From for WalletConnectCtxError { impl From for WalletConnectCtxError { fn from(value: SessionError) -> Self { WalletConnectCtxError::SessionError(value.to_string()) } } + +/// Session key and topic derivation errors. +#[derive(Debug, Clone, thiserror::Error)] +pub enum SessionError { + #[error("Failed to generate symmetric session key: {0}")] + SymKeyGeneration(String), +} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 1a3fd9cd60..f6884aa81d 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -4,7 +4,6 @@ mod inbound_message; mod metadata; #[allow(unused)] mod pairing; #[allow(unused)] mod session; -mod session_key; use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index fdaedc353e..fec1394457 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,10 +1,10 @@ -use crate::{error::WalletConnectCtxError, session_key::SessionKey, WalletConnectCtx, SUPPORTED_ACCOUNTS, - SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; +use crate::error::SessionError; +use crate::{error::WalletConnectCtxError, WalletConnectCtx, SUPPORTED_ACCOUNTS, SUPPORTED_CHAINS, SUPPORTED_EVENTS, + SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; use chrono::Utc; use common::log::info; use futures::lock::Mutex; use mm2_err_handle::prelude::{MapToMmResult, MmResult}; -use rand::rngs::OsRng; use relay_rpc::auth::ed25519_dalek::SigningKey; use relay_rpc::rpc::params::session_delete::SessionDeleteRequest; use relay_rpc::rpc::params::session_extend::SessionExtendRequest; @@ -20,12 +20,73 @@ use serde_json::Value; use std::collections::HashMap; use std::ops::Deref; use std::{collections::BTreeMap, sync::Arc}; +use {hkdf::Hkdf, + rand::{rngs::OsRng, CryptoRng, RngCore}, + sha2::{Digest, Sha256}, + std::fmt::Debug, + x25519_dalek::{EphemeralSecret, PublicKey}}; const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; +#[derive(Clone)] +pub struct SessionKey { + sym_key: [u8; 32], + public_key: PublicKey, +} + +impl std::fmt::Debug for SessionKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SessionKey") + .field("sym_key", &"*******") + .field("public_key", &self.public_key) + .finish() + } +} + +impl SessionKey { + /// Creates new session key from `osrng`. + pub fn from_osrng(sender_public_key: &[u8; 32]) -> Result { + SessionKey::diffie_hellman(OsRng, sender_public_key) + } + + /// Performs Diffie-Hellman symmetric key derivation. + pub fn diffie_hellman(csprng: T, sender_public_key: &[u8; 32]) -> Result + where + T: RngCore + CryptoRng, + { + let single_use_private_key = EphemeralSecret::random_from_rng(csprng); + let public_key = PublicKey::from(&single_use_private_key); + + let ikm = single_use_private_key.diffie_hellman(&PublicKey::from(*sender_public_key)); + + let mut session_sym_key = Self { + sym_key: [0u8; 32], + public_key, + }; + let hk = Hkdf::::new(None, ikm.as_bytes()); + hk.expand(&[], &mut session_sym_key.sym_key) + .map_err(|e| SessionError::SymKeyGeneration(e.to_string()))?; + + Ok(session_sym_key) + } + + /// Gets symmetic key reference. + pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } + + /// Gets "our" public key used in symmetric key derivation. + pub fn diffie_public_key(&self) -> &[u8; 32] { self.public_key.as_bytes() } + + /// Generates new session topic. + pub fn generate_topic(&self) -> String { + let mut hasher = Sha256::new(); + hasher.update(self.sym_key); + hex::encode(hasher.finalize()) + } +} + #[derive(Debug, Clone)] pub enum SessionType { Controller, @@ -152,12 +213,6 @@ impl Session { } } - pub fn from_session_info(topic: Topic, session_info: SessionInfo) -> Self { - Self { - session: Arc::new(Mutex::new(HashMap::from([(topic, session_info)]))), - } - } - pub(crate) async fn create_proposal_session( ctx: &WalletConnectCtx, topic: Topic, diff --git a/mm2src/kdf_walletconnect/src/session_key.rs b/mm2src/kdf_walletconnect/src/session_key.rs deleted file mode 100644 index b1b1f7a89f..0000000000 --- a/mm2src/kdf_walletconnect/src/session_key.rs +++ /dev/null @@ -1,68 +0,0 @@ -use {hkdf::Hkdf, - rand::{rngs::OsRng, CryptoRng, RngCore}, - sha2::{Digest, Sha256}, - std::fmt::Debug, - x25519_dalek::{EphemeralSecret, PublicKey}}; - -/// Session key and topic derivation errors. -#[derive(Debug, Clone, thiserror::Error)] -pub enum SessionError { - #[error("Failed to generate symmetric session key: {0}")] - SymKeyGeneration(String), -} - -#[derive(Clone)] -pub struct SessionKey { - sym_key: [u8; 32], - public_key: PublicKey, -} - -impl std::fmt::Debug for SessionKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("SessionKey") - .field("sym_key", &"*******") - .field("public_key", &self.public_key) - .finish() - } -} - -impl SessionKey { - /// Creates new session key from `osrng`. - pub fn from_osrng(sender_public_key: &[u8; 32]) -> Result { - SessionKey::diffie_hellman(OsRng, sender_public_key) - } - - /// Performs Diffie-Hellman symmetric key derivation. - pub fn diffie_hellman(csprng: T, sender_public_key: &[u8; 32]) -> Result - where - T: RngCore + CryptoRng, - { - let single_use_private_key = EphemeralSecret::random_from_rng(csprng); - let public_key = PublicKey::from(&single_use_private_key); - - let ikm = single_use_private_key.diffie_hellman(&PublicKey::from(*sender_public_key)); - - let mut session_sym_key = Self { - sym_key: [0u8; 32], - public_key, - }; - let hk = Hkdf::::new(None, ikm.as_bytes()); - hk.expand(&[], &mut session_sym_key.sym_key) - .map_err(|e| SessionError::SymKeyGeneration(e.to_string()))?; - - Ok(session_sym_key) - } - - /// Gets symmetic key reference. - pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } - - /// Gets "our" public key used in symmetric key derivation. - pub fn diffie_public_key(&self) -> &[u8; 32] { self.public_key.as_bytes() } - - /// Generates new session topic. - pub fn generate_topic(&self) -> String { - let mut hasher = Sha256::new(); - hasher.update(self.sym_key); - hex::encode(hasher.finalize()) - } -} From 1f2adb2fe882dcd61e1c350d9e2c55f9f6b37266 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 15 Sep 2024 16:21:15 +0100 Subject: [PATCH 012/125] minor changes to namespaces --- .../kdf_walletconnect/src/inbound_message.rs | 57 +++++-- mm2src/kdf_walletconnect/src/lib.rs | 39 ++++- mm2src/kdf_walletconnect/src/session.rs | 159 +++++++++++++++--- mm2src/mm2_main/src/rpc.rs | 1 - 4 files changed, 208 insertions(+), 48 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 1c783f9cc5..e2bcfb7868 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -6,6 +6,7 @@ use relay_rpc::{domain::Topic, use crate::{error::WalletConnectCtxError, pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}, + session::handle_session_event, WalletConnectCtx}; pub(crate) async fn process_inbound_request( @@ -13,27 +14,51 @@ pub(crate) async fn process_inbound_request( request: Request, topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { - let response = match request.params { + match request.params { Params::SessionPropose(proposal) => { - ctx.session + let response = ctx + .sessions .process_proposal_request(&ctx, proposal, topic.clone()) - .await + .await?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, + Params::SessionExtend(param) => { + let response = ctx.sessions.process_session_extend_request(topic, param).await?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, + Params::SessionDelete(param) => { + let response = ctx.sessions.process_session_delete_request(param)?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, + Params::SessionPing(()) => { + let response = ctx.sessions.process_session_ping_request()?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, + Params::SessionSettle(param) => { + let response = ctx.sessions.process_session_settle_request(topic, param).await?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, + Params::SessionUpdate(param) => { + let response = ctx.sessions.process_session_update_request(topic, param).await?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; }, - Params::SessionExtend(param) => ctx.session.process_session_extend_request(topic, param).await, - Params::SessionDelete(param) => ctx.session.process_session_delete_request(param), - Params::SessionPing(()) => ctx.session.process_session_ping_request(), - Params::SessionSettle(param) => ctx.session.process_session_settle_request(topic, param).await, - Params::SessionUpdate(param) => ctx.session.process_session_update_request(topic, param).await, Params::SessionRequest(_) => todo!(), - Params::SessionEvent(_) => todo!(), + Params::SessionEvent(param) => handle_session_event(&ctx, param).await?, - Params::PairingPing(_param) => process_pairing_ping_response().await, - Params::PairingDelete(param) => process_pairing_delete_response(&ctx, topic, param).await, - Params::PairingExtend(param) => process_pairing_extend_response(&ctx, topic, param).await, + Params::PairingPing(_param) => { + let response = process_pairing_ping_response().await?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, + Params::PairingDelete(param) => { + let response = process_pairing_delete_response(&ctx, topic, param).await?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, + Params::PairingExtend(param) => { + let response = process_pairing_extend_response(&ctx, topic, param).await?; + ctx.publish_response(topic, response.0, response.1, request.id).await?; + }, _ => todo!(), - }?; - - ctx.publish_response(topic, response.0, response.1, request.id).await?; + }; // ctx.session.session_delete_cleanup(ctx.clone(), topic).await? @@ -50,7 +75,7 @@ pub(crate) async fn process_inbound_response( let params = serde_json::from_value::(value.result)?; match params { ResponseParamsSuccess::SessionPropose(param) => { - ctx.session.handle_session_propose_response(topic, param).await; + ctx.sessions.handle_session_propose_response(topic, param).await; Ok(()) }, ResponseParamsSuccess::SessionSettle(success) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index f6884aa81d..e763726096 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -5,6 +5,7 @@ mod metadata; #[allow(unused)] mod pairing; #[allow(unused)] mod session; +use chrono::Utc; use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, @@ -42,9 +43,10 @@ const SUPPORTED_ACCOUNTS: &[&str] = &["eip155:5:0xBA5BA3955463ADcc7aa3E33bbdfb8A pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, - pub session: Session, + pub sessions: Session, pub msg_handler: Arc>>, pub connection_live_handler: Arc>>, + pub active_chain_id: Arc>, } impl Default for WalletConnectCtx { @@ -62,12 +64,43 @@ impl WalletConnectCtx { Self { client, pairing, - session: Session::new(), + sessions: Session::new(), msg_handler: Arc::new(Mutex::new(msg_receiver)), connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), + active_chain_id: Arc::new(Mutex::new("1".to_string())), } } + pub async fn get_active_chain(&self) -> String { self.active_chain_id.lock().await.clone() } + + pub async fn get_active_sessions(&self) -> impl IntoIterator { + let sessions = self.sessions.lock().await; + sessions + .values() + .filter_map(|session| { + if session.expiry > Utc::now().timestamp() as u64 { + Some(session.pairing_topic.clone()) + } else { + None + } + }) + .collect::>() + } + + pub async fn get_inactive_sessions(&self) -> impl IntoIterator { + let sessions = self.sessions.lock().await; + sessions + .values() + .filter_map(|session| { + if session.expiry <= Utc::now().timestamp() as u64 { + Some(session.pairing_topic.clone()) + } else { + None + } + }) + .collect::>() + } + pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { let auth = { let key = SigningKey::generate(&mut rand::thread_rng()); @@ -87,7 +120,7 @@ impl WalletConnectCtx { async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { { - let sessions = self.session.lock().await; + let sessions = self.sessions.lock().await; if let Some(sesssion) = sessions.get(topic) { return Ok(sesssion.session_key.symmetric_key().to_vec()); } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index fec1394457..e427885700 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -6,7 +6,9 @@ use common::log::info; use futures::lock::Mutex; use mm2_err_handle::prelude::{MapToMmResult, MmResult}; use relay_rpc::auth::ed25519_dalek::SigningKey; +use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_delete::SessionDeleteRequest; +use relay_rpc::rpc::params::session_event::SessionEventRequest; use relay_rpc::rpc::params::session_extend::SessionExtendRequest; use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::session_update::SessionUpdateRequest; @@ -17,7 +19,7 @@ use relay_rpc::{domain::{SubscriptionId, Topic}, session_settle::{Controller, SessionSettleRequest}, Metadata, Relay, RequestParams, ResponseParamsSuccess}}; use serde_json::Value; -use std::collections::HashMap; +use std::collections::{BTreeSet, HashMap}; use std::ops::Deref; use std::{collections::BTreeMap, sync::Arc}; use {hkdf::Hkdf, @@ -102,8 +104,8 @@ pub struct SessionInfo { pub controller: Controller, pub proposer: Proposer, pub relay: Relay, - pub namespaces: ProposeNamespaces, - pub settled_namespaces: SettleNamespaces, + pub namespaces: BTreeMap, + pub propose_namespaces: ProposeNamespaces, pub expiry: u64, pub pairing_topic: Topic, pub session_type: SessionType, @@ -125,13 +127,6 @@ impl SessionInfo { events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), }); - let mut settled_namespaces = BTreeMap::::new(); - settled_namespaces.insert("eip155".to_string(), SettleNamespace { - accounts: SUPPORTED_ACCOUNTS.iter().map(|a| a.to_string()).collect(), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - }); - let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), data: None, @@ -156,9 +151,9 @@ impl SessionInfo { subscription_id, session_key, controller, + namespaces: BTreeMap::new(), proposer, - namespaces: ProposeNamespaces(namespaces), - settled_namespaces: SettleNamespaces(settled_namespaces), + propose_namespaces: ProposeNamespaces(namespaces), relay, expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, pairing_topic, @@ -166,15 +161,21 @@ impl SessionInfo { } } - fn supported_propose_namespaces(&self) -> &ProposeNamespaces { &self.namespaces } - - fn supported_settle_namespaces(&self) -> &SettleNamespaces { &self.settled_namespaces } + fn supported_propose_namespaces(&self) -> &ProposeNamespaces { &self.propose_namespaces } fn create_settle_request(&self) -> RequestParams { + let mut settled_namespaces = BTreeMap::::new(); + settled_namespaces.insert("eip155".to_string(), Namespace { + accounts: Some(SUPPORTED_ACCOUNTS.iter().map(|a| a.to_string()).collect()), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + chains: None, + }); + RequestParams::SessionSettle(SessionSettleRequest { relay: self.relay.clone(), controller: self.controller.clone(), - namespaces: self.supported_settle_namespaces().clone(), + namespaces: SettleNamespaces(settled_namespaces), expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, }) } @@ -194,12 +195,12 @@ impl SessionInfo { #[derive(Debug, Clone)] pub struct Session { - session: Arc>>, + sessions: Arc>>, } impl Deref for Session { type Target = Arc>>; - fn deref(&self) -> &Self::Target { &self.session } + fn deref(&self) -> &Self::Target { &self.sessions } } impl Default for Session { @@ -209,7 +210,7 @@ impl Default for Session { impl Session { pub fn new() -> Self { Self { - session: Default::default(), + sessions: Default::default(), } } @@ -242,14 +243,14 @@ impl Session { }; { - let mut sessions = ctx.session.lock().await; + let mut sessions = ctx.sessions.lock().await; sessions.insert(session_topic.clone(), session.clone()); } let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![session.relay], proposer: session.proposer, - required_namespaces: session.namespaces, + required_namespaces: session.propose_namespaces, }); let irn_metadata = session_proposal.irn_metadata(); @@ -278,7 +279,7 @@ impl Session { topic: &Topic, extend: SessionExtendRequest, ) -> WcRequestResponseResult { - let mut sessions = self.session.lock().await; + let mut sessions = self.sessions.lock().await; if let Some(session) = sessions.get_mut(topic) { session.expiry = extend.expiry; info!("Updated extended, info: {:?}", session); @@ -327,7 +328,7 @@ impl Session { .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; { - let mut sessions = ctx.session.deref().lock().await; + let mut sessions = ctx.sessions.deref().lock().await; _ = sessions.insert(session_topic.clone(), session.clone()); } @@ -345,9 +346,9 @@ impl Session { settle: SessionSettleRequest, ) -> WcRequestResponseResult { { - let mut sessions = self.session.lock().await; + let mut sessions = self.sessions.lock().await; if let Some(session) = sessions.get_mut(topic) { - session.settled_namespaces = settle.namespaces.clone(); + session.namespaces = settle.namespaces.0.clone(); session.controller = settle.controller.clone(); session.relay = settle.relay.clone(); session.expiry = settle.expiry; @@ -396,7 +397,7 @@ impl Session { ctx: Arc, topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.session.lock().await; + let mut sessions = ctx.sessions.lock().await; sessions.remove(topic).ok_or_else(|| { WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()) })?; @@ -422,9 +423,9 @@ impl Session { topic: &Topic, update: SessionUpdateRequest, ) -> WcRequestResponseResult { - let mut sessions = self.session.lock().await; + let mut sessions = self.sessions.lock().await; if let Some(session) = sessions.get_mut(topic) { - session.settled_namespaces = update.namespaces.clone(); + session.namespaces = update.namespaces.0.clone(); info!("Updated extended, info: {:?}", session); } @@ -436,3 +437,105 @@ impl Session { Ok((value, irn_metadata)) } } + +pub enum SessionEvents { + ChainCHanged(Vec), + AccountsChanged(Vec), + Unknown, +} + +impl SessionEvents { + fn from_events(event: SessionEventRequest) -> MmResult { + match event.event.name.as_str() { + "chainCHanged" => { + let data = serde_json::from_value::>(event.event.data)?; + Ok(SessionEvents::ChainCHanged(data)) + }, + "accountsChanged" => { + let data = serde_json::from_value::>(event.event.data)?; + Ok(SessionEvents::AccountsChanged(data)) + }, + _ => Ok(SessionEvents::Unknown), + } + } +} + +pub async fn handle_session_event( + ctx: &WalletConnectCtx, + event: SessionEventRequest, +) -> MmResult<(), WalletConnectCtxError> { + let session_event = SessionEvents::from_events(event.clone())?; + match session_event { + SessionEvents::ChainCHanged(data) => handle_chain_changed_event(ctx, event.chain_id, data).await, + SessionEvents::AccountsChanged(data) => handle_account_changed_event(ctx, event.chain_id, data).await, + SessionEvents::Unknown => todo!(), + } +} + +async fn handle_chain_changed_event( + ctx: &WalletConnectCtx, + chain_id: String, + data: Vec, +) -> MmResult<(), WalletConnectCtxError> { + *ctx.active_chain_id.lock().await = chain_id.clone(); + + { + let mut sessions = ctx.sessions.lock().await; + let current_time = Utc::now().timestamp() as u64; + sessions.retain(|_, session| session.expiry > current_time); + }; + + let mut sessions = ctx.sessions.lock().await; + for session in sessions.values_mut() { + for id in &data { + if let Some((namespace, chain)) = parse_chain_and_chain_id(&chain_id) { + if let Some(ns) = session.namespaces.get_mut(&namespace) { + ns.chains + .get_or_insert_with(BTreeSet::new) + .insert(format!("{namespace}:{id}")); + } + } + } + } + + //TODO: Notify about chain changed. + Ok(()) +} + +async fn handle_account_changed_event( + ctx: &WalletConnectCtx, + chain_id: String, + data: Vec, +) -> MmResult<(), WalletConnectCtxError> { + *ctx.active_chain_id.lock().await = chain_id.clone(); + + let mut sessions = ctx.sessions.lock().await; + let current_time = Utc::now().timestamp() as u64; + + sessions.retain(|_, session| session.expiry > current_time); + + let mut sessions = ctx.sessions.lock().await; + for session in sessions.values_mut() { + for address in &data { + if let Some((namespace, _)) = parse_chain_and_chain_id(&chain_id) { + if let Some(ns) = session.namespaces.get_mut(&namespace) { + ns.accounts + .get_or_insert_with(BTreeSet::new) + .insert(format!("{chain_id}:{address}")); + } + } + } + } + + //TODO: Notify about account changed. + Ok(()) +} + +fn parse_chain_and_chain_id(chain: &str) -> Option<(String, String)> { + let sp = chain.split(':').collect::>(); + if sp.len() == 2 { + return None; + }; + + Some((sp[0].to_owned(), sp[1].to_owned())) +} diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index bb07a3ef88..215b1a1ef0 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -75,7 +75,6 @@ const PUBLIC_METHODS: &[Option<&str>] = &[ ]; pub type DispatcherResult = Result>; - #[derive(Display, Serialize, SerializeErrorType)] #[serde(tag = "error_type", content = "error_data")] pub enum DispatcherError { From 658357f760a138929fd264420a5dcfb37da2ca04 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 16 Sep 2024 14:07:39 +0100 Subject: [PATCH 013/125] some improvements --- .../kdf_walletconnect/src/inbound_message.rs | 61 +- mm2src/kdf_walletconnect/src/lib.rs | 15 +- mm2src/kdf_walletconnect/src/pairing.rs | 28 +- mm2src/kdf_walletconnect/src/session.rs | 549 ++++++++++-------- 4 files changed, 343 insertions(+), 310 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index e2bcfb7868..ed29c1b20a 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -6,7 +6,9 @@ use relay_rpc::{domain::Topic, use crate::{error::WalletConnectCtxError, pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}, - session::handle_session_event, + session::{process_proposal_request, process_session_delete_request, process_session_extend_request, + process_session_ping_request, process_session_propose_response, process_session_settle_request, + process_session_update_request, SessionEvents}, WalletConnectCtx}; pub(crate) async fn process_inbound_request( @@ -14,54 +16,27 @@ pub(crate) async fn process_inbound_request( request: Request, topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { + let message_id = request.id; match request.params { - Params::SessionPropose(proposal) => { - let response = ctx - .sessions - .process_proposal_request(&ctx, proposal, topic.clone()) - .await?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, - Params::SessionExtend(param) => { - let response = ctx.sessions.process_session_extend_request(topic, param).await?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, - Params::SessionDelete(param) => { - let response = ctx.sessions.process_session_delete_request(param)?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, - Params::SessionPing(()) => { - let response = ctx.sessions.process_session_ping_request()?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, - Params::SessionSettle(param) => { - let response = ctx.sessions.process_session_settle_request(topic, param).await?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, - Params::SessionUpdate(param) => { - let response = ctx.sessions.process_session_update_request(topic, param).await?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; + Params::SessionPropose(proposal) => process_proposal_request(&ctx, proposal, topic, &message_id).await?, + Params::SessionExtend(param) => process_session_extend_request(&ctx, topic, &message_id, param).await?, + Params::SessionDelete(param) => process_session_delete_request(&ctx, topic, &message_id, param).await?, + Params::SessionPing(()) => process_session_ping_request(&ctx, topic, &message_id).await?, + Params::SessionSettle(param) => process_session_settle_request(&ctx, topic, &message_id, param).await?, + Params::SessionUpdate(param) => process_session_update_request(&ctx, topic, &message_id, param).await?, + Params::SessionEvent(param) => { + SessionEvents::from_events(param)? + .handle_session_event(&ctx, topic, &message_id) + .await? }, Params::SessionRequest(_) => todo!(), - Params::SessionEvent(param) => handle_session_event(&ctx, param).await?, - Params::PairingPing(_param) => { - let response = process_pairing_ping_response().await?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, - Params::PairingDelete(param) => { - let response = process_pairing_delete_response(&ctx, topic, param).await?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, - Params::PairingExtend(param) => { - let response = process_pairing_extend_response(&ctx, topic, param).await?; - ctx.publish_response(topic, response.0, response.1, request.id).await?; - }, + Params::PairingPing(_param) => process_pairing_ping_response(&ctx, topic, &message_id).await?, + Params::PairingDelete(param) => process_pairing_delete_response(&ctx, topic, &message_id, param).await?, + Params::PairingExtend(param) => process_pairing_extend_response(&ctx, topic, &message_id, param).await?, _ => todo!(), }; - // ctx.session.session_delete_cleanup(ctx.clone(), topic).await? - Ok(()) } @@ -75,7 +50,7 @@ pub(crate) async fn process_inbound_response( let params = serde_json::from_value::(value.result)?; match params { ResponseParamsSuccess::SessionPropose(param) => { - ctx.sessions.handle_session_propose_response(topic, param).await; + process_session_propose_response(&ctx, topic, param).await; Ok(()) }, ResponseParamsSuccess::SessionSettle(success) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index e763726096..296f0eed28 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -23,7 +23,7 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, rpc::{params::IrnMetadata, Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; -use session::Session; +use session::{create_proposal_session, Session}; use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; @@ -39,6 +39,7 @@ const SUPPORTED_METHODS: &[&str] = &[ const SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5"]; const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; const SUPPORTED_ACCOUNTS: &[&str] = &["eip155:5:0xBA5BA3955463ADcc7aa3E33bbdfb8A68e0933dD8"]; +const DEFAULT_CHAIN_ID: &str = "1"; // eth mainnet. pub struct WalletConnectCtx { pub client: Client, @@ -67,11 +68,11 @@ impl WalletConnectCtx { sessions: Session::new(), msg_handler: Arc::new(Mutex::new(msg_receiver)), connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), - active_chain_id: Arc::new(Mutex::new("1".to_string())), + active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), } } - pub async fn get_active_chain(&self) -> String { self.active_chain_id.lock().await.clone() } + pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } pub async fn get_active_sessions(&self) -> impl IntoIterator { let sessions = self.sessions.lock().await; @@ -152,7 +153,7 @@ impl WalletConnectCtx { .create(metadata.clone(), Some(methods), &self.client) .await?; - Session::create_proposal_session(self, topic, metadata).await?; + create_proposal_session(self, topic, metadata).await?; Ok(url) } @@ -184,10 +185,10 @@ impl WalletConnectCtx { topic: &Topic, params: serde_json::Value, irn_metadata: IrnMetadata, - message_id: MessageId, + message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { let response = Response::Success(SuccessfulResponse { - id: message_id, + id: *message_id, jsonrpc: JSON_RPC_VERSION_STR.into(), result: params, }); @@ -206,9 +207,9 @@ impl WalletConnectCtx { payload: Payload, ) -> MmResult<(), WalletConnectCtxError> { let sym_key = self.sym_key(topic).await?; - let payload = serde_json::to_string(&payload).map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + info!("\n Sending Outbound request: {payload}!"); let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key) diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index ee637c7169..febbab1f72 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -2,25 +2,34 @@ use crate::session::{WcRequestResponseResult, THIRTY_DAYS}; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::domain::MessageId; use relay_rpc::rpc::params::pairing_ping::PairingPingRequest; use relay_rpc::rpc::params::{RelayProtocolMetadata, RequestParams}; use relay_rpc::{domain::Topic, rpc::params::{pairing_delete::PairingDeleteRequest, pairing_extend::PairingExtendRequest, ResponseParamsSuccess}}; -pub(crate) async fn process_pairing_ping_response() -> WcRequestResponseResult { +pub(crate) async fn process_pairing_ping_response( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, +) -> MmResult<(), WalletConnectCtxError> { let response = ResponseParamsSuccess::PairingPing(true); let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let value = serde_json::to_value(response)?; - Ok((value, irn_metadata)) + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) } pub(crate) async fn process_pairing_extend_response( ctx: &WalletConnectCtx, topic: &Topic, + message_id: &MessageId, extend: PairingExtendRequest, -) -> WcRequestResponseResult { +) -> MmResult<(), WalletConnectCtxError> { { let mut pairings = ctx.pairing.pairings.lock().await; if let Some(pairing) = pairings.get_mut(topic.as_ref()) { @@ -33,14 +42,17 @@ pub(crate) async fn process_pairing_extend_response( let irn_metadata = response.irn_metadata(); let value = serde_json::to_value(response)?; - Ok((value, irn_metadata)) + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) } pub(crate) async fn process_pairing_delete_response( ctx: &WalletConnectCtx, topic: &Topic, + message_id: &MessageId, _delete: PairingDeleteRequest, -) -> WcRequestResponseResult { +) -> MmResult<(), WalletConnectCtxError> { { ctx.pairing.disconnect(topic.as_ref(), &ctx.client).await?; } @@ -49,7 +61,9 @@ pub(crate) async fn process_pairing_delete_response( let irn_metadata = response.irn_metadata(); let value = serde_json::to_value(response)?; - Ok((value, irn_metadata)) + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) } pub(crate) async fn pairing_ping_request() -> WcRequestResponseResult { diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index e427885700..629712e9a2 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,11 +1,13 @@ use crate::error::SessionError; use crate::{error::WalletConnectCtxError, WalletConnectCtx, SUPPORTED_ACCOUNTS, SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; +use chrono::naive::serde; use chrono::Utc; use common::log::info; use futures::lock::Mutex; use mm2_err_handle::prelude::{MapToMmResult, MmResult}; use relay_rpc::auth::ed25519_dalek::SigningKey; +use relay_rpc::domain::MessageId; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_delete::SessionDeleteRequest; use relay_rpc::rpc::params::session_event::SessionEventRequest; @@ -180,16 +182,22 @@ impl SessionInfo { }) } - fn create_proposal_response(&self) -> Result<(Value, IrnMetadata), WalletConnectCtxError> { + async fn proposal_response( + &self, + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { let response = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { relay: self.relay.clone(), responder_public_key: self.controller.public_key.clone(), }); let irn_metadata = response.irn_metadata(); - let value = - serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; - Ok((value, irn_metadata)) + Ok(()) } } @@ -213,322 +221,357 @@ impl Session { sessions: Default::default(), } } +} - pub(crate) async fn create_proposal_session( - ctx: &WalletConnectCtx, - topic: Topic, - metadata: Metadata, - ) -> MmResult<(), WalletConnectCtxError> { - let (session, session_topic) = { - let signing_key = SigningKey::generate(&mut OsRng); - let public_key = signing_key.verifying_key(); - let session_key = SessionKey::from_osrng(public_key.as_bytes())?; - let session_topic: Topic = session_key.generate_topic().into(); - let subscription_id = ctx - .client - .subscribe(session_topic.clone()) - .await - .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - - ( - SessionInfo::new( - subscription_id, - session_key, - topic.clone(), - metadata, - SessionType::Proposer, - ), - session_topic, - ) - }; - - { - let mut sessions = ctx.sessions.lock().await; - sessions.insert(session_topic.clone(), session.clone()); - } +pub(crate) async fn create_proposal_session( + ctx: &WalletConnectCtx, + topic: Topic, + metadata: Metadata, +) -> MmResult<(), WalletConnectCtxError> { + let (session, session_topic) = { + let signing_key = SigningKey::generate(&mut OsRng); + let public_key = signing_key.verifying_key(); + let session_key = SessionKey::from_osrng(public_key.as_bytes())?; + let session_topic: Topic = session_key.generate_topic().into(); - let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { - relays: vec![session.relay], - proposer: session.proposer, - required_namespaces: session.propose_namespaces, - }); - let irn_metadata = session_proposal.irn_metadata(); + info!("Session topic: {session_topic:?}"); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - ctx.publish_request(&topic, session_proposal.into(), irn_metadata) - .await?; + ( + SessionInfo::new( + subscription_id, + session_key, + topic.clone(), + metadata, + SessionType::Proposer, + ), + session_topic, + ) + }; - Ok(()) + { + let mut sessions = ctx.sessions.lock().await; + sessions.insert(session_topic.clone(), session.clone()); } - pub(crate) async fn handle_session_propose_response( - &self, - session_topic: &Topic, - response: SessionProposeResponse, - ) { - let mut sessions = self.lock().await; - if let Some(session) = sessions.get_mut(session_topic) { - info!("session found!"); - session.proposer.public_key = response.responder_public_key; - session.relay = response.relay; - session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; - }; - } + let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { + relays: vec![session.relay], + proposer: session.proposer, + required_namespaces: session.propose_namespaces, + }); + let irn_metadata = session_proposal.irn_metadata(); - pub(crate) async fn process_session_extend_request( - &self, - topic: &Topic, - extend: SessionExtendRequest, - ) -> WcRequestResponseResult { - let mut sessions = self.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { - session.expiry = extend.expiry; - info!("Updated extended, info: {:?}", session); - } + ctx.publish_request(&topic, session_proposal.into(), irn_metadata) + .await?; - let response = ResponseParamsSuccess::SessionExtend(true); - let irn_metadata = response.irn_metadata(); - let value = - serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + Ok(()) +} - Ok((value, irn_metadata)) +pub(crate) async fn process_session_propose_response( + ctx: &WalletConnectCtx, + session_topic: &Topic, + response: SessionProposeResponse, +) { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(session_topic) { + info!("session found!"); + session.proposer.public_key = response.responder_public_key; + session.relay = response.relay; + session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; + }; +} + +pub(crate) async fn process_session_extend_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + extend: SessionExtendRequest, +) -> MmResult<(), WalletConnectCtxError> { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.expiry = extend.expiry; + info!("Updated extended, info: {:?}", session); } - /// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal - pub async fn process_proposal_request( - &self, - ctx: &WalletConnectCtx, - proposal: SessionProposeRequest, - pairing_topic: Topic, - ) -> WcRequestResponseResult { - let sender_public_key = hex::decode(&proposal.proposer.public_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? - .as_slice() - .try_into() - .unwrap(); - - let session_key = SessionKey::from_osrng(&sender_public_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; - let session_topic: Topic = session_key.generate_topic().into(); - let subscription_id = ctx - .client - .subscribe(session_topic.clone()) - .await - .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + let response = ResponseParamsSuccess::SessionExtend(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; - let session = SessionInfo::new( - subscription_id, - session_key, - pairing_topic, - proposal.proposer.metadata, - SessionType::Controller, - ); - session - .supported_propose_namespaces() - .supported(&proposal.required_namespaces) - .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; + ctx.publish_response(topic, value, irn_metadata, message_id).await?; - { - let mut sessions = ctx.sessions.deref().lock().await; - _ = sessions.insert(session_topic.clone(), session.clone()); - } + Ok(()) +} - let settle_params = session.create_settle_request(); - let irn_metadata = settle_params.irn_metadata(); - ctx.publish_request(&session_topic, settle_params.into(), irn_metadata) - .await?; +/// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal +pub async fn process_proposal_request( + ctx: &WalletConnectCtx, + proposal: SessionProposeRequest, + topic: &Topic, + message_id: &MessageId, +) -> MmResult<(), WalletConnectCtxError> { + let sender_public_key = hex::decode(&proposal.proposer.public_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? + .as_slice() + .try_into() + .unwrap(); + + let session_key = SessionKey::from_osrng(&sender_public_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + + let session = SessionInfo::new( + subscription_id, + session_key, + topic.clone(), + proposal.proposer.metadata, + SessionType::Controller, + ); + session + .supported_propose_namespaces() + .supported(&proposal.required_namespaces) + .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; - Ok(session.create_proposal_response()?) + { + let mut sessions = ctx.sessions.deref().lock().await; + _ = sessions.insert(session_topic.clone(), session.clone()); } - pub(crate) async fn process_session_settle_request( - &self, - topic: &Topic, - settle: SessionSettleRequest, - ) -> WcRequestResponseResult { - { - let mut sessions = self.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { - session.namespaces = settle.namespaces.0.clone(); - session.controller = settle.controller.clone(); - session.relay = settle.relay.clone(); - session.expiry = settle.expiry; - - info!("Session successfully settled for topic: {:?}", topic); - info!("Updated session info: {:?}", session); - } - } + let settle_params = session.create_settle_request(); + let irn_metadata = settle_params.irn_metadata(); - let response = ResponseParamsSuccess::SessionSettle(true); - let irn_metadata = response.irn_metadata(); - let value = - serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + ctx.publish_request(&session_topic, settle_params.into(), irn_metadata) + .await?; - Ok((value, irn_metadata)) - } + session.proposal_response(ctx, topic, message_id).await +} - pub(crate) fn process_session_ping_request(&self) -> WcRequestResponseResult { - let response = ResponseParamsSuccess::SessionPing(true); - let irn_metadata = response.irn_metadata(); - let value = - serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; +pub(crate) async fn process_session_settle_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + settle: SessionSettleRequest, +) -> MmResult<(), WalletConnectCtxError> { + { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.namespaces = settle.namespaces.0.clone(); + session.controller = settle.controller.clone(); + session.relay = settle.relay.clone(); + session.expiry = settle.expiry; - Ok((value, irn_metadata)) + info!("Session successfully settled for topic: {:?}", topic); + info!("Updated session info: {:?}", session); + } } - pub(crate) fn process_session_delete_request( - &self, - delete_params: SessionDeleteRequest, - ) -> WcRequestResponseResult { - info!( - "\nSession is being terminated reason={}, code={}", - delete_params.message, delete_params.code, - ); - - let response = ResponseParamsSuccess::SessionDelete(true); - let irn_metadata = response.irn_metadata(); - let value = - serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let response = ResponseParamsSuccess::SessionSettle(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; - Ok((value, irn_metadata)) - } + ctx.publish_response(topic, value, irn_metadata, message_id).await?; - pub(crate) async fn session_delete_cleanup( - &self, - ctx: Arc, - topic: &Topic, - ) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.sessions.lock().await; - sessions.remove(topic).ok_or_else(|| { - WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()) - })?; + Ok(()) +} - ctx.client.unsubscribe(topic.clone()).await?; +pub(crate) async fn process_session_ping_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, +) -> MmResult<(), WalletConnectCtxError> { + let response = ResponseParamsSuccess::SessionPing(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; - // Check if there are no active sessions remaining - if sessions.is_empty() { - info!("\nNo active sessions left, disconnecting the pairing"); + ctx.publish_response(topic, value, irn_metadata, message_id).await?; - // Attempt to disconnect and remove the pairing associated with the topic - ctx.pairing - .disconnect(topic.as_ref(), &ctx.client) - .await - .map_err(|e| WalletConnectCtxError::InternalError(format!("Failed to disconnect pairing: {}", e)))?; - } + Ok(()) +} - Ok(()) - } +pub(crate) async fn process_session_delete_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + delete_params: SessionDeleteRequest, +) -> MmResult<(), WalletConnectCtxError> { + let response = ResponseParamsSuccess::SessionDelete(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; - pub(crate) async fn process_session_update_request( - &self, - topic: &Topic, - update: SessionUpdateRequest, - ) -> WcRequestResponseResult { - let mut sessions = self.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { - session.namespaces = update.namespaces.0.clone(); - info!("Updated extended, info: {:?}", session); - } + ctx.publish_response(topic, value, irn_metadata, message_id).await?; - let response = ResponseParamsSuccess::SessionUpdate(true); - let irn_metadata = response.irn_metadata(); - let value = - serde_json::to_value(response).map_err(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + Ok(()) +} + +pub(crate) async fn session_delete_cleanup( + ctx: Arc, + topic: &Topic, +) -> MmResult<(), WalletConnectCtxError> { + let mut sessions = ctx.sessions.lock().await; + sessions + .remove(topic) + .ok_or_else(|| WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()))?; + + ctx.client.unsubscribe(topic.clone()).await?; - Ok((value, irn_metadata)) + // Check if there are no active sessions remaining + if sessions.is_empty() { + info!("\nNo active sessions left, disconnecting the pairing"); + + // Attempt to disconnect and remove the pairing associated with the topic + ctx.pairing + .disconnect(topic.as_ref(), &ctx.client) + .await + .map_err(|e| WalletConnectCtxError::InternalError(format!("Failed to disconnect pairing: {}", e)))?; } + + Ok(()) +} + +pub(crate) async fn process_session_update_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + update: SessionUpdateRequest, +) -> MmResult<(), WalletConnectCtxError> { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.namespaces = update.namespaces.0.clone(); + info!("Updated extended, info: {:?}", session); + } + + let response = ResponseParamsSuccess::SessionUpdate(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) } pub enum SessionEvents { - ChainCHanged(Vec), - AccountsChanged(Vec), + ChainCHanged(String, Vec), + AccountsChanged(String, Vec), Unknown, } impl SessionEvents { - fn from_events(event: SessionEventRequest) -> MmResult { + pub fn from_events(event: SessionEventRequest) -> MmResult { match event.event.name.as_str() { "chainCHanged" => { let data = serde_json::from_value::>(event.event.data)?; - Ok(SessionEvents::ChainCHanged(data)) + Ok(SessionEvents::ChainCHanged(event.chain_id, data)) }, "accountsChanged" => { let data = serde_json::from_value::>(event.event.data)?; - Ok(SessionEvents::AccountsChanged(data)) + Ok(SessionEvents::AccountsChanged(event.chain_id, data)) }, _ => Ok(SessionEvents::Unknown), } } -} -pub async fn handle_session_event( - ctx: &WalletConnectCtx, - event: SessionEventRequest, -) -> MmResult<(), WalletConnectCtxError> { - let session_event = SessionEvents::from_events(event.clone())?; - match session_event { - SessionEvents::ChainCHanged(data) => handle_chain_changed_event(ctx, event.chain_id, data).await, - SessionEvents::AccountsChanged(data) => handle_account_changed_event(ctx, event.chain_id, data).await, - SessionEvents::Unknown => todo!(), + pub async fn handle_session_event( + &self, + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { + match &self { + SessionEvents::ChainCHanged(chain_id, data) => { + Self::handle_chain_changed_event(ctx, chain_id, data, topic, message_id).await + }, + SessionEvents::AccountsChanged(chain_id, data) => { + Self::handle_account_changed_event(ctx, chain_id, data, topic, message_id).await + }, + SessionEvents::Unknown => todo!(), + } } -} -async fn handle_chain_changed_event( - ctx: &WalletConnectCtx, - chain_id: String, - data: Vec, -) -> MmResult<(), WalletConnectCtxError> { - *ctx.active_chain_id.lock().await = chain_id.clone(); + async fn handle_chain_changed_event( + ctx: &WalletConnectCtx, + chain_id: &str, + data: &Vec, + topic: &Topic, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { + *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); - { - let mut sessions = ctx.sessions.lock().await; - let current_time = Utc::now().timestamp() as u64; - sessions.retain(|_, session| session.expiry > current_time); - }; + { + let mut sessions = ctx.sessions.lock().await; + let current_time = Utc::now().timestamp() as u64; + sessions.retain(|_, session| session.expiry > current_time); + }; - let mut sessions = ctx.sessions.lock().await; - for session in sessions.values_mut() { - for id in &data { - if let Some((namespace, chain)) = parse_chain_and_chain_id(&chain_id) { - if let Some(ns) = session.namespaces.get_mut(&namespace) { - ns.chains - .get_or_insert_with(BTreeSet::new) - .insert(format!("{namespace}:{id}")); + let mut sessions = ctx.sessions.lock().await; + for session in sessions.values_mut() { + for id in data { + if let Some((namespace, chain)) = parse_chain_and_chain_id(chain_id) { + if let Some(ns) = session.namespaces.get_mut(&namespace) { + ns.chains + .get_or_insert_with(BTreeSet::new) + .insert(format!("{namespace}:{id}")); + } } } } - } - //TODO: Notify about chain changed. - Ok(()) -} + //TODO: Notify about chain changed. -async fn handle_account_changed_event( - ctx: &WalletConnectCtx, - chain_id: String, - data: Vec, -) -> MmResult<(), WalletConnectCtxError> { - *ctx.active_chain_id.lock().await = chain_id.clone(); + let params = ResponseParamsSuccess::SessionEvent(true); + let irn_metadata = params.irn_metadata(); - let mut sessions = ctx.sessions.lock().await; - let current_time = Utc::now().timestamp() as u64; + let value = serde_json::to_value(params)?; + ctx.publish_response(topic, value, irn_metadata, message_id).await?; - sessions.retain(|_, session| session.expiry > current_time); + Ok(()) + } - let mut sessions = ctx.sessions.lock().await; - for session in sessions.values_mut() { - for address in &data { - if let Some((namespace, _)) = parse_chain_and_chain_id(&chain_id) { - if let Some(ns) = session.namespaces.get_mut(&namespace) { - ns.accounts - .get_or_insert_with(BTreeSet::new) - .insert(format!("{chain_id}:{address}")); + async fn handle_account_changed_event( + ctx: &WalletConnectCtx, + chain_id: &str, + data: &Vec, + topic: &Topic, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { + *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); + + let mut sessions = ctx.sessions.lock().await; + let current_time = Utc::now().timestamp() as u64; + + sessions.retain(|_, session| session.expiry > current_time); + + let mut sessions = ctx.sessions.lock().await; + for session in sessions.values_mut() { + for address in data { + if let Some((namespace, _)) = parse_chain_and_chain_id(chain_id) { + if let Some(ns) = session.namespaces.get_mut(&namespace) { + ns.accounts + .get_or_insert_with(BTreeSet::new) + .insert(format!("{chain_id}:{address}")); + } } } } - } - //TODO: Notify about account changed. - Ok(()) + //TODO: Notify about account changed. + // + + let params = ResponseParamsSuccess::SessionEvent(true); + let irn_metadata = params.irn_metadata(); + + let value = serde_json::to_value(params)?; + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) + } } fn parse_chain_and_chain_id(chain: &str) -> Option<(String, String)> { From 98026acecdf2f23d9fc33294f6561c0a9a75e023 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 16 Sep 2024 15:33:52 +0100 Subject: [PATCH 014/125] add some session fn doc comments --- mm2src/kdf_walletconnect/src/session.rs | 43 +++++++++++++------------ 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 629712e9a2..3d1b508e20 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -91,25 +91,41 @@ impl SessionKey { } } +/// In the WalletConnect protocol, a session involves two parties: a controller +/// (typically a wallet) and a proposer (typically a dApp). This enum is used +/// to distinguish between these two roles. #[derive(Debug, Clone)] pub enum SessionType { + /// Represents the controlling party in a session, typically a wallet. Controller, + /// Represents the proposing party in a session, typically a dApp. Proposer, } +/// This struct is typically used in the core session management logic of a WalletConnect +/// implementation. It's used to store, retrieve, and update session information throughout +/// the lifecycle of a WalletConnect connection. #[derive(Debug, Clone)] pub struct SessionInfo { /// Pairing subscription id. pub subscription_id: SubscriptionId, /// Session symmetric key pub session_key: SessionKey, + /// Information about the controlling party (typically a wallet). pub controller: Controller, + /// Information about the proposing party (typically a dApp). pub proposer: Proposer, + /// Details about the relay used for communication. pub relay: Relay, + /// Agreed-upon namespaces for the session, mapping namespace strings to their definitions. pub namespaces: BTreeMap, + /// Namespaces proposed for the session, may differ from agreed namespaces. pub propose_namespaces: ProposeNamespaces, + /// Unix timestamp (in seconds) when the session expires. pub expiry: u64, + /// Topic used for the initial pairing process. pub pairing_topic: Topic, + /// Indicates whether this session info represents a Controller or Proposer perspective. pub session_type: SessionType, } @@ -223,6 +239,7 @@ impl Session { } } +/// Creates a new session proposal form topic and metadata. pub(crate) async fn create_proposal_session( ctx: &WalletConnectCtx, topic: Topic, @@ -271,6 +288,7 @@ pub(crate) async fn create_proposal_session( Ok(()) } +/// Process session propose reponse. pub(crate) async fn process_session_propose_response( ctx: &WalletConnectCtx, session_topic: &Topic, @@ -285,6 +303,7 @@ pub(crate) async fn process_session_propose_response( }; } +/// Process session extend request. pub(crate) async fn process_session_extend_request( ctx: &WalletConnectCtx, topic: &Topic, @@ -306,6 +325,7 @@ pub(crate) async fn process_session_extend_request( Ok(()) } +/// Process session proposal request /// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal pub async fn process_proposal_request( ctx: &WalletConnectCtx, @@ -354,6 +374,7 @@ pub async fn process_proposal_request( session.proposal_response(ctx, topic, message_id).await } +/// Process session settle request. pub(crate) async fn process_session_settle_request( ctx: &WalletConnectCtx, topic: &Topic, @@ -541,28 +562,8 @@ impl SessionEvents { topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { - *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); - - let mut sessions = ctx.sessions.lock().await; - let current_time = Utc::now().timestamp() as u64; - - sessions.retain(|_, session| session.expiry > current_time); - - let mut sessions = ctx.sessions.lock().await; - for session in sessions.values_mut() { - for address in data { - if let Some((namespace, _)) = parse_chain_and_chain_id(chain_id) { - if let Some(ns) = session.namespaces.get_mut(&namespace) { - ns.accounts - .get_or_insert_with(BTreeSet::new) - .insert(format!("{chain_id}:{address}")); - } - } - } - } - + // TODO: Handle account change logic. //TODO: Notify about account changed. - // let params = ResponseParamsSuccess::SessionEvent(true); let irn_metadata = params.irn_metadata(); From 9dddb9113572663fc17437233a4d2219c1a5f4e7 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 16 Sep 2024 20:06:26 +0100 Subject: [PATCH 015/125] big improvements to session handling --- .../kdf_walletconnect/src/inbound_message.rs | 14 +- mm2src/kdf_walletconnect/src/lib.rs | 58 +-- mm2src/kdf_walletconnect/src/session.rs | 427 ++---------------- .../kdf_walletconnect/src/session/delete.rs | 49 ++ mm2src/kdf_walletconnect/src/session/event.rs | 114 +++++ .../kdf_walletconnect/src/session/extend.rs | 29 ++ mm2src/kdf_walletconnect/src/session/ping.rs | 20 + .../kdf_walletconnect/src/session/propose.rs | 163 +++++++ .../kdf_walletconnect/src/session/settle.rs | 71 +++ .../kdf_walletconnect/src/session/update.rs | 27 ++ .../src/rpc/lp_commands/lp_commands.rs | 3 +- 11 files changed, 559 insertions(+), 416 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/session/delete.rs create mode 100644 mm2src/kdf_walletconnect/src/session/event.rs create mode 100644 mm2src/kdf_walletconnect/src/session/extend.rs create mode 100644 mm2src/kdf_walletconnect/src/session/ping.rs create mode 100644 mm2src/kdf_walletconnect/src/session/propose.rs create mode 100644 mm2src/kdf_walletconnect/src/session/settle.rs create mode 100644 mm2src/kdf_walletconnect/src/session/update.rs diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index ed29c1b20a..8f2d169418 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -6,9 +6,13 @@ use relay_rpc::{domain::Topic, use crate::{error::WalletConnectCtxError, pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}, - session::{process_proposal_request, process_session_delete_request, process_session_extend_request, - process_session_ping_request, process_session_propose_response, process_session_settle_request, - process_session_update_request, SessionEvents}, + session::{delete::process_session_delete_request, + event::SessionEvents, + extend::process_session_extend_request, + ping::process_session_ping_request, + propose::{process_proposal_request, process_session_propose_response}, + settle::process_session_settle_request, + update::process_session_update_request}, WalletConnectCtx}; pub(crate) async fn process_inbound_request( @@ -45,13 +49,13 @@ pub(crate) async fn process_inbound_response( response: Response, topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { + println!("got a response: {:?}", response); match response { Response::Success(value) => { let params = serde_json::from_value::(value.result)?; match params { ResponseParamsSuccess::SessionPropose(param) => { - process_session_propose_response(&ctx, topic, param).await; - Ok(()) + process_session_propose_response(&ctx, topic, param).await }, ResponseParamsSuccess::SessionSettle(success) | ResponseParamsSuccess::SessionUpdate(success) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 296f0eed28..f44680fe1a 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -16,18 +16,18 @@ use inbound_message::{process_inbound_request, process_inbound_response}; use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; -use pairing_api::{Methods, PairingClient}; +use pairing_api::PairingClient; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, - rpc::{params::IrnMetadata, Params, Payload, Request, Response, SuccessfulResponse, - JSON_RPC_VERSION_STR}}; -use session::{create_proposal_session, Session}; + rpc::{params::{session::ProposeNamespaces, IrnMetadata}, + Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; +use session::{propose::create_proposal_session, Session}; use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; -const SUPPORTED_PROTOCOL: &str = "irn"; +pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; const SUPPORTED_METHODS: &[&str] = &[ "eth_sendTransaction", "eth_signTransaction", @@ -72,6 +72,33 @@ impl WalletConnectCtx { } } + pub async fn create_pairing( + &self, + required_namespaces: Option, + ) -> MmResult { + let metadata = generate_metadata(); + + let (topic, url) = self.pairing.create(metadata.clone(), None).await?; + + info!("Subscribing to topic: {topic:?}"); + self.client.subscribe(topic.clone()).await?; + info!("Subscribed to topic: {topic:?}"); + + create_proposal_session(self, topic, metadata, required_namespaces).await?; + + Ok(url) + } + + pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { + let topic = self.pairing.pair(url, activate).await?; + + info!("Subscribing to topic: {topic:?}"); + self.client.subscribe(topic.clone()).await?; + info!("Subscribed to topic: {topic:?}"); + + Ok(topic) + } + pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } pub async fn get_active_sessions(&self) -> impl IntoIterator { @@ -141,27 +168,6 @@ impl WalletConnectCtx { ))) } - pub async fn create_pairing(&self) -> MmResult { - let metadata = generate_metadata(); - let methods = Methods(vec![SUPPORTED_METHODS - .iter() - .map(|m| m.to_string()) - .collect::>()]); - - let (topic, url) = self - .pairing - .create(metadata.clone(), Some(methods), &self.client) - .await?; - - create_proposal_session(self, topic, metadata).await?; - - Ok(url) - } - - pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { - Ok(self.pairing.pair(url, activate, &self.client).await?) - } - /// Private function to publish a request. async fn publish_request( &self, diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 3d1b508e20..91df397524 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,4 +1,13 @@ +pub(crate) mod delete; +pub(crate) mod event; +pub(crate) mod extend; +pub(crate) mod ping; +pub(crate) mod propose; +pub(crate) mod settle; +pub(crate) mod update; + use crate::error::SessionError; +use crate::metadata::generate_metadata; use crate::{error::WalletConnectCtxError, WalletConnectCtx, SUPPORTED_ACCOUNTS, SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; use chrono::naive::serde; @@ -23,7 +32,9 @@ use relay_rpc::{domain::{SubscriptionId, Topic}, use serde_json::Value; use std::collections::{BTreeSet, HashMap}; use std::ops::Deref; +use std::vec; use std::{collections::BTreeMap, sync::Arc}; +use x25519_dalek::{SharedSecret, StaticSecret}; use {hkdf::Hkdf, rand::{rngs::OsRng, CryptoRng, RngCore}, sha2::{Digest, Sha256}, @@ -51,6 +62,14 @@ impl std::fmt::Debug for SessionKey { } impl SessionKey { + /// Creates a new SessionKey with a given public key and empty symmetric key. + pub fn new(public_key: PublicKey) -> Self { + Self { + sym_key: [0u8; 32], + public_key, + } + } + /// Creates new session key from `osrng`. pub fn from_osrng(sender_public_key: &[u8; 32]) -> Result { SessionKey::diffie_hellman(OsRng, sender_public_key) @@ -61,7 +80,7 @@ impl SessionKey { where T: RngCore + CryptoRng, { - let single_use_private_key = EphemeralSecret::random_from_rng(csprng); + let single_use_private_key = StaticSecret::random_from_rng(csprng); let public_key = PublicKey::from(&single_use_private_key); let ikm = single_use_private_key.diffie_hellman(&PublicKey::from(*sender_public_key)); @@ -77,6 +96,23 @@ impl SessionKey { Ok(session_sym_key) } + /// Generates the symmetric key given the ephemeral secret and the peer's public key. + pub fn generate_symmetric_key( + &mut self, + static_secret: StaticSecret, + peer_public_key: &[u8; 32], + ) -> Result<(), SessionError> { + let shared_secret = static_secret.diffie_hellman(&PublicKey::from(*peer_public_key)); + self.derive_symmetric_key(&shared_secret) + } + + /// Derives the symmetric key from a shared secret. + fn derive_symmetric_key(&mut self, shared_secret: &SharedSecret) -> Result<(), SessionError> { + let hk = Hkdf::::new(None, shared_secret.as_bytes()); + hk.expand(&[], &mut self.sym_key) + .map_err(|e| SessionError::SymKeyGeneration(e.to_string())) + } + /// Gets symmetic key reference. pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } @@ -178,48 +214,12 @@ impl SessionInfo { session_type, } } - - fn supported_propose_namespaces(&self) -> &ProposeNamespaces { &self.propose_namespaces } - - fn create_settle_request(&self) -> RequestParams { - let mut settled_namespaces = BTreeMap::::new(); - settled_namespaces.insert("eip155".to_string(), Namespace { - accounts: Some(SUPPORTED_ACCOUNTS.iter().map(|a| a.to_string()).collect()), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - chains: None, - }); - - RequestParams::SessionSettle(SessionSettleRequest { - relay: self.relay.clone(), - controller: self.controller.clone(), - namespaces: SettleNamespaces(settled_namespaces), - expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, - }) - } - - async fn proposal_response( - &self, - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { - let response = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { - relay: self.relay.clone(), - responder_public_key: self.controller.public_key.clone(), - }); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) - } } -#[derive(Debug, Clone)] pub struct Session { sessions: Arc>>, + keypair: StaticSecret, + public_key: PublicKey, } impl Deref for Session { @@ -233,353 +233,12 @@ impl Default for Session { impl Session { pub fn new() -> Self { + let static_secret = StaticSecret::random_from_rng(OsRng); + let public_key = PublicKey::from(&static_secret); Self { sessions: Default::default(), + keypair: static_secret, + public_key, } } } - -/// Creates a new session proposal form topic and metadata. -pub(crate) async fn create_proposal_session( - ctx: &WalletConnectCtx, - topic: Topic, - metadata: Metadata, -) -> MmResult<(), WalletConnectCtxError> { - let (session, session_topic) = { - let signing_key = SigningKey::generate(&mut OsRng); - let public_key = signing_key.verifying_key(); - let session_key = SessionKey::from_osrng(public_key.as_bytes())?; - let session_topic: Topic = session_key.generate_topic().into(); - - info!("Session topic: {session_topic:?}"); - let subscription_id = ctx - .client - .subscribe(session_topic.clone()) - .await - .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - - ( - SessionInfo::new( - subscription_id, - session_key, - topic.clone(), - metadata, - SessionType::Proposer, - ), - session_topic, - ) - }; - - { - let mut sessions = ctx.sessions.lock().await; - sessions.insert(session_topic.clone(), session.clone()); - } - - let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { - relays: vec![session.relay], - proposer: session.proposer, - required_namespaces: session.propose_namespaces, - }); - let irn_metadata = session_proposal.irn_metadata(); - - ctx.publish_request(&topic, session_proposal.into(), irn_metadata) - .await?; - - Ok(()) -} - -/// Process session propose reponse. -pub(crate) async fn process_session_propose_response( - ctx: &WalletConnectCtx, - session_topic: &Topic, - response: SessionProposeResponse, -) { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(session_topic) { - info!("session found!"); - session.proposer.public_key = response.responder_public_key; - session.relay = response.relay; - session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; - }; -} - -/// Process session extend request. -pub(crate) async fn process_session_extend_request( - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - extend: SessionExtendRequest, -) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { - session.expiry = extend.expiry; - info!("Updated extended, info: {:?}", session); - } - - let response = ResponseParamsSuccess::SessionExtend(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) -} - -/// Process session proposal request -/// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal -pub async fn process_proposal_request( - ctx: &WalletConnectCtx, - proposal: SessionProposeRequest, - topic: &Topic, - message_id: &MessageId, -) -> MmResult<(), WalletConnectCtxError> { - let sender_public_key = hex::decode(&proposal.proposer.public_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? - .as_slice() - .try_into() - .unwrap(); - - let session_key = SessionKey::from_osrng(&sender_public_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; - let session_topic: Topic = session_key.generate_topic().into(); - let subscription_id = ctx - .client - .subscribe(session_topic.clone()) - .await - .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - - let session = SessionInfo::new( - subscription_id, - session_key, - topic.clone(), - proposal.proposer.metadata, - SessionType::Controller, - ); - session - .supported_propose_namespaces() - .supported(&proposal.required_namespaces) - .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; - - { - let mut sessions = ctx.sessions.deref().lock().await; - _ = sessions.insert(session_topic.clone(), session.clone()); - } - - let settle_params = session.create_settle_request(); - let irn_metadata = settle_params.irn_metadata(); - - ctx.publish_request(&session_topic, settle_params.into(), irn_metadata) - .await?; - - session.proposal_response(ctx, topic, message_id).await -} - -/// Process session settle request. -pub(crate) async fn process_session_settle_request( - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - settle: SessionSettleRequest, -) -> MmResult<(), WalletConnectCtxError> { - { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { - session.namespaces = settle.namespaces.0.clone(); - session.controller = settle.controller.clone(); - session.relay = settle.relay.clone(); - session.expiry = settle.expiry; - - info!("Session successfully settled for topic: {:?}", topic); - info!("Updated session info: {:?}", session); - } - } - - let response = ResponseParamsSuccess::SessionSettle(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) -} - -pub(crate) async fn process_session_ping_request( - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, -) -> MmResult<(), WalletConnectCtxError> { - let response = ResponseParamsSuccess::SessionPing(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) -} - -pub(crate) async fn process_session_delete_request( - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - delete_params: SessionDeleteRequest, -) -> MmResult<(), WalletConnectCtxError> { - let response = ResponseParamsSuccess::SessionDelete(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) -} - -pub(crate) async fn session_delete_cleanup( - ctx: Arc, - topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.sessions.lock().await; - sessions - .remove(topic) - .ok_or_else(|| WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()))?; - - ctx.client.unsubscribe(topic.clone()).await?; - - // Check if there are no active sessions remaining - if sessions.is_empty() { - info!("\nNo active sessions left, disconnecting the pairing"); - - // Attempt to disconnect and remove the pairing associated with the topic - ctx.pairing - .disconnect(topic.as_ref(), &ctx.client) - .await - .map_err(|e| WalletConnectCtxError::InternalError(format!("Failed to disconnect pairing: {}", e)))?; - } - - Ok(()) -} - -pub(crate) async fn process_session_update_request( - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - update: SessionUpdateRequest, -) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { - session.namespaces = update.namespaces.0.clone(); - info!("Updated extended, info: {:?}", session); - } - - let response = ResponseParamsSuccess::SessionUpdate(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) -} - -pub enum SessionEvents { - ChainCHanged(String, Vec), - AccountsChanged(String, Vec), - Unknown, -} - -impl SessionEvents { - pub fn from_events(event: SessionEventRequest) -> MmResult { - match event.event.name.as_str() { - "chainCHanged" => { - let data = serde_json::from_value::>(event.event.data)?; - Ok(SessionEvents::ChainCHanged(event.chain_id, data)) - }, - "accountsChanged" => { - let data = serde_json::from_value::>(event.event.data)?; - Ok(SessionEvents::AccountsChanged(event.chain_id, data)) - }, - _ => Ok(SessionEvents::Unknown), - } - } - - pub async fn handle_session_event( - &self, - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { - match &self { - SessionEvents::ChainCHanged(chain_id, data) => { - Self::handle_chain_changed_event(ctx, chain_id, data, topic, message_id).await - }, - SessionEvents::AccountsChanged(chain_id, data) => { - Self::handle_account_changed_event(ctx, chain_id, data, topic, message_id).await - }, - SessionEvents::Unknown => todo!(), - } - } - - async fn handle_chain_changed_event( - ctx: &WalletConnectCtx, - chain_id: &str, - data: &Vec, - topic: &Topic, - message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { - *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); - - { - let mut sessions = ctx.sessions.lock().await; - let current_time = Utc::now().timestamp() as u64; - sessions.retain(|_, session| session.expiry > current_time); - }; - - let mut sessions = ctx.sessions.lock().await; - for session in sessions.values_mut() { - for id in data { - if let Some((namespace, chain)) = parse_chain_and_chain_id(chain_id) { - if let Some(ns) = session.namespaces.get_mut(&namespace) { - ns.chains - .get_or_insert_with(BTreeSet::new) - .insert(format!("{namespace}:{id}")); - } - } - } - } - - //TODO: Notify about chain changed. - - let params = ResponseParamsSuccess::SessionEvent(true); - let irn_metadata = params.irn_metadata(); - - let value = serde_json::to_value(params)?; - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) - } - - async fn handle_account_changed_event( - ctx: &WalletConnectCtx, - chain_id: &str, - data: &Vec, - topic: &Topic, - message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { - // TODO: Handle account change logic. - //TODO: Notify about account changed. - - let params = ResponseParamsSuccess::SessionEvent(true); - let irn_metadata = params.irn_metadata(); - - let value = serde_json::to_value(params)?; - ctx.publish_response(topic, value, irn_metadata, message_id).await?; - - Ok(()) - } -} - -fn parse_chain_and_chain_id(chain: &str) -> Option<(String, String)> { - let sp = chain.split(':').collect::>(); - if sp.len() == 2 { - return None; - }; - - Some((sp[0].to_owned(), sp[1].to_owned())) -} diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/delete.rs new file mode 100644 index 0000000000..f4d71639fb --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/delete.rs @@ -0,0 +1,49 @@ +use std::sync::Arc; + +use common::log::info; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::rpc::params::RelayProtocolMetadata; +use relay_rpc::{domain::{MessageId, Topic}, + rpc::params::{session_delete::SessionDeleteRequest, ResponseParamsSuccess}}; + +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + +pub(crate) async fn process_session_delete_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + delete_params: SessionDeleteRequest, +) -> MmResult<(), WalletConnectCtxError> { + let response = ResponseParamsSuccess::SessionDelete(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) +} + +pub(crate) async fn session_delete_cleanup( + ctx: Arc, + topic: &Topic, +) -> MmResult<(), WalletConnectCtxError> { + let mut sessions = ctx.sessions.lock().await; + sessions + .remove(topic) + .ok_or_else(|| WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()))?; + + ctx.client.unsubscribe(topic.clone()).await?; + + // Check if there are no active sessions remaining + if sessions.is_empty() { + info!("\nNo active sessions left, disconnecting the pairing"); + + // Attempt to disconnect and remove the pairing associated with the topic + ctx.pairing + .disconnect(topic.as_ref(), &ctx.client) + .await + .map_err(|e| WalletConnectCtxError::InternalError(format!("Failed to disconnect pairing: {}", e)))?; + } + + Ok(()) +} diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs new file mode 100644 index 0000000000..4439d9279e --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -0,0 +1,114 @@ +use std::collections::BTreeSet; + +use chrono::Utc; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::{domain::{MessageId, Topic}, + rpc::params::{session_event::SessionEventRequest, RelayProtocolMetadata, ResponseParamsSuccess}}; + +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + +pub enum SessionEvents { + ChainCHanged(String, Vec), + AccountsChanged(String, Vec), + Unknown, +} + +impl SessionEvents { + pub fn from_events(event: SessionEventRequest) -> MmResult { + match event.event.name.as_str() { + "chainCHanged" => { + let data = serde_json::from_value::>(event.event.data)?; + Ok(SessionEvents::ChainCHanged(event.chain_id, data)) + }, + "accountsChanged" => { + let data = serde_json::from_value::>(event.event.data)?; + Ok(SessionEvents::AccountsChanged(event.chain_id, data)) + }, + _ => Ok(SessionEvents::Unknown), + } + } + + pub async fn handle_session_event( + &self, + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { + match &self { + SessionEvents::ChainCHanged(chain_id, data) => { + Self::handle_chain_changed_event(ctx, chain_id, data, topic, message_id).await + }, + SessionEvents::AccountsChanged(chain_id, data) => { + Self::handle_account_changed_event(ctx, chain_id, data, topic, message_id).await + }, + SessionEvents::Unknown => todo!(), + } + } + + async fn handle_chain_changed_event( + ctx: &WalletConnectCtx, + chain_id: &str, + data: &Vec, + topic: &Topic, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { + *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); + + { + let mut sessions = ctx.sessions.lock().await; + let current_time = Utc::now().timestamp() as u64; + sessions.retain(|_, session| session.expiry > current_time); + }; + + let mut sessions = ctx.sessions.lock().await; + for session in sessions.values_mut() { + for id in data { + if let Some((namespace, chain)) = parse_chain_and_chain_id(chain_id) { + if let Some(ns) = session.namespaces.get_mut(&namespace) { + ns.chains + .get_or_insert_with(BTreeSet::new) + .insert(format!("{namespace}:{id}")); + } + } + } + } + + //TODO: Notify about chain changed. + + let params = ResponseParamsSuccess::SessionEvent(true); + let irn_metadata = params.irn_metadata(); + + let value = serde_json::to_value(params)?; + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) + } + + async fn handle_account_changed_event( + ctx: &WalletConnectCtx, + chain_id: &str, + data: &[String], + topic: &Topic, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { + // TODO: Handle account change logic. + //TODO: Notify about account changed. + + let params = ResponseParamsSuccess::SessionEvent(true); + let irn_metadata = params.irn_metadata(); + + let value = serde_json::to_value(params)?; + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) + } +} + +fn parse_chain_and_chain_id(chain: &str) -> Option<(String, String)> { + let sp = chain.split(':').collect::>(); + if sp.len() == 2 { + return None; + }; + + Some((sp[0].to_owned(), sp[1].to_owned())) +} diff --git a/mm2src/kdf_walletconnect/src/session/extend.rs b/mm2src/kdf_walletconnect/src/session/extend.rs new file mode 100644 index 0000000000..1cefb72b11 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/extend.rs @@ -0,0 +1,29 @@ +use common::log::info; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::rpc::params::RelayProtocolMetadata; +use relay_rpc::{domain::{MessageId, Topic}, + rpc::params::{session_extend::SessionExtendRequest, ResponseParamsSuccess}}; + +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + +/// Process session extend request. +pub(crate) async fn process_session_extend_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + extend: SessionExtendRequest, +) -> MmResult<(), WalletConnectCtxError> { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.expiry = extend.expiry; + info!("Updated extended, info: {:?}", session); + } + + let response = ResponseParamsSuccess::SessionExtend(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) +} diff --git a/mm2src/kdf_walletconnect/src/session/ping.rs b/mm2src/kdf_walletconnect/src/session/ping.rs new file mode 100644 index 0000000000..887404e3d9 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/ping.rs @@ -0,0 +1,20 @@ +use mm2_err_handle::prelude::MmResult; +use relay_rpc::rpc::params::RelayProtocolMetadata; +use relay_rpc::{domain::{MessageId, Topic}, + rpc::params::ResponseParamsSuccess}; + +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + +pub(crate) async fn process_session_ping_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, +) -> MmResult<(), WalletConnectCtxError> { + let response = ResponseParamsSuccess::SessionPing(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) +} diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs new file mode 100644 index 0000000000..6516ef77b8 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -0,0 +1,163 @@ +use std::{collections::BTreeMap, ops::Deref}; + +use chrono::Utc; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::{domain::{MessageId, Topic}, + rpc::params::{session::{Namespace, ProposeNamespace, ProposeNamespaces}, + session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, + Metadata, Relay, RequestParams, ResponseParamsSuccess}}; + +use super::{settle::send_session_settle_request, SessionInfo}; +use crate::{error::WalletConnectCtxError, + metadata::generate_metadata, + session::{SessionKey, SessionType, THIRTY_DAYS}, + WalletConnectCtx, SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; +use mm2_err_handle::map_to_mm::MapToMmResult; +use relay_rpc::rpc::params::RelayProtocolMetadata; + +/// Creates a new session proposal form topic and metadata. +pub(crate) async fn create_proposal_session( + ctx: &WalletConnectCtx, + topic: Topic, + metadata: Metadata, + required_namespaces: Option, +) -> MmResult<(), WalletConnectCtxError> { + let proposer = Proposer { + metadata: generate_metadata(), + public_key: hex::encode(ctx.sessions.public_key.as_bytes()), + }; + let mut namespaces = BTreeMap::::new(); + namespaces.insert("eip155".to_string(), ProposeNamespace { + chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + }); + + let relays = Relay { + protocol: SUPPORTED_PROTOCOL.to_string(), + data: None, + }; + + let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { + relays: vec![relays], + proposer, + required_namespaces: required_namespaces.unwrap_or(ProposeNamespaces(namespaces)), + }); + let irn_metadata = session_proposal.irn_metadata(); + + ctx.publish_request(&topic, session_proposal.into(), irn_metadata) + .await?; + + Ok(()) +} + +async fn send_proposal_request_response( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + responder_public_key: String, +) -> MmResult<(), WalletConnectCtxError> { + let relay = Relay { + protocol: SUPPORTED_PROTOCOL.to_string(), + data: None, + }; + let response = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { + relay, + responder_public_key, + }); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) +} + +/// Process session proposal request +/// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal +pub async fn process_proposal_request( + ctx: &WalletConnectCtx, + proposal: SessionProposeRequest, + topic: &Topic, + message_id: &MessageId, +) -> MmResult<(), WalletConnectCtxError> { + let sender_public_key = hex::decode(&proposal.proposer.public_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? + .as_slice() + .try_into() + .unwrap(); + + let session_key = SessionKey::from_osrng(&sender_public_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + + let session = SessionInfo::new( + subscription_id, + session_key, + topic.clone(), + proposal.proposer.metadata, + SessionType::Controller, + ); + session + .propose_namespaces + .supported(&proposal.required_namespaces) + .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; + + { + let mut sessions = ctx.sessions.deref().lock().await; + _ = sessions.insert(session_topic.clone(), session.clone()); + } + + { + send_session_settle_request(ctx, session, session_topic).await?; + }; + + send_proposal_request_response(ctx, topic, message_id, proposal.proposer.public_key).await +} + +/// Process session propose reponse. +pub(crate) async fn process_session_propose_response( + ctx: &WalletConnectCtx, + pairing_topic: &Topic, + response: SessionProposeResponse, +) -> MmResult<(), WalletConnectCtxError> { + let other_public_key = hex::decode(&response.responder_public_key) + .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? + .as_slice() + .try_into() + .unwrap(); + + let mut session_key = SessionKey::new(ctx.sessions.public_key); + session_key.generate_symmetric_key(ctx.sessions.keypair.clone(), &other_public_key)?; + + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + + let mut session = SessionInfo::new( + subscription_id, + session_key, + pairing_topic.clone(), + Metadata::default(), + SessionType::Controller, + ); + session.relay = response.relay; + session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; + session.controller.public_key = response.responder_public_key; + + let mut sessions = ctx.sessions.lock().await; + sessions.insert(session_topic.clone(), session.clone()); + + // Activate pairing_topic + ctx.pairing.activate(pairing_topic.as_ref()).await?; + + Ok(()) +} diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs new file mode 100644 index 0000000000..45470b8b10 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -0,0 +1,71 @@ +use std::collections::BTreeMap; + +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{SUPPORTED_ACCOUNTS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; + +use chrono::Utc; +use common::log::info; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::rpc::params::session::{Namespace, SettleNamespaces}; +use relay_rpc::rpc::params::session_settle::Controller; +use relay_rpc::rpc::params::{Relay, RelayProtocolMetadata, RequestParams}; +use relay_rpc::{domain::{MessageId, Topic}, + rpc::params::{session_settle::SessionSettleRequest, ResponseParamsSuccess}}; + +use super::{SessionInfo, THIRTY_DAYS}; + +pub(crate) async fn send_session_settle_request( + ctx: &WalletConnectCtx, + session_info: SessionInfo, + session_topic: Topic, +) -> MmResult<(), WalletConnectCtxError> { + let mut settled_namespaces = BTreeMap::::new(); + settled_namespaces.insert("eip155".to_string(), Namespace { + accounts: Some(SUPPORTED_ACCOUNTS.iter().map(|a| a.to_string()).collect()), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + chains: None, + }); + + let request = RequestParams::SessionSettle(SessionSettleRequest { + relay: session_info.relay.clone(), + controller: session_info.controller.clone(), + namespaces: SettleNamespaces(settled_namespaces), + expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, + }); + let irn_metadata = request.irn_metadata(); + + ctx.publish_request(&session_topic, request.into(), irn_metadata) + .await?; + + Ok(()) +} + +/// Process session settle request. +pub(crate) async fn process_session_settle_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + settle: SessionSettleRequest, +) -> MmResult<(), WalletConnectCtxError> { + { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.namespaces = settle.namespaces.0.clone(); + session.controller = settle.controller.clone(); + session.relay = settle.relay.clone(); + session.expiry = settle.expiry; + + info!("Session successfully settled for topic: {:?}", topic); + info!("Updated session info: {:?}", session); + } + } + + let response = ResponseParamsSuccess::SessionSettle(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) +} diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs new file mode 100644 index 0000000000..aad3ca9d94 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -0,0 +1,27 @@ +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use common::log::info; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::rpc::params::RelayProtocolMetadata; +use relay_rpc::{domain::{MessageId, Topic}, + rpc::params::{session_update::SessionUpdateRequest, ResponseParamsSuccess}}; + +pub(crate) async fn process_session_update_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + update: SessionUpdateRequest, +) -> MmResult<(), WalletConnectCtxError> { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.namespaces = update.namespaces.0.clone(); + info!("Updated extended, info: {:?}", session); + } + + let response = ResponseParamsSuccess::SessionUpdate(true); + let irn_metadata = response.irn_metadata(); + let value = serde_json::to_value(response)?; + + ctx.publish_response(topic, value, irn_metadata, message_id).await?; + + Ok(()) +} diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs index fdaaac19a5..d9628f38df 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs @@ -115,6 +115,7 @@ pub async fn trezor_connection_status( }) } +//////////// TESTING PURPOSES ///////////// use serde::Serialize; #[derive(Deserialize)] @@ -158,7 +159,7 @@ pub async fn create_new_pairing( ) -> MmResult { let url = ctx .wallect_connect - .create_pairing() + .create_pairing(None) .await .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; From 52a0f72de8408c79c24e1a6ed6379995a40eecc7 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 17 Sep 2024 11:27:19 +0100 Subject: [PATCH 016/125] implement session delete and cleaup --- Cargo.lock | 1 + mm2src/kdf_walletconnect/Cargo.toml | 1 + mm2src/kdf_walletconnect/src/error.rs | 46 ++++++++++--------- .../kdf_walletconnect/src/inbound_message.rs | 13 ++++-- mm2src/kdf_walletconnect/src/lib.rs | 13 ++---- mm2src/kdf_walletconnect/src/session.rs | 24 +++++----- .../kdf_walletconnect/src/session/delete.rs | 45 +++++++++--------- .../kdf_walletconnect/src/session/propose.rs | 11 ++--- .../kdf_walletconnect/src/session/update.rs | 1 + mm2src/mm2_main/src/rpc.rs | 18 +------- 10 files changed, 83 insertions(+), 90 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e1767f2209..5991622189 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3552,6 +3552,7 @@ dependencies = [ "chrono", "common", "derive_more", + "enum_derives", "futures 0.3.28", "hex", "hkdf", diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 343f7ea511..876d6e54f1 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -10,6 +10,7 @@ edition = "2021" chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } derive_more = "0.99" +enum_derives = { path = "../derives/enum_derives" } futures = { version = "0.3", package = "futures", features = [ "compat", "async-await", diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index c11fd3cc38..dc8d7fc470 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -1,29 +1,41 @@ -use derive_more::Display; +use enum_derives::EnumFromStringify; use pairing_api::PairingClientError; use relay_client::error::{ClientError, Error}; use relay_rpc::rpc::{PublishError, SubscriptionError}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Display, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, EnumFromStringify, thiserror::Error)] pub enum WalletConnectCtxError { + #[error("Pairing Error: {0}")] + #[from_stringify("PairingClientError")] PairingError(String), - EncodeError(String), + #[error("Publish Error: {0}")] PublishError(String), + #[error("Client Error: {0}")] + #[from_stringify("ClientError")] ClientError(String), - PairingNotFound(String), + #[error("Subscription Error: {0}")] SubscriptionError(String), + #[error("Internal Error: {0}")] InternalError(String), + #[error("Serde Error: {0}")] + #[from_stringify("serde_json::Error")] SerdeError(String), - UnsuccessfulResponse(String), + #[error("UnSuccessfulResponse Error: {0}")] + UnSuccessfulResponse(String), + #[error("Session Error: {0}")] + #[from_stringify("SessionError")] SessionError(String), -} - -impl From for WalletConnectCtxError { - fn from(error: PairingClientError) -> Self { WalletConnectCtxError::PairingError(error.to_string()) } -} - -impl From for WalletConnectCtxError { - fn from(error: ClientError) -> Self { WalletConnectCtxError::ClientError(error.to_string()) } + #[error("Unknown params")] + InvalidRequest, + #[error("Request is not yet implemented")] + NotImplemented, + #[error("Hex Error: {0}")] + #[from_stringify("hex::FromHexError")] + HexError(String), + #[error("Payload Error: {0}")] + #[from_stringify("wc_common::PayloadError")] + PayloadError(String), } impl From> for WalletConnectCtxError { @@ -34,14 +46,6 @@ impl From> for WalletConnectCtxError { fn from(error: Error) -> Self { WalletConnectCtxError::SubscriptionError(format!("{error:?}")) } } -impl From for WalletConnectCtxError { - fn from(value: serde_json::Error) -> Self { WalletConnectCtxError::SerdeError(value.to_string()) } -} - -impl From for WalletConnectCtxError { - fn from(value: SessionError) -> Self { WalletConnectCtxError::SessionError(value.to_string()) } -} - /// Session key and topic derivation errors. #[derive(Debug, Clone, thiserror::Error)] pub enum SessionError { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 8f2d169418..40cc68b7ca 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use common::log::info; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::{domain::Topic, rpc::{params::ResponseParamsSuccess, Params, Request, Response}}; @@ -33,12 +34,18 @@ pub(crate) async fn process_inbound_request( .handle_session_event(&ctx, topic, &message_id) .await? }, - Params::SessionRequest(_) => todo!(), + Params::SessionRequest(_) => { + info!("SessionRequest is not yet implemented."); + return MmError::err(WalletConnectCtxError::NotImplemented); + }, Params::PairingPing(_param) => process_pairing_ping_response(&ctx, topic, &message_id).await?, Params::PairingDelete(param) => process_pairing_delete_response(&ctx, topic, &message_id, param).await?, Params::PairingExtend(param) => process_pairing_extend_response(&ctx, topic, &message_id, param).await?, - _ => todo!(), + _ => { + info!("Unknown request params received."); + return MmError::err(WalletConnectCtxError::InvalidRequest); + }, }; Ok(()) @@ -68,7 +75,7 @@ pub(crate) async fn process_inbound_response( | ResponseParamsSuccess::PairingDelete(success) | ResponseParamsSuccess::PairingPing(success) => { if !success { - return MmError::err(WalletConnectCtxError::UnsuccessfulResponse(format!( + return MmError::err(WalletConnectCtxError::UnSuccessfulResponse(format!( "Unsuccessful response={params:?}" ))); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index f44680fe1a..93837bee39 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -157,15 +157,12 @@ impl WalletConnectCtx { { let pairings = self.pairing.pairings.lock().await; if let Some(pairing) = pairings.get(topic.as_ref()) { - let key = hex::decode(pairing.sym_key.clone()) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let key = hex::decode(pairing.sym_key.clone())?; return Ok(key); } } - MmError::err(WalletConnectCtxError::PairingNotFound(format!( - "Topic not found:{topic}" - ))) + MmError::err(WalletConnectCtxError::PairingError(format!("Topic not found:{topic}"))) } /// Private function to publish a request. @@ -213,13 +210,11 @@ impl WalletConnectCtx { payload: Payload, ) -> MmResult<(), WalletConnectCtxError> { let sym_key = self.sym_key(topic).await?; - let payload = - serde_json::to_string(&payload).map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let payload = serde_json::to_string(&payload)?; info!("\n Sending Outbound request: {payload}!"); - let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key)?; { self.client .publish( diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 91df397524..bdb409f967 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -71,35 +71,33 @@ impl SessionKey { } /// Creates new session key from `osrng`. - pub fn from_osrng(sender_public_key: &[u8; 32]) -> Result { - SessionKey::diffie_hellman(OsRng, sender_public_key) + pub fn from_osrng(other_public_key: &[u8; 32]) -> Result { + SessionKey::diffie_hellman(OsRng, other_public_key) } /// Performs Diffie-Hellman symmetric key derivation. - pub fn diffie_hellman(csprng: T, sender_public_key: &[u8; 32]) -> Result + pub fn diffie_hellman(csprng: T, other_public_key: &[u8; 32]) -> Result where T: RngCore + CryptoRng, { - let single_use_private_key = StaticSecret::random_from_rng(csprng); - let public_key = PublicKey::from(&single_use_private_key); + let static_private_key = StaticSecret::random_from_rng(csprng); + let public_key = PublicKey::from(&static_private_key); + let shared_secret = static_private_key.diffie_hellman(&PublicKey::from(*other_public_key)); - let ikm = single_use_private_key.diffie_hellman(&PublicKey::from(*sender_public_key)); - - let mut session_sym_key = Self { + let mut session_key = Self { sym_key: [0u8; 32], public_key, }; - let hk = Hkdf::::new(None, ikm.as_bytes()); - hk.expand(&[], &mut session_sym_key.sym_key) - .map_err(|e| SessionError::SymKeyGeneration(e.to_string()))?; - Ok(session_sym_key) + session_key.derive_symmetric_key(&shared_secret)?; + + Ok(session_key) } /// Generates the symmetric key given the ephemeral secret and the peer's public key. pub fn generate_symmetric_key( &mut self, - static_secret: StaticSecret, + static_secret: &StaticSecret, peer_public_key: &[u8; 32], ) -> Result<(), SessionError> { let shared_secret = static_secret.diffie_hellman(&PublicKey::from(*peer_public_key)); diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/delete.rs index f4d71639fb..42f28d43bd 100644 --- a/mm2src/kdf_walletconnect/src/session/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/delete.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use common::log::info; +use common::log::{debug, info}; use mm2_err_handle::prelude::MmResult; use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{domain::{MessageId, Topic}, @@ -20,29 +20,32 @@ pub(crate) async fn process_session_delete_request( ctx.publish_response(topic, value, irn_metadata, message_id).await?; + session_delete_cleanup(ctx, topic).await?; + Ok(()) } -pub(crate) async fn session_delete_cleanup( - ctx: Arc, - topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.sessions.lock().await; - sessions - .remove(topic) - .ok_or_else(|| WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()))?; - - ctx.client.unsubscribe(topic.clone()).await?; - - // Check if there are no active sessions remaining - if sessions.is_empty() { - info!("\nNo active sessions left, disconnecting the pairing"); - - // Attempt to disconnect and remove the pairing associated with the topic - ctx.pairing - .disconnect(topic.as_ref(), &ctx.client) - .await - .map_err(|e| WalletConnectCtxError::InternalError(format!("Failed to disconnect pairing: {}", e)))?; +async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectCtxError> { + let (session_count, pairing_topic) = { + let mut sessions = ctx.sessions.lock().await; + let session = sessions.remove(topic).ok_or_else(|| { + WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()) + })?; + + ctx.client.unsubscribe(topic.clone()).await?; + + // Get the pairing topic + let pairing_topic = session.pairing_topic.clone(); + // Check if there are no more sessions for this pairing + let session_count = sessions.values().filter(|s| s.pairing_topic == pairing_topic).count(); + + (session_count, pairing_topic) + }; + + if session_count == 0 { + debug!("No active sessions left for pairing {}, disconnecting", pairing_topic); + // Attempt to disconnect the pairing + ctx.pairing.disconnect(pairing_topic.as_ref(), &ctx.client).await?; } Ok(()) diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 6516ef77b8..9200f3750a 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -81,14 +81,12 @@ pub async fn process_proposal_request( topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { - let sender_public_key = hex::decode(&proposal.proposer.public_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? + let sender_public_key = hex::decode(&proposal.proposer.public_key)? .as_slice() .try_into() .unwrap(); - let session_key = SessionKey::from_osrng(&sender_public_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))?; + let session_key = SessionKey::from_osrng(&sender_public_key)?; let session_topic: Topic = session_key.generate_topic().into(); let subscription_id = ctx .client @@ -126,14 +124,13 @@ pub(crate) async fn process_session_propose_response( pairing_topic: &Topic, response: SessionProposeResponse, ) -> MmResult<(), WalletConnectCtxError> { - let other_public_key = hex::decode(&response.responder_public_key) - .map_to_mm(|err| WalletConnectCtxError::EncodeError(err.to_string()))? + let other_public_key = hex::decode(&response.responder_public_key)? .as_slice() .try_into() .unwrap(); let mut session_key = SessionKey::new(ctx.sessions.public_key); - session_key.generate_symmetric_key(ctx.sessions.keypair.clone(), &other_public_key)?; + session_key.generate_symmetric_key(&ctx.sessions.keypair, &other_public_key)?; let session_topic: Topic = session_key.generate_topic().into(); let subscription_id = ctx diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index aad3ca9d94..5e9d411e3a 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -23,5 +23,6 @@ pub(crate) async fn process_session_update_request( ctx.publish_response(topic, value, irn_metadata, message_id).await?; + info!("published response"); Ok(()) } diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index 215b1a1ef0..389f81a8b8 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -313,23 +313,9 @@ async fn rpc_service(req: Request, ctx_h: u32, client: SocketAddr) -> Resp let res = try_sf!(process_rpc_request(ctx, req, req_json, client).await, ACCESS_CONTROL_ALLOW_ORIGIN => rpc_cors); let (mut parts, body) = res.into_parts(); - let body_escaped = { - let body_utf8 = match std::str::from_utf8(&body) { - Ok(body_utf8) => body_utf8, - Err(_) => { - return Response::builder() - .status(500) - .header(ACCESS_CONTROL_ALLOW_ORIGIN, rpc_cors) - .header(CONTENT_TYPE, APPLICATION_JSON) - .body(Body::from(err_to_rpc_json_string("Non UTF-8 output"))) - .unwrap(); - }, - }; - let escaped = escape_answer(body_utf8); - escaped.as_bytes().to_vec() - }; + parts.headers.insert(ACCESS_CONTROL_ALLOW_ORIGIN, rpc_cors); - Response::from_parts(parts, Body::from(body_escaped)) + Response::from_parts(parts, Body::from(body)) } // TODO: This should exclude TCP internals, as including them results in having to From 9f5944c79b311832de1caaf8fb294ee2580ac4bf Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 17 Sep 2024 12:42:51 +0100 Subject: [PATCH 017/125] improve code and locking --- .../kdf_walletconnect/src/inbound_message.rs | 6 +-- mm2src/kdf_walletconnect/src/lib.rs | 40 +++++++++++-------- mm2src/kdf_walletconnect/src/session/event.rs | 34 +++++++--------- .../kdf_walletconnect/src/session/update.rs | 11 +++-- 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 40cc68b7ca..97c033a659 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,5 +1,3 @@ -use std::sync::Arc; - use common::log::info; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::{domain::Topic, @@ -17,7 +15,7 @@ use crate::{error::WalletConnectCtxError, WalletConnectCtx}; pub(crate) async fn process_inbound_request( - ctx: Arc, + ctx: &WalletConnectCtx, request: Request, topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { @@ -52,7 +50,7 @@ pub(crate) async fn process_inbound_request( } pub(crate) async fn process_inbound_response( - ctx: Arc, + ctx: &WalletConnectCtx, response: Response, topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 93837bee39..d01662171c 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -6,7 +6,8 @@ mod metadata; #[allow(unused)] mod session; use chrono::Utc; -use common::{executor::Timer, log::info}; +use common::{executor::{spawn, Timer}, + log::{error, info}}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex, @@ -232,29 +233,34 @@ impl WalletConnectCtx { } pub async fn published_message_event_loop(self: Arc) { + let self_clone = self.clone(); let mut recv = self.msg_handler.lock().await; while let Some(msg) = recv.next().await { - let message = { - let key = self.sym_key(&msg.topic).await.unwrap(); - decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() - }; + info!("received message"); + if let Err(e) = self_clone.handle_single_message(msg).await { + info!("Error processing message: {:?}", e); + } + } + } - info!("\nInbound message payload={message}"); + async fn handle_single_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectCtxError> { + let message = { + let key = self.sym_key(&msg.topic).await?; + decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() + }; - let response = serde_json::from_str::(&message).unwrap(); - let result = match response { - Payload::Request(request) => process_inbound_request(self.clone(), request, &msg.topic).await, - Payload::Response(response) => process_inbound_response(self.clone(), response, &msg.topic).await, - }; + info!("Inbound message payload={message}"); - // TODO: Handle errors. - match result { - Ok(()) => info!("Inbound message was handled succesfully"), - Err(err) => info!("Error while handling inbound message: {err:?}"), - }; + let payload: Payload = serde_json::from_str(&message)?; + + match payload { + Payload::Request(request) => process_inbound_request(&self, request, &msg.topic).await?, + Payload::Response(response) => process_inbound_response(&self, response, &msg.topic).await?, } - } + info!("Inbound message was handled successfully"); + Ok(()) + } pub async fn spawn_connection_live_watcher(self: Arc) { let mut recv = self.connection_live_handler.lock().await; while let Some(_msg) = recv.next().await { diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index 4439d9279e..14008e63a2 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -8,7 +8,7 @@ use relay_rpc::{domain::{MessageId, Topic}, use crate::{error::WalletConnectCtxError, WalletConnectCtx}; pub enum SessionEvents { - ChainCHanged(String, Vec), + ChainChanged(String), AccountsChanged(String, Vec), Unknown, } @@ -16,10 +16,7 @@ pub enum SessionEvents { impl SessionEvents { pub fn from_events(event: SessionEventRequest) -> MmResult { match event.event.name.as_str() { - "chainCHanged" => { - let data = serde_json::from_value::>(event.event.data)?; - Ok(SessionEvents::ChainCHanged(event.chain_id, data)) - }, + "chainChanged" => Ok(SessionEvents::ChainChanged(event.chain_id)), "accountsChanged" => { let data = serde_json::from_value::>(event.event.data)?; Ok(SessionEvents::AccountsChanged(event.chain_id, data)) @@ -35,8 +32,8 @@ impl SessionEvents { message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { match &self { - SessionEvents::ChainCHanged(chain_id, data) => { - Self::handle_chain_changed_event(ctx, chain_id, data, topic, message_id).await + SessionEvents::ChainChanged(chain_id) => { + Self::handle_chain_changed_event(ctx, chain_id, topic, message_id).await }, SessionEvents::AccountsChanged(chain_id, data) => { Self::handle_account_changed_event(ctx, chain_id, data, topic, message_id).await @@ -48,26 +45,23 @@ impl SessionEvents { async fn handle_chain_changed_event( ctx: &WalletConnectCtx, chain_id: &str, - data: &Vec, topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { - *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); - { - let mut sessions = ctx.sessions.lock().await; - let current_time = Utc::now().timestamp() as u64; - sessions.retain(|_, session| session.expiry > current_time); - }; + *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); + + { + let mut sessions = ctx.sessions.lock().await; + let current_time = Utc::now().timestamp() as u64; + sessions.retain(|_, session| session.expiry > current_time); + }; - let mut sessions = ctx.sessions.lock().await; - for session in sessions.values_mut() { - for id in data { + let mut sessions = ctx.sessions.lock().await; + for session in sessions.values_mut() { if let Some((namespace, chain)) = parse_chain_and_chain_id(chain_id) { if let Some(ns) = session.namespaces.get_mut(&namespace) { - ns.chains - .get_or_insert_with(BTreeSet::new) - .insert(format!("{namespace}:{id}")); + ns.chains.get_or_insert_with(BTreeSet::new).insert(chain_id.to_owned()); } } } diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index 5e9d411e3a..7c22419f00 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -11,10 +11,13 @@ pub(crate) async fn process_session_update_request( message_id: &MessageId, update: SessionUpdateRequest, ) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { - session.namespaces = update.namespaces.0.clone(); - info!("Updated extended, info: {:?}", session); + { + let mut sessions = ctx.sessions.lock().await; + if let Some(session) = sessions.get_mut(topic) { + session.namespaces = update.namespaces.0.clone(); + info!("Updated extended"); + }; + drop(sessions) } let response = ResponseParamsSuccess::SessionUpdate(true); From dff1b421246e95253a49f5b3a83ec18093fb8294 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 17 Sep 2024 12:43:05 +0100 Subject: [PATCH 018/125] remove unused dep --- mm2src/kdf_walletconnect/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 876d6e54f1..be496cbdf0 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -# chacha20poly1305 = "0.10" chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } derive_more = "0.99" @@ -29,3 +28,4 @@ secp256k1 = { version = "0.20" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } x25519-dalek = { version = "2.0", features = ["static_secrets"] } + From 591fbdba847d5f70df9bc6fff429c3d31689f0e7 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 17 Sep 2024 21:15:25 +0100 Subject: [PATCH 019/125] refactorings and cleanupds --- mm2src/kdf_walletconnect/src/error.rs | 30 +++++++ .../kdf_walletconnect/src/inbound_message.rs | 22 ++--- mm2src/kdf_walletconnect/src/lib.rs | 83 ++++++++++++------- mm2src/kdf_walletconnect/src/pairing.rs | 21 ++--- mm2src/kdf_walletconnect/src/session.rs | 47 +++-------- .../kdf_walletconnect/src/session/delete.rs | 16 ++-- mm2src/kdf_walletconnect/src/session/event.rs | 45 +++++----- .../kdf_walletconnect/src/session/extend.rs | 12 +-- mm2src/kdf_walletconnect/src/session/ping.rs | 12 +-- .../kdf_walletconnect/src/session/propose.rs | 56 ++++--------- .../kdf_walletconnect/src/session/settle.rs | 20 ++--- .../kdf_walletconnect/src/session/update.rs | 13 +-- 12 files changed, 176 insertions(+), 201 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index dc8d7fc470..3abee01e0b 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -4,6 +4,36 @@ use relay_client::error::{ClientError, Error}; use relay_rpc::rpc::{PublishError, SubscriptionError}; use serde::{Deserialize, Serialize}; +// Error codes for various cases +pub(crate) const INVALID_METHOD: i32 = 1001; +pub(crate) const INVALID_EVENT: i32 = 1002; +pub(crate) const INVALID_UPDATE_REQUEST: i32 = 1003; +pub(crate) const INVALID_EXTEND_REQUEST: i32 = 1004; +pub(crate) const INVALID_SESSION_SETTLE_REQUEST: i32 = 1005; + +// Unauthorized error codes +pub(crate) const UNAUTHORIZED_METHOD: i32 = 3001; +pub(crate) const UNAUTHORIZED_EVENT: i32 = 3002; +pub(crate) const UNAUTHORIZED_UPDATE_REQUEST: i32 = 3003; +pub(crate) const UNAUTHORIZED_EXTEND_REQUEST: i32 = 3004; +pub(crate) const UNAUTHORIZED_CHAIN: i32 = 3005; + +// EIP-1193 error code +pub(crate) const USER_REJECTED_REQUEST: i32 = 4001; + +// Rejected (CAIP-25) error codes +pub(crate) const USER_REJECTED: i32 = 5000; +pub(crate) const USER_REJECTED_CHAINS: i32 = 5001; +pub(crate) const USER_REJECTED_METHODS: i32 = 5002; +pub(crate) const USER_REJECTED_EVENTS: i32 = 5003; + +// Unsupported error codes +pub(crate) const UNSUPPORTED_CHAINS: i32 = 5100; +pub(crate) const UNSUPPORTED_METHODS: i32 = 5101; +pub(crate) const UNSUPPORTED_EVENTS: i32 = 5102; +pub(crate) const UNSUPPORTED_ACCOUNTS: i32 = 5103; +pub(crate) const UNSUPPORTED_NAMESPACE_KEY: i32 = 5104; + #[derive(Debug, Serialize, Deserialize, EnumFromStringify, thiserror::Error)] pub enum WalletConnectCtxError { #[error("Pairing Error: {0}")] diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 97c033a659..1058eeb65f 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -21,15 +21,15 @@ pub(crate) async fn process_inbound_request( ) -> MmResult<(), WalletConnectCtxError> { let message_id = request.id; match request.params { - Params::SessionPropose(proposal) => process_proposal_request(&ctx, proposal, topic, &message_id).await?, - Params::SessionExtend(param) => process_session_extend_request(&ctx, topic, &message_id, param).await?, - Params::SessionDelete(param) => process_session_delete_request(&ctx, topic, &message_id, param).await?, - Params::SessionPing(()) => process_session_ping_request(&ctx, topic, &message_id).await?, - Params::SessionSettle(param) => process_session_settle_request(&ctx, topic, &message_id, param).await?, - Params::SessionUpdate(param) => process_session_update_request(&ctx, topic, &message_id, param).await?, + Params::SessionPropose(proposal) => process_proposal_request(ctx, proposal, topic, &message_id).await?, + Params::SessionExtend(param) => process_session_extend_request(ctx, topic, &message_id, param).await?, + Params::SessionDelete(param) => process_session_delete_request(ctx, topic, &message_id, param).await?, + Params::SessionPing(()) => process_session_ping_request(ctx, topic, &message_id).await?, + Params::SessionSettle(param) => process_session_settle_request(ctx, topic, &message_id, param).await?, + Params::SessionUpdate(param) => process_session_update_request(ctx, topic, &message_id, param).await?, Params::SessionEvent(param) => { SessionEvents::from_events(param)? - .handle_session_event(&ctx, topic, &message_id) + .handle_session_event(ctx, topic, &message_id) .await? }, Params::SessionRequest(_) => { @@ -37,9 +37,9 @@ pub(crate) async fn process_inbound_request( return MmError::err(WalletConnectCtxError::NotImplemented); }, - Params::PairingPing(_param) => process_pairing_ping_response(&ctx, topic, &message_id).await?, - Params::PairingDelete(param) => process_pairing_delete_response(&ctx, topic, &message_id, param).await?, - Params::PairingExtend(param) => process_pairing_extend_response(&ctx, topic, &message_id, param).await?, + Params::PairingPing(_param) => process_pairing_ping_response(ctx, topic, &message_id).await?, + Params::PairingDelete(param) => process_pairing_delete_response(ctx, topic, &message_id, param).await?, + Params::PairingExtend(param) => process_pairing_extend_response(ctx, topic, &message_id, param).await?, _ => { info!("Unknown request params received."); return MmError::err(WalletConnectCtxError::InvalidRequest); @@ -60,7 +60,7 @@ pub(crate) async fn process_inbound_response( let params = serde_json::from_value::(value.result)?; match params { ResponseParamsSuccess::SessionPropose(param) => { - process_session_propose_response(&ctx, topic, param).await + process_session_propose_response(ctx, topic, param).await }, ResponseParamsSuccess::SessionSettle(success) | ResponseParamsSuccess::SessionUpdate(success) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d01662171c..8bb3925236 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,13 +1,12 @@ -mod error; +#[allow(unused)] mod error; mod handler; mod inbound_message; mod metadata; #[allow(unused)] mod pairing; -#[allow(unused)] mod session; +mod session; use chrono::Utc; -use common::{executor::{spawn, Timer}, - log::{error, info}}; +use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, lock::Mutex, @@ -20,12 +19,14 @@ use mm2_err_handle::prelude::*; use pairing_api::PairingClient; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; +use relay_rpc::rpc::params::{RelayProtocolMetadata, RequestParams}; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, - rpc::{params::{session::ProposeNamespaces, IrnMetadata}, - Params, Payload, Request, Response, SuccessfulResponse, JSON_RPC_VERSION_STR}}; + rpc::{params::{session::{ProposeNamespace, ProposeNamespaces}, + IrnMetadata, Metadata, Relay, ResponseParamsError, ResponseParamsSuccess}, + ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; use session::{propose::create_proposal_session, Session}; -use std::{sync::Arc, time::Duration}; +use std::{collections::BTreeMap, sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; @@ -49,6 +50,9 @@ pub struct WalletConnectCtx { pub msg_handler: Arc>>, pub connection_live_handler: Arc>>, pub active_chain_id: Arc>, + pub relay: Relay, + pub namespaces: ProposeNamespaces, + pub metadata: Metadata, } impl Default for WalletConnectCtx { @@ -63,6 +67,18 @@ impl WalletConnectCtx { let pairing = PairingClient::new(); let client = Client::new(Handler::new("Komodefi", msg_sender, conn_live_sender)); + let mut required = BTreeMap::new(); + required.insert("eip155".to_string(), ProposeNamespace { + chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + }); + + let relay = Relay { + protocol: SUPPORTED_PROTOCOL.to_string(), + data: None, + }; + Self { client, pairing, @@ -70,6 +86,9 @@ impl WalletConnectCtx { msg_handler: Arc::new(Mutex::new(msg_receiver)), connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), + relay, + namespaces: ProposeNamespaces(required), + metadata: generate_metadata(), } } @@ -77,15 +96,13 @@ impl WalletConnectCtx { &self, required_namespaces: Option, ) -> MmResult { - let metadata = generate_metadata(); - - let (topic, url) = self.pairing.create(metadata.clone(), None).await?; + let (topic, url) = self.pairing.create(self.metadata.clone(), None).await?; info!("Subscribing to topic: {topic:?}"); self.client.subscribe(topic.clone()).await?; info!("Subscribed to topic: {topic:?}"); - create_proposal_session(self, topic, metadata, required_namespaces).await?; + create_proposal_session(self, topic, required_namespaces).await?; Ok(url) } @@ -167,14 +184,10 @@ impl WalletConnectCtx { } /// Private function to publish a request. - async fn publish_request( - &self, - topic: &Topic, - params: Params, - irn_metadata: IrnMetadata, - ) -> MmResult<(), WalletConnectCtxError> { + async fn publish_request(&self, topic: &Topic, param: RequestParams) -> MmResult<(), WalletConnectCtxError> { + let irn_metadata = param.irn_metadata(); let message_id = MessageIdGenerator::new().next(); - let request = Request::new(message_id, params); + let request = Request::new(message_id, param.into()); self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; @@ -183,20 +196,32 @@ impl WalletConnectCtx { Ok(()) } - /// Private function to publish a request response. - async fn publish_response( + /// Private function to publish a success request response. + async fn publish_response_ok( &self, topic: &Topic, - params: serde_json::Value, - irn_metadata: IrnMetadata, + result: ResponseParamsSuccess, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { - let response = Response::Success(SuccessfulResponse { - id: *message_id, - jsonrpc: JSON_RPC_VERSION_STR.into(), - result: params, - }); + let irn_metadata = result.irn_metadata(); + let value = serde_json::to_value(result)?; + let response = Response::Success(SuccessfulResponse::new(*message_id, value)); + self.publish_payload(topic, irn_metadata, Payload::Response(response)) + .await?; + + Ok(()) + } + /// Private function to publish an error request response. + async fn publish_response_err( + &self, + topic: &Topic, + error_data: ResponseParamsError, + message_id: &MessageId, + ) -> MmResult<(), WalletConnectCtxError> { + let error = error_data.error(); + let irn_metadata = error_data.irn_metadata(); + let response = Response::Error(ErrorResponse::new(*message_id, error)); self.publish_payload(topic, irn_metadata, Payload::Response(response)) .await?; @@ -254,8 +279,8 @@ impl WalletConnectCtx { let payload: Payload = serde_json::from_str(&message)?; match payload { - Payload::Request(request) => process_inbound_request(&self, request, &msg.topic).await?, - Payload::Response(response) => process_inbound_response(&self, response, &msg.topic).await?, + Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, + Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await?, } info!("Inbound message was handled successfully"); diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index febbab1f72..3f3b82da31 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -15,11 +15,8 @@ pub(crate) async fn process_pairing_ping_response( topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { - let response = ResponseParamsSuccess::PairingPing(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::PairingPing(true); + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } @@ -38,11 +35,8 @@ pub(crate) async fn process_pairing_extend_response( }; } - let response = ResponseParamsSuccess::PairingPing(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::PairingPing(true); + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } @@ -57,11 +51,8 @@ pub(crate) async fn process_pairing_delete_response( ctx.pairing.disconnect(topic.as_ref(), &ctx.client).await?; } - let response = ResponseParamsSuccess::PairingDelete(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::PairingDelete(true); + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index bdb409f967..830ceb0fff 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -7,39 +7,26 @@ pub(crate) mod settle; pub(crate) mod update; use crate::error::SessionError; -use crate::metadata::generate_metadata; -use crate::{error::WalletConnectCtxError, WalletConnectCtx, SUPPORTED_ACCOUNTS, SUPPORTED_CHAINS, SUPPORTED_EVENTS, - SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; -use chrono::naive::serde; +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + use chrono::Utc; -use common::log::info; use futures::lock::Mutex; -use mm2_err_handle::prelude::{MapToMmResult, MmResult}; -use relay_rpc::auth::ed25519_dalek::SigningKey; -use relay_rpc::domain::MessageId; +use mm2_err_handle::prelude::MmResult; use relay_rpc::rpc::params::session::Namespace; -use relay_rpc::rpc::params::session_delete::SessionDeleteRequest; -use relay_rpc::rpc::params::session_event::SessionEventRequest; -use relay_rpc::rpc::params::session_extend::SessionExtendRequest; use relay_rpc::rpc::params::session_propose::Proposer; -use relay_rpc::rpc::params::session_update::SessionUpdateRequest; -use relay_rpc::rpc::params::{IrnMetadata, RelayProtocolMetadata}; +use relay_rpc::rpc::params::IrnMetadata; use relay_rpc::{domain::{SubscriptionId, Topic}, - rpc::params::{session::{ProposeNamespace, ProposeNamespaces, SettleNamespace, SettleNamespaces}, - session_propose::{SessionProposeRequest, SessionProposeResponse}, - session_settle::{Controller, SessionSettleRequest}, - Metadata, Relay, RequestParams, ResponseParamsSuccess}}; + rpc::params::{session::ProposeNamespaces, session_settle::Controller, Metadata, Relay}}; use serde_json::Value; -use std::collections::{BTreeSet, HashMap}; +use std::collections::HashMap; use std::ops::Deref; -use std::vec; use std::{collections::BTreeMap, sync::Arc}; use x25519_dalek::{SharedSecret, StaticSecret}; use {hkdf::Hkdf, rand::{rngs::OsRng, CryptoRng, RngCore}, sha2::{Digest, Sha256}, std::fmt::Debug, - x25519_dalek::{EphemeralSecret, PublicKey}}; + x25519_dalek::PublicKey}; const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; @@ -74,7 +61,6 @@ impl SessionKey { pub fn from_osrng(other_public_key: &[u8; 32]) -> Result { SessionKey::diffie_hellman(OsRng, other_public_key) } - /// Performs Diffie-Hellman symmetric key derivation. pub fn diffie_hellman(csprng: T, other_public_key: &[u8; 32]) -> Result where @@ -88,7 +74,6 @@ impl SessionKey { sym_key: [0u8; 32], public_key, }; - session_key.derive_symmetric_key(&shared_secret)?; Ok(session_key) @@ -165,25 +150,13 @@ pub struct SessionInfo { impl SessionInfo { pub fn new( + ctx: &WalletConnectCtx, subscription_id: SubscriptionId, session_key: SessionKey, pairing_topic: Topic, metadata: Metadata, session_type: SessionType, ) -> Self { - // Initialize the namespaces for both proposer and controller - let mut namespaces = BTreeMap::::new(); - namespaces.insert("eip155".to_string(), ProposeNamespace { - chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - }); - - let relay = Relay { - protocol: SUPPORTED_PROTOCOL.to_string(), - data: None, - }; - // handle proposer or controller let (proposer, controller) = match session_type { SessionType::Proposer => ( @@ -205,8 +178,8 @@ impl SessionInfo { controller, namespaces: BTreeMap::new(), proposer, - propose_namespaces: ProposeNamespaces(namespaces), - relay, + propose_namespaces: ctx.namespaces.clone(), + relay: ctx.relay.clone(), expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, pairing_topic, session_type, diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/delete.rs index 42f28d43bd..a793d637b7 100644 --- a/mm2src/kdf_walletconnect/src/session/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/delete.rs @@ -1,24 +1,18 @@ -use std::sync::Arc; +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; -use common::log::{debug, info}; +use common::log::debug; use mm2_err_handle::prelude::MmResult; -use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_delete::SessionDeleteRequest, ResponseParamsSuccess}}; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; - pub(crate) async fn process_session_delete_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, - delete_params: SessionDeleteRequest, + _delete_params: SessionDeleteRequest, ) -> MmResult<(), WalletConnectCtxError> { - let response = ResponseParamsSuccess::SessionDelete(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::SessionDelete(true); + ctx.publish_response_ok(topic, param, message_id).await?; session_delete_cleanup(ctx, topic).await?; diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index 14008e63a2..f6cdf9b52a 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -1,11 +1,11 @@ -use std::collections::BTreeSet; +use crate::{error::{WalletConnectCtxError, UNSUPPORTED_CHAINS}, + WalletConnectCtx}; use chrono::Utc; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session_event::SessionEventRequest, RelayProtocolMetadata, ResponseParamsSuccess}}; - -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + rpc::{params::{session_event::SessionEventRequest, ResponseParamsError, ResponseParamsSuccess}, + ErrorData}}; pub enum SessionEvents { ChainChanged(String), @@ -57,11 +57,24 @@ impl SessionEvents { sessions.retain(|_, session| session.expiry > current_time); }; - let mut sessions = ctx.sessions.lock().await; - for session in sessions.values_mut() { - if let Some((namespace, chain)) = parse_chain_and_chain_id(chain_id) { + if let Some((namespace, _chain)) = parse_chain_and_chain_id(chain_id) { + if ctx.namespaces.get(&namespace).is_none() { + let error_data = ErrorData { + code: UNSUPPORTED_CHAINS, + message: "Chain_Id was changed to an unsupported chain".to_string(), + data: None, + }; + + ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) + .await?; + } + + let mut sessions = ctx.sessions.lock().await; + for session in sessions.values_mut() { if let Some(ns) = session.namespaces.get_mut(&namespace) { - ns.chains.get_or_insert_with(BTreeSet::new).insert(chain_id.to_owned()); + if let Some(chains) = ns.chains.as_mut() { + chains.insert(chain_id.to_owned()); + } } } } @@ -70,29 +83,23 @@ impl SessionEvents { //TODO: Notify about chain changed. let params = ResponseParamsSuccess::SessionEvent(true); - let irn_metadata = params.irn_metadata(); - - let value = serde_json::to_value(params)?; - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + ctx.publish_response_ok(topic, params, message_id).await?; Ok(()) } async fn handle_account_changed_event( ctx: &WalletConnectCtx, - chain_id: &str, - data: &[String], + _chain_id: &str, + _data: &[String], topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { // TODO: Handle account change logic. //TODO: Notify about account changed. - let params = ResponseParamsSuccess::SessionEvent(true); - let irn_metadata = params.irn_metadata(); - - let value = serde_json::to_value(params)?; - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/extend.rs b/mm2src/kdf_walletconnect/src/session/extend.rs index 1cefb72b11..33ddbf7a9b 100644 --- a/mm2src/kdf_walletconnect/src/session/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/extend.rs @@ -1,11 +1,10 @@ +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + use common::log::info; use mm2_err_handle::prelude::MmResult; -use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_extend::SessionExtendRequest, ResponseParamsSuccess}}; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; - /// Process session extend request. pub(crate) async fn process_session_extend_request( ctx: &WalletConnectCtx, @@ -19,11 +18,8 @@ pub(crate) async fn process_session_extend_request( info!("Updated extended, info: {:?}", session); } - let response = ResponseParamsSuccess::SessionExtend(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::SessionExtend(true); + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/ping.rs b/mm2src/kdf_walletconnect/src/session/ping.rs index 887404e3d9..3da8d26d03 100644 --- a/mm2src/kdf_walletconnect/src/session/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/ping.rs @@ -1,20 +1,16 @@ +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + use mm2_err_handle::prelude::MmResult; -use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::ResponseParamsSuccess}; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; - pub(crate) async fn process_session_ping_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { - let response = ResponseParamsSuccess::SessionPing(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::SessionPing(true); + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 9200f3750a..8d551e6211 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -1,52 +1,34 @@ -use std::{collections::BTreeMap, ops::Deref}; +use super::{settle::send_session_settle_request, SessionInfo}; +use crate::{error::WalletConnectCtxError, + session::{SessionKey, SessionType, THIRTY_DAYS}, + WalletConnectCtx}; use chrono::Utc; +use mm2_err_handle::map_to_mm::MapToMmResult; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session::{Namespace, ProposeNamespace, ProposeNamespaces}, + rpc::params::{session::ProposeNamespaces, session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, - Metadata, Relay, RequestParams, ResponseParamsSuccess}}; - -use super::{settle::send_session_settle_request, SessionInfo}; -use crate::{error::WalletConnectCtxError, - metadata::generate_metadata, - session::{SessionKey, SessionType, THIRTY_DAYS}, - WalletConnectCtx, SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS, SUPPORTED_PROTOCOL}; -use mm2_err_handle::map_to_mm::MapToMmResult; -use relay_rpc::rpc::params::RelayProtocolMetadata; + Metadata, RequestParams, ResponseParamsSuccess}}; +use std::ops::Deref; /// Creates a new session proposal form topic and metadata. pub(crate) async fn create_proposal_session( ctx: &WalletConnectCtx, topic: Topic, - metadata: Metadata, required_namespaces: Option, ) -> MmResult<(), WalletConnectCtxError> { let proposer = Proposer { - metadata: generate_metadata(), + metadata: ctx.metadata.clone(), public_key: hex::encode(ctx.sessions.public_key.as_bytes()), }; - let mut namespaces = BTreeMap::::new(); - namespaces.insert("eip155".to_string(), ProposeNamespace { - chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - }); - - let relays = Relay { - protocol: SUPPORTED_PROTOCOL.to_string(), - data: None, - }; - let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { - relays: vec![relays], + relays: vec![ctx.relay.clone()], proposer, - required_namespaces: required_namespaces.unwrap_or(ProposeNamespaces(namespaces)), + required_namespaces: required_namespaces.unwrap_or(ctx.namespaces.clone()), }); - let irn_metadata = session_proposal.irn_metadata(); - ctx.publish_request(&topic, session_proposal.into(), irn_metadata) - .await?; + ctx.publish_request(&topic, session_proposal).await?; Ok(()) } @@ -57,18 +39,12 @@ async fn send_proposal_request_response( message_id: &MessageId, responder_public_key: String, ) -> MmResult<(), WalletConnectCtxError> { - let relay = Relay { - protocol: SUPPORTED_PROTOCOL.to_string(), - data: None, - }; - let response = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { - relay, + let param = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { + relay: ctx.relay.clone(), responder_public_key, }); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } @@ -95,6 +71,7 @@ pub async fn process_proposal_request( .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; let session = SessionInfo::new( + ctx, subscription_id, session_key, topic.clone(), @@ -140,6 +117,7 @@ pub(crate) async fn process_session_propose_response( .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; let mut session = SessionInfo::new( + ctx, subscription_id, session_key, pairing_topic.clone(), diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index 45470b8b10..cc5c2e8f86 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -1,5 +1,4 @@ -use std::collections::BTreeMap; - +use super::{SessionInfo, THIRTY_DAYS}; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use crate::{SUPPORTED_ACCOUNTS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; @@ -7,12 +6,10 @@ use chrono::Utc; use common::log::info; use mm2_err_handle::prelude::MmResult; use relay_rpc::rpc::params::session::{Namespace, SettleNamespaces}; -use relay_rpc::rpc::params::session_settle::Controller; -use relay_rpc::rpc::params::{Relay, RelayProtocolMetadata, RequestParams}; +use relay_rpc::rpc::params::RequestParams; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_settle::SessionSettleRequest, ResponseParamsSuccess}}; - -use super::{SessionInfo, THIRTY_DAYS}; +use std::collections::BTreeMap; pub(crate) async fn send_session_settle_request( ctx: &WalletConnectCtx, @@ -33,10 +30,8 @@ pub(crate) async fn send_session_settle_request( namespaces: SettleNamespaces(settled_namespaces), expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, }); - let irn_metadata = request.irn_metadata(); - ctx.publish_request(&session_topic, request.into(), irn_metadata) - .await?; + ctx.publish_request(&session_topic, request).await?; Ok(()) } @@ -61,11 +56,8 @@ pub(crate) async fn process_session_settle_request( } } - let response = ResponseParamsSuccess::SessionSettle(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::SessionSettle(true); + ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index 7c22419f00..1e46617a5f 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -1,7 +1,6 @@ use crate::{error::WalletConnectCtxError, WalletConnectCtx}; -use common::log::info; + use mm2_err_handle::prelude::MmResult; -use relay_rpc::rpc::params::RelayProtocolMetadata; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_update::SessionUpdateRequest, ResponseParamsSuccess}}; @@ -15,17 +14,11 @@ pub(crate) async fn process_session_update_request( let mut sessions = ctx.sessions.lock().await; if let Some(session) = sessions.get_mut(topic) { session.namespaces = update.namespaces.0.clone(); - info!("Updated extended"); }; - drop(sessions) } - let response = ResponseParamsSuccess::SessionUpdate(true); - let irn_metadata = response.irn_metadata(); - let value = serde_json::to_value(response)?; - - ctx.publish_response(topic, value, irn_metadata, message_id).await?; + let param = ResponseParamsSuccess::SessionUpdate(true); + ctx.publish_response_ok(topic, param, message_id).await?; - info!("published response"); Ok(()) } From f6e7864f0a6c7281dac72bd7e4da00563ecb5225 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 18 Sep 2024 13:54:14 +0100 Subject: [PATCH 020/125] minor changes --- mm2src/kdf_walletconnect/src/lib.rs | 4 +-- mm2src/kdf_walletconnect/src/session/event.rs | 30 ++++++++++++++----- .../kdf_walletconnect/src/session/propose.rs | 28 +++++++---------- .../kdf_walletconnect/src/session/settle.rs | 1 - 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 8bb3925236..f761cc9f87 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -25,7 +25,7 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, rpc::{params::{session::{ProposeNamespace, ProposeNamespaces}, IrnMetadata, Metadata, Relay, ResponseParamsError, ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; -use session::{propose::create_proposal_session, Session}; +use session::{propose::new_proposal, Session}; use std::{collections::BTreeMap, sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; @@ -102,7 +102,7 @@ impl WalletConnectCtx { self.client.subscribe(topic.clone()).await?; info!("Subscribed to topic: {topic:?}"); - create_proposal_session(self, topic, required_namespaces).await?; + new_proposal(self, topic, required_namespaces).await?; Ok(url) } diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index f6cdf9b52a..1b851f6cc2 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -1,8 +1,8 @@ -use crate::{error::{WalletConnectCtxError, UNSUPPORTED_CHAINS}, +use crate::{error::{WalletConnectCtxError, INVALID_EVENT, UNSUPPORTED_CHAINS}, WalletConnectCtx}; use chrono::Utc; -use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::{domain::{MessageId, Topic}, rpc::{params::{session_event::SessionEventRequest, ResponseParamsError, ResponseParamsSuccess}, ErrorData}}; @@ -10,7 +10,7 @@ use relay_rpc::{domain::{MessageId, Topic}, pub enum SessionEvents { ChainChanged(String), AccountsChanged(String, Vec), - Unknown, + Unknown(String), } impl SessionEvents { @@ -21,7 +21,7 @@ impl SessionEvents { let data = serde_json::from_value::>(event.event.data)?; Ok(SessionEvents::AccountsChanged(event.chain_id, data)) }, - _ => Ok(SessionEvents::Unknown), + _ => Ok(SessionEvents::Unknown(event.event.name)), } } @@ -36,9 +36,21 @@ impl SessionEvents { Self::handle_chain_changed_event(ctx, chain_id, topic, message_id).await }, SessionEvents::AccountsChanged(chain_id, data) => { - Self::handle_account_changed_event(ctx, chain_id, data, topic, message_id).await + Self::handle_accounts_changed_event(ctx, chain_id, data, topic, message_id).await + }, + SessionEvents::Unknown(name) => { + let error_data = ErrorData { + code: INVALID_EVENT, + message: format!("Received an invalid/unsupported session event: {name}"), + data: None, + }; + ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) + .await?; + + return MmError::err(WalletConnectCtxError::SessionError(format!( + "Unsupported session event" + ))); }, - SessionEvents::Unknown => todo!(), } } @@ -67,6 +79,10 @@ impl SessionEvents { ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) .await?; + + return MmError::err(WalletConnectCtxError::SessionError(format!( + "Unsupported chainChanged chain_id from session request: {chain_id}", + ))); } let mut sessions = ctx.sessions.lock().await; @@ -88,7 +104,7 @@ impl SessionEvents { Ok(()) } - async fn handle_account_changed_event( + async fn handle_accounts_changed_event( ctx: &WalletConnectCtx, _chain_id: &str, _data: &[String], diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 8d551e6211..512e3f7cd6 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -13,7 +13,7 @@ use relay_rpc::{domain::{MessageId, Topic}, use std::ops::Deref; /// Creates a new session proposal form topic and metadata. -pub(crate) async fn create_proposal_session( +pub(crate) async fn new_proposal( ctx: &WalletConnectCtx, topic: Topic, required_namespaces: Option, @@ -33,22 +33,6 @@ pub(crate) async fn create_proposal_session( Ok(()) } -async fn send_proposal_request_response( - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - responder_public_key: String, -) -> MmResult<(), WalletConnectCtxError> { - let param = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { - relay: ctx.relay.clone(), - responder_public_key, - }); - - ctx.publish_response_ok(topic, param, message_id).await?; - - Ok(()) -} - /// Process session proposal request /// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal pub async fn process_proposal_request( @@ -92,7 +76,15 @@ pub async fn process_proposal_request( send_session_settle_request(ctx, session, session_topic).await?; }; - send_proposal_request_response(ctx, topic, message_id, proposal.proposer.public_key).await + // Respond to incoming session propose. + let param = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { + relay: ctx.relay.clone(), + responder_public_key: proposal.proposer.public_key, + }); + + ctx.publish_response_ok(topic, param, message_id).await?; + + Ok(()) } /// Process session propose reponse. diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index cc5c2e8f86..7a06c487db 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -52,7 +52,6 @@ pub(crate) async fn process_session_settle_request( session.expiry = settle.expiry; info!("Session successfully settled for topic: {:?}", topic); - info!("Updated session info: {:?}", session); } } From f535f0b3fd6f7d5d7e4d1895019d3b02c9e282dc Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 19 Sep 2024 04:47:01 +0100 Subject: [PATCH 021/125] make session single --- Cargo.lock | 3 + mm2src/coins/Cargo.toml | 1 + mm2src/coins/tendermint/tendermint_coin.rs | 15 ++- mm2src/coins_activation/Cargo.toml | 1 + .../src/tendermint_with_assets_activation.rs | 21 +++++ mm2src/kdf_walletconnect/Cargo.toml | 1 + mm2src/kdf_walletconnect/src/lib.rs | 91 +++++++++++++------ mm2src/kdf_walletconnect/src/session.rs | 36 +++----- .../kdf_walletconnect/src/session/delete.rs | 25 ++--- mm2src/kdf_walletconnect/src/session/event.rs | 17 ++-- .../kdf_walletconnect/src/session/extend.rs | 4 +- .../kdf_walletconnect/src/session/propose.rs | 27 +++--- .../kdf_walletconnect/src/session/settle.rs | 11 +-- .../kdf_walletconnect/src/session/update.rs | 6 +- 14 files changed, 155 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5991622189..9acd166d20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1043,6 +1043,7 @@ dependencies = [ "js-sys", "jsonrpc-core", "jubjub", + "kdf_walletconnect", "keys", "lazy_static", "libc", @@ -1141,6 +1142,7 @@ dependencies = [ "ethereum-types", "futures 0.3.28", "hex", + "kdf_walletconnect", "lightning", "lightning-background-processor", "lightning-invoice", @@ -3549,6 +3551,7 @@ dependencies = [ name = "kdf_walletconnect" version = "0.1.0" dependencies = [ + "async-trait", "chrono", "common", "derive_more", diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index 732a6df7e2..08824493d1 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -68,6 +68,7 @@ hex = "0.4.2" http = "0.2" itertools = { version = "0.10", features = ["use_std"] } jsonrpc-core = "18.0.0" +kdf_walletconnect = { path = "../kdf_walletconnect" } keys = { path = "../mm2_bitcoin/keys" } lazy_static = "1.4" libc = "0.2" diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index bc5e12f6ff..0abac08bc0 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -61,6 +61,7 @@ use futures01::Future; use hex::FromHexError; use instant::Duration; use itertools::Itertools; +use kdf_walletconnect::WcCoinOps; use keys::{KeyPair, Public}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_err_handle::prelude::*; @@ -178,7 +179,7 @@ pub struct TendermintProtocolInfo { decimals: u8, denom: String, pub account_prefix: String, - chain_id: String, + pub chain_id: String, gas_price: Option, chain_registry_name: Option, } @@ -3309,6 +3310,18 @@ fn parse_expected_sequence_number(e: &str) -> MmResult Vec { vec![] } + //"cosmoshub-4".to_owned() + fn chain_id(&self) -> Vec { vec![] } + + fn coin_namespace(&self) -> String { "cosmos".to_owned() } + + fn methods(&self) -> Vec { vec!["cosmos_signDirect".to_owned(), "cosmos_signAmino".to_owned()] } + + fn use_walletconnect(&self) -> bool { true } +} + #[cfg(test)] pub mod tendermint_coin_tests { use super::*; diff --git a/mm2src/coins_activation/Cargo.toml b/mm2src/coins_activation/Cargo.toml index aef4b9b557..87075ce024 100644 --- a/mm2src/coins_activation/Cargo.toml +++ b/mm2src/coins_activation/Cargo.toml @@ -21,6 +21,7 @@ derive_more = "0.99" ethereum-types = { version = "0.13", default-features = false, features = ["std", "serialize"] } futures = { version = "0.3", package = "futures", features = ["compat", "async-await"] } hex = "0.4.2" +kdf_walletconnect = { path = "../kdf_walletconnect" } mm2_core = { path = "../mm2_core" } mm2_err_handle = { path = "../mm2_err_handle" } mm2_event_stream = { path = "../mm2_event_stream" } diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 349e37b23d..4364b57dcb 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -54,6 +54,8 @@ pub struct TendermintActivationParams { with_pubkey: Option, #[serde(default)] is_keplr_from_ledger: bool, + #[serde(default)] + is_walletconnect: bool, } fn deserialize_account_public_key<'de, D>(deserializer: D) -> Result, D::Error> @@ -236,6 +238,25 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { let conf = TendermintConf::try_from_json(&ticker, coin_conf)?; + // let is_walletconnect = activation_request.is_walletconnect; + // + // if is_walletconnect { + // let pubkey = ctx + // .wallect_connect + // .get_account_from_chain_id("cosmos", &protocol_conf.chain_id) + // .await + // .expect("shouldn't fail yet"); + // + // if ctx.is_watcher() || ctx.use_watchers() { + // return MmError::err(TendermintInitError { + // ticker: ticker.clone(), + // kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, + // }); + // } + // + // TendermintActivationPolicy::with_public_key(pubkey) + // } + // let is_keplr_from_ledger = activation_request.is_keplr_from_ledger && activation_request.with_pubkey.is_some(); let activation_policy = if let Some(pubkey) = activation_request.with_pubkey { diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index be496cbdf0..0892f12150 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +async-trait = "0.1.52" chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } derive_more = "0.99" diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index f761cc9f87..fab8fdbf68 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -5,7 +5,7 @@ mod metadata; #[allow(unused)] mod pairing; mod session; -use chrono::Utc; +use async_trait::async_trait; use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, @@ -25,7 +25,7 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, rpc::{params::{session::{ProposeNamespace, ProposeNamespaces}, IrnMetadata, Metadata, Relay, ResponseParamsError, ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; -use session::{propose::new_proposal, Session}; +use session::{propose::new_proposal, Session, SymKeyPair}; use std::{collections::BTreeMap, sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; @@ -46,13 +46,14 @@ const DEFAULT_CHAIN_ID: &str = "1"; // eth mainnet. pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, - pub sessions: Session, + pub session: Arc>>, pub msg_handler: Arc>>, pub connection_live_handler: Arc>>, pub active_chain_id: Arc>, pub relay: Relay, pub namespaces: ProposeNamespaces, pub metadata: Metadata, + pub(crate) key_pair: SymKeyPair, } impl Default for WalletConnectCtx { @@ -82,13 +83,14 @@ impl WalletConnectCtx { Self { client, pairing, - sessions: Session::new(), + session: Arc::new(Mutex::new(None)), msg_handler: Arc::new(Mutex::new(msg_receiver)), connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), relay, namespaces: ProposeNamespaces(required), metadata: generate_metadata(), + key_pair: SymKeyPair::new(), } } @@ -119,32 +121,41 @@ impl WalletConnectCtx { pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } - pub async fn get_active_sessions(&self) -> impl IntoIterator { - let sessions = self.sessions.lock().await; - sessions - .values() - .filter_map(|session| { - if session.expiry > Utc::now().timestamp() as u64 { - Some(session.pairing_topic.clone()) - } else { - None - } - }) - .collect::>() + pub async fn get_session(&self) -> Option { + let session = self.session.lock().await; + session.clone() } - pub async fn get_inactive_sessions(&self) -> impl IntoIterator { - let sessions = self.sessions.lock().await; - sessions - .values() - .filter_map(|session| { - if session.expiry <= Utc::now().timestamp() as u64 { - Some(session.pairing_topic.clone()) - } else { - None + pub async fn get_account_from_chain_id( + &self, + chain: &str, + chain_id: &str, + ) -> MmResult { + // Lock the active_chain_id and check if the chain matches + if *self.active_chain_id.lock().await != chain { + // Lock the session + let session = self.session.lock().await; + + // Check if a session exists + if let Some(session) = session.as_ref() { + if let Some(namespace) = session.namespaces.get(chain) { + if let Some(accounts) = &namespace.accounts { + for account_name in accounts { + let account_vec = account_name.split(':').collect::>(); + + // Check if the account vector has the expected format (length >= 3) + if account_vec.len() >= 3 && account_vec[1] == chain_id { + let account = account_vec[2].to_owned(); + return Ok(account); + } + } + } } - }) - .collect::>() + } + } + + // If the chain doesn't match, or no valid account is found, return an error + MmError::err(WalletConnectCtxError::InvalidRequest) } pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { @@ -166,9 +177,11 @@ impl WalletConnectCtx { async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { { - let sessions = self.sessions.lock().await; - if let Some(sesssion) = sessions.get(topic) { - return Ok(sesssion.session_key.symmetric_key().to_vec()); + let session = self.session.lock().await; + if let Some(session) = session.as_ref() { + if &session.topic == topic { + return Ok(session.session_key.symmetric_key().to_vec()); + } } } @@ -299,3 +312,21 @@ impl WalletConnectCtx { } } } + +#[async_trait] +pub trait WcCoinOps { + /// Returns the coin's namespace identifier (e.g., "eip155" for Ethereum). + fn coin_namespace(&self) -> String; + + /// Returns the list of supported chains for the coin. + fn chain_id(&self) -> Vec; + + /// Returns the list of supported methods for the coin (e.g., `eth_sendTransaction`). + fn methods(&self) -> Vec; + + /// Returns the list of supported events for the coin (e.g., `chainChanged`). + fn events(&self) -> Vec; + + /// Returns a boolean indicating whether WalletConnect should be used for this coin. + fn use_walletconnect(&self) -> bool; +} diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 830ceb0fff..b4dfb9a2df 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -10,7 +10,6 @@ use crate::error::SessionError; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; -use futures::lock::Mutex; use mm2_err_handle::prelude::MmResult; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; @@ -18,9 +17,7 @@ use relay_rpc::rpc::params::IrnMetadata; use relay_rpc::{domain::{SubscriptionId, Topic}, rpc::params::{session::ProposeNamespaces, session_settle::Controller, Metadata, Relay}}; use serde_json::Value; -use std::collections::HashMap; -use std::ops::Deref; -use std::{collections::BTreeMap, sync::Arc}; +use std::collections::BTreeMap; use x25519_dalek::{SharedSecret, StaticSecret}; use {hkdf::Hkdf, rand::{rngs::OsRng, CryptoRng, RngCore}, @@ -125,7 +122,9 @@ pub enum SessionType { /// implementation. It's used to store, retrieve, and update session information throughout /// the lifecycle of a WalletConnect connection. #[derive(Debug, Clone)] -pub struct SessionInfo { +pub struct Session { + /// Session topic + pub topic: Topic, /// Pairing subscription id. pub subscription_id: SubscriptionId, /// Session symmetric key @@ -148,9 +147,10 @@ pub struct SessionInfo { pub session_type: SessionType, } -impl SessionInfo { +impl Session { pub fn new( ctx: &WalletConnectCtx, + session_topic: Topic, subscription_id: SubscriptionId, session_key: SessionKey, pairing_topic: Topic, @@ -183,32 +183,22 @@ impl SessionInfo { expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, pairing_topic, session_type, + topic: session_topic, } } } -pub struct Session { - sessions: Arc>>, - keypair: StaticSecret, - public_key: PublicKey, +pub(crate) struct SymKeyPair { + pub(crate) secret: StaticSecret, + pub(crate) public_key: PublicKey, } -impl Deref for Session { - type Target = Arc>>; - fn deref(&self) -> &Self::Target { &self.sessions } -} - -impl Default for Session { - fn default() -> Self { Self::new() } -} - -impl Session { - pub fn new() -> Self { +impl SymKeyPair { + pub(crate) fn new() -> Self { let static_secret = StaticSecret::random_from_rng(OsRng); let public_key = PublicKey::from(&static_secret); Self { - sessions: Default::default(), - keypair: static_secret, + secret: static_secret, public_key, } } diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/delete.rs index a793d637b7..d1702bb5a2 100644 --- a/mm2src/kdf_walletconnect/src/session/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/delete.rs @@ -20,26 +20,19 @@ pub(crate) async fn process_session_delete_request( } async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectCtxError> { - let (session_count, pairing_topic) = { - let mut sessions = ctx.sessions.lock().await; - let session = sessions.remove(topic).ok_or_else(|| { - WalletConnectCtxError::InternalError("Attempt to remove non-existing session".to_string()) - })?; - + { ctx.client.unsubscribe(topic.clone()).await?; - - // Get the pairing topic - let pairing_topic = session.pairing_topic.clone(); - // Check if there are no more sessions for this pairing - let session_count = sessions.values().filter(|s| s.pairing_topic == pairing_topic).count(); - - (session_count, pairing_topic) }; - if session_count == 0 { - debug!("No active sessions left for pairing {}, disconnecting", pairing_topic); + if let Some(session) = ctx.session.lock().await.as_mut().take() { + debug!( + "No active sessions left for pairing {}, disconnecting", + session.pairing_topic + ); // Attempt to disconnect the pairing - ctx.pairing.disconnect(pairing_topic.as_ref(), &ctx.client).await?; + ctx.pairing + .disconnect(session.pairing_topic.as_ref(), &ctx.client) + .await?; } Ok(()) diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index 1b851f6cc2..44fbbcac5a 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -1,7 +1,6 @@ use crate::{error::{WalletConnectCtxError, INVALID_EVENT, UNSUPPORTED_CHAINS}, WalletConnectCtx}; -use chrono::Utc; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::{domain::{MessageId, Topic}, rpc::{params::{session_event::SessionEventRequest, ResponseParamsError, ResponseParamsSuccess}, @@ -47,9 +46,9 @@ impl SessionEvents { ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) .await?; - return MmError::err(WalletConnectCtxError::SessionError(format!( + MmError::err(WalletConnectCtxError::SessionError(format!( "Unsupported session event" - ))); + ))) }, } } @@ -63,12 +62,8 @@ impl SessionEvents { { *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); - { - let mut sessions = ctx.sessions.lock().await; - let current_time = Utc::now().timestamp() as u64; - sessions.retain(|_, session| session.expiry > current_time); - }; - + // TODO: validate session expiration. + // if let Some((namespace, _chain)) = parse_chain_and_chain_id(chain_id) { if ctx.namespaces.get(&namespace).is_none() { let error_data = ErrorData { @@ -85,8 +80,8 @@ impl SessionEvents { ))); } - let mut sessions = ctx.sessions.lock().await; - for session in sessions.values_mut() { + let mut session = ctx.session.lock().await; + if let Some(session) = session.as_mut() { if let Some(ns) = session.namespaces.get_mut(&namespace) { if let Some(chains) = ns.chains.as_mut() { chains.insert(chain_id.to_owned()); diff --git a/mm2src/kdf_walletconnect/src/session/extend.rs b/mm2src/kdf_walletconnect/src/session/extend.rs index 33ddbf7a9b..e637008264 100644 --- a/mm2src/kdf_walletconnect/src/session/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/extend.rs @@ -12,8 +12,8 @@ pub(crate) async fn process_session_extend_request( message_id: &MessageId, extend: SessionExtendRequest, ) -> MmResult<(), WalletConnectCtxError> { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { + let mut session = ctx.session.lock().await; + if let Some(session) = session.as_mut() { session.expiry = extend.expiry; info!("Updated extended, info: {:?}", session); } diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 512e3f7cd6..1b35b6fb30 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -1,4 +1,4 @@ -use super::{settle::send_session_settle_request, SessionInfo}; +use super::{settle::send_session_settle_request, Session}; use crate::{error::WalletConnectCtxError, session::{SessionKey, SessionType, THIRTY_DAYS}, WalletConnectCtx}; @@ -10,7 +10,6 @@ use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session::ProposeNamespaces, session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, Metadata, RequestParams, ResponseParamsSuccess}}; -use std::ops::Deref; /// Creates a new session proposal form topic and metadata. pub(crate) async fn new_proposal( @@ -20,7 +19,7 @@ pub(crate) async fn new_proposal( ) -> MmResult<(), WalletConnectCtxError> { let proposer = Proposer { metadata: ctx.metadata.clone(), - public_key: hex::encode(ctx.sessions.public_key.as_bytes()), + public_key: hex::encode(ctx.key_pair.public_key.as_bytes()), }; let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], @@ -54,8 +53,9 @@ pub async fn process_proposal_request( .await .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - let session = SessionInfo::new( + let session = Session::new( ctx, + session_topic.clone(), subscription_id, session_key, topic.clone(), @@ -68,12 +68,12 @@ pub async fn process_proposal_request( .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; { - let mut sessions = ctx.sessions.deref().lock().await; - _ = sessions.insert(session_topic.clone(), session.clone()); + let mut old_session = ctx.session.lock().await; + *old_session = Some(session.clone()); } { - send_session_settle_request(ctx, session, session_topic).await?; + send_session_settle_request(ctx, &session).await?; }; // Respond to incoming session propose. @@ -98,8 +98,8 @@ pub(crate) async fn process_session_propose_response( .try_into() .unwrap(); - let mut session_key = SessionKey::new(ctx.sessions.public_key); - session_key.generate_symmetric_key(&ctx.sessions.keypair, &other_public_key)?; + let mut session_key = SessionKey::new(ctx.key_pair.public_key); + session_key.generate_symmetric_key(&ctx.key_pair.secret, &other_public_key)?; let session_topic: Topic = session_key.generate_topic().into(); let subscription_id = ctx @@ -108,8 +108,9 @@ pub(crate) async fn process_session_propose_response( .await .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; - let mut session = SessionInfo::new( + let mut session = Session::new( ctx, + session_topic, subscription_id, session_key, pairing_topic.clone(), @@ -120,8 +121,10 @@ pub(crate) async fn process_session_propose_response( session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; session.controller.public_key = response.responder_public_key; - let mut sessions = ctx.sessions.lock().await; - sessions.insert(session_topic.clone(), session.clone()); + { + let mut old_session = ctx.session.lock().await; + *old_session = Some(session); + }; // Activate pairing_topic ctx.pairing.activate(pairing_topic.as_ref()).await?; diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index 7a06c487db..7969ea1100 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -1,4 +1,4 @@ -use super::{SessionInfo, THIRTY_DAYS}; +use super::{Session, THIRTY_DAYS}; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use crate::{SUPPORTED_ACCOUNTS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; @@ -13,8 +13,7 @@ use std::collections::BTreeMap; pub(crate) async fn send_session_settle_request( ctx: &WalletConnectCtx, - session_info: SessionInfo, - session_topic: Topic, + session_info: &Session, ) -> MmResult<(), WalletConnectCtxError> { let mut settled_namespaces = BTreeMap::::new(); settled_namespaces.insert("eip155".to_string(), Namespace { @@ -31,7 +30,7 @@ pub(crate) async fn send_session_settle_request( expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, }); - ctx.publish_request(&session_topic, request).await?; + ctx.publish_request(&session_info.topic, request).await?; Ok(()) } @@ -44,8 +43,8 @@ pub(crate) async fn process_session_settle_request( settle: SessionSettleRequest, ) -> MmResult<(), WalletConnectCtxError> { { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { + let mut session = ctx.session.lock().await; + if let Some(session) = session.as_mut() { session.namespaces = settle.namespaces.0.clone(); session.controller = settle.controller.clone(); session.relay = settle.relay.clone(); diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index 1e46617a5f..2e76c48074 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -11,10 +11,10 @@ pub(crate) async fn process_session_update_request( update: SessionUpdateRequest, ) -> MmResult<(), WalletConnectCtxError> { { - let mut sessions = ctx.sessions.lock().await; - if let Some(session) = sessions.get_mut(topic) { + let mut session = ctx.session.lock().await; + if let Some(session) = session.as_mut() { session.namespaces = update.namespaces.0.clone(); - }; + } } let param = ResponseParamsSuccess::SessionUpdate(true); From 3eb8969fce92586917c2015e0d9686fe170a1d02 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 19 Sep 2024 06:05:51 +0100 Subject: [PATCH 022/125] minor changes --- mm2src/kdf_walletconnect/src/chain/mod.rs | 2 ++ mm2src/kdf_walletconnect/src/lib.rs | 9 +++++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/chain/mod.rs diff --git a/mm2src/kdf_walletconnect/src/chain/mod.rs b/mm2src/kdf_walletconnect/src/chain/mod.rs new file mode 100644 index 0000000000..139597f9cb --- /dev/null +++ b/mm2src/kdf_walletconnect/src/chain/mod.rs @@ -0,0 +1,2 @@ + + diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index fab8fdbf68..d9d1be2de2 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,3 +1,4 @@ +mod chain; #[allow(unused)] mod error; mod handler; mod inbound_message; @@ -37,10 +38,10 @@ const SUPPORTED_METHODS: &[&str] = &[ "personal_sign", "eth_signTypedData", "eth_signTypedData_v4", + "cosmos_getAccounts", ]; -const SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5"]; +const SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5", "cosmos:cosmoshub-4"]; const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; -const SUPPORTED_ACCOUNTS: &[&str] = &["eip155:5:0xBA5BA3955463ADcc7aa3E33bbdfb8A68e0933dD8"]; const DEFAULT_CHAIN_ID: &str = "1"; // eth mainnet. pub struct WalletConnectCtx { @@ -126,9 +127,9 @@ impl WalletConnectCtx { session.clone() } - pub async fn get_account_from_chain_id( + pub async fn get_account_for_chain_id( &self, - chain: &str, + : &str, chain_id: &str, ) -> MmResult { // Lock the active_chain_id and check if the chain matches From 2d6848878d1d86824cd27ddfd03602b19022fcc6 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 19 Sep 2024 23:29:36 +0100 Subject: [PATCH 023/125] save dev state --- mm2src/coins/tendermint/tendermint_coin.rs | 7 +- .../src/tendermint_with_assets_activation.rs | 19 ---- mm2src/kdf_walletconnect/src/chain/mod.rs | 35 ++++++ mm2src/kdf_walletconnect/src/error.rs | 2 + .../kdf_walletconnect/src/inbound_message.rs | 11 +- mm2src/kdf_walletconnect/src/lib.rs | 100 ++++++++---------- .../kdf_walletconnect/src/session/settle.rs | 8 +- 7 files changed, 95 insertions(+), 87 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 0abac08bc0..1fc3689682 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -3311,13 +3311,10 @@ fn parse_expected_sequence_number(e: &str) -> MmResult Vec { vec![] } //"cosmoshub-4".to_owned() - fn chain_id(&self) -> Vec { vec![] } + fn chain_id(&self) -> Vec { todo!() } - fn coin_namespace(&self) -> String { "cosmos".to_owned() } - - fn methods(&self) -> Vec { vec!["cosmos_signDirect".to_owned(), "cosmos_signAmino".to_owned()] } + fn chain(&self) -> String { "cosmos".to_owned() } fn use_walletconnect(&self) -> bool { true } } diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 4364b57dcb..dc26c0e9f0 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -238,25 +238,6 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { let conf = TendermintConf::try_from_json(&ticker, coin_conf)?; - // let is_walletconnect = activation_request.is_walletconnect; - // - // if is_walletconnect { - // let pubkey = ctx - // .wallect_connect - // .get_account_from_chain_id("cosmos", &protocol_conf.chain_id) - // .await - // .expect("shouldn't fail yet"); - // - // if ctx.is_watcher() || ctx.use_watchers() { - // return MmError::err(TendermintInitError { - // ticker: ticker.clone(), - // kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, - // }); - // } - // - // TendermintActivationPolicy::with_public_key(pubkey) - // } - // let is_keplr_from_ledger = activation_request.is_keplr_from_ledger && activation_request.with_pubkey.is_some(); let activation_policy = if let Some(pubkey) = activation_request.with_pubkey { diff --git a/mm2src/kdf_walletconnect/src/chain/mod.rs b/mm2src/kdf_walletconnect/src/chain/mod.rs index 139597f9cb..db24df4893 100644 --- a/mm2src/kdf_walletconnect/src/chain/mod.rs +++ b/mm2src/kdf_walletconnect/src/chain/mod.rs @@ -1,2 +1,37 @@ +use std::collections::{BTreeMap, BTreeSet}; +use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; +pub(crate) const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; + +pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &[ + "eth_sendTransaction", + "eth_signTransaction", + "eth_sign", + "personal_sign", + "eth_signTypedData", + "eth_signTypedData_v4", +]; +pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5"]; + +pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; +pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; + +pub(crate) fn build_required_namespaces() -> ProposeNamespaces { + let mut required = BTreeMap::new(); + + // build eth + required.insert("eip155".to_string(), ProposeNamespace { + chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + }); + + required.insert("cosmos".to_string(), ProposeNamespace { + chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: BTreeSet::new(), + }); + + ProposeNamespaces(required) +} diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 3abee01e0b..74b53ba53c 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -66,6 +66,8 @@ pub enum WalletConnectCtxError { #[error("Payload Error: {0}")] #[from_stringify("wc_common::PayloadError")] PayloadError(String), + #[error("Account not found for chain_id: {0}")] + NoAccountFound(String), } impl From> for WalletConnectCtxError { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 1058eeb65f..be7b2085ea 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,4 +1,5 @@ use common::log::info; +use futures::SinkExt; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::{domain::Topic, rpc::{params::ResponseParamsSuccess, Params, Request, Response}}; @@ -32,7 +33,15 @@ pub(crate) async fn process_inbound_request( .handle_session_event(ctx, topic, &message_id) .await? }, - Params::SessionRequest(_) => { + Params::SessionRequest(param) => { + if ¶m.request.method == "cosmos_getAccounts" { + let mut sender = ctx.session_request_sender.lock().await; + sender + .send(param.clone()) + .await + .expect("event sending shouldn't fail just yet"); + // TODO: send back a success response. + } info!("SessionRequest is not yet implemented."); return MmError::err(WalletConnectCtxError::NotImplemented); }, diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d9d1be2de2..eba9884b4a 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -7,9 +7,10 @@ mod metadata; mod session; use async_trait::async_trait; +use chain::build_required_namespaces; use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; -use futures::{channel::mpsc::{unbounded, UnboundedReceiver}, +use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, lock::Mutex, StreamExt}; use handler::Handler; @@ -20,41 +21,33 @@ use mm2_err_handle::prelude::*; use pairing_api::PairingClient; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; -use relay_rpc::rpc::params::{RelayProtocolMetadata, RequestParams}; +use relay_rpc::rpc::params::{session_request::SessionRequestRequest, RelayProtocolMetadata, RequestParams}; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, - rpc::{params::{session::{ProposeNamespace, ProposeNamespaces}, - IrnMetadata, Metadata, Relay, ResponseParamsError, ResponseParamsSuccess}, + rpc::{params::{session::ProposeNamespaces, IrnMetadata, Metadata, Relay, ResponseParamsError, + ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; use session::{propose::new_proposal, Session, SymKeyPair}; -use std::{collections::BTreeMap, sync::Arc, time::Duration}; +use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; -const SUPPORTED_METHODS: &[&str] = &[ - "eth_sendTransaction", - "eth_signTransaction", - "eth_sign", - "personal_sign", - "eth_signTypedData", - "eth_signTypedData_v4", - "cosmos_getAccounts", -]; -const SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5", "cosmos:cosmoshub-4"]; -const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; const DEFAULT_CHAIN_ID: &str = "1"; // eth mainnet. pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, pub session: Arc>>, - pub msg_handler: Arc>>, - pub connection_live_handler: Arc>>, pub active_chain_id: Arc>, - pub relay: Relay, - pub namespaces: ProposeNamespaces, - pub metadata: Metadata, pub(crate) key_pair: SymKeyPair, + relay: Relay, + namespaces: ProposeNamespaces, + metadata: Metadata, + inbound_message_handler: Arc>>, + connection_live_handler: Arc>>, + + session_request_sender: Arc>>, + session_request_handler: Arc>>, } impl Default for WalletConnectCtx { @@ -65,16 +58,12 @@ impl WalletConnectCtx { pub fn new() -> Self { let (msg_sender, msg_receiver) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); + let (session_request_sender, session_request_receiver) = unbounded(); let pairing = PairingClient::new(); let client = Client::new(Handler::new("Komodefi", msg_sender, conn_live_sender)); - let mut required = BTreeMap::new(); - required.insert("eip155".to_string(), ProposeNamespace { - chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - }); + let required = build_required_namespaces(); let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), @@ -85,13 +74,15 @@ impl WalletConnectCtx { client, pairing, session: Arc::new(Mutex::new(None)), - msg_handler: Arc::new(Mutex::new(msg_receiver)), - connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), relay, - namespaces: ProposeNamespaces(required), + namespaces: required, metadata: generate_metadata(), key_pair: SymKeyPair::new(), + inbound_message_handler: Arc::new(Mutex::new(msg_receiver)), + connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), + session_request_handler: Arc::new(Mutex::new(session_request_receiver)), + session_request_sender: Arc::new(Mutex::new(session_request_sender)), } } @@ -127,27 +118,26 @@ impl WalletConnectCtx { session.clone() } - pub async fn get_account_for_chain_id( - &self, - : &str, - chain_id: &str, - ) -> MmResult { - // Lock the active_chain_id and check if the chain matches - if *self.active_chain_id.lock().await != chain { - // Lock the session + pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { + let active_chain_id = self.active_chain_id.lock().await; + if *active_chain_id == chain_id { let session = self.session.lock().await; - - // Check if a session exists if let Some(session) = session.as_ref() { - if let Some(namespace) = session.namespaces.get(chain) { - if let Some(accounts) = &namespace.accounts { - for account_name in accounts { - let account_vec = account_name.split(':').collect::>(); - - // Check if the account vector has the expected format (length >= 3) - if account_vec.len() >= 3 && account_vec[1] == chain_id { - let account = account_vec[2].to_owned(); - return Ok(account); + // Iterate through namespaces to find the matching chain_id + for (namespace_key, namespace) in &session.namespaces { + if let Some(chains) = &namespace.chains { + let key = format!("{namespace_key}:{chain_id}"); + // Check if the chain_id exists within the namespace chains + if chains.contains(&key) { + if let Some(accounts) = &namespace.accounts { + // Loop through the accounts and extract the account for the correct chain + for account_name in accounts { + let account_vec = account_name.split(':').collect::>(); + if account_vec.len() >= 3 && account_vec[1] == chain_id { + let account = account_vec[2].to_owned(); + return Ok(account); + } + } } } } @@ -156,7 +146,7 @@ impl WalletConnectCtx { } // If the chain doesn't match, or no valid account is found, return an error - MmError::err(WalletConnectCtxError::InvalidRequest) + MmError::err(WalletConnectCtxError::NoAccountFound(chain_id.to_string())) } pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { @@ -273,7 +263,7 @@ impl WalletConnectCtx { pub async fn published_message_event_loop(self: Arc) { let self_clone = self.clone(); - let mut recv = self.msg_handler.lock().await; + let mut recv = self.inbound_message_handler.lock().await; while let Some(msg) = recv.next().await { info!("received message"); if let Err(e) = self_clone.handle_single_message(msg).await { @@ -317,17 +307,11 @@ impl WalletConnectCtx { #[async_trait] pub trait WcCoinOps { /// Returns the coin's namespace identifier (e.g., "eip155" for Ethereum). - fn coin_namespace(&self) -> String; + fn chain(&self) -> String; /// Returns the list of supported chains for the coin. fn chain_id(&self) -> Vec; - /// Returns the list of supported methods for the coin (e.g., `eth_sendTransaction`). - fn methods(&self) -> Vec; - - /// Returns the list of supported events for the coin (e.g., `chainChanged`). - fn events(&self) -> Vec; - /// Returns a boolean indicating whether WalletConnect should be used for this coin. fn use_walletconnect(&self) -> bool; } diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index 7969ea1100..85352760c4 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -1,6 +1,6 @@ use super::{Session, THIRTY_DAYS}; +use crate::chain::{ETH_SUPPORTED_CHAINS, ETH_SUPPORTED_METHODS, SUPPORTED_EVENTS}; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; -use crate::{SUPPORTED_ACCOUNTS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; use chrono::Utc; use common::log::info; @@ -17,10 +17,10 @@ pub(crate) async fn send_session_settle_request( ) -> MmResult<(), WalletConnectCtxError> { let mut settled_namespaces = BTreeMap::::new(); settled_namespaces.insert("eip155".to_string(), Namespace { - accounts: Some(SUPPORTED_ACCOUNTS.iter().map(|a| a.to_string()).collect()), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + chains: Some(ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect()), + methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - chains: None, + accounts: None, }); let request = RequestParams::SessionSettle(SessionSettleRequest { From 42dd5ba33675fab6b923307a37ac7d47399359d2 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 21 Sep 2024 19:42:46 +0100 Subject: [PATCH 024/125] implement coin activation for tendermint and other minor changes --- mm2src/coins/tendermint/tendermint_coin.rs | 5 + .../src/tendermint_with_assets_activation.rs | 80 +- mm2src/crypto/Cargo.toml | 2 - mm2src/kdf_walletconnect/src/chain/cosmos.rs | 98 + mm2src/kdf_walletconnect/src/chain/mod.rs | 31 +- mm2src/kdf_walletconnect/src/error.rs | 12 +- .../kdf_walletconnect/src/inbound_message.rs | 76 +- mm2src/kdf_walletconnect/src/lib.rs | 56 +- mm2src/kdf_walletconnect/src/session.rs | 2 +- .../kdf_walletconnect/src/session/propose.rs | 2 +- mm2src/mm2_core/src/mm_ctx.rs | 2 +- mm2src/mm2_test_helpers/Cargo.lock | 4909 +++++++++++++++++ 12 files changed, 5216 insertions(+), 59 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/chain/cosmos.rs create mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 1fc3689682..c338195aea 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -422,6 +422,11 @@ pub enum TendermintInitErrorKind { BalanceStreamInitError(String), #[display(fmt = "Watcher features can not be used with pubkey-only activation policy.")] CantUseWatchersWithPubkeyPolicy, + #[display( + fmt = "Unable to fetch chain account from WalletConnect. Please try again or reconnect your session - {}", + _0 + )] + UnableToFetchChainAccount(String), } #[derive(Display, Debug, Serialize, SerializeErrorType)] diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index dc26c0e9f0..554b7bc877 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -18,6 +18,7 @@ use coins::tendermint::{tendermint_priv_key_policy, RpcNode, TendermintActivatio use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, MmCoinEnum, PrivKeyBuildPolicy}; use common::executor::{AbortSettings, SpawnAbortable}; use common::{true_f, Future01CompatExt}; +use kdf_walletconnect::chain::cosmos::CosmosAccountAlgo; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; @@ -38,6 +39,14 @@ impl RegisterTokenInfo for TendermintCoin { } } +#[derive(Clone, Default, Deserialize)] +pub struct WalletConnectParams { + #[serde(default)] + pub account_index: u8, + #[serde(default)] + pub enabled: bool, +} + #[derive(Clone, Deserialize)] pub struct TendermintActivationParams { nodes: Vec, @@ -55,7 +64,7 @@ pub struct TendermintActivationParams { #[serde(default)] is_keplr_from_ledger: bool, #[serde(default)] - is_walletconnect: bool, + walletconnect: WalletConnectParams, } fn deserialize_account_public_key<'de, D>(deserializer: D) -> Result, D::Error> @@ -219,6 +228,41 @@ impl From for EnablePlatformCoinWithTokensError { } } +async fn get_walletconnect_pubkey( + ctx: &MmArc, + param: &WalletConnectParams, + chain_id: &str, + ticker: &str, +) -> MmResult { + if ctx.is_watcher() || ctx.use_watchers() { + return MmError::err(TendermintInitError { + ticker: ticker.to_string(), + kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, + }); + }; + + let account = ctx + .wallect_connect + .cosmos_get_account(param.account_index, "cosmos", chain_id) + .await + .mm_err(|err| TendermintInitError { + ticker: ticker.to_string(), + kind: TendermintInitErrorKind::UnableToFetchChainAccount(err.to_string()), + })?; + + let pubkey = match account.algo { + CosmosAccountAlgo::Secp256k1 => { + TendermintPublicKey::from_raw_secp256k1(&account.pubkey).ok_or("Invalid secp256k1 pubkey".to_owned()) + }, + } + .map_to_mm(|e| TendermintInitError { + ticker: ticker.to_string(), + kind: TendermintInitErrorKind::Internal(e), + })?; + + Ok(TendermintActivationPolicy::with_public_key(pubkey)) +} + #[async_trait] impl PlatformCoinWithTokensActivationOps for TendermintCoin { type ActivationRequest = TendermintActivationParams; @@ -238,17 +282,35 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { let conf = TendermintConf::try_from_json(&ticker, coin_conf)?; - let is_keplr_from_ledger = activation_request.is_keplr_from_ledger && activation_request.with_pubkey.is_some(); - let activation_policy = if let Some(pubkey) = activation_request.with_pubkey { - if ctx.is_watcher() || ctx.use_watchers() { - return MmError::err(TendermintInitError { - ticker: ticker.clone(), - kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, - }); - } + let use_with_pubkey = activation_request.with_pubkey.is_some(); + let is_keplr_from_ledger = activation_request.is_keplr_from_ledger && use_with_pubkey; + let use_walletconnect = activation_request.walletconnect.enabled; + + if use_walletconnect && use_with_pubkey { + return MmError::err(TendermintInitError { + ticker: ticker.clone(), + kind: TendermintInitErrorKind::Internal("Can't activate tendermint in pubkey and WalletConnect mode enabled. Make sure only one is enabled.".to_string()), + }); + }; + + if (use_with_pubkey || use_walletconnect) && (ctx.is_watcher() || ctx.use_watchers()) { + return MmError::err(TendermintInitError { + ticker: ticker.clone(), + kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, + }); + }; + let activation_policy = if let Some(pubkey) = activation_request.with_pubkey { TendermintActivationPolicy::with_public_key(pubkey) + } else if use_walletconnect { + get_walletconnect_pubkey( + &ctx, + &activation_request.walletconnect, + protocol_conf.chain_id.as_ref(), + &ticker, + ) + .await? } else { let private_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx).mm_err(|e| TendermintInitError { diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index 68e49a531a..258c1cf098 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -61,5 +61,3 @@ tokio = { version = "1.20", default-features = false } [features] trezor-udp = ["trezor/trezor-udp"] -[patch.crates-io] -rand_core = "=0.6.4" \ No newline at end of file diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs new file mode 100644 index 0000000000..25217d5064 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -0,0 +1,98 @@ +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use chrono::Utc; +use common::log::info; +use futures::StreamExt; +use mm2_err_handle::prelude::{MmError, MmResult}; +use relay_rpc::rpc::params::{session_request::{Request as SessionRequest, SessionRequestRequest}, + RequestParams, ResponseParamsSuccess}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + +use super::WcRequestMethods; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[serde(rename_all = "lowercase")] +pub enum CosmosAccountAlgo { + Secp256k1, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct CosmosAccount { + pub address: String, + #[serde(deserialize_with = "deserialize_pubkey")] + pub pubkey: Vec, + pub algo: CosmosAccountAlgo, +} + +fn deserialize_pubkey<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let value = Value::deserialize(deserializer)?; + + match value { + Value::Object(map) => { + let mut vec = Vec::new(); + for i in 0..map.len() { + if let Some(Value::Number(num)) = map.get(&i.to_string()) { + if let Some(byte) = num.as_u64() { + vec.push(byte as u8); + } else { + return Err(serde::de::Error::custom("Invalid byte value")); + } + } else { + return Err(serde::de::Error::custom("Invalid pubkey format")); + } + } + Ok(vec) + }, + Value::Array(arr) => arr + .into_iter() + .map(|v| { + v.as_u64() + .ok_or_else(|| serde::de::Error::custom("Invalid byte value")) + .map(|n| n as u8) + }) + .collect(), + _ => Err(serde::de::Error::custom("Pubkey must be an object or array")), + } +} + +pub async fn cosmos_get_accounts_impl( + ctx: &WalletConnectCtx, + chain: &str, + chain_id: &str, +) -> MmResult, WalletConnectCtxError> { + let account = ctx.get_account_for_chain_id(chain_id).await?; + + let session = ctx.session.lock().await; + let session_topic = session.as_ref().map(|s| s.topic.clone()); + drop(session); + + if let Some(topic) = session_topic { + let request = SessionRequest { + method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: serde_json::to_value(&account).unwrap(), + }; + let request = SessionRequestRequest { + request, + chain_id: format!("{chain}:{chain_id}"), + }; + + let session_request = RequestParams::SessionRequest(request); + ctx.publish_request(&topic, session_request).await?; + + let mut session_handler = ctx.session_request_handler.lock().await; + if let Some((message_id, data)) = session_handler.next().await { + info!("Got cosmos account: {data:?}"); + let result = serde_json::from_value::>(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&topic, response, &message_id).await?; + + return Ok(result); + } + } + + MmError::err(WalletConnectCtxError::InvalidRequest) +} diff --git a/mm2src/kdf_walletconnect/src/chain/mod.rs b/mm2src/kdf_walletconnect/src/chain/mod.rs index db24df4893..e1bf9ee4f0 100644 --- a/mm2src/kdf_walletconnect/src/chain/mod.rs +++ b/mm2src/kdf_walletconnect/src/chain/mod.rs @@ -1,6 +1,7 @@ -use std::collections::{BTreeMap, BTreeSet}; +pub mod cosmos; use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; +use std::collections::{BTreeMap, BTreeSet}; pub(crate) const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; @@ -10,13 +11,39 @@ pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &[ "eth_sign", "personal_sign", "eth_signTypedData", - "eth_signTypedData_v4", ]; pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5"]; pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; +#[derive(Debug, Clone)] +pub enum WcRequestMethods { + EthSendTransaction, + EthSignTransaction, + EthSign, + EthPersonalSign, + EthSignTypedData, + CosmosSignDirect, + CosmosSignAmino, + CosmosGetAccounts, +} + +impl AsRef for WcRequestMethods { + fn as_ref(&self) -> &str { + match self { + Self::EthSignTransaction => "eth_signTransaction", + Self::EthSendTransaction => "eth_sendTransaction", + Self::EthSign => "eth_sign", + Self::EthPersonalSign => "personal_sign", + Self::EthSignTypedData => "eth_signTypedData", + Self::CosmosSignDirect => "cosmos_signDirect", + Self::CosmosSignAmino => "cosmos_signAmino", + Self::CosmosGetAccounts => "cosmos_getAccounts", + } + } +} + pub(crate) fn build_required_namespaces() -> ProposeNamespaces { let mut required = BTreeMap::new(); diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 74b53ba53c..4d9a826005 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -68,14 +68,22 @@ pub enum WalletConnectCtxError { PayloadError(String), #[error("Account not found for chain_id: {0}")] NoAccountFound(String), + #[error("Account not found for index: {0}")] + NoAccountFoundForIndex(u8), + #[error("Empty account approved for chain_id: {0}")] + EmptyAccount(String), } impl From> for WalletConnectCtxError { - fn from(error: Error) -> Self { WalletConnectCtxError::PublishError(format!("{error:?}")) } + fn from(error: Error) -> Self { + WalletConnectCtxError::PublishError(format!("{error:?}")) + } } impl From> for WalletConnectCtxError { - fn from(error: Error) -> Self { WalletConnectCtxError::SubscriptionError(format!("{error:?}")) } + fn from(error: Error) -> Self { + WalletConnectCtxError::SubscriptionError(format!("{error:?}")) + } } /// Session key and topic derivation errors. diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index be7b2085ea..b83a297585 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -3,6 +3,8 @@ use futures::SinkExt; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::{domain::Topic, rpc::{params::ResponseParamsSuccess, Params, Request, Response}}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; use crate::{error::WalletConnectCtxError, pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}, @@ -15,6 +17,13 @@ use crate::{error::WalletConnectCtxError, update::process_session_update_request}, WalletConnectCtx}; +#[derive(Debug, Serialize, Deserialize)] +#[serde(untagged)] +pub enum SuccessResponses { + ResponseParamsSuccess(ResponseParamsSuccess), + Other(Value), +} + pub(crate) async fn process_inbound_request( ctx: &WalletConnectCtx, request: Request, @@ -33,15 +42,8 @@ pub(crate) async fn process_inbound_request( .handle_session_event(ctx, topic, &message_id) .await? }, - Params::SessionRequest(param) => { - if ¶m.request.method == "cosmos_getAccounts" { - let mut sender = ctx.session_request_sender.lock().await; - sender - .send(param.clone()) - .await - .expect("event sending shouldn't fail just yet"); - // TODO: send back a success response. - } + Params::SessionRequest(_param) => { + // TODO: send back a success response. info!("SessionRequest is not yet implemented."); return MmError::err(WalletConnectCtxError::NotImplemented); }, @@ -63,30 +65,44 @@ pub(crate) async fn process_inbound_response( response: Response, topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { - println!("got a response: {:?}", response); + let message_id = response.id(); + match response { Response::Success(value) => { - let params = serde_json::from_value::(value.result)?; - match params { - ResponseParamsSuccess::SessionPropose(param) => { - process_session_propose_response(ctx, topic, param).await - }, - ResponseParamsSuccess::SessionSettle(success) - | ResponseParamsSuccess::SessionUpdate(success) - | ResponseParamsSuccess::SessionExtend(success) - | ResponseParamsSuccess::SessionRequest(success) - | ResponseParamsSuccess::SessionEvent(success) - | ResponseParamsSuccess::SessionDelete(success) - | ResponseParamsSuccess::SessionPing(success) - | ResponseParamsSuccess::PairingExtend(success) - | ResponseParamsSuccess::PairingDelete(success) - | ResponseParamsSuccess::PairingPing(success) => { - if !success { - return MmError::err(WalletConnectCtxError::UnSuccessfulResponse(format!( - "Unsuccessful response={params:?}" - ))); - } + let success_response = serde_json::from_value::(value.result)?; + match success_response { + SuccessResponses::ResponseParamsSuccess(params) => match params { + // Handle known success responses match success_response { + ResponseParamsSuccess::SessionPropose(param) => { + process_session_propose_response(ctx, topic, param).await + }, + ResponseParamsSuccess::SessionSettle(success) + | ResponseParamsSuccess::SessionUpdate(success) + | ResponseParamsSuccess::SessionExtend(success) + | ResponseParamsSuccess::SessionRequest(success) + | ResponseParamsSuccess::SessionEvent(success) + | ResponseParamsSuccess::SessionDelete(success) + | ResponseParamsSuccess::SessionPing(success) + | ResponseParamsSuccess::PairingExtend(success) + | ResponseParamsSuccess::PairingDelete(success) + | ResponseParamsSuccess::PairingPing(success) => { + if !success { + return MmError::err(WalletConnectCtxError::UnSuccessfulResponse(format!( + "Unsuccessful response={params:?}" + ))); + }; + Ok(()) + }, + }, + SuccessResponses::Other(value) => { + ctx.session_request_sender + .lock() + .await + .send((message_id, value)) + .await + .ok(); + println!("Sent"); Ok(()) }, } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index eba9884b4a..694eda3371 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,4 +1,4 @@ -mod chain; +pub mod chain; #[allow(unused)] mod error; mod handler; mod inbound_message; @@ -7,7 +7,8 @@ mod metadata; mod session; use async_trait::async_trait; -use chain::build_required_namespaces; +use chain::{build_required_namespaces, + cosmos::{cosmos_get_accounts_impl, CosmosAccount}}; use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, @@ -21,18 +22,21 @@ use mm2_err_handle::prelude::*; use pairing_api::PairingClient; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; -use relay_rpc::rpc::params::{session_request::SessionRequestRequest, RelayProtocolMetadata, RequestParams}; +use relay_rpc::rpc::params::{RelayProtocolMetadata, RequestParams}; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, rpc::{params::{session::ProposeNamespaces, IrnMetadata, Metadata, Relay, ResponseParamsError, ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; -use session::{propose::new_proposal, Session, SymKeyPair}; +use serde_json::Value; +use session::{propose::send_proposal, Session, SymKeyPair}; use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; -const DEFAULT_CHAIN_ID: &str = "1"; // eth mainnet. +const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; // cosmos. + +type SessionEventMessage = (MessageId, Value); pub struct WalletConnectCtx { pub client: Client, @@ -46,8 +50,8 @@ pub struct WalletConnectCtx { inbound_message_handler: Arc>>, connection_live_handler: Arc>>, - session_request_sender: Arc>>, - session_request_handler: Arc>>, + session_request_sender: Arc>>, + session_request_handler: Arc>>, } impl Default for WalletConnectCtx { @@ -86,6 +90,7 @@ impl WalletConnectCtx { } } + /// Create a WalletConnect pairing connection url. pub async fn create_pairing( &self, required_namespaces: Option, @@ -96,11 +101,12 @@ impl WalletConnectCtx { self.client.subscribe(topic.clone()).await?; info!("Subscribed to topic: {topic:?}"); - new_proposal(self, topic, required_namespaces).await?; + send_proposal(self, topic, required_namespaces).await?; Ok(url) } + /// Connect to a WalletConnect pairing url. pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { let topic = self.pairing.pair(url, activate).await?; @@ -111,6 +117,13 @@ impl WalletConnectCtx { Ok(topic) } + /// Set active chain. + pub async fn set_active_chain(&self, chain_id: &str) { + let mut active_chain = self.active_chain_id.lock().await; + *active_chain = chain_id.to_owned(); + } + + /// Get current active chain id. pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } pub async fn get_session(&self) -> Option { @@ -118,6 +131,7 @@ impl WalletConnectCtx { session.clone() } + /// Get available accounts for a given chain_id. pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { let active_chain_id = self.active_chain_id.lock().await; if *active_chain_id == chain_id { @@ -132,10 +146,10 @@ impl WalletConnectCtx { if let Some(accounts) = &namespace.accounts { // Loop through the accounts and extract the account for the correct chain for account_name in accounts { + // "cosmos:cosmoshub-4:cosmos1fg2nemunucn496fewakqfe0mllcqfulrmjnj77" let account_vec = account_name.split(':').collect::>(); - if account_vec.len() >= 3 && account_vec[1] == chain_id { - let account = account_vec[2].to_owned(); - return Ok(account); + if account_vec.len() >= 3 { + return Ok(account_vec[2].to_owned()); } } } @@ -149,6 +163,25 @@ impl WalletConnectCtx { MmError::err(WalletConnectCtxError::NoAccountFound(chain_id.to_string())) } + pub async fn cosmos_get_account( + &self, + account_index: u8, + chain: &str, + chain_id: &str, + ) -> MmResult { + let accounts = cosmos_get_accounts_impl(self, chain, chain_id).await?; + + if accounts.is_empty() { + return MmError::err(WalletConnectCtxError::EmptyAccount(chain_id.to_string())); + }; + + if accounts.len() < account_index as usize + 1 { + return MmError::err(WalletConnectCtxError::NoAccountFoundForIndex(account_index)); + }; + + Ok(accounts[account_index as usize].clone()) + } + pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { let auth = { let key = SigningKey::generate(&mut rand::thread_rng()); @@ -159,6 +192,7 @@ impl WalletConnectCtx { .unwrap() }; let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); + self.client.connect(&opts).await?; info!("WC connected"); diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index b4dfb9a2df..2444791394 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -25,7 +25,7 @@ use {hkdf::Hkdf, std::fmt::Debug, x25519_dalek::PublicKey}; -const FIVE_MINUTES: u64 = 300; +pub(crate) const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 1b35b6fb30..3952ef0d15 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -12,7 +12,7 @@ use relay_rpc::{domain::{MessageId, Topic}, Metadata, RequestParams, ResponseParamsSuccess}}; /// Creates a new session proposal form topic and metadata. -pub(crate) async fn new_proposal( +pub(crate) async fn send_proposal( ctx: &WalletConnectCtx, topic: Topic, required_namespaces: Option, diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs index f6ee573e6d..acbb4355e9 100644 --- a/mm2src/mm2_core/src/mm_ctx.rs +++ b/mm2src/mm2_core/src/mm_ctx.rs @@ -320,7 +320,7 @@ impl MmCtx { pub fn is_watcher(&self) -> bool { self.conf["is_watcher"].as_bool().unwrap_or_default() } - pub fn use_watchers(&self) -> bool { self.conf["use_watchers"].as_bool().unwrap_or(true) } + pub fn use_watchers(&self) -> bool { self.conf["use_watchers"].as_bool().unwrap_or(false) } pub fn netid(&self) -> u16 { let netid = self.conf["netid"].as_u64().unwrap_or(0); diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock new file mode 100644 index 0000000000..18887a3dc1 --- /dev/null +++ b/mm2src/mm2_test_helpers/Cargo.lock @@ -0,0 +1,4909 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[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.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", + "zeroize", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[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-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel 2.3.1", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if 1.0.0", + "event-listener 5.3.1", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if 1.0.0", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers 0.3.0", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.3.0", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[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 = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bip32" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" +dependencies = [ + "bs58", + "hkd32", + "hmac 0.11.0", + "ripemd160", + "secp256k1 0.20.3", + "sha2 0.9.9", + "subtle", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "bitcoin" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" +dependencies = [ + "bech32", + "bitcoin_hashes", + "secp256k1 0.24.3", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitcrypto" +version = "0.1.0" +dependencies = [ + "groestl", + "primitives", + "ripemd160", + "serialization", + "sha-1", + "sha2 0.10.8", + "sha3 0.9.1", + "siphasher", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[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 = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding 0.2.1", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[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-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +dependencies = [ + "byteorder", + "iovec", +] + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "chain" +version = "0.1.0" +dependencies = [ + "bitcoin", + "bitcrypto", + "primitives", + "rustc-hex", + "serialization", + "serialization_derive", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clap" +version = "2.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" +dependencies = [ + "bitflags 1.3.2", + "textwrap", + "unicode-width", +] + +[[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 = "common" +version = "0.1.0" +dependencies = [ + "anyhow", + "arrayref", + "async-trait", + "backtrace", + "bytes 1.7.2", + "cc", + "cfg-if 1.0.0", + "chrono", + "crossbeam", + "derive_more", + "env_logger", + "findshlibs", + "fnv", + "futures 0.1.31", + "futures 0.3.30", + "futures-timer", + "gstuff", + "hex", + "http 0.2.12", + "http-body 0.1.0", + "hyper", + "hyper-rustls", + "instant", + "itertools", + "js-sys", + "lazy_static", + "libc", + "lightning", + "log", + "parking_lot", + "parking_lot_core 0.6.3", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hash", + "ser_error", + "ser_error_derive", + "serde", + "serde-wasm-bindgen", + "serde_derive", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "tokio", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", + "winapi", +] + +[[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_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto" +version = "1.0.0" +dependencies = [ + "aes", + "argon2", + "arrayref", + "async-trait", + "base64 0.21.7", + "bip32", + "bip39", + "bitcrypto", + "bs58", + "cbc", + "cfg-if 1.0.0", + "cipher", + "common", + "derive_more", + "enum-primitive-derive", + "enum_derives", + "futures 0.3.30", + "hex", + "hmac 0.12.1", + "http 0.2.12", + "hw_common", + "keys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_eth", + "mm2_metamask", + "num-traits", + "parking_lot", + "primitives", + "rpc", + "rpc_task", + "rustc-hex", + "secp256k1 0.20.3", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "trezor", + "wasm-bindgen-test", + "web3", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version 0.4.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "db_common" +version = "0.1.0" +dependencies = [ + "common", + "crossbeam-channel", + "futures 0.3.30", + "hex", + "log", + "rusqlite", + "sql-builder", + "tokio", + "uuid", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote 1.0.37", + "rustc_version 0.4.1", + "syn 2.0.77", +] + +[[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", + "crypto-common", + "subtle", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "edit-distance" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enum-primitive-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" +dependencies = [ + "num-traits", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "enum_derives" +version = "0.1.0" +dependencies = [ + "itertools", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[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 = "ethabi" +version = "17.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethcore-transaction" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "ethereum-types", + "ethkey", + "keccak-hash", + "rlp", + "rustc-hex", + "unexpected", +] + +[[package]] +name = "ethereum-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", +] + +[[package]] +name = "ethkey" +version = "0.3.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "byteorder", + "edit-distance", + "ethereum-types", + "log", + "mem", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "tiny-keccak 1.4.4", +] + +[[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 = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "findshlibs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers 0.2.6", + "send_wrapper", +] + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "groestl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "gstuff" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes 1.7.2", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.5.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +dependencies = [ + "ahash", +] + +[[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 = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[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.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkd32" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" +dependencies = [ + "hmac 0.11.0", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + +[[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.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" +dependencies = [ + "bytes 0.4.12", + "fnv", + "itoa 0.4.8", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes 1.7.2", + "fnv", + "itoa 1.0.11", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes 1.7.2", + "fnv", + "itoa 1.0.11", +] + +[[package]] +name = "http-body" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", + "http 0.1.21", + "tokio-buf", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes 1.7.2", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[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 = "hw_common" +version = "0.1.0" +dependencies = [ + "async-trait", + "bip32", + "common", + "derive_more", + "futures 0.3.30", + "js-sys", + "mm2_err_handle", + "rusb", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes 1.7.2", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa 1.0.11", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "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", + "rustls", + "tokio", + "tokio-rustls", + "webpki-roots", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg 1.3.0", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding 0.3.3", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipnet" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures 0.3.30", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "jsonwebtoken" +version = "8.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" +dependencies = [ + "base64 0.21.7", + "pem", + "ring 0.16.20", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] +name = "kdf_walletconnect" +version = "0.1.0" +dependencies = [ + "async-trait", + "chrono", + "common", + "derive_more", + "enum_derives", + "futures 0.3.30", + "hex", + "hkdf", + "mm2_err_handle", + "pairing_api", + "rand 0.8.5", + "relay_client", + "relay_rpc", + "secp256k1 0.20.3", + "serde", + "serde_json", + "sha2 0.10.8", + "thiserror", + "wc_common", + "x25519-dalek", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-hash" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" +dependencies = [ + "primitive-types", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "keys" +version = "0.1.0" +dependencies = [ + "base58", + "bech32", + "bitcrypto", + "derive_more", + "lazy_static", + "primitives", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.158" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" + +[[package]] +name = "libsqlite3-sys" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libusb1-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lightning" +version = "0.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" +dependencies = [ + "bitcoin", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg 1.3.0", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "mem" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "metrics" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" +dependencies = [ + "ahash", + "metrics-macros", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" +dependencies = [ + "base64 0.21.7", + "hyper", + "indexmap 1.9.3", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "metrics-util" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" +dependencies = [ + "aho-corasick", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.13.1", + "indexmap 1.9.3", + "metrics", + "num_cpus", + "ordered-float", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + +[[package]] +name = "minicov" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "mm2_core" +version = "0.1.0" +dependencies = [ + "arrayref", + "async-std", + "async-trait", + "cfg-if 1.0.0", + "common", + "db_common", + "derive_more", + "futures 0.3.30", + "gstuff", + "hex", + "instant", + "kdf_walletconnect", + "lazy_static", + "mm2_err_handle", + "mm2_event_stream", + "mm2_metrics", + "mm2_rpc", + "primitives", + "rand 0.7.3", + "rustls", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "shared_ref_counter", + "tokio", + "uuid", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_err_handle" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.1.31", + "http 0.2.12", + "itertools", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_eth" +version = "0.1.0" +dependencies = [ + "ethabi", + "ethkey", + "hex", + "indexmap 1.9.3", + "itertools", + "mm2_err_handle", + "secp256k1 0.20.3", + "serde", + "serde_json", + "web3", +] + +[[package]] +name = "mm2_event_stream" +version = "0.1.0" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "common", + "futures 0.3.30", + "parking_lot", + "serde", + "tokio", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_io" +version = "0.1.0" +dependencies = [ + "async-std", + "common", + "derive_more", + "futures 0.3.30", + "gstuff", + "mm2_err_handle", + "rand 0.7.3", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_metamask" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.30", + "itertools", + "js-sys", + "jsonrpc-core", + "lazy_static", + "mm2_err_handle", + "mm2_eth", + "parking_lot", + "serde", + "serde_derive", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "web3", +] + +[[package]] +name = "mm2_metrics" +version = "0.1.0" +dependencies = [ + "base64 0.21.7", + "common", + "derive_more", + "futures 0.3.30", + "hyper", + "hyper-rustls", + "itertools", + "metrics", + "metrics-exporter-prometheus", + "metrics-util", + "mm2_err_handle", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "mm2_net" +version = "0.1.0" +dependencies = [ + "async-trait", + "base64 0.21.7", + "bytes 1.7.2", + "cfg-if 1.0.0", + "common", + "derive_more", + "ethkey", + "futures 0.3.30", + "futures-util", + "gstuff", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "hyper", + "js-sys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_state_machine", + "pin-project", + "prost", + "rand 0.7.3", + "rustls", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-rustls", + "tonic", + "tower-service", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "mm2_number" +version = "0.1.0" +dependencies = [ + "bigdecimal", + "num-bigint", + "num-rational", + "num-traits", + "paste", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_rpc" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.3.30", + "gstuff", + "http 0.2.12", + "mm2_err_handle", + "mm2_number", + "rpc", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "mm2_state_machine" +version = "0.1.0" +dependencies = [ + "async-trait", +] + +[[package]] +name = "mm2_test_helpers" +version = "0.1.0" +dependencies = [ + "bytes 1.7.2", + "cfg-if 1.0.0", + "chrono", + "common", + "crypto", + "db_common", + "futures 0.3.30", + "gstuff", + "http 0.2.12", + "lazy_static", + "mm2_core", + "mm2_io", + "mm2_metrics", + "mm2_net", + "mm2_number", + "mm2_rpc", + "rand 0.7.3", + "regex", + "rpc", + "serde", + "serde_derive", + "serde_json", + "uuid", +] + +[[package]] +name = "native-tls" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec 1.13.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg 1.3.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "object" +version = "0.36.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +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" +version = "0.10.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" +dependencies = [ + "bitflags 2.6.0", + "cfg-if 1.0.0", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-sys" +version = "0.9.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "pairing_api" +version = "0.1.0" +dependencies = [ + "anyhow", + "chrono", + "hex", + "lazy_static", + "paste", + "rand 0.8.5", + "regex", + "relay_client", + "relay_rpc", + "serde", + "serde_json", + "structopt", + "thiserror", + "tokio", + "url", + "wc_common", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "rustc_version 0.2.3", + "smallvec 0.6.14", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.5.4", + "smallvec 1.13.2", + "windows-targets", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" +dependencies = [ + "base64 0.13.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if 1.0.0", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "uint", +] + +[[package]] +name = "primitives" +version = "0.1.0" +dependencies = [ + "bitcoin_hashes", + "byteorder", + "rustc-hex", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes 1.7.2", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "quanta" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" +dependencies = [ + "crossbeam-utils", + "libc", + "mach2", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg 0.2.1", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +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", + "wasm-bindgen", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +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-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[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.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "relay_client" +version = "0.1.0" +dependencies = [ + "chrono", + "data-encoding", + "futures-util", + "getrandom 0.2.15", + "http 1.1.0", + "js-sys", + "pin-project", + "rand 0.7.3", + "relay_rpc", + "serde", + "serde_json", + "serde_qs", + "thiserror", + "tokio", + "tokio-tungstenite-wasm", + "tokio-util", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "relay_rpc" +version = "0.1.0" +dependencies = [ + "anyhow", + "bs58", + "chrono", + "data-encoding", + "derive_more", + "ed25519-dalek", + "hex", + "jsonwebtoken", + "once_cell", + "paste", + "rand 0.8.5", + "regex", + "serde", + "serde-aux", + "serde_json", + "sha2 0.10.8", + "strum", + "thiserror", + "url", +] + +[[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]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom 0.2.15", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes 1.7.2", + "rustc-hex", +] + +[[package]] +name = "rpc" +version = "0.1.0" +dependencies = [ + "chain", + "keys", + "log", + "primitives", + "rustc-hex", + "script", + "serde", + "serde_derive", + "serde_json", + "serialization", +] + +[[package]] +name = "rpc_task" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.30", + "mm2_err_handle", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", +] + +[[package]] +name = "rusb" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" +dependencies = [ + "libc", + "libusb1-sys", +] + +[[package]] +name = "rusqlite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" +dependencies = [ + "bitflags 1.3.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec 1.13.2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "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 = [ + "ring 0.17.8", + "rustls-webpki", + "sct", +] + +[[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 = "rustversion" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" +dependencies = [ + "windows-sys 0.59.0", +] + +[[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 = "script" +version = "0.1.0" +dependencies = [ + "bitcrypto", + "blake2b_simd", + "chain", + "keys", + "log", + "primitives", + "serde", + "serialization", +] + +[[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 = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "rand 0.6.5", + "secp256k1-sys 0.4.2", +] + +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "bitcoin_hashes", + "secp256k1-sys 0.6.1", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "ser_error" +version = "0.1.0" +dependencies = [ + "serde", +] + +[[package]] +name = "ser_error_derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "ser_error", + "syn 1.0.109", +] + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-aux" +version = "4.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "indexmap 2.5.0", + "itoa 1.0.11", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_qs" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cac3f1e2ca2fe333923a1ae72caca910b98ed0630bb35ef6f8c8517d6e81afa" +dependencies = [ + "percent-encoding", + "serde", + "thiserror", +] + +[[package]] +name = "serde_repr" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "serialization" +version = "0.1.0" +dependencies = [ + "byteorder", + "derive_more", + "primitives", + "test_helpers", +] + +[[package]] +name = "serialization_derive" +version = "0.1.0" +dependencies = [ + "quote 0.3.15", + "syn 0.11.11", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "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 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shared_ref_counter" +version = "0.1.0" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "simple_asn1" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror", + "time", +] + +[[package]] +name = "siphasher" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" + +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg 1.3.0", +] + +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "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.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sql-builder" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" +dependencies = [ + "anyhow", + "thiserror", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "structopt" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" +dependencies = [ + "heck 0.3.3", + "proc-macro-error", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote 1.0.37", + "rustversion", + "syn 2.0.77", +] + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +dependencies = [ + "cfg-if 1.0.0", + "fastrand", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test_helpers" +version = "0.1.0" +dependencies = [ + "hex", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa 1.0.11", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +dependencies = [ + "backtrace", + "bytes 1.7.2", + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-buf" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e80b39df6afcc12cdf752398ade96a6b9e99c903dfdc36e53ad10b9c366bca72" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", +] + +[[package]] +name = "tokio-tungstenite-wasm" +version = "0.1.1-alpha.0" +source = "git+https://github.com/KomodoPlatform/tokio-tungstenite-wasm.git?rev=8fc7e2f#8fc7e2ff4c970bee0c0867399cb9a941881ea183" +dependencies = [ + "futures-channel", + "futures-util", + "http 0.2.12", + "httparse", + "js-sys", + "thiserror", + "tokio", + "tokio-tungstenite", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes 1.7.2", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" +dependencies = [ + "indexmap 2.5.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "base64 0.21.7", + "bytes 1.7.2", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "percent-encoding", + "pin-project", + "prost", + "tokio-stream", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trezor" +version = "0.1.1" +dependencies = [ + "async-std", + "async-trait", + "bip32", + "byteorder", + "common", + "derive_more", + "ethcore-transaction", + "ethereum-types", + "ethkey", + "futures 0.3.30", + "hw_common", + "js-sys", + "lazy_static", + "mm2_err_handle", + "prost", + "rand 0.7.3", + "rpc_task", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" +dependencies = [ + "base64 0.13.1", + "byteorder", + "bytes 1.7.2", + "http 0.2.12", + "httparse", + "log", + "native-tls", + "rand 0.8.5", + "sha-1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unexpected" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom 0.2.15", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote 1.0.37", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68497a05fb21143a08a7d24fc81763384a3072ee43c44e86aad1744d6adef9d9" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "minicov", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "wc_common" +version = "0.1.0" +dependencies = [ + "base64 0.21.7", + "chacha20poly1305", + "thiserror", +] + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web3" +version = "0.19.0" +source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" +dependencies = [ + "arrayvec 0.7.6", + "derive_more", + "ethabi", + "ethereum-types", + "futures 0.3.30", + "futures-timer", + "getrandom 0.2.15", + "hex", + "idna 0.2.3", + "js-sys", + "jsonrpc-core", + "log", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rlp", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tiny-keccak 2.0.2", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", + "serde", + "zeroize", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +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 1.0.37", + "syn 2.0.77", +] From edcb5a767756b251d55f679825935494b79f3e95 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 22 Sep 2024 04:09:53 +0100 Subject: [PATCH 025/125] improve code and minor needed changes --- mm2src/kdf_walletconnect/src/chain/mod.rs | 43 +++------------ mm2src/kdf_walletconnect/src/lib.rs | 5 +- mm2src/kdf_walletconnect/src/metadata.rs | 2 +- mm2src/kdf_walletconnect/src/session/event.rs | 53 +++++++------------ .../kdf_walletconnect/src/session/settle.rs | 6 +-- 5 files changed, 35 insertions(+), 74 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/chain/mod.rs b/mm2src/kdf_walletconnect/src/chain/mod.rs index e1bf9ee4f0..72053387b7 100644 --- a/mm2src/kdf_walletconnect/src/chain/mod.rs +++ b/mm2src/kdf_walletconnect/src/chain/mod.rs @@ -1,29 +1,13 @@ pub mod cosmos; - use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; -use std::collections::{BTreeMap, BTreeSet}; - -pub(crate) const SUPPORTED_EVENTS: &[&str] = &["chainChanged", "accountsChanged"]; - -pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &[ - "eth_sendTransaction", - "eth_signTransaction", - "eth_sign", - "personal_sign", - "eth_signTypedData", -]; -pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:5"]; +use std::collections::BTreeMap; -pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; -pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; +pub(crate) const SUPPORTED_EVENTS: &[&str] = &[]; +pub(crate) const SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; +pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; #[derive(Debug, Clone)] pub enum WcRequestMethods { - EthSendTransaction, - EthSignTransaction, - EthSign, - EthPersonalSign, - EthSignTypedData, CosmosSignDirect, CosmosSignAmino, CosmosGetAccounts, @@ -32,11 +16,6 @@ pub enum WcRequestMethods { impl AsRef for WcRequestMethods { fn as_ref(&self) -> &str { match self { - Self::EthSignTransaction => "eth_signTransaction", - Self::EthSendTransaction => "eth_sendTransaction", - Self::EthSign => "eth_sign", - Self::EthPersonalSign => "personal_sign", - Self::EthSignTypedData => "eth_signTypedData", Self::CosmosSignDirect => "cosmos_signDirect", Self::CosmosSignAmino => "cosmos_signAmino", Self::CosmosGetAccounts => "cosmos_getAccounts", @@ -46,18 +25,10 @@ impl AsRef for WcRequestMethods { pub(crate) fn build_required_namespaces() -> ProposeNamespaces { let mut required = BTreeMap::new(); - - // build eth - required.insert("eip155".to_string(), ProposeNamespace { - chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - }); - required.insert("cosmos".to_string(), ProposeNamespace { - chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: BTreeSet::new(), + chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + events: SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), }); ProposeNamespaces(required) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 694eda3371..d504388527 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -8,7 +8,8 @@ mod session; use async_trait::async_trait; use chain::{build_required_namespaces, - cosmos::{cosmos_get_accounts_impl, CosmosAccount}}; + cosmos::{cosmos_get_accounts_impl, CosmosAccount}, + SUPPORTED_CHAINS}; use common::{executor::Timer, log::info}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, @@ -117,6 +118,8 @@ impl WalletConnectCtx { Ok(topic) } + pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|chain| chain == &chain_id) } + /// Set active chain. pub async fn set_active_chain(&self, chain_id: &str) { let mut active_chain = self.active_chain_id.lock().await; diff --git a/mm2src/kdf_walletconnect/src/metadata.rs b/mm2src/kdf_walletconnect/src/metadata.rs index 777bbd6148..7edccf9088 100644 --- a/mm2src/kdf_walletconnect/src/metadata.rs +++ b/mm2src/kdf_walletconnect/src/metadata.rs @@ -10,7 +10,7 @@ pub(crate) fn generate_metadata() -> Metadata { Metadata { description: APP_DESCRIPTION.to_owned(), url: AUTH_TOKEN_SUB.to_owned(), - icons: vec![], + icons: vec!["https://avatars.githubusercontent.com/u/21276113?s=200&v=4".to_owned()], name: APP_NAME.to_owned(), } } diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index 44fbbcac5a..eede3933dc 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -59,42 +59,29 @@ impl SessionEvents { topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { - { - *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); - - // TODO: validate session expiration. - // - if let Some((namespace, _chain)) = parse_chain_and_chain_id(chain_id) { - if ctx.namespaces.get(&namespace).is_none() { - let error_data = ErrorData { - code: UNSUPPORTED_CHAINS, - message: "Chain_Id was changed to an unsupported chain".to_string(), - data: None, - }; - - ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) - .await?; - - return MmError::err(WalletConnectCtxError::SessionError(format!( - "Unsupported chainChanged chain_id from session request: {chain_id}", - ))); - } - - let mut session = ctx.session.lock().await; - if let Some(session) = session.as_mut() { - if let Some(ns) = session.namespaces.get_mut(&namespace) { - if let Some(chains) = ns.chains.as_mut() { - chains.insert(chain_id.to_owned()); - } + if ctx.is_chain_supported(chain_id) { + if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { + if let Some(namespace) = ctx.namespaces.get(&key) { + if namespace.chains.contains(&chain) { + // TODO: Notify GUI about chain changed. + // Update active chain_id + *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); + let params = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, params, message_id).await?; + + return Ok(()); } } } - } - - //TODO: Notify about chain changed. + }; - let params = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, params, message_id).await?; + let error_data = ErrorData { + code: UNSUPPORTED_CHAINS, + message: "Chain_Id was changed to an unsupported chain".to_string(), + data: None, + }; + ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) + .await?; Ok(()) } @@ -118,7 +105,7 @@ impl SessionEvents { fn parse_chain_and_chain_id(chain: &str) -> Option<(String, String)> { let sp = chain.split(':').collect::>(); - if sp.len() == 2 { + if sp.len() != 2 { return None; }; diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index 85352760c4..b9a851f300 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -1,5 +1,5 @@ use super::{Session, THIRTY_DAYS}; -use crate::chain::{ETH_SUPPORTED_CHAINS, ETH_SUPPORTED_METHODS, SUPPORTED_EVENTS}; +use crate::chain::{SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; @@ -17,8 +17,8 @@ pub(crate) async fn send_session_settle_request( ) -> MmResult<(), WalletConnectCtxError> { let mut settled_namespaces = BTreeMap::::new(); settled_namespaces.insert("eip155".to_string(), Namespace { - chains: Some(ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect()), - methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + chains: Some(SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect()), + methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), accounts: None, }); From e606ca4e07ae9d878056cea14fa394da8742926a Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 23 Sep 2024 05:01:26 +0100 Subject: [PATCH 026/125] improve relayer disconnection, remove unneeded changes, track topic subscriptions --- .cargo/config.toml | 4 +- mm2src/coins/Cargo.toml | 24 +- mm2src/coins/tendermint/tendermint_coin.rs | 10 - mm2src/crypto/Cargo.toml | 1 - mm2src/crypto/src/walletconnect.rs | 0 mm2src/kdf_walletconnect/Cargo.toml | 2 - mm2src/kdf_walletconnect/src/chain/cosmos.rs | 7 +- mm2src/kdf_walletconnect/src/handler.rs | 4 +- mm2src/kdf_walletconnect/src/lib.rs | 118 +- .../kdf_walletconnect/src/session/propose.rs | 6 +- .../kdf_walletconnect/src/session/update.rs | 4 +- mm2src/mm2_test_helpers/Cargo.lock | 4909 ----------------- 12 files changed, 103 insertions(+), 4986 deletions(-) delete mode 100644 mm2src/crypto/src/walletconnect.rs delete mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/.cargo/config.toml b/.cargo/config.toml index 1bbbfea3c5..861d0669fb 100644 --- a/.cargo/config.toml +++ b/.cargo/config.toml @@ -2,7 +2,7 @@ JEMALLOC_SYS_WITH_MALLOC_CONF = "background_thread:true,narenas:1,tcache:false,dirty_decay_ms:0,muzzy_decay_ms:0,metadata_thp:auto" [target.'cfg(all())'] -rustflags = ["-Zshare-generics=y", '--cfg=curve25519_dalek_backend="fiat"'] +rustflags = [ "-Zshare-generics=y", '--cfg=curve25519_dalek_backend="fiat"' ] # # Install lld using package manager # [target.x86_64-unknown-linux-gnu] @@ -24,4 +24,4 @@ rustflags = ["-Zshare-generics=y", '--cfg=curve25519_dalek_backend="fiat"'] [target.wasm32-unknown-unknown] runner = 'wasm-bindgen-test-runner' -rustflags = ["--cfg=web_sys_unstable_apis"] +rustflags = [ "--cfg=web_sys_unstable_apis" ] diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index 08824493d1..4296e5dac9 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -7,19 +7,19 @@ edition = "2018" zhtlc-native-tests = [] # TODO enable-solana = [ - "dep:bincode", - "dep:ed25519-dalek-bip32", - "dep:solana-client", - "dep:solana-sdk", - "dep:solana-transaction-status", - "dep:spl-token", - "dep:spl-associated-token-account", - "dep:satomic-swap" + "dep:bincode", + "dep:ed25519-dalek-bip32", + "dep:solana-client", + "dep:solana-sdk", + "dep:solana-transaction-status", + "dep:spl-token", + "dep:spl-associated-token-account", + "dep:satomic-swap" ] enable-sia = [ - "dep:reqwest", - "dep:blake2b_simd", - "dep:sia-rust" + "dep:reqwest", + "dep:blake2b_simd", + "dep:sia-rust" ] default = [] run-docker-tests = [] @@ -188,5 +188,3 @@ wagyu-zcash-parameters = { version = "0.2" } [build-dependencies] prost-build = { version = "0.11", default-features = false } tonic-build = { version = "0.9", default-features = false, features = ["prost"] } - - diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index c338195aea..d4e1c190d7 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -61,7 +61,6 @@ use futures01::Future; use hex::FromHexError; use instant::Duration; use itertools::Itertools; -use kdf_walletconnect::WcCoinOps; use keys::{KeyPair, Public}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_err_handle::prelude::*; @@ -3315,15 +3314,6 @@ fn parse_expected_sequence_number(e: &str) -> MmResult Vec { todo!() } - - fn chain(&self) -> String { "cosmos".to_owned() } - - fn use_walletconnect(&self) -> bool { true } -} - #[cfg(test)] pub mod tendermint_coin_tests { use super::*; diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index 258c1cf098..dd3bbec752 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -60,4 +60,3 @@ tokio = { version = "1.20", default-features = false } [features] trezor-udp = ["trezor/trezor-udp"] - diff --git a/mm2src/crypto/src/walletconnect.rs b/mm2src/crypto/src/walletconnect.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 0892f12150..d83ce583ed 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -3,8 +3,6 @@ name = "kdf_walletconnect" version = "0.1.0" edition = "2021" -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - [dependencies] async-trait = "0.1.52" chrono = { version = "0.4.23", "features" = ["serde"] } diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs index 25217d5064..27c742e06f 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -65,9 +65,10 @@ pub async fn cosmos_get_accounts_impl( ) -> MmResult, WalletConnectCtxError> { let account = ctx.get_account_for_chain_id(chain_id).await?; - let session = ctx.session.lock().await; - let session_topic = session.as_ref().map(|s| s.topic.clone()); - drop(session); + let session_topic = { + let session = ctx.session.lock().await; + session.as_ref().map(|s| s.topic.clone()) + }; if let Some(topic) = session_topic { let request = SessionRequest { diff --git a/mm2src/kdf_walletconnect/src/handler.rs b/mm2src/kdf_walletconnect/src/handler.rs index e4fbb5b164..2840ce4486 100644 --- a/mm2src/kdf_walletconnect/src/handler.rs +++ b/mm2src/kdf_walletconnect/src/handler.rs @@ -32,7 +32,7 @@ impl ConnectionHandler for Handler { info!("\n[{}] connection closed: frame={frame:?}", self.name); if let Err(e) = self.conn_live_sender.start_send(()) { - info!("\n[{}] failed to send the to the receiver: {e}", self.name); + info!("\n[{}] failed to send to the receiver: {e}", self.name); } } @@ -43,7 +43,7 @@ impl ConnectionHandler for Handler { ); if let Err(e) = self.msg_sender.start_send(message) { - info!("\n[{}] failed to send the to the receiver: {e}", self.name); + info!("\n[{}] failed to send to the receiver: {e}", self.name); } } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d504388527..d7f1291fa9 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -10,7 +10,8 @@ use async_trait::async_trait; use chain::{build_required_namespaces, cosmos::{cosmos_get_accounts_impl, CosmosAccount}, SUPPORTED_CHAINS}; -use common::{executor::Timer, log::info}; +use common::{executor::Timer, + log::{error, info}}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, lock::Mutex, @@ -35,7 +36,7 @@ use std::{sync::Arc, time::Duration}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; -const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; // cosmos. +const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; // tendermint e.g ATOM type SessionEventMessage = (MessageId, Value); @@ -45,9 +46,12 @@ pub struct WalletConnectCtx { pub session: Arc>>, pub active_chain_id: Arc>, pub(crate) key_pair: SymKeyPair, + relay: Relay, - namespaces: ProposeNamespaces, metadata: Metadata, + namespaces: ProposeNamespaces, + subscriptions: Arc>>, + inbound_message_handler: Arc>>, connection_live_handler: Arc>>, @@ -78,7 +82,7 @@ impl WalletConnectCtx { Self { client, pairing, - session: Arc::new(Mutex::new(None)), + session: Default::default(), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), relay, namespaces: required, @@ -88,9 +92,28 @@ impl WalletConnectCtx { connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), session_request_handler: Arc::new(Mutex::new(session_request_receiver)), session_request_sender: Arc::new(Mutex::new(session_request_sender)), + subscriptions: Default::default(), } } + pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { + let auth = { + let key = SigningKey::generate(&mut rand::thread_rng()); + AuthToken::new(AUTH_TOKEN_SUB) + .aud(RELAY_ADDRESS) + .ttl(Duration::from_secs(60 * 60)) + .as_jwt(&key) + .unwrap() + }; + let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); + + self.client.connect(&opts).await?; + + info!("WC connected"); + + Ok(()) + } + /// Create a WalletConnect pairing connection url. pub async fn create_pairing( &self, @@ -99,10 +122,17 @@ impl WalletConnectCtx { let (topic, url) = self.pairing.create(self.metadata.clone(), None).await?; info!("Subscribing to topic: {topic:?}"); + self.client.subscribe(topic.clone()).await?; + info!("Subscribed to topic: {topic:?}"); - send_proposal(self, topic, required_namespaces).await?; + send_proposal(self, topic.clone(), required_namespaces).await?; + + { + let mut subs = self.subscriptions.lock().await; + subs.push(topic); + }; Ok(url) } @@ -115,6 +145,11 @@ impl WalletConnectCtx { self.client.subscribe(topic.clone()).await?; info!("Subscribed to topic: {topic:?}"); + { + let mut subs = self.subscriptions.lock().await; + subs.push(topic.clone()); + }; + Ok(topic) } @@ -185,24 +220,6 @@ impl WalletConnectCtx { Ok(accounts[account_index as usize].clone()) } - pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { - let auth = { - let key = SigningKey::generate(&mut rand::thread_rng()); - AuthToken::new(AUTH_TOKEN_SUB) - .aud(RELAY_ADDRESS) - .ttl(Duration::from_secs(60 * 60)) - .as_jwt(&key) - .unwrap() - }; - let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); - - self.client.connect(&opts).await?; - - info!("WC connected"); - - Ok(()) - } - async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { { let session = self.session.lock().await; @@ -327,28 +344,45 @@ impl WalletConnectCtx { info!("Inbound message was handled successfully"); Ok(()) } + pub async fn spawn_connection_live_watcher(self: Arc) { let mut recv = self.connection_live_handler.lock().await; - while let Some(_msg) = recv.next().await { - info!("connection disconnected, reconnecting"); - if let Err(err) = self.connect_client().await { - common::log::error!("{err:?}"); - Timer::sleep(5.).await; - continue; - }; - info!("reconnecting success!"); - } - } -} + let mut retry_count = 0; -#[async_trait] -pub trait WcCoinOps { - /// Returns the coin's namespace identifier (e.g., "eip155" for Ethereum). - fn chain(&self) -> String; + while let Some(_msg) = recv.next().await { + info!("Connection disconnected. Attempting to reconnect..."); + + // Try reconnecting + match self.connect_client().await { + Ok(_) => { + info!( + "Successfully reconnected to client after {} attempt(s).", + retry_count + 1 + ); + retry_count = 0; + }, + Err(err) => { + retry_count += 1; + common::log::error!( + "Error while reconnecting to client (attempt {}): {:?}. Retrying in 5 seconds...", + retry_count, + err + ); + Timer::sleep(5.).await; + continue; + }, + } - /// Returns the list of supported chains for the coin. - fn chain_id(&self) -> Vec; + // Subscribe to existing topics again after reconnecting + let subs = self.subscriptions.lock().await; + for topic in &*subs { + match self.client.subscribe(topic.clone()).await { + Ok(_) => info!("Successfully reconnected to topic: {:?}", topic), + Err(err) => error!("Failed to subscribe to topic: {:?}. Error: {:?}", topic, err), + } + } - /// Returns a boolean indicating whether WalletConnect should be used for this coin. - fn use_walletconnect(&self) -> bool; + info!("Reconnection process complete."); + } + } } diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 3952ef0d15..68c788a085 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -70,6 +70,8 @@ pub async fn process_proposal_request( { let mut old_session = ctx.session.lock().await; *old_session = Some(session.clone()); + let mut subs = ctx.subscriptions.lock().await; + subs.push(session_topic.clone()); } { @@ -110,7 +112,7 @@ pub(crate) async fn process_session_propose_response( let mut session = Session::new( ctx, - session_topic, + session_topic.clone(), subscription_id, session_key, pairing_topic.clone(), @@ -124,6 +126,8 @@ pub(crate) async fn process_session_propose_response( { let mut old_session = ctx.session.lock().await; *old_session = Some(session); + let mut subs = ctx.subscriptions.lock().await; + subs.push(session_topic.clone()); }; // Activate pairing_topic diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index 2e76c48074..842b23ce71 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -4,6 +4,8 @@ use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_update::SessionUpdateRequest, ResponseParamsSuccess}}; +// TODO: Handle properly when multi chain is supported. +// Hanlding for only cosmos support. pub(crate) async fn process_session_update_request( ctx: &WalletConnectCtx, topic: &Topic, @@ -14,7 +16,7 @@ pub(crate) async fn process_session_update_request( let mut session = ctx.session.lock().await; if let Some(session) = session.as_mut() { session.namespaces = update.namespaces.0.clone(); - } + }; } let param = ResponseParamsSuccess::SessionUpdate(true); diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock deleted file mode 100644 index 18887a3dc1..0000000000 --- a/mm2src/mm2_test_helpers/Cargo.lock +++ /dev/null @@ -1,4909 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[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.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" - -[[package]] -name = "argon2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" -dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", - "zeroize", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.3.1", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" -dependencies = [ - "async-lock", - "cfg-if 1.0.0", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[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-process" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" -dependencies = [ - "async-channel 2.3.1", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if 1.0.0", - "event-listener 5.3.1", - "futures-lite", - "rustix", - "tracing", -] - -[[package]] -name = "async-signal" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if 1.0.0", - "futures-core", - "futures-io", - "rustix", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-std" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers 0.3.0", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.82" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.3.0", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - -[[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 = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "bip32" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" -dependencies = [ - "bs58", - "hkd32", - "hmac 0.11.0", - "ripemd160", - "secp256k1 0.20.3", - "sha2 0.9.9", - "subtle", - "zeroize", -] - -[[package]] -name = "bip39" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" -dependencies = [ - "bitcoin_hashes", - "rand_core 0.6.4", - "zeroize", -] - -[[package]] -name = "bitcoin" -version = "0.29.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" -dependencies = [ - "bech32", - "bitcoin_hashes", - "secp256k1 0.24.3", -] - -[[package]] -name = "bitcoin_hashes" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" - -[[package]] -name = "bitcrypto" -version = "0.1.0" -dependencies = [ - "groestl", - "primitives", - "ripemd160", - "serialization", - "sha-1", - "sha2 0.10.8", - "sha3 0.9.1", - "siphasher", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[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 = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding 0.2.1", - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel 2.3.1", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[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-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - -[[package]] -name = "bytes" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "cc" -version = "1.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "chain" -version = "0.1.0" -dependencies = [ - "bitcoin", - "bitcrypto", - "primitives", - "rustc-hex", - "serialization", - "serialization_derive", -] - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-targets", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - -[[package]] -name = "clap" -version = "2.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c" -dependencies = [ - "bitflags 1.3.2", - "textwrap", - "unicode-width", -] - -[[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 = "common" -version = "0.1.0" -dependencies = [ - "anyhow", - "arrayref", - "async-trait", - "backtrace", - "bytes 1.7.2", - "cc", - "cfg-if 1.0.0", - "chrono", - "crossbeam", - "derive_more", - "env_logger", - "findshlibs", - "fnv", - "futures 0.1.31", - "futures 0.3.30", - "futures-timer", - "gstuff", - "hex", - "http 0.2.12", - "http-body 0.1.0", - "hyper", - "hyper-rustls", - "instant", - "itertools", - "js-sys", - "lazy_static", - "libc", - "lightning", - "log", - "parking_lot", - "parking_lot_core 0.6.3", - "primitive-types", - "rand 0.7.3", - "regex", - "rustc-hash", - "ser_error", - "ser_error_derive", - "serde", - "serde-wasm-bindgen", - "serde_derive", - "serde_json", - "serde_repr", - "sha2 0.10.8", - "tokio", - "uuid", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", - "winapi", -] - -[[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_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto" -version = "1.0.0" -dependencies = [ - "aes", - "argon2", - "arrayref", - "async-trait", - "base64 0.21.7", - "bip32", - "bip39", - "bitcrypto", - "bs58", - "cbc", - "cfg-if 1.0.0", - "cipher", - "common", - "derive_more", - "enum-primitive-derive", - "enum_derives", - "futures 0.3.30", - "hex", - "hmac 0.12.1", - "http 0.2.12", - "hw_common", - "keys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_eth", - "mm2_metamask", - "num-traits", - "parking_lot", - "primitives", - "rpc", - "rpc_task", - "rustc-hex", - "secp256k1 0.20.3", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", - "serde_json", - "sha2 0.10.8", - "trezor", - "wasm-bindgen-test", - "web3", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version 0.4.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "data-encoding" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "db_common" -version = "0.1.0" -dependencies = [ - "common", - "crossbeam-channel", - "futures 0.3.30", - "hex", - "log", - "rusqlite", - "sql-builder", - "tokio", - "uuid", -] - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "deranged" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" -dependencies = [ - "powerfmt", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case", - "proc-macro2", - "quote 1.0.37", - "rustc_version 0.4.1", - "syn 2.0.77", -] - -[[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", - "crypto-common", - "subtle", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek", - "ed25519", - "rand_core 0.6.4", - "serde", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "edit-distance" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "enum-primitive-derive" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" -dependencies = [ - "num-traits", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "enum_derives" -version = "0.1.0" -dependencies = [ - "itertools", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[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 = "ethabi" -version = "17.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3 0.10.8", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "ethcore-transaction" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "ethereum-types", - "ethkey", - "keccak-hash", - "rlp", - "rustc-hex", - "unexpected", -] - -[[package]] -name = "ethereum-types" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - -[[package]] -name = "ethkey" -version = "0.3.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "byteorder", - "edit-distance", - "ethereum-types", - "log", - "mem", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "tiny-keccak 1.4.4", -] - -[[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 = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - -[[package]] -name = "fastrand" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "findshlibs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers 0.2.6", - "send_wrapper", -] - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures 0.1.31", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "groestl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "gstuff" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes 1.7.2", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.5.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" -dependencies = [ - "ahash", -] - -[[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 = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "heck" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" -dependencies = [ - "unicode-segmentation", -] - -[[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.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkd32" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" -dependencies = [ - "hmac 0.11.0", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac 0.12.1", -] - -[[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.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -dependencies = [ - "bytes 0.4.12", - "fnv", - "itoa 0.4.8", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes 1.7.2", - "fnv", - "itoa 1.0.11", -] - -[[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" -dependencies = [ - "bytes 1.7.2", - "fnv", - "itoa 1.0.11", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "http 0.1.21", - "tokio-buf", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes 1.7.2", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - -[[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 = "hw_common" -version = "0.1.0" -dependencies = [ - "async-trait", - "bip32", - "common", - "derive_more", - "futures 0.3.30", - "js-sys", - "mm2_err_handle", - "rusb", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes 1.7.2", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa 1.0.11", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "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", - "rustls", - "tokio", - "tokio-rustls", - "webpki-roots", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg 1.3.0", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding 0.3.3", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipnet" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures 0.3.30", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "jsonwebtoken" -version = "8.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6971da4d9c3aa03c3d8f3ff0f4155b534aad021292003895a469716b2a230378" -dependencies = [ - "base64 0.21.7", - "pem", - "ring 0.16.20", - "serde", - "serde_json", - "simple_asn1", -] - -[[package]] -name = "kdf_walletconnect" -version = "0.1.0" -dependencies = [ - "async-trait", - "chrono", - "common", - "derive_more", - "enum_derives", - "futures 0.3.30", - "hex", - "hkdf", - "mm2_err_handle", - "pairing_api", - "rand 0.8.5", - "relay_client", - "relay_rpc", - "secp256k1 0.20.3", - "serde", - "serde_json", - "sha2 0.10.8", - "thiserror", - "wc_common", - "x25519-dalek", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "keccak-hash" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" -dependencies = [ - "primitive-types", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "keys" -version = "0.1.0" -dependencies = [ - "base58", - "bech32", - "bitcrypto", - "derive_more", - "lazy_static", - "primitives", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.158" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" - -[[package]] -name = "libsqlite3-sys" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "libusb1-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "lightning" -version = "0.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" -dependencies = [ - "bitcoin", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg 1.3.0", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -dependencies = [ - "value-bag", -] - -[[package]] -name = "mach2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" -dependencies = [ - "libc", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "mem" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "metrics" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash", - "metrics-macros", - "portable-atomic", -] - -[[package]] -name = "metrics-exporter-prometheus" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" -dependencies = [ - "base64 0.21.7", - "hyper", - "indexmap 1.9.3", - "ipnet", - "metrics", - "metrics-util", - "quanta", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "metrics-macros" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "metrics-util" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" -dependencies = [ - "aho-corasick", - "crossbeam-epoch", - "crossbeam-utils", - "hashbrown 0.13.1", - "indexmap 1.9.3", - "metrics", - "num_cpus", - "ordered-float", - "quanta", - "radix_trie", - "sketches-ddsketch", -] - -[[package]] -name = "minicov" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" -dependencies = [ - "cc", - "walkdir", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", -] - -[[package]] -name = "mm2_core" -version = "0.1.0" -dependencies = [ - "arrayref", - "async-std", - "async-trait", - "cfg-if 1.0.0", - "common", - "db_common", - "derive_more", - "futures 0.3.30", - "gstuff", - "hex", - "instant", - "kdf_walletconnect", - "lazy_static", - "mm2_err_handle", - "mm2_event_stream", - "mm2_metrics", - "mm2_rpc", - "primitives", - "rand 0.7.3", - "rustls", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "shared_ref_counter", - "tokio", - "uuid", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_err_handle" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.1.31", - "http 0.2.12", - "itertools", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_eth" -version = "0.1.0" -dependencies = [ - "ethabi", - "ethkey", - "hex", - "indexmap 1.9.3", - "itertools", - "mm2_err_handle", - "secp256k1 0.20.3", - "serde", - "serde_json", - "web3", -] - -[[package]] -name = "mm2_event_stream" -version = "0.1.0" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "common", - "futures 0.3.30", - "parking_lot", - "serde", - "tokio", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_io" -version = "0.1.0" -dependencies = [ - "async-std", - "common", - "derive_more", - "futures 0.3.30", - "gstuff", - "mm2_err_handle", - "rand 0.7.3", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_metamask" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.30", - "itertools", - "js-sys", - "jsonrpc-core", - "lazy_static", - "mm2_err_handle", - "mm2_eth", - "parking_lot", - "serde", - "serde_derive", - "serde_json", - "wasm-bindgen", - "wasm-bindgen-futures", - "web3", -] - -[[package]] -name = "mm2_metrics" -version = "0.1.0" -dependencies = [ - "base64 0.21.7", - "common", - "derive_more", - "futures 0.3.30", - "hyper", - "hyper-rustls", - "itertools", - "metrics", - "metrics-exporter-prometheus", - "metrics-util", - "mm2_err_handle", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "mm2_net" -version = "0.1.0" -dependencies = [ - "async-trait", - "base64 0.21.7", - "bytes 1.7.2", - "cfg-if 1.0.0", - "common", - "derive_more", - "ethkey", - "futures 0.3.30", - "futures-util", - "gstuff", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "hyper", - "js-sys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_state_machine", - "pin-project", - "prost", - "rand 0.7.3", - "rustls", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-rustls", - "tonic", - "tower-service", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "mm2_number" -version = "0.1.0" -dependencies = [ - "bigdecimal", - "num-bigint", - "num-rational", - "num-traits", - "paste", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_rpc" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.3.30", - "gstuff", - "http 0.2.12", - "mm2_err_handle", - "mm2_number", - "rpc", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "uuid", -] - -[[package]] -name = "mm2_state_machine" -version = "0.1.0" -dependencies = [ - "async-trait", -] - -[[package]] -name = "mm2_test_helpers" -version = "0.1.0" -dependencies = [ - "bytes 1.7.2", - "cfg-if 1.0.0", - "chrono", - "common", - "crypto", - "db_common", - "futures 0.3.30", - "gstuff", - "http 0.2.12", - "lazy_static", - "mm2_core", - "mm2_io", - "mm2_metrics", - "mm2_net", - "mm2_number", - "mm2_rpc", - "rand 0.7.3", - "regex", - "rpc", - "serde", - "serde_derive", - "serde_json", - "uuid", -] - -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec 1.13.2", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-conv" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-rational" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg 1.3.0", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -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" -version = "0.10.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" -dependencies = [ - "bitflags 2.6.0", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "openssl-probe" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" - -[[package]] -name = "openssl-sys" -version = "0.9.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - -[[package]] -name = "pairing_api" -version = "0.1.0" -dependencies = [ - "anyhow", - "chrono", - "hex", - "lazy_static", - "paste", - "rand 0.8.5", - "regex", - "relay_client", - "relay_rpc", - "serde", - "serde_json", - "structopt", - "thiserror", - "tokio", - "url", - "wc_common", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec 0.7.6", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version 0.2.3", - "smallvec 0.6.14", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.5.4", - "smallvec 1.13.2", - "windows-targets", -] - -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "pem" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8835c273a76a90455d7344889b0964598e3316e2a79ede8e36f16bdcf2228b8" -dependencies = [ - "base64 0.13.1", -] - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" - -[[package]] -name = "polling" -version = "3.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" -dependencies = [ - "cfg-if 1.0.0", - "concurrent-queue", - "hermit-abi 0.4.0", - "pin-project-lite", - "rustix", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "portable-atomic" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da544ee218f0d287a911e9c99a39a8c9bc8fcad3cb8db5959940044ecfc67265" - -[[package]] -name = "powerfmt" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "primitive-types" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "uint", -] - -[[package]] -name = "primitives" -version = "0.1.0" -dependencies = [ - "bitcoin_hashes", - "byteorder", - "rustc-hex", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro-error" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" -dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", - "version_check", -] - -[[package]] -name = "proc-macro-error-attr" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes 1.7.2", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "quanta" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" -dependencies = [ - "crossbeam-utils", - "libc", - "mach2", - "once_cell", - "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", - "web-sys", - "winapi", -] - -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -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", - "wasm-bindgen", - "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -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-cpuid" -version = "10.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" -dependencies = [ - "bitflags 1.3.2", -] - -[[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.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.5.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0884ad60e090bf1345b93da0a5de8923c93884cd03f40dfcfddd3b4bee661853" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "regex" -version = "1.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "relay_client" -version = "0.1.0" -dependencies = [ - "chrono", - "data-encoding", - "futures-util", - "getrandom 0.2.15", - "http 1.1.0", - "js-sys", - "pin-project", - "rand 0.7.3", - "relay_rpc", - "serde", - "serde_json", - "serde_qs", - "thiserror", - "tokio", - "tokio-tungstenite-wasm", - "tokio-util", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "relay_rpc" -version = "0.1.0" -dependencies = [ - "anyhow", - "bs58", - "chrono", - "data-encoding", - "derive_more", - "ed25519-dalek", - "hex", - "jsonwebtoken", - "once_cell", - "paste", - "rand 0.8.5", - "regex", - "serde", - "serde-aux", - "serde_json", - "sha2 0.10.8", - "strum", - "thiserror", - "url", -] - -[[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]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if 1.0.0", - "getrandom 0.2.15", - "libc", - "spin 0.9.8", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes 1.7.2", - "rustc-hex", -] - -[[package]] -name = "rpc" -version = "0.1.0" -dependencies = [ - "chain", - "keys", - "log", - "primitives", - "rustc-hex", - "script", - "serde", - "serde_derive", - "serde_json", - "serialization", -] - -[[package]] -name = "rpc_task" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.30", - "mm2_err_handle", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", -] - -[[package]] -name = "rusb" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" -dependencies = [ - "libc", - "libusb1-sys", -] - -[[package]] -name = "rusqlite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec 1.13.2", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver 1.0.23", -] - -[[package]] -name = "rustix" -version = "0.38.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "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 = [ - "ring 0.17.8", - "rustls-webpki", - "sct", -] - -[[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 = "rustversion" -version = "1.0.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "schannel" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" -dependencies = [ - "windows-sys 0.59.0", -] - -[[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 = "script" -version = "0.1.0" -dependencies = [ - "bitcrypto", - "blake2b_simd", - "chain", - "keys", - "log", - "primitives", - "serde", - "serialization", -] - -[[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 = "secp256k1" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" -dependencies = [ - "rand 0.6.5", - "secp256k1-sys 0.4.2", -] - -[[package]] -name = "secp256k1" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" -dependencies = [ - "bitcoin_hashes", - "secp256k1-sys 0.6.1", -] - -[[package]] -name = "secp256k1-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" -dependencies = [ - "cc", -] - -[[package]] -name = "secp256k1-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" -dependencies = [ - "cc", -] - -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.6.0", - "core-foundation", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - -[[package]] -name = "security-framework-sys" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "ser_error" -version = "0.1.0" -dependencies = [ - "serde", -] - -[[package]] -name = "ser_error_derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "ser_error", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-aux" -version = "4.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d2e8bfba469d06512e11e3311d4d051a4a387a5b42d010404fecf3200321c95" -dependencies = [ - "serde", - "serde_json", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "serde_json" -version = "1.0.128" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "indexmap 2.5.0", - "itoa 1.0.11", - "memchr", - "ryu", - "serde", -] - -[[package]] -name = "serde_qs" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cac3f1e2ca2fe333923a1ae72caca910b98ed0630bb35ef6f8c8517d6e81afa" -dependencies = [ - "percent-encoding", - "serde", - "thiserror", -] - -[[package]] -name = "serde_repr" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "serialization" -version = "0.1.0" -dependencies = [ - "byteorder", - "derive_more", - "primitives", - "test_helpers", -] - -[[package]] -name = "serialization_derive" -version = "0.1.0" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "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 1.0.0", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shared_ref_counter" -version = "0.1.0" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "simple_asn1" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085" -dependencies = [ - "num-bigint", - "num-traits", - "thiserror", - "time", -] - -[[package]] -name = "siphasher" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" - -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg 1.3.0", -] - -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "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.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "sql-builder" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" -dependencies = [ - "anyhow", - "thiserror", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "structopt" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6b5c64445ba8094a6ab0c3cd2ad323e07171012d9c98b0b15651daf1787a10" -dependencies = [ - "clap", - "lazy_static", - "structopt-derive", -] - -[[package]] -name = "structopt-derive" -version = "0.4.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcb5ae327f9cc13b68763b5749770cb9e048a99bd9dfdfa58d0cf05d5f64afe0" -dependencies = [ - "heck 0.3.3", - "proc-macro-error", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "strum" -version = "0.26.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" -dependencies = [ - "strum_macros", -] - -[[package]] -name = "strum_macros" -version = "0.26.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote 1.0.37", - "rustversion", - "syn 2.0.77", -] - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "tempfile" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" -dependencies = [ - "cfg-if 1.0.0", - "fastrand", - "once_cell", - "rustix", - "windows-sys 0.59.0", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test_helpers" -version = "0.1.0" -dependencies = [ - "hex", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "thiserror" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.63" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "time" -version = "0.3.36" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" -dependencies = [ - "deranged", - "itoa 1.0.11", - "num-conv", - "powerfmt", - "serde", - "time-core", - "time-macros", -] - -[[package]] -name = "time-core" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" - -[[package]] -name = "time-macros" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" -dependencies = [ - "num-conv", - "time-core", -] - -[[package]] -name = "tiny-keccak" -version = "1.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" -dependencies = [ - "backtrace", - "bytes 1.7.2", - "libc", - "mio", - "pin-project-lite", - "signal-hook-registry", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-buf" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-tungstenite" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e80b39df6afcc12cdf752398ade96a6b9e99c903dfdc36e53ad10b9c366bca72" -dependencies = [ - "futures-util", - "log", - "native-tls", - "tokio", - "tokio-native-tls", - "tungstenite", -] - -[[package]] -name = "tokio-tungstenite-wasm" -version = "0.1.1-alpha.0" -source = "git+https://github.com/KomodoPlatform/tokio-tungstenite-wasm.git?rev=8fc7e2f#8fc7e2ff4c970bee0c0867399cb9a941881ea183" -dependencies = [ - "futures-channel", - "futures-util", - "http 0.2.12", - "httparse", - "js-sys", - "thiserror", - "tokio", - "tokio-tungstenite", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "tokio-util" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" -dependencies = [ - "bytes 1.7.2", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.22.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b072cee73c449a636ffd6f32bd8de3a9f7119139aff882f44943ce2986dc5cf" -dependencies = [ - "indexmap 2.5.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "base64 0.21.7", - "bytes 1.7.2", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "percent-encoding", - "pin-project", - "prost", - "tokio-stream", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "trezor" -version = "0.1.1" -dependencies = [ - "async-std", - "async-trait", - "bip32", - "byteorder", - "common", - "derive_more", - "ethcore-transaction", - "ethereum-types", - "ethkey", - "futures 0.3.30", - "hw_common", - "js-sys", - "lazy_static", - "mm2_err_handle", - "prost", - "rand 0.7.3", - "rpc_task", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "tungstenite" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ad3713a14ae247f22a728a0456a545df14acf3867f905adff84be99e23b3ad1" -dependencies = [ - "base64 0.13.1", - "byteorder", - "bytes 1.7.2", - "http 0.2.12", - "httparse", - "log", - "native-tls", - "rand 0.8.5", - "sha-1", - "thiserror", - "url", - "utf-8", -] - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unexpected" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-segmentation" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" - -[[package]] -name = "unicode-width" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna 0.5.0", - "percent-encoding", -] - -[[package]] -name = "utf-8" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" - -[[package]] -name = "uuid" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" -dependencies = [ - "getrandom 0.2.15", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "value-bag" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote 1.0.37", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "wasm-bindgen-test" -version = "0.3.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68497a05fb21143a08a7d24fc81763384a3072ee43c44e86aad1744d6adef9d9" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "minicov", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "wc_common" -version = "0.1.0" -dependencies = [ - "base64 0.21.7", - "chacha20poly1305", - "thiserror", -] - -[[package]] -name = "web-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web3" -version = "0.19.0" -source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" -dependencies = [ - "arrayvec 0.7.6", - "derive_more", - "ethabi", - "ethereum-types", - "futures 0.3.30", - "futures-timer", - "getrandom 0.2.15", - "hex", - "idna 0.2.3", - "js-sys", - "jsonrpc-core", - "log", - "parking_lot", - "pin-project", - "rand 0.8.5", - "rlp", - "serde", - "serde-wasm-bindgen", - "serde_json", - "tiny-keccak 2.0.2", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.6.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" -dependencies = [ - "memchr", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "x25519-dalek" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" -dependencies = [ - "curve25519-dalek", - "rand_core 0.6.4", - "serde", - "zeroize", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -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 1.0.37", - "syn 2.0.77", -] From d7b5a17180560ac7c54be15850232f79370edd6d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 23 Sep 2024 09:38:43 +0100 Subject: [PATCH 027/125] fix tendermint pubkey derivation from walletconnect --- Cargo.lock | 1 + .../src/tendermint_with_assets_activation.rs | 2 +- mm2src/kdf_walletconnect/Cargo.toml | 1 + mm2src/kdf_walletconnect/src/chain/cosmos.rs | 13 +++++++++++-- mm2src/kdf_walletconnect/src/lib.rs | 1 - 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9acd166d20..4736c261e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3552,6 +3552,7 @@ name = "kdf_walletconnect" version = "0.1.0" dependencies = [ "async-trait", + "base64 0.21.7", "chrono", "common", "derive_more", diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 554b7bc877..c15e6cad0d 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -251,7 +251,7 @@ async fn get_walletconnect_pubkey( })?; let pubkey = match account.algo { - CosmosAccountAlgo::Secp256k1 => { + CosmosAccountAlgo::Secp256k1 | CosmosAccountAlgo::TendermintSecp256k1 => { TendermintPublicKey::from_raw_secp256k1(&account.pubkey).ok_or("Invalid secp256k1 pubkey".to_owned()) }, } diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index d83ce583ed..b8f5bd9a29 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] async-trait = "0.1.52" +base64 = "0.21.2" chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } derive_more = "0.99" diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs index 27c742e06f..9bd944c941 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -1,4 +1,5 @@ use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use base64::{engine::general_purpose, Engine}; use chrono::Utc; use common::log::info; use futures::StreamExt; @@ -11,9 +12,11 @@ use serde_json::Value; use super::WcRequestMethods; #[derive(Serialize, Deserialize, Debug, Clone)] -#[serde(rename_all = "lowercase")] pub enum CosmosAccountAlgo { + #[serde(rename = "lowercase")] Secp256k1, + #[serde(rename = "tendermint/PubKeySecp256k1")] + TendermintSecp256k1, } #[derive(Debug, Clone, Serialize, Deserialize)] @@ -54,7 +57,13 @@ where .map(|n| n as u8) }) .collect(), - _ => Err(serde::de::Error::custom("Pubkey must be an object or array")), + Value::String(data) => { + let data = general_purpose::STANDARD + .decode(data) + .map_err(|err| serde::de::Error::custom(err.to_string()))?; + Ok(data) + }, + _ => Err(serde::de::Error::custom("Pubkey must be an string, object or array")), } } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d7f1291fa9..0ddb8900ea 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -6,7 +6,6 @@ mod metadata; #[allow(unused)] mod pairing; mod session; -use async_trait::async_trait; use chain::{build_required_namespaces, cosmos::{cosmos_get_accounts_impl, CosmosAccount}, SUPPORTED_CHAINS}; From 3a85a174e87117a3a78c6c0624dd92fbdb47f05b Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 23 Sep 2024 12:36:50 +0100 Subject: [PATCH 028/125] start persistent session storage implementation --- Cargo.lock | 1 + mm2src/kdf_walletconnect/Cargo.toml | 1 + mm2src/kdf_walletconnect/src/lib.rs | 1 + mm2src/kdf_walletconnect/src/storage/mod.rs | 26 +++++++++++++++++++ .../kdf_walletconnect/src/storage/sqlite.rs | 10 +++++++ mm2src/kdf_walletconnect/src/storage/wasm.rs | 0 6 files changed, 39 insertions(+) create mode 100644 mm2src/kdf_walletconnect/src/storage/mod.rs create mode 100644 mm2src/kdf_walletconnect/src/storage/sqlite.rs create mode 100644 mm2src/kdf_walletconnect/src/storage/wasm.rs diff --git a/Cargo.lock b/Cargo.lock index 4736c261e7..70b45b19cb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3555,6 +3555,7 @@ dependencies = [ "base64 0.21.7", "chrono", "common", + "db_common", "derive_more", "enum_derives", "futures 0.3.28", diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index b8f5bd9a29..3c15f941e0 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -8,6 +8,7 @@ async-trait = "0.1.52" base64 = "0.21.2" chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } +db_common = { path = "../db_common" } derive_more = "0.99" enum_derives = { path = "../derives/enum_derives" } futures = { version = "0.3", package = "futures", features = [ diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 0ddb8900ea..5984bee4b0 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -5,6 +5,7 @@ mod inbound_message; mod metadata; #[allow(unused)] mod pairing; mod session; +mod storage; use chain::{build_required_namespaces, cosmos::{cosmos_get_accounts_impl, CosmosAccount}, diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs new file mode 100644 index 0000000000..bf4c603af2 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -0,0 +1,26 @@ +use async_trait::async_trait; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces}; + +use crate::session::Session; + +pub(crate) mod sqlite; +pub(crate) mod wasm; + +pub(crate) const SESSION_STORAGE_TABLE_NAME: &str = "kdf_wc_session_storage"; + +#[derive(Debug, thiserror::Error)] +pub(crate) enum WalletConnectStorageError { + #[error("Table Error: {0}")] + TableError(String), +} + +#[async_trait] +pub(crate) trait WalletConnectStorageOps { + fn init(&self) -> MmResult<(), WalletConnectStorageError>; + fn save_session(&self, session: &Session) -> MmResult<(), WalletConnectStorageError>; + fn get_all_sessions(&self) -> MmResult, WalletConnectStorageError>; + fn delete_session(&self, topic: &Topic) -> MmResult<(), WalletConnectStorageError>; + fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), WalletConnectStorageError>; + fn update_expiry(&self, expiry: u64) -> MmResult<(), WalletConnectStorageError>; +} diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs new file mode 100644 index 0000000000..fd0951fd69 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -0,0 +1,10 @@ +use db_common::sqlite::validate_table_name; +use mm2_err_handle::prelude::MmResult; + +use super::{WalletConnectStorageError, SESSION_STORAGE_TABLE_NAME}; + +fn validate_sql_table_name() -> MmResult { + validate_table_name(SESSION_STORAGE_TABLE_NAME) + .map_err(|err| WalletConnectStorageError::TableError(err.to_string()))?; + Ok(SESSION_STORAGE_TABLE_NAME.to_owned()) +} diff --git a/mm2src/kdf_walletconnect/src/storage/wasm.rs b/mm2src/kdf_walletconnect/src/storage/wasm.rs new file mode 100644 index 0000000000..e69de29bb2 From be98c407a61f512100bebe00f21fdb73a07d4561 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 24 Sep 2024 09:43:54 +0100 Subject: [PATCH 029/125] implement sqlite session storage table and insert session method --- mm2src/db_common/src/async_sql_conn.rs | 4 + mm2src/kdf_walletconnect/src/error.rs | 8 +- mm2src/kdf_walletconnect/src/session.rs | 9 ++ mm2src/kdf_walletconnect/src/storage/mod.rs | 22 ++- .../kdf_walletconnect/src/storage/sqlite.rs | 125 +++++++++++++++++- mm2src/kdf_walletconnect/src/storage/wasm.rs | 1 + 6 files changed, 144 insertions(+), 25 deletions(-) diff --git a/mm2src/db_common/src/async_sql_conn.rs b/mm2src/db_common/src/async_sql_conn.rs index 78357405a1..f9e8747fd7 100644 --- a/mm2src/db_common/src/async_sql_conn.rs +++ b/mm2src/db_common/src/async_sql_conn.rs @@ -43,6 +43,10 @@ impl std::error::Error for AsyncConnError { } } +impl From for AsyncConnError { + fn from(err: String) -> Self { Self::Internal(InternalError(err)) } +} + #[derive(Debug)] pub struct InternalError(pub String); diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 4d9a826005..f996967a2c 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -75,15 +75,11 @@ pub enum WalletConnectCtxError { } impl From> for WalletConnectCtxError { - fn from(error: Error) -> Self { - WalletConnectCtxError::PublishError(format!("{error:?}")) - } + fn from(error: Error) -> Self { WalletConnectCtxError::PublishError(format!("{error:?}")) } } impl From> for WalletConnectCtxError { - fn from(error: Error) -> Self { - WalletConnectCtxError::SubscriptionError(format!("{error:?}")) - } + fn from(error: Error) -> Self { WalletConnectCtxError::SubscriptionError(format!("{error:?}")) } } /// Session key and topic derivation errors. diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 2444791394..0f65cd05f8 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -118,6 +118,15 @@ pub enum SessionType { Proposer, } +impl ToString for SessionType { + fn to_string(&self) -> String { + match self { + Self::Controller => "Controller".to_string(), + Self::Proposer => "Proposer".to_string(), + } + } +} + /// This struct is typically used in the core session management logic of a WalletConnect /// implementation. It's used to store, retrieve, and update session information throughout /// the lifecycle of a WalletConnect connection. diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index bf4c603af2..4a9c0ccf82 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::*; use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces}; use crate::session::Session; @@ -9,18 +10,15 @@ pub(crate) mod wasm; pub(crate) const SESSION_STORAGE_TABLE_NAME: &str = "kdf_wc_session_storage"; -#[derive(Debug, thiserror::Error)] -pub(crate) enum WalletConnectStorageError { - #[error("Table Error: {0}")] - TableError(String), -} - #[async_trait] pub(crate) trait WalletConnectStorageOps { - fn init(&self) -> MmResult<(), WalletConnectStorageError>; - fn save_session(&self, session: &Session) -> MmResult<(), WalletConnectStorageError>; - fn get_all_sessions(&self) -> MmResult, WalletConnectStorageError>; - fn delete_session(&self, topic: &Topic) -> MmResult<(), WalletConnectStorageError>; - fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), WalletConnectStorageError>; - fn update_expiry(&self, expiry: u64) -> MmResult<(), WalletConnectStorageError>; + type Error: std::fmt::Debug + NotMmError + NotEqual + Send; + + async fn init(&self) -> MmResult<(), Self::Error>; + async fn is_initialized(&self) -> MmResult; + async fn save_session(&self, session: Session) -> MmResult<(), Self::Error>; + async fn get_sessions(&self) -> MmResult, Self::Error>; + async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error>; + async fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), Self::Error>; + async fn update_expiry(&self, expiry: u64) -> MmResult<(), Self::Error>; } diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index fd0951fd69..01ac12acd9 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -1,10 +1,121 @@ -use db_common::sqlite::validate_table_name; -use mm2_err_handle::prelude::MmResult; +use async_trait::async_trait; +use db_common::sqlite::rusqlite::{Connection, Result as SqlResult}; +use db_common::sqlite::{query_single_row, string_from_row, CHECK_TABLE_EXISTS_SQL}; +use db_common::{async_sql_conn::{AsyncConnError, AsyncConnection}, + sqlite::validate_table_name}; +use futures::lock::{Mutex, MutexGuard}; +use mm2_err_handle::prelude::*; +use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces}; +use std::sync::Arc; -use super::{WalletConnectStorageError, SESSION_STORAGE_TABLE_NAME}; +use super::WalletConnectStorageOps; +use crate::session::Session; -fn validate_sql_table_name() -> MmResult { - validate_table_name(SESSION_STORAGE_TABLE_NAME) - .map_err(|err| WalletConnectStorageError::TableError(err.to_string()))?; - Ok(SESSION_STORAGE_TABLE_NAME.to_owned()) +const SESSION_TBALE_NAME: &str = "session"; + +/// Sessions table +fn create_sessions_table() -> SqlResult { + validate_table_name(SESSION_TBALE_NAME)?; + Ok(format!( + "CREATE TABLE IF NOT EXISTS {SESSION_TBALE_NAME} ( + topic VARCHAR(255) PRIMARY KEY, + subscription_id VARCHAR(255) NOT NULL, + session_key TEXT NOT NULL, + expiry BIGINT NOT NULL, + pairing_topic VARCHAR(255) NOT NULL, + session_type VARCHAR(50) NOT NULL, + proposer TEXT NOT NULL, + controller TEXT NOT NULL, + relay TEXT NOT NULL, + namespaces TEXT, + proposed_namespace TEXT + );" + )) +} + +#[derive(Clone, Debug)] +pub struct SqliteSessionStorage { + pub conn: Arc>, +} + +#[async_trait] +impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { + type Error = AsyncConnError; + + async fn init(&self) -> MmResult<(), Self::Error> { + self.call(move |conn| { + conn.execute(&create_sessions_table()?, []).map(|_| ())?; + Ok(()) + }) + .await + .map_to_mm(AsyncConnError::from) + } + + async fn is_initialized(&self) -> MmResult { + validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?; + self.call(move |conn| { + let initialized = query_single_row(conn, CHECK_TABLE_EXISTS_SQL, [SESSION_TBALE_NAME], string_from_row)?; + Ok(initialized.is_some()) + }) + .await + .map_to_mm(AsyncConnError::from) + } + + async fn save_session(&self, session: Session) -> MmResult<(), Self::Error> { + validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?; + let sql = format!( + "INSERT INTO {} ( + topic, subscription_id, session_key, expiry, pairing_topic, session_type, proposer, controller, relay, namespace, propose_namespaces + ) VALUES ( + ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11 + );", + SESSION_TBALE_NAME + ); + + self.call(move |conn| { + let transaction = conn.transaction()?; + + let session_key = + serde_json::to_string(&session.session_key).map_err(|err| AsyncConnError::from(err.to_string()))?; + let relay = serde_json::to_string(&session.relay).map_err(|err| AsyncConnError::from(err.to_string()))?; + let proposer = + serde_json::to_string(&session.proposer).map_err(|err| AsyncConnError::from(err.to_string()))?; + let controller = + serde_json::to_string(&session.controller).map_err(|err| AsyncConnError::from(err.to_string()))?; + let namespaces = + serde_json::to_string(&session.namespaces).map_err(|err| AsyncConnError::from(err.to_string()))?; + let propose_namespaces = serde_json::to_string(&session.propose_namespaces) + .map_err(|err| AsyncConnError::from(err.to_string()))?; + + let params = [ + session.topic.to_string(), + session.subscription_id.to_string(), + session_key, + session.expiry.to_string(), + session.pairing_topic.to_string(), + session.session_type.to_string(), + proposer, + controller, + relay, + namespaces, + propose_namespaces, + ]; + transaction.execute(&sql, params)?; + transaction.commit()?; + + Ok(()) + }) + .await + .map_to_mm(AsyncConnError::from) + } + + async fn get_sessions(&self) -> MmResult, Self::Error> { todo!() } + + async fn update_expiry(&self, expiry: u64) -> MmResult<(), Self::Error> { todo!() } + + async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { todo!() } + + async fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), Self::Error> { + todo!() + } } diff --git a/mm2src/kdf_walletconnect/src/storage/wasm.rs b/mm2src/kdf_walletconnect/src/storage/wasm.rs index e69de29bb2..8b13789179 100644 --- a/mm2src/kdf_walletconnect/src/storage/wasm.rs +++ b/mm2src/kdf_walletconnect/src/storage/wasm.rs @@ -0,0 +1 @@ + From 6453a33234e38065b1b85c68a283064a38f9200c Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 25 Sep 2024 07:55:51 +0100 Subject: [PATCH 030/125] fix cyclic deps and continue storage implementations --- Cargo.lock | 4 ++- .../src/tendermint_with_assets_activation.rs | 6 +++-- mm2src/kdf_walletconnect/Cargo.toml | 4 +++ mm2src/kdf_walletconnect/src/chain/cosmos.rs | 2 +- mm2src/kdf_walletconnect/src/error.rs | 2 ++ mm2src/kdf_walletconnect/src/lib.rs | 11 ++++---- mm2src/kdf_walletconnect/src/session.rs | 15 ++++++----- mm2src/kdf_walletconnect/src/storage/mod.rs | 4 +-- .../kdf_walletconnect/src/storage/sqlite.rs | 6 ++--- mm2src/kdf_walletconnect/src/storage/wasm.rs | 27 +++++++++++++++++++ mm2src/mm2_core/Cargo.toml | 1 - mm2src/mm2_core/src/mm_ctx.rs | 5 ++-- mm2src/mm2_main/Cargo.toml | 1 + mm2src/mm2_main/src/lp_native_dex.rs | 9 ++++--- .../src/rpc/lp_commands/lp_commands.rs | 11 +++++--- 15 files changed, 76 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70b45b19cb..28ed4208d2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3561,6 +3561,8 @@ dependencies = [ "futures 0.3.28", "hex", "hkdf", + "mm2_core", + "mm2_db", "mm2_err_handle", "pairing_api", "rand 0.8.4", @@ -4494,7 +4496,6 @@ dependencies = [ "gstuff", "hex", "instant", - "kdf_walletconnect", "lazy_static", "mm2_err_handle", "mm2_event_stream", @@ -4675,6 +4676,7 @@ dependencies = [ "instant", "itertools", "js-sys", + "kdf_walletconnect", "keys", "lazy_static", "libc", diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index c15e6cad0d..54134daae5 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -19,6 +19,7 @@ use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, MmCoinEnum, PrivKe use common::executor::{AbortSettings, SpawnAbortable}; use common::{true_f, Future01CompatExt}; use kdf_walletconnect::chain::cosmos::CosmosAccountAlgo; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; @@ -241,8 +242,9 @@ async fn get_walletconnect_pubkey( }); }; - let account = ctx - .wallect_connect + let walletconnect_ctx = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + + let account = walletconnect_ctx .cosmos_get_account(param.account_index, "cosmos", chain_id) .await .mm_err(|err| TendermintInitError { diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 3c15f941e0..b73e75c2c2 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -17,6 +17,8 @@ futures = { version = "0.3", package = "futures", features = [ ] } hex = "0.4.2" hkdf = "0.12.4" +mm2_core = { path = "../mm2_core" } +mm2_db = { path = "../mm2_db" } mm2_err_handle = { path = "../mm2_err_handle" } pairing_api = { path = "../../../kdf-wc/pairing_api" } rand = "0.8" @@ -30,3 +32,5 @@ serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } x25519-dalek = { version = "2.0", features = ["static_secrets"] } +[target.'cfg(target_arch = "wasm32")'.dependencies] +mm2_db = { path = "../mm2_db" } diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs index 9bd944c941..cc8ca0b1c5 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -13,7 +13,7 @@ use super::WcRequestMethods; #[derive(Serialize, Deserialize, Debug, Clone)] pub enum CosmosAccountAlgo { - #[serde(rename = "lowercase")] + #[serde(rename = "secp256k")] Secp256k1, #[serde(rename = "tendermint/PubKeySecp256k1")] TendermintSecp256k1, diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index f996967a2c..c73146e05d 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -72,6 +72,8 @@ pub enum WalletConnectCtxError { NoAccountFoundForIndex(u8), #[error("Empty account approved for chain_id: {0}")] EmptyAccount(String), + #[error("WalletConnect is not initaliazed yet!")] + NotInitialized, } impl From> for WalletConnectCtxError { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 5984bee4b0..931d5e9c4a 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -19,6 +19,7 @@ use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, use handler::Handler; use inbound_message::{process_inbound_request, process_inbound_response}; use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; +use mm2_core::mm_ctx::{from_ctx, MmArc}; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; use pairing_api::PairingClient; @@ -59,12 +60,8 @@ pub struct WalletConnectCtx { session_request_handler: Arc>>, } -impl Default for WalletConnectCtx { - fn default() -> Self { Self::new() } -} - impl WalletConnectCtx { - pub fn new() -> Self { + pub fn init() -> Self { let (msg_sender, msg_receiver) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); let (session_request_sender, session_request_receiver) = unbounded(); @@ -96,6 +93,10 @@ impl WalletConnectCtx { } } + pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectCtxError> { + from_ctx(&ctx.wallet_connect, move || Ok(Self::init())).map_to_mm(WalletConnectCtxError::InternalError) + } + pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { let auth = { let key = SigningKey::generate(&mut rand::thread_rng()); diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 0f65cd05f8..9d6d5269ec 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -16,6 +16,7 @@ use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::IrnMetadata; use relay_rpc::{domain::{SubscriptionId, Topic}, rpc::params::{session::ProposeNamespaces, session_settle::Controller, Metadata, Relay}}; +use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::BTreeMap; use x25519_dalek::{SharedSecret, StaticSecret}; @@ -30,10 +31,10 @@ pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; -#[derive(Clone)] +#[derive(Clone, Serialize, Deserialize)] pub struct SessionKey { sym_key: [u8; 32], - public_key: PublicKey, + public_key: [u8; 32], } impl std::fmt::Debug for SessionKey { @@ -50,7 +51,7 @@ impl SessionKey { pub fn new(public_key: PublicKey) -> Self { Self { sym_key: [0u8; 32], - public_key, + public_key: public_key.to_bytes(), } } @@ -69,7 +70,7 @@ impl SessionKey { let mut session_key = Self { sym_key: [0u8; 32], - public_key, + public_key: public_key.to_bytes(), }; session_key.derive_symmetric_key(&shared_secret)?; @@ -97,7 +98,7 @@ impl SessionKey { pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } /// Gets "our" public key used in symmetric key derivation. - pub fn diffie_public_key(&self) -> &[u8; 32] { self.public_key.as_bytes() } + pub fn diffie_public_key(&self) -> &[u8; 32] { &self.public_key } /// Generates new session topic. pub fn generate_topic(&self) -> String { @@ -110,7 +111,7 @@ impl SessionKey { /// In the WalletConnect protocol, a session involves two parties: a controller /// (typically a wallet) and a proposer (typically a dApp). This enum is used /// to distinguish between these two roles. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub enum SessionType { /// Represents the controlling party in a session, typically a wallet. Controller, @@ -130,7 +131,7 @@ impl ToString for SessionType { /// This struct is typically used in the core session management logic of a WalletConnect /// implementation. It's used to store, retrieve, and update session information throughout /// the lifecycle of a WalletConnect connection. -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Deserialize, Serialize)] pub struct Session { /// Session topic pub topic: Topic, diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 4a9c0ccf82..19e6442a01 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -5,8 +5,8 @@ use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces}; use crate::session::Session; -pub(crate) mod sqlite; -pub(crate) mod wasm; +#[cfg(not(target_arch = "wasm32"))] pub(crate) mod sqlite; +#[cfg(target_arch = "wasm32")] pub(crate) mod wasm; pub(crate) const SESSION_STORAGE_TABLE_NAME: &str = "kdf_wc_session_storage"; diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 01ac12acd9..761c89cb1d 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -75,8 +75,8 @@ impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { self.call(move |conn| { let transaction = conn.transaction()?; - let session_key = - serde_json::to_string(&session.session_key).map_err(|err| AsyncConnError::from(err.to_string()))?; + //let session_key = + // serde_json::to_string(&session.session_key).map_err(|err| AsyncConnError::from(err.to_string()))?; let relay = serde_json::to_string(&session.relay).map_err(|err| AsyncConnError::from(err.to_string()))?; let proposer = serde_json::to_string(&session.proposer).map_err(|err| AsyncConnError::from(err.to_string()))?; @@ -90,7 +90,7 @@ impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { let params = [ session.topic.to_string(), session.subscription_id.to_string(), - session_key, + "session_key".to_string(), session.expiry.to_string(), session.pairing_topic.to_string(), session.session_type.to_string(), diff --git a/mm2src/kdf_walletconnect/src/storage/wasm.rs b/mm2src/kdf_walletconnect/src/storage/wasm.rs index 8b13789179..b336a0f354 100644 --- a/mm2src/kdf_walletconnect/src/storage/wasm.rs +++ b/mm2src/kdf_walletconnect/src/storage/wasm.rs @@ -1 +1,28 @@ +use async_trait::async_trait; +use mm2_db::indexed_db::{DbIdentifier, DbInstance, DbLocked, IndexedDb, IndexedDbBuilder, InitDbResult}; +const DB_VERSION: u32 = 1; + +pub type SessionStorageIDBLocked<'a> = DbLocked<'a, SessionStorageIDB>; + +pub struct SessionStorageIDB { + inner: IndexedDb, +} + +#[async_trait] +impl DbInstance for SessionStorageIDB { + const DB_NAME: &'static str = "nft_cache"; + + async fn init(db_id: DbIdentifier) -> InitDbResult { + let inner = IndexedDbBuilder::new(db_id) + .with_version(DB_VERSION) + //.with_table::() + .build() + .await?; + Ok(SessionStorageIDB { inner }) + } +} + +impl SessionStorageIDB { + pub(crate) fn get_inner(&self) -> &IndexedDb { &self.inner } +} diff --git a/mm2src/mm2_core/Cargo.toml b/mm2src/mm2_core/Cargo.toml index 47c9d4270f..9c5c362a93 100644 --- a/mm2src/mm2_core/Cargo.toml +++ b/mm2src/mm2_core/Cargo.toml @@ -16,7 +16,6 @@ db_common = { path = "../db_common" } derive_more = "0.99" futures = { version = "0.3", package = "futures", features = ["compat", "async-await", "thread-pool"] } hex = "0.4.2" -kdf_walletconnect = { path = "../kdf_walletconnect" } lazy_static = "1.4" mm2_err_handle = { path = "../mm2_err_handle" } mm2_event_stream = { path = "../mm2_event_stream" } diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs index acbb4355e9..145ead33c2 100644 --- a/mm2src/mm2_core/src/mm_ctx.rs +++ b/mm2src/mm2_core/src/mm_ctx.rs @@ -5,7 +5,6 @@ use common::executor::{abortable_queue::{AbortableQueue, WeakSpawner}, use common::log::{self, LogLevel, LogOnError, LogState}; use common::{cfg_native, cfg_wasm32, small_rng}; use gstuff::{try_s, Constructible, ERR, ERRL}; -use kdf_walletconnect::WalletConnectCtx; use lazy_static::lazy_static; use mm2_event_stream::{controller::Controller, Event, EventStreamConfiguration}; use mm2_metrics::{MetricsArc, MetricsOps}; @@ -143,7 +142,7 @@ pub struct MmCtx { /// asynchronous handle for rusqlite connection. #[cfg(not(target_arch = "wasm32"))] pub async_sqlite_connection: Constructible>>, - pub wallect_connect: Arc, + pub wallet_connect: Mutex>>, } impl MmCtx { @@ -193,7 +192,7 @@ impl MmCtx { nft_ctx: Mutex::new(None), #[cfg(not(target_arch = "wasm32"))] async_sqlite_connection: Constructible::default(), - wallect_connect: Arc::new(WalletConnectCtx::default()), + wallet_connect: Mutex::new(None), } } diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index 9cf79be15d..e51d12123a 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -64,6 +64,7 @@ http = "0.2" hw_common = { path = "../hw_common" } instant = { version = "0.1.12" } itertools = "0.10" +kdf_walletconnect = { path = "../kdf_walletconnect" } keys = { path = "../mm2_bitcoin/keys" } lazy_static = "1.4" # ledger = { path = "../ledger" } diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index cb2d5e91e4..08fdaa9e46 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -25,6 +25,7 @@ use common::log::{info, warn}; use crypto::{from_hw_error, CryptoCtx, HwError, HwProcessingError, HwRpcError, WithHwRpcError}; use derive_more::Display; use enum_derives::EnumFromTrait; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::{MmArc, MmCtx}; use mm2_err_handle::common_errors::InternalError; use mm2_err_handle::prelude::*; @@ -473,14 +474,16 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { init_message_service(&ctx).await?; // connect walletconnect - ctx.wallect_connect + let wallet_connect = + WalletConnectCtx::from_ctx(&ctx).map_err(|err| MmInitError::WalletInitError(err.to_string()))?; + wallet_connect .connect_client() .await .map_err(|err| MmInitError::WalletInitError(err.to_string()))?; ctx.spawner() - .spawn(ctx.wallect_connect.clone().published_message_event_loop()); + .spawn(wallet_connect.clone().published_message_event_loop()); ctx.spawner() - .spawn(ctx.wallect_connect.clone().spawn_connection_live_watcher()); + .spawn(wallet_connect.clone().spawn_connection_live_watcher()); let balance_update_ordermatch_handler = BalanceUpdateOrdermatchHandler::new(ctx.clone()); register_balance_update_handler(ctx.clone(), Box::new(balance_update_ordermatch_handler)).await; diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs index d9628f38df..d76ceb6013 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs @@ -2,6 +2,7 @@ use common::HttpStatusCode; use crypto::{CryptoCtx, CryptoCtxError, HwConnectionStatus, HwPubkey}; use derive_more::Display; use http::StatusCode; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use rpc::v1::types::H160 as H160Json; @@ -133,8 +134,9 @@ pub async fn connect_to_peer( ctx: MmArc, req: ConnectPairingRequest, ) -> MmResult { - let topic = ctx - .wallect_connect + let walletconnect_ctx = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + + let topic = walletconnect_ctx .connect_to_pairing(&req.url, true) .await .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; @@ -157,8 +159,9 @@ pub async fn create_new_pairing( ctx: MmArc, _req: CreatePairingRequest, ) -> MmResult { - let url = ctx - .wallect_connect + let walletconnect_ctx = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + + let url = walletconnect_ctx .create_pairing(None) .await .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; From 9f87a9e913b27f2ef40d3fd41414e149588c970d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 03:51:56 +0100 Subject: [PATCH 031/125] implement WASM persistent storage --- Cargo.lock | 6 + mm2src/kdf_walletconnect/Cargo.toml | 12 + mm2src/kdf_walletconnect/src/chain/cosmos.rs | 2 +- mm2src/kdf_walletconnect/src/error.rs | 82 + mm2src/kdf_walletconnect/src/lib.rs | 19 +- mm2src/kdf_walletconnect/src/session.rs | 10 +- .../kdf_walletconnect/src/session/propose.rs | 2 + .../src/storage/indexed_db.rs | 106 + mm2src/kdf_walletconnect/src/storage/mod.rs | 86 +- .../kdf_walletconnect/src/storage/sqlite.rs | 40 +- mm2src/kdf_walletconnect/src/storage/wasm.rs | 28 - mm2src/mm2_net/Cargo.toml | 6 +- mm2src/mm2_test_helpers/Cargo.lock | 4107 +++++++++++++++++ mm2src/mm2_test_helpers/src/for_tests.rs | 3 + 14 files changed, 4446 insertions(+), 63 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/storage/indexed_db.rs delete mode 100644 mm2src/kdf_walletconnect/src/storage/wasm.rs create mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index 28ed4208d2..5a5079313b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3553,6 +3553,7 @@ version = "0.1.0" dependencies = [ "async-trait", "base64 0.21.7", + "cfg-if 1.0.0", "chrono", "common", "db_common", @@ -3564,6 +3565,7 @@ dependencies = [ "mm2_core", "mm2_db", "mm2_err_handle", + "mm2_test_helpers", "pairing_api", "rand 0.8.4", "relay_client", @@ -3573,7 +3575,11 @@ dependencies = [ "serde_json", "sha2 0.10.8", "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", "wc_common", + "web-sys", "x25519-dalek 2.0.1", ] diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index b73e75c2c2..23e8f02486 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -8,6 +8,7 @@ async-trait = "0.1.52" base64 = "0.21.2" chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } +cfg-if = "1.0" db_common = { path = "../db_common" } derive_more = "0.99" enum_derives = { path = "../derives/enum_derives" } @@ -34,3 +35,14 @@ x25519-dalek = { version = "2.0", features = ["static_secrets"] } [target.'cfg(target_arch = "wasm32")'.dependencies] mm2_db = { path = "../mm2_db" } +mm2_test_helpers = { path = "../mm2_test_helpers" } +wasm-bindgen = "0.2.86" +wasm-bindgen-test = { version = "0.3.2" } +wasm-bindgen-futures = "0.4.21" +web-sys = { version = "0.3.55", features = ["console", "CloseEvent", "DomException", "ErrorEvent", "IdbDatabase", + "IdbCursor", "IdbCursorWithValue", "IdbFactory", "IdbIndex", "IdbIndexParameters", "IdbObjectStore", + "IdbObjectStoreParameters", "IdbOpenDbRequest", "IdbKeyRange", "IdbTransaction", "IdbTransactionMode", + "IdbVersionChangeEvent", "MessageEvent", "MessagePort", "ReadableStreamDefaultReader", "ReadableStream"]} + +[dev-dependencies] +mm2_test_helpers = { path = "../mm2_test_helpers" } diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs index cc8ca0b1c5..356764aa40 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -13,7 +13,7 @@ use super::WcRequestMethods; #[derive(Serialize, Deserialize, Debug, Clone)] pub enum CosmosAccountAlgo { - #[serde(rename = "secp256k")] + #[serde(rename = "secp256k1")] Secp256k1, #[serde(rename = "tendermint/PubKeySecp256k1")] TendermintSecp256k1, diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index c73146e05d..aae333f737 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -1,4 +1,8 @@ use enum_derives::EnumFromStringify; +#[cfg(target_arch = "wasm32")] +use mm2_db::indexed_db::cursor_prelude::*; +#[cfg(target_arch = "wasm32")] +use mm2_db::indexed_db::{DbTransactionError, InitDbError}; use pairing_api::PairingClientError; use relay_client::error::{ClientError, Error}; use relay_rpc::rpc::{PublishError, SubscriptionError}; @@ -74,6 +78,8 @@ pub enum WalletConnectCtxError { EmptyAccount(String), #[error("WalletConnect is not initaliazed yet!")] NotInitialized, + #[error("Storage Error: {0}")] + StorageError(String), } impl From> for WalletConnectCtxError { @@ -90,3 +96,79 @@ pub enum SessionError { #[error("Failed to generate symmetric session key: {0}")] SymKeyGeneration(String), } + +#[cfg(target_arch = "wasm32")] +#[derive(Debug, Clone, thiserror::Error)] +pub enum WcIndexedDbError { + #[error("Internal Error: {0}")] + InternalError(String), + #[error("Not supported: {0}")] + NotSupported(String), + #[error("Delete Error: {0}")] + DeletionError(String), + #[error("Insert Error: {0}")] + AddToStorageErr(String), + #[error("GetFromStorage Error: {0}")] + GetFromStorageError(String), + #[error("Decoding Error: {0}")] + DecodingError(String), +} + +#[cfg(target_arch = "wasm32")] +impl From for WcIndexedDbError { + fn from(e: InitDbError) -> Self { + match &e { + InitDbError::NotSupported(_) => WcIndexedDbError::NotSupported(e.to_string()), + InitDbError::EmptyTableList + | InitDbError::DbIsOpenAlready { .. } + | InitDbError::InvalidVersion(_) + | InitDbError::OpeningError(_) + | InitDbError::TypeMismatch { .. } + | InitDbError::UnexpectedState(_) + | InitDbError::UpgradingError { .. } => WcIndexedDbError::InternalError(e.to_string()), + } + } +} + +#[cfg(target_arch = "wasm32")] +impl From for WcIndexedDbError { + fn from(e: DbTransactionError) -> Self { + match e { + DbTransactionError::ErrorSerializingItem(_) | DbTransactionError::ErrorDeserializingItem(_) => { + WcIndexedDbError::DecodingError(e.to_string()) + }, + DbTransactionError::ErrorUploadingItem(_) => WcIndexedDbError::AddToStorageErr(e.to_string()), + DbTransactionError::ErrorGettingItems(_) | DbTransactionError::ErrorCountingItems(_) => { + WcIndexedDbError::GetFromStorageError(e.to_string()) + }, + DbTransactionError::ErrorDeletingItems(_) => WcIndexedDbError::DeletionError(e.to_string()), + DbTransactionError::NoSuchTable { .. } + | DbTransactionError::ErrorCreatingTransaction(_) + | DbTransactionError::ErrorOpeningTable { .. } + | DbTransactionError::ErrorSerializingIndex { .. } + | DbTransactionError::UnexpectedState(_) + | DbTransactionError::TransactionAborted + | DbTransactionError::MultipleItemsByUniqueIndex { .. } + | DbTransactionError::NoSuchIndex { .. } + | DbTransactionError::InvalidIndex { .. } => WcIndexedDbError::InternalError(e.to_string()), + } + } +} + +#[cfg(target_arch = "wasm32")] +impl From for WcIndexedDbError { + fn from(value: CursorError) -> Self { + match value { + CursorError::ErrorSerializingIndexFieldValue { .. } + | CursorError::ErrorDeserializingIndexValue { .. } + | CursorError::ErrorDeserializingItem(_) => Self::DecodingError(value.to_string()), + CursorError::ErrorOpeningCursor { .. } + | CursorError::AdvanceError { .. } + | CursorError::InvalidKeyRange { .. } + | CursorError::IncorrectNumberOfKeysPerIndex { .. } + | CursorError::UnexpectedState(_) + | CursorError::IncorrectUsage { .. } + | CursorError::TypeMismatch { .. } => Self::InternalError(value.to_string()), + } + } +} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 931d5e9c4a..785ffaecbb 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -34,6 +34,7 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, use serde_json::Value; use session::{propose::send_proposal, Session, SymKeyPair}; use std::{sync::Arc, time::Duration}; +use storage::SessionStorageDb; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; @@ -46,22 +47,22 @@ pub struct WalletConnectCtx { pub pairing: PairingClient, pub session: Arc>>, pub active_chain_id: Arc>, + pub(crate) key_pair: SymKeyPair, + pub(crate) storage: SessionStorageDb, relay: Relay, metadata: Metadata, namespaces: ProposeNamespaces, subscriptions: Arc>>, - inbound_message_handler: Arc>>, connection_live_handler: Arc>>, - session_request_sender: Arc>>, session_request_handler: Arc>>, } impl WalletConnectCtx { - pub fn init() -> Self { + pub fn try_init(ctx: &MmArc) -> MmResult { let (msg_sender, msg_receiver) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); let (session_request_sender, session_request_receiver) = unbounded(); @@ -76,7 +77,9 @@ impl WalletConnectCtx { data: None, }; - Self { + let storage = SessionStorageDb::init(ctx)?; + + Ok(Self { client, pairing, session: Default::default(), @@ -85,16 +88,20 @@ impl WalletConnectCtx { namespaces: required, metadata: generate_metadata(), key_pair: SymKeyPair::new(), + storage, inbound_message_handler: Arc::new(Mutex::new(msg_receiver)), connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), session_request_handler: Arc::new(Mutex::new(session_request_receiver)), session_request_sender: Arc::new(Mutex::new(session_request_sender)), subscriptions: Default::default(), - } + }) } pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectCtxError> { - from_ctx(&ctx.wallet_connect, move || Ok(Self::init())).map_to_mm(WalletConnectCtxError::InternalError) + from_ctx(&ctx.wallet_connect, move || { + Self::try_init(ctx).map_err(|err| err.to_string()) + }) + .map_to_mm(WalletConnectCtxError::InternalError) } pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 9d6d5269ec..beeb14053f 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -31,10 +31,10 @@ pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; -#[derive(Clone, Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct SessionKey { - sym_key: [u8; 32], - public_key: [u8; 32], + pub(crate) sym_key: [u8; 32], + pub(crate) public_key: [u8; 32], } impl std::fmt::Debug for SessionKey { @@ -111,7 +111,7 @@ impl SessionKey { /// In the WalletConnect protocol, a session involves two parties: a controller /// (typically a wallet) and a proposer (typically a dApp). This enum is used /// to distinguish between these two roles. -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum SessionType { /// Represents the controlling party in a session, typically a wallet. Controller, @@ -131,7 +131,7 @@ impl ToString for SessionType { /// This struct is typically used in the core session management logic of a WalletConnect /// implementation. It's used to store, retrieve, and update session information throughout /// the lifecycle of a WalletConnect connection. -#[derive(Debug, Clone, Deserialize, Serialize)] +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] pub struct Session { /// Session topic pub topic: Topic, diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 68c788a085..c0c057a88b 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -75,6 +75,7 @@ pub async fn process_proposal_request( } { + println!("{:?}", session); send_session_settle_request(ctx, &session).await?; }; @@ -124,6 +125,7 @@ pub(crate) async fn process_session_propose_response( session.controller.public_key = response.responder_public_key; { + println!("{:?}", session); let mut old_session = ctx.session.lock().await; *old_session = Some(session); let mut subs = ctx.subscriptions.lock().await; diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs new file mode 100644 index 0000000000..1a1b43422a --- /dev/null +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -0,0 +1,106 @@ +use super::WalletConnectStorageOps; +use crate::error::WcIndexedDbError; +use crate::session::Session; +use async_trait::async_trait; +use mm2_core::mm_ctx::MmArc; +use mm2_db::indexed_db::{ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, + InitDbResult, OnUpgradeResult, SharedDb, TableSignature}; +use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::*; +use relay_rpc::domain::Topic; + +const DB_VERSION: u32 = 1; + +pub type IDBSessionStorageLocked<'a> = DbLocked<'a, IDBSessionStorageInner>; + +impl TableSignature for Session { + const TABLE_NAME: &'static str = "sessions"; + + fn on_upgrade_needed(upgrader: &DbUpgrader, old_version: u32, new_version: u32) -> OnUpgradeResult<()> { + if let (0, 1) = (old_version, new_version) { + let table = upgrader.create_table(Self::TABLE_NAME)?; + table.create_index("topic", false)?; + } + Ok(()) + } +} + +pub struct IDBSessionStorageInner(IndexedDb); + +#[async_trait] +impl DbInstance for IDBSessionStorageInner { + const DB_NAME: &'static str = "wc_session_storage"; + + async fn init(db_id: DbIdentifier) -> InitDbResult { + let inner = IndexedDbBuilder::new(db_id) + .with_version(DB_VERSION) + .with_table::() + .build() + .await?; + + Ok(Self(inner)) + } +} + +impl IDBSessionStorageInner { + pub(crate) fn get_inner(&self) -> &IndexedDb { &self.0 } +} + +#[derive(Clone)] +pub struct IDBSessionStorage(SharedDb); + +impl IDBSessionStorage { + pub(crate) fn new(ctx: &MmArc) -> MmResult { + Ok(Self(ConstructibleDb::new(ctx).into_shared())) + } + + async fn lock_db(&self) -> MmResult, WcIndexedDbError> { + Ok(self + .0 + .get_or_initialize() + .await + .mm_err(|err| WcIndexedDbError::InternalError(err.to_string()))?) + } +} + +#[async_trait::async_trait] +impl WalletConnectStorageOps for IDBSessionStorage { + type Error = WcIndexedDbError; + + async fn init(&self) -> MmResult<(), Self::Error> { Ok(()) } + + async fn is_initialized(&self) -> MmResult { Ok(true) } + + async fn save_session(&self, session: Session) -> MmResult<(), Self::Error> { + let lock_db = self.lock_db().await?; + let transaction = lock_db.get_inner().transaction().await?; + let session_table = transaction.table::().await?; + session_table + .replace_item_by_unique_index("topic", session.topic.clone(), &session) + .await?; + + Ok(()) + } + + async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { + let lock_db = self.lock_db().await?; + let transaction = lock_db.get_inner().transaction().await?; + let session_table = transaction.table::().await?; + + Ok(session_table + .get_item_by_unique_index("topic", topic) + .await? + .map(|s| s.1)) + } + + async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { + let lock_db = self.lock_db().await?; + let transaction = lock_db.get_inner().transaction().await?; + let session_table = transaction.table::().await?; + + session_table.delete_item_by_unique_index("topic", topic).await?; + Ok(()) + } + + async fn update_session(&self, session: Session) -> MmResult<(), Self::Error> { self.save_session(session).await } +} diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 19e6442a01..4690a5cda1 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -1,14 +1,13 @@ use async_trait::async_trait; +use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; -use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces}; +use relay_rpc::domain::Topic; -use crate::session::Session; +use crate::{error::WalletConnectCtxError, session::Session}; +#[cfg(target_arch = "wasm32")] pub(crate) mod indexed_db; #[cfg(not(target_arch = "wasm32"))] pub(crate) mod sqlite; -#[cfg(target_arch = "wasm32")] pub(crate) mod wasm; - -pub(crate) const SESSION_STORAGE_TABLE_NAME: &str = "kdf_wc_session_storage"; #[async_trait] pub(crate) trait WalletConnectStorageOps { @@ -17,8 +16,79 @@ pub(crate) trait WalletConnectStorageOps { async fn init(&self) -> MmResult<(), Self::Error>; async fn is_initialized(&self) -> MmResult; async fn save_session(&self, session: Session) -> MmResult<(), Self::Error>; - async fn get_sessions(&self) -> MmResult, Self::Error>; + async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error>; async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error>; - async fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), Self::Error>; - async fn update_expiry(&self, expiry: u64) -> MmResult<(), Self::Error>; + async fn update_session(&self, session: Session) -> MmResult<(), Self::Error>; +} + +pub(crate) struct SessionStorageDb { + #[cfg(target_arch = "wasm32")] + pub(crate) db: indexed_db::IDBSessionStorage, + #[cfg(not(target_arch = "wasm32"))] + pub(crate) db: sqlite::SqliteSessionStorage, +} + +impl SessionStorageDb { + pub(crate) fn init(ctx: &MmArc) -> MmResult { + let selfi = SessionStorageDb { + #[cfg(target_arch = "wasm32")] + db: indexed_db::IDBSessionStorage::new(ctx) + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?, + #[cfg(not(target_arch = "wasm32"))] + db: sqlite::SqliteSessionStorage::new(ctx).mm_err(WalletConnectCtxError::StorageError)?, + }; + + Ok(selfi) + } +} + +#[cfg(test)] +pub(crate) mod session_storage_tests { + + #[cfg(target_arch = "wasm32")] + common::cfg_wasm32! { + use wasm_bindgen_test::*; + wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); + } + use common::cross_test; + use mm2_test_helpers::for_tests::mm_ctx_with_custom_async_db; + use relay_rpc::{domain::{SubscriptionId, Topic}, + rpc::params::Metadata}; + + use crate::{session::{Session, SessionKey, SessionType}, + WalletConnectCtx}; + + use super::WalletConnectStorageOps; + + cross_test!(save_session_impl, { + let mm_ctx = mm_ctx_with_custom_async_db().await; + let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); + let session_key = SessionKey { + sym_key: [ + 115, 159, 247, 31, 199, 84, 88, 59, 158, 252, 98, 225, 51, 125, 201, 239, 142, 34, 9, 201, 128, 114, + 144, 166, 102, 131, 87, 191, 33, 24, 153, 7, + ], + public_key: [ + 115, 159, 247, 31, 199, 84, 88, 59, 158, 252, 98, 225, 51, 125, 201, 239, 142, 34, 9, 201, 128, 114, + 144, 166, 102, 131, 87, 191, 33, 24, 153, 7, + ], + }; + + let session = Session::new( + &wc_ctx, + Topic::generate(), + SubscriptionId::generate(), + session_key, + Topic::generate(), + Metadata::default(), + SessionType::Controller, + ); + + // try save session + wc_ctx.storage.db.save_session(session.clone()).await.unwrap(); + + // try get session + let db_session = wc_ctx.storage.db.get_session(&session.topic).await.unwrap(); + assert_eq!(session, db_session.unwrap()); + }); } diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 761c89cb1d..9e1bb94d2d 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -1,11 +1,12 @@ use async_trait::async_trait; -use db_common::sqlite::rusqlite::{Connection, Result as SqlResult}; +use db_common::sqlite::rusqlite::Result as SqlResult; use db_common::sqlite::{query_single_row, string_from_row, CHECK_TABLE_EXISTS_SQL}; use db_common::{async_sql_conn::{AsyncConnError, AsyncConnection}, sqlite::validate_table_name}; use futures::lock::{Mutex, MutexGuard}; +use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use relay_rpc::{domain::Topic, rpc::params::session::SettleNamespaces}; +use relay_rpc::domain::Topic; use std::sync::Arc; use super::WalletConnectStorageOps; @@ -34,16 +35,29 @@ fn create_sessions_table() -> SqlResult { } #[derive(Clone, Debug)] -pub struct SqliteSessionStorage { - pub conn: Arc>, +pub(crate) struct SqliteSessionStorage { + pub conn: Arc>, +} + +impl SqliteSessionStorage { + pub(crate) fn new(ctx: &MmArc) -> MmResult { + let conn = ctx + .async_sqlite_connection + .ok_or("async_sqlite_connection is not initialized".to_owned())?; + + Ok(Self { conn: conn.clone() }) + } + + pub(crate) async fn lock_db(&self) -> MutexGuard<'_, AsyncConnection> { self.conn.lock().await } } #[async_trait] -impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { +impl WalletConnectStorageOps for SqliteSessionStorage { type Error = AsyncConnError; async fn init(&self) -> MmResult<(), Self::Error> { - self.call(move |conn| { + let lock = self.lock_db().await; + lock.call(move |conn| { conn.execute(&create_sessions_table()?, []).map(|_| ())?; Ok(()) }) @@ -52,8 +66,9 @@ impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { } async fn is_initialized(&self) -> MmResult { + let lock = self.lock_db().await; validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?; - self.call(move |conn| { + lock.call(move |conn| { let initialized = query_single_row(conn, CHECK_TABLE_EXISTS_SQL, [SESSION_TBALE_NAME], string_from_row)?; Ok(initialized.is_some()) }) @@ -62,6 +77,7 @@ impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { } async fn save_session(&self, session: Session) -> MmResult<(), Self::Error> { + let lock = self.lock_db().await; validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?; let sql = format!( "INSERT INTO {} ( @@ -72,7 +88,7 @@ impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { SESSION_TBALE_NAME ); - self.call(move |conn| { + lock.call(move |conn| { let transaction = conn.transaction()?; //let session_key = @@ -109,13 +125,9 @@ impl WalletConnectStorageOps for MutexGuard<'_, AsyncConnection> { .map_to_mm(AsyncConnError::from) } - async fn get_sessions(&self) -> MmResult, Self::Error> { todo!() } - - async fn update_expiry(&self, expiry: u64) -> MmResult<(), Self::Error> { todo!() } + async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { todo!() } async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { todo!() } - async fn update_namespace(&self, topic: &Topic, namespace: SettleNamespaces) -> MmResult<(), Self::Error> { - todo!() - } + async fn update_session(&self, _session: Session) -> MmResult<(), Self::Error> { todo!() } } diff --git a/mm2src/kdf_walletconnect/src/storage/wasm.rs b/mm2src/kdf_walletconnect/src/storage/wasm.rs deleted file mode 100644 index b336a0f354..0000000000 --- a/mm2src/kdf_walletconnect/src/storage/wasm.rs +++ /dev/null @@ -1,28 +0,0 @@ -use async_trait::async_trait; -use mm2_db::indexed_db::{DbIdentifier, DbInstance, DbLocked, IndexedDb, IndexedDbBuilder, InitDbResult}; - -const DB_VERSION: u32 = 1; - -pub type SessionStorageIDBLocked<'a> = DbLocked<'a, SessionStorageIDB>; - -pub struct SessionStorageIDB { - inner: IndexedDb, -} - -#[async_trait] -impl DbInstance for SessionStorageIDB { - const DB_NAME: &'static str = "nft_cache"; - - async fn init(db_id: DbIdentifier) -> InitDbResult { - let inner = IndexedDbBuilder::new(db_id) - .with_version(DB_VERSION) - //.with_table::() - .build() - .await?; - Ok(SessionStorageIDB { inner }) - } -} - -impl SessionStorageIDB { - pub(crate) fn get_inner(&self) -> &IndexedDb { &self.inner } -} diff --git a/mm2src/mm2_net/Cargo.toml b/mm2src/mm2_net/Cargo.toml index d92e0c08b6..c9718bd755 100644 --- a/mm2src/mm2_net/Cargo.toml +++ b/mm2src/mm2_net/Cargo.toml @@ -48,7 +48,11 @@ wasm-bindgen-test = { version = "0.3.2" } wasm-bindgen-futures = "0.4.21" web-sys = { version = "0.3.55", features = ["console", "CloseEvent", "DomException", "ErrorEvent", "IdbDatabase", "IdbCursor", "IdbCursorWithValue", "IdbFactory", "IdbIndex", "IdbIndexParameters", "IdbObjectStore", - "IdbObjectStoreParameters", "IdbOpenDbRequest", "IdbKeyRange", "IdbTransaction", "IdbTransactionMode", + "IdbObjectStoreParameters", "IdbOpenDbRequest", "IdbKeyRange", "IdbTransaction", "IdbTransactionMode", "Request", + "RequestInit", + "RequestMode", + "Response", + "Window","Headers", "IdbVersionChangeEvent", "MessageEvent", "MessagePort", "ReadableStreamDefaultReader", "ReadableStream", "SharedWorker", "Url", "WebSocket"] } diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock new file mode 100644 index 0000000000..b7c1a47c49 --- /dev/null +++ b/mm2src/mm2_test_helpers/Cargo.lock @@ -0,0 +1,4107 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", + "zeroize", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[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-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel 2.3.1", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if 1.0.0", + "event-listener 5.3.1", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if 1.0.0", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers 0.3.0", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.3.0", +] + +[[package]] +name = "autocfg" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bip32" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" +dependencies = [ + "bs58", + "hkd32", + "hmac 0.11.0", + "ripemd160", + "secp256k1 0.20.3", + "sha2 0.9.9", + "subtle", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "bitcoin" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" +dependencies = [ + "bech32", + "bitcoin_hashes", + "secp256k1 0.24.3", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitcrypto" +version = "0.1.0" +dependencies = [ + "groestl", + "primitives", + "ripemd160", + "serialization", + "sha-1", + "sha2 0.10.8", + "sha3 0.9.1", + "siphasher", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[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 = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding 0.2.1", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[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-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +dependencies = [ + "byteorder", + "iovec", +] + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chain" +version = "0.1.0" +dependencies = [ + "bitcoin", + "bitcrypto", + "primitives", + "rustc-hex", + "serialization", + "serialization_derive", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[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 = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "common" +version = "0.1.0" +dependencies = [ + "anyhow", + "arrayref", + "async-trait", + "backtrace", + "bytes 1.7.2", + "cc", + "cfg-if 1.0.0", + "chrono", + "crossbeam", + "derive_more", + "env_logger", + "findshlibs", + "fnv", + "futures 0.1.31", + "futures 0.3.30", + "futures-timer", + "gstuff", + "hex", + "http 0.2.12", + "http-body 0.1.0", + "hyper", + "hyper-rustls", + "instant", + "itertools", + "js-sys", + "lazy_static", + "libc", + "lightning", + "log", + "parking_lot", + "parking_lot_core 0.6.3", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hash", + "ser_error", + "ser_error_derive", + "serde", + "serde-wasm-bindgen", + "serde_derive", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "tokio", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", + "winapi", +] + +[[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_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto" +version = "1.0.0" +dependencies = [ + "aes", + "argon2", + "arrayref", + "async-trait", + "base64", + "bip32", + "bip39", + "bitcrypto", + "bs58", + "cbc", + "cfg-if 1.0.0", + "cipher", + "common", + "derive_more", + "enum-primitive-derive", + "enum_derives", + "futures 0.3.30", + "hex", + "hmac 0.12.1", + "http 0.2.12", + "hw_common", + "keys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_eth", + "mm2_metamask", + "num-traits", + "parking_lot", + "primitives", + "rpc", + "rpc_task", + "rustc-hex", + "secp256k1 0.20.3", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "trezor", + "wasm-bindgen-test", + "web3", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "db_common" +version = "0.1.0" +dependencies = [ + "common", + "crossbeam-channel", + "futures 0.3.30", + "hex", + "log", + "rusqlite", + "sql-builder", + "tokio", + "uuid", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote 1.0.37", + "rustc_version 0.4.1", + "syn 2.0.77", +] + +[[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", + "crypto-common", + "subtle", +] + +[[package]] +name = "edit-distance" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enum-primitive-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" +dependencies = [ + "num-traits", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "enum_derives" +version = "0.1.0" +dependencies = [ + "itertools", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[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 = "ethabi" +version = "17.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethcore-transaction" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "ethereum-types", + "ethkey", + "keccak-hash", + "rlp", + "rustc-hex", + "unexpected", +] + +[[package]] +name = "ethereum-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", +] + +[[package]] +name = "ethkey" +version = "0.3.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "byteorder", + "edit-distance", + "ethereum-types", + "log", + "mem", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "tiny-keccak 1.4.4", +] + +[[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 = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "findshlibs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers 0.2.6", + "send_wrapper", +] + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "groestl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "gstuff" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes 1.7.2", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.5.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +dependencies = [ + "ahash", +] + +[[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 = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkd32" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" +dependencies = [ + "hmac 0.11.0", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[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.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" +dependencies = [ + "bytes 0.4.12", + "fnv", + "itoa 0.4.8", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes 1.7.2", + "fnv", + "itoa 1.0.11", +] + +[[package]] +name = "http-body" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", + "http 0.1.21", + "tokio-buf", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes 1.7.2", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" + +[[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 = "hw_common" +version = "0.1.0" +dependencies = [ + "async-trait", + "bip32", + "common", + "derive_more", + "futures 0.3.30", + "js-sys", + "mm2_err_handle", + "rusb", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes 1.7.2", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa 1.0.11", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "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", + "rustls", + "tokio", + "tokio-rustls", + "webpki-roots", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg 1.3.0", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding 0.3.3", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipnet" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures 0.3.30", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-hash" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" +dependencies = [ + "primitive-types", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "keys" +version = "0.1.0" +dependencies = [ + "base58", + "bech32", + "bitcrypto", + "derive_more", + "lazy_static", + "primitives", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libsqlite3-sys" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libusb1-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lightning" +version = "0.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" +dependencies = [ + "bitcoin", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg 1.3.0", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "mem" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "metrics" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" +dependencies = [ + "ahash", + "metrics-macros", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" +dependencies = [ + "base64", + "hyper", + "indexmap 1.9.3", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "metrics-util" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" +dependencies = [ + "aho-corasick", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.13.1", + "indexmap 1.9.3", + "metrics", + "num_cpus", + "ordered-float", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + +[[package]] +name = "minicov" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "mm2_core" +version = "0.1.0" +dependencies = [ + "arrayref", + "async-std", + "async-trait", + "cfg-if 1.0.0", + "common", + "db_common", + "derive_more", + "futures 0.3.30", + "gstuff", + "hex", + "instant", + "lazy_static", + "mm2_err_handle", + "mm2_event_stream", + "mm2_metrics", + "mm2_rpc", + "primitives", + "rand 0.7.3", + "rustls", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "shared_ref_counter", + "tokio", + "uuid", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_err_handle" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.1.31", + "http 0.2.12", + "itertools", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_eth" +version = "0.1.0" +dependencies = [ + "ethabi", + "ethkey", + "hex", + "indexmap 1.9.3", + "itertools", + "mm2_err_handle", + "secp256k1 0.20.3", + "serde", + "serde_json", + "web3", +] + +[[package]] +name = "mm2_event_stream" +version = "0.1.0" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "common", + "futures 0.3.30", + "parking_lot", + "serde", + "tokio", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_io" +version = "0.1.0" +dependencies = [ + "async-std", + "common", + "derive_more", + "futures 0.3.30", + "gstuff", + "mm2_err_handle", + "rand 0.7.3", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_metamask" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.30", + "itertools", + "js-sys", + "jsonrpc-core", + "lazy_static", + "mm2_err_handle", + "mm2_eth", + "parking_lot", + "serde", + "serde_derive", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "web3", +] + +[[package]] +name = "mm2_metrics" +version = "0.1.0" +dependencies = [ + "base64", + "common", + "derive_more", + "futures 0.3.30", + "hyper", + "hyper-rustls", + "itertools", + "metrics", + "metrics-exporter-prometheus", + "metrics-util", + "mm2_err_handle", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "mm2_net" +version = "0.1.0" +dependencies = [ + "async-trait", + "base64", + "bytes 1.7.2", + "cfg-if 1.0.0", + "common", + "derive_more", + "ethkey", + "futures 0.3.30", + "futures-util", + "gstuff", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "hyper", + "js-sys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_state_machine", + "pin-project", + "prost", + "rand 0.7.3", + "rustls", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-rustls", + "tonic", + "tower-service", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "mm2_number" +version = "0.1.0" +dependencies = [ + "bigdecimal", + "num-bigint", + "num-rational", + "num-traits", + "paste", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_rpc" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.3.30", + "gstuff", + "http 0.2.12", + "mm2_err_handle", + "mm2_number", + "rpc", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "mm2_state_machine" +version = "0.1.0" +dependencies = [ + "async-trait", +] + +[[package]] +name = "mm2_test_helpers" +version = "0.1.0" +dependencies = [ + "bytes 1.7.2", + "cfg-if 1.0.0", + "chrono", + "common", + "crypto", + "db_common", + "futures 0.3.30", + "gstuff", + "http 0.2.12", + "lazy_static", + "mm2_core", + "mm2_io", + "mm2_metrics", + "mm2_net", + "mm2_number", + "mm2_rpc", + "rand 0.7.3", + "regex", + "rpc", + "serde", + "serde_derive", + "serde_json", + "uuid", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec 1.13.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "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", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg 1.3.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "object" +version = "0.36.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +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 = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "rustc_version 0.2.3", + "smallvec 0.6.14", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.5.6", + "smallvec 1.13.2", + "windows-targets", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if 1.0.0", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "portable-atomic" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "uint", +] + +[[package]] +name = "primitives" +version = "0.1.0" +dependencies = [ + "bitcoin_hashes", + "byteorder", + "rustc-hex", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes 1.7.2", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "quanta" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" +dependencies = [ + "crossbeam-utils", + "libc", + "mach2", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg 0.2.1", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +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", + "wasm-bindgen", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +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-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[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.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom 0.2.15", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes 1.7.2", + "rustc-hex", +] + +[[package]] +name = "rpc" +version = "0.1.0" +dependencies = [ + "chain", + "keys", + "log", + "primitives", + "rustc-hex", + "script", + "serde", + "serde_derive", + "serde_json", + "serialization", +] + +[[package]] +name = "rpc_task" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.30", + "mm2_err_handle", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", +] + +[[package]] +name = "rusb" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" +dependencies = [ + "libc", + "libusb1-sys", +] + +[[package]] +name = "rusqlite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" +dependencies = [ + "bitflags 1.3.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec 1.13.2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "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 = [ + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[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 = "script" +version = "0.1.0" +dependencies = [ + "bitcrypto", + "blake2b_simd", + "chain", + "keys", + "log", + "primitives", + "serde", + "serialization", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "rand 0.6.5", + "secp256k1-sys 0.4.2", +] + +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "bitcoin_hashes", + "secp256k1-sys 0.6.1", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "ser_error" +version = "0.1.0" +dependencies = [ + "serde", +] + +[[package]] +name = "ser_error_derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "ser_error", + "syn 1.0.109", +] + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "indexmap 2.5.0", + "itoa 1.0.11", + "memchr", + "ryu", + "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 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "serialization" +version = "0.1.0" +dependencies = [ + "byteorder", + "derive_more", + "primitives", + "test_helpers", +] + +[[package]] +name = "serialization_derive" +version = "0.1.0" +dependencies = [ + "quote 0.3.15", + "syn 0.11.11", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "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 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shared_ref_counter" +version = "0.1.0" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "siphasher" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" + +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg 1.3.0", +] + +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "sql-builder" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" +dependencies = [ + "anyhow", + "thiserror", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test_helpers" +version = "0.1.0" +dependencies = [ + "hex", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "tiny-keccak" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +dependencies = [ + "backtrace", + "bytes 1.7.2", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-buf" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes 1.7.2", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap 2.5.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "base64", + "bytes 1.7.2", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "percent-encoding", + "pin-project", + "prost", + "tokio-stream", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trezor" +version = "0.1.1" +dependencies = [ + "async-std", + "async-trait", + "bip32", + "byteorder", + "common", + "derive_more", + "ethcore-transaction", + "ethereum-types", + "ethkey", + "futures 0.3.30", + "hw_common", + "js-sys", + "lazy_static", + "mm2_err_handle", + "prost", + "rand 0.7.3", + "rpc_task", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unexpected" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom 0.2.15", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote 1.0.37", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68497a05fb21143a08a7d24fc81763384a3072ee43c44e86aad1744d6adef9d9" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "minicov", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web3" +version = "0.19.0" +source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" +dependencies = [ + "arrayvec 0.7.6", + "derive_more", + "ethabi", + "ethereum-types", + "futures 0.3.30", + "futures-timer", + "getrandom 0.2.15", + "hex", + "idna", + "js-sys", + "jsonrpc-core", + "log", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rlp", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tiny-keccak 2.0.2", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.77", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +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 1.0.37", + "syn 2.0.77", +] diff --git a/mm2src/mm2_test_helpers/src/for_tests.rs b/mm2src/mm2_test_helpers/src/for_tests.rs index 56fa519ccc..8e132cf3e0 100644 --- a/mm2src/mm2_test_helpers/src/for_tests.rs +++ b/mm2src/mm2_test_helpers/src/for_tests.rs @@ -1131,6 +1131,9 @@ pub async fn mm_ctx_with_custom_async_db() -> MmArc { ctx } +#[cfg(target_arch = "wasm32")] +pub async fn mm_ctx_with_custom_async_db() -> MmArc { MmCtxBuilder::new().with_test_db_namespace().into_mm_arc() } + /// Automatically kill a wrapped process. pub struct RaiiKill { pub handle: Child, From 6135665bb38c6ab569034d48bdc714efc6623cd6 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 09:58:57 +0100 Subject: [PATCH 032/125] implement persistent indexed_db session storage --- .../src/tendermint_with_assets_activation.rs | 3 +- mm2src/kdf_walletconnect/src/lib.rs | 57 ++++++++++++++++--- .../kdf_walletconnect/src/session/propose.rs | 19 ++++++- .../src/storage/indexed_db.rs | 17 +++++- mm2src/kdf_walletconnect/src/storage/mod.rs | 7 ++- .../kdf_walletconnect/src/storage/sqlite.rs | 7 ++- mm2src/mm2_main/src/lp_native_dex.rs | 19 ++----- .../src/rpc/lp_commands/lp_commands.rs | 6 +- 8 files changed, 102 insertions(+), 33 deletions(-) diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 54134daae5..d701aa4523 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -242,7 +242,8 @@ async fn get_walletconnect_pubkey( }); }; - let walletconnect_ctx = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + let walletconnect_ctx = + WalletConnectCtx::try_from_ctx_or_initialize(ctx).expect("WalletConnectCtx should be initialized by now!"); let account = walletconnect_ctx .cosmos_get_account(param.account_index, "cosmos", chain_id) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 785ffaecbb..6a788f40af 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -10,6 +10,7 @@ mod storage; use chain::{build_required_namespaces, cosmos::{cosmos_get_accounts_impl, CosmosAccount}, SUPPORTED_CHAINS}; +use common::executor::SpawnFuture; use common::{executor::Timer, log::{error, info}}; use error::WalletConnectCtxError; @@ -34,7 +35,7 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, use serde_json::Value; use session::{propose::send_proposal, Session, SymKeyPair}; use std::{sync::Arc, time::Duration}; -use storage::SessionStorageDb; +use storage::{SessionStorageDb, WalletConnectStorageOps}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; @@ -97,7 +98,7 @@ impl WalletConnectCtx { }) } - pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectCtxError> { + pub fn try_from_ctx_or_initialize(ctx: &MmArc) -> MmResult, WalletConnectCtxError> { from_ctx(&ctx.wallet_connect, move || { Self::try_init(ctx).map_err(|err| err.to_string()) }) @@ -323,18 +324,18 @@ impl WalletConnectCtx { Ok(()) } - pub async fn published_message_event_loop(self: Arc) { - let self_clone = self.clone(); + pub async fn message_handler_event_loop(self: Arc) { + let selfi = self.clone(); let mut recv = self.inbound_message_handler.lock().await; while let Some(msg) = recv.next().await { info!("received message"); - if let Err(e) = self_clone.handle_single_message(msg).await { + if let Err(e) = selfi.handle_published_message(msg).await { info!("Error processing message: {:?}", e); } } } - async fn handle_single_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectCtxError> { + async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectCtxError> { let message = { let key = self.sym_key(&msg.topic).await?; decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() @@ -353,7 +354,28 @@ impl WalletConnectCtx { Ok(()) } - pub async fn spawn_connection_live_watcher(self: Arc) { + async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectCtxError> { + let sessions = self + .storage + .db + .get_all_sessions() + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + if let Some(session) = sessions.first() { + info!("Session found! activating :{}", session.topic); + + let mut ctx_session = self.session.lock().await; + *ctx_session = Some(session.clone()); + + // subcribe to session topics + self.client.subscribe(session.topic.clone()).await?; + self.client.subscribe(session.pairing_topic.clone()).await?; + } + + Ok(()) + } + + async fn connection_live_watcher(self: Arc) { let mut recv = self.connection_live_handler.lock().await; let mut retry_count = 0; @@ -394,3 +416,24 @@ impl WalletConnectCtx { } } } + +/// This function spwans related WalletConnect related tasks and needed initialization before +/// WalletConnect can be usable in KDF. +pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectCtxError> { + // Initialized WalletConnectCtx + let wallet_connect = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + + // WalletConnectCtx is initialized, now we can connect to relayer client. + wallet_connect.connect_client().await?; + + // spawn message handler event loop + ctx.spawner().spawn(wallet_connect.clone().message_handler_event_loop()); + + // spawn WalletConnect client disconnect task + ctx.spawner().spawn(wallet_connect.clone().connection_live_watcher()); + + // load session from storage + wallet_connect.load_session_from_storage().await?; + + Ok(()) +} diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index c0c057a88b..80d40f7c18 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -1,11 +1,12 @@ use super::{settle::send_session_settle_request, Session}; use crate::{error::WalletConnectCtxError, session::{SessionKey, SessionType, THIRTY_DAYS}, + storage::WalletConnectStorageOps, WalletConnectCtx}; use chrono::Utc; use mm2_err_handle::map_to_mm::MapToMmResult; -use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session::ProposeNamespaces, session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, @@ -68,6 +69,13 @@ pub async fn process_proposal_request( .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; { + // save session to storage + ctx.storage + .db + .save_session(&session) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + let mut old_session = ctx.session.lock().await; *old_session = Some(session.clone()); let mut subs = ctx.subscriptions.lock().await; @@ -75,7 +83,6 @@ pub async fn process_proposal_request( } { - println!("{:?}", session); send_session_settle_request(ctx, &session).await?; }; @@ -125,7 +132,13 @@ pub(crate) async fn process_session_propose_response( session.controller.public_key = response.responder_public_key; { - println!("{:?}", session); + // save session to storage + ctx.storage + .db + .save_session(&session) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + let mut old_session = ctx.session.lock().await; *old_session = Some(session); let mut subs = ctx.subscriptions.lock().await; diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index 1a1b43422a..6496116785 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -71,7 +71,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { async fn is_initialized(&self) -> MmResult { Ok(true) } - async fn save_session(&self, session: Session) -> MmResult<(), Self::Error> { + async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -93,6 +93,19 @@ impl WalletConnectStorageOps for IDBSessionStorage { .map(|s| s.1)) } + async fn get_all_sessions(&self) -> MmResult, Self::Error> { + let lock_db = self.lock_db().await?; + let transaction = lock_db.get_inner().transaction().await?; + let session_table = transaction.table::().await?; + + Ok(session_table + .get_all_items() + .await? + .into_iter() + .map(|s| s.1) + .collect::>()) + } + async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; @@ -102,5 +115,5 @@ impl WalletConnectStorageOps for IDBSessionStorage { Ok(()) } - async fn update_session(&self, session: Session) -> MmResult<(), Self::Error> { self.save_session(session).await } + async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { self.save_session(&session).await } } diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 4690a5cda1..1bd3247181 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -15,10 +15,11 @@ pub(crate) trait WalletConnectStorageOps { async fn init(&self) -> MmResult<(), Self::Error>; async fn is_initialized(&self) -> MmResult; - async fn save_session(&self, session: Session) -> MmResult<(), Self::Error>; + async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error>; async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error>; + async fn get_all_sessions(&self) -> MmResult, Self::Error>; async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error>; - async fn update_session(&self, session: Session) -> MmResult<(), Self::Error>; + async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error>; } pub(crate) struct SessionStorageDb { @@ -85,7 +86,7 @@ pub(crate) mod session_storage_tests { ); // try save session - wc_ctx.storage.db.save_session(session.clone()).await.unwrap(); + wc_ctx.storage.db.save_session(&session).await.unwrap(); // try get session let db_session = wc_ctx.storage.db.get_session(&session.topic).await.unwrap(); diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 9e1bb94d2d..bdad09c63c 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -76,7 +76,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { .map_to_mm(AsyncConnError::from) } - async fn save_session(&self, session: Session) -> MmResult<(), Self::Error> { + async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { let lock = self.lock_db().await; validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?; let sql = format!( @@ -88,6 +88,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { SESSION_TBALE_NAME ); + let session = session.clone(); lock.call(move |conn| { let transaction = conn.transaction()?; @@ -127,7 +128,9 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { todo!() } + async fn get_all_sessions(&self) -> MmResult, Self::Error> { todo!() } + async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { todo!() } - async fn update_session(&self, _session: Session) -> MmResult<(), Self::Error> { todo!() } + async fn update_session(&self, _session: &Session) -> MmResult<(), Self::Error> { todo!() } } diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index 08fdaa9e46..3293c0833e 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -25,7 +25,7 @@ use common::log::{info, warn}; use crypto::{from_hw_error, CryptoCtx, HwError, HwProcessingError, HwRpcError, WithHwRpcError}; use derive_more::Display; use enum_derives::EnumFromTrait; -use kdf_walletconnect::WalletConnectCtx; +use kdf_walletconnect::initialize_walletconnect; use mm2_core::mm_ctx::{MmArc, MmCtx}; use mm2_err_handle::common_errors::InternalError; use mm2_err_handle::prelude::*; @@ -473,18 +473,6 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { init_message_service(&ctx).await?; - // connect walletconnect - let wallet_connect = - WalletConnectCtx::from_ctx(&ctx).map_err(|err| MmInitError::WalletInitError(err.to_string()))?; - wallet_connect - .connect_client() - .await - .map_err(|err| MmInitError::WalletInitError(err.to_string()))?; - ctx.spawner() - .spawn(wallet_connect.clone().published_message_event_loop()); - ctx.spawner() - .spawn(wallet_connect.clone().spawn_connection_live_watcher()); - let balance_update_ordermatch_handler = BalanceUpdateOrdermatchHandler::new(ctx.clone()); register_balance_update_handler(ctx.clone(), Box::new(balance_update_ordermatch_handler)).await; @@ -503,6 +491,11 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { #[cfg(target_arch = "wasm32")] init_wasm_event_streaming(&ctx); + // Initialize WalletConnect + initialize_walletconnect(&ctx) + .await + .mm_err(|err| MmInitError::WalletInitError(err.to_string()))?; + ctx.spawner().spawn(clean_memory_loop(ctx.weak())); Ok(()) diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs index d76ceb6013..39547af0c3 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs @@ -134,7 +134,8 @@ pub async fn connect_to_peer( ctx: MmArc, req: ConnectPairingRequest, ) -> MmResult { - let walletconnect_ctx = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + let walletconnect_ctx = + WalletConnectCtx::try_from_ctx_or_initialize(&ctx).expect("WalletConnectCtx should be initialized by now!"); let topic = walletconnect_ctx .connect_to_pairing(&req.url, true) @@ -159,7 +160,8 @@ pub async fn create_new_pairing( ctx: MmArc, _req: CreatePairingRequest, ) -> MmResult { - let walletconnect_ctx = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + let walletconnect_ctx = + WalletConnectCtx::try_from_ctx_or_initialize(&ctx).expect("WalletConnectCtx should be initialized by now!"); let url = walletconnect_ctx .create_pairing(None) From 5457d800415830dfddfb9b4b042607c6f4e62535 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 12:40:38 +0100 Subject: [PATCH 033/125] save dev state - implement wc rpc commands --- mm2src/kdf_walletconnect/src/error.rs | 2 + .../kdf_walletconnect/src/inbound_message.rs | 36 ++++++------ mm2src/kdf_walletconnect/src/lib.rs | 13 ++--- mm2src/kdf_walletconnect/src/pairing.rs | 35 +----------- .../src/rpc_commands/delete_connection.rs | 27 +++++++++ .../src/rpc_commands/get_chain_id.rs | 20 +++++++ .../src/rpc_commands/get_session.rs | 19 +++++++ .../kdf_walletconnect/src/rpc_commands/mod.rs | 15 +++++ .../src/rpc_commands/new_connection.rs | 22 ++++++++ .../src/rpc_commands/ping.rs | 24 ++++++++ .../kdf_walletconnect/src/session/delete.rs | 24 ++++++-- mm2src/kdf_walletconnect/src/session/event.rs | 3 +- .../kdf_walletconnect/src/session/extend.rs | 2 +- mm2src/kdf_walletconnect/src/session/ping.rs | 14 ++++- .../kdf_walletconnect/src/session/propose.rs | 4 +- .../kdf_walletconnect/src/session/settle.rs | 2 +- .../kdf_walletconnect/src/session/update.rs | 2 +- .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 12 +++- .../src/rpc/lp_commands/lp_commands.rs | 56 ------------------- 19 files changed, 202 insertions(+), 130 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs create mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs create mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs create mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/mod.rs create mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs create mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/ping.rs diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index aae333f737..1c3104bd47 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -38,6 +38,8 @@ pub(crate) const UNSUPPORTED_EVENTS: i32 = 5102; pub(crate) const UNSUPPORTED_ACCOUNTS: i32 = 5103; pub(crate) const UNSUPPORTED_NAMESPACE_KEY: i32 = 5104; +pub(crate) const USER_REQUESTED: i64 = 6000; + #[derive(Debug, Serialize, Deserialize, EnumFromStringify, thiserror::Error)] pub enum WalletConnectCtxError { #[error("Pairing Error: {0}")] diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index b83a297585..ae6e42be25 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -7,14 +7,14 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use crate::{error::WalletConnectCtxError, - pairing::{process_pairing_delete_response, process_pairing_extend_response, process_pairing_ping_response}, - session::{delete::process_session_delete_request, + pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, + session::{delete::reply_session_delete_request, event::SessionEvents, - extend::process_session_extend_request, - ping::process_session_ping_request, - propose::{process_proposal_request, process_session_propose_response}, - settle::process_session_settle_request, - update::process_session_update_request}, + extend::reply_session_extend_request, + ping::reply_session_ping_request, + propose::{process_session_propose_response, reply_session_proposal_request}, + settle::reply_session_settle_request, + update::reply_session_update_request}, WalletConnectCtx}; #[derive(Debug, Serialize, Deserialize)] @@ -31,26 +31,25 @@ pub(crate) async fn process_inbound_request( ) -> MmResult<(), WalletConnectCtxError> { let message_id = request.id; match request.params { - Params::SessionPropose(proposal) => process_proposal_request(ctx, proposal, topic, &message_id).await?, - Params::SessionExtend(param) => process_session_extend_request(ctx, topic, &message_id, param).await?, - Params::SessionDelete(param) => process_session_delete_request(ctx, topic, &message_id, param).await?, - Params::SessionPing(()) => process_session_ping_request(ctx, topic, &message_id).await?, - Params::SessionSettle(param) => process_session_settle_request(ctx, topic, &message_id, param).await?, - Params::SessionUpdate(param) => process_session_update_request(ctx, topic, &message_id, param).await?, + Params::SessionPropose(proposal) => reply_session_proposal_request(ctx, proposal, topic, &message_id).await?, + Params::SessionExtend(param) => reply_session_extend_request(ctx, topic, &message_id, param).await?, + Params::SessionDelete(param) => reply_session_delete_request(ctx, topic, &message_id, param).await?, + Params::SessionPing(()) => reply_session_ping_request(ctx, topic, &message_id).await?, + Params::SessionSettle(param) => reply_session_settle_request(ctx, topic, &message_id, param).await?, + Params::SessionUpdate(param) => reply_session_update_request(ctx, topic, &message_id, param).await?, Params::SessionEvent(param) => { SessionEvents::from_events(param)? .handle_session_event(ctx, topic, &message_id) .await? }, Params::SessionRequest(_param) => { - // TODO: send back a success response. - info!("SessionRequest is not yet implemented."); + // TODO: Implement when integrating KDF as a wallet. return MmError::err(WalletConnectCtxError::NotImplemented); }, - Params::PairingPing(_param) => process_pairing_ping_response(ctx, topic, &message_id).await?, - Params::PairingDelete(param) => process_pairing_delete_response(ctx, topic, &message_id, param).await?, - Params::PairingExtend(param) => process_pairing_extend_response(ctx, topic, &message_id, param).await?, + Params::PairingPing(_param) => reply_pairing_ping_response(ctx, topic, &message_id).await?, + Params::PairingDelete(param) => reply_pairing_delete_response(ctx, topic, &message_id, param).await?, + Params::PairingExtend(param) => reply_pairing_extend_response(ctx, topic, &message_id, param).await?, _ => { info!("Unknown request params received."); return MmError::err(WalletConnectCtxError::InvalidRequest); @@ -72,7 +71,6 @@ pub(crate) async fn process_inbound_response( let success_response = serde_json::from_value::(value.result)?; match success_response { SuccessResponses::ResponseParamsSuccess(params) => match params { - // Handle known success responses match success_response { ResponseParamsSuccess::SessionPropose(param) => { process_session_propose_response(ctx, topic, param).await }, diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 6a788f40af..8f1d07700d 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -4,6 +4,8 @@ mod handler; mod inbound_message; mod metadata; #[allow(unused)] mod pairing; +pub mod rpc_commands; + mod session; mod storage; @@ -33,7 +35,7 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; use serde_json::Value; -use session::{propose::send_proposal, Session, SymKeyPair}; +use session::{propose::send_proposal_request, Session, SymKeyPair}; use std::{sync::Arc, time::Duration}; use storage::{SessionStorageDb, WalletConnectStorageOps}; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; @@ -124,7 +126,7 @@ impl WalletConnectCtx { } /// Create a WalletConnect pairing connection url. - pub async fn create_pairing( + pub async fn new_connection( &self, required_namespaces: Option, ) -> MmResult { @@ -136,7 +138,7 @@ impl WalletConnectCtx { info!("Subscribed to topic: {topic:?}"); - send_proposal(self, topic.clone(), required_namespaces).await?; + send_proposal_request(self, topic.clone(), required_namespaces).await?; { let mut subs = self.subscriptions.lock().await; @@ -173,10 +175,7 @@ impl WalletConnectCtx { /// Get current active chain id. pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } - pub async fn get_session(&self) -> Option { - let session = self.session.lock().await; - session.clone() - } + pub async fn get_session(&self) -> Option { self.session.lock().await.clone() } /// Get available accounts for a given chain_id. pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index 3f3b82da31..4838074e4f 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -10,7 +10,7 @@ use relay_rpc::{domain::Topic, rpc::params::{pairing_delete::PairingDeleteRequest, pairing_extend::PairingExtendRequest, ResponseParamsSuccess}}; -pub(crate) async fn process_pairing_ping_response( +pub(crate) async fn reply_pairing_ping_response( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, @@ -21,7 +21,7 @@ pub(crate) async fn process_pairing_ping_response( Ok(()) } -pub(crate) async fn process_pairing_extend_response( +pub(crate) async fn reply_pairing_extend_response( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, @@ -41,7 +41,7 @@ pub(crate) async fn process_pairing_extend_response( Ok(()) } -pub(crate) async fn process_pairing_delete_response( +pub(crate) async fn reply_pairing_delete_response( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, @@ -56,32 +56,3 @@ pub(crate) async fn process_pairing_delete_response( Ok(()) } - -pub(crate) async fn pairing_ping_request() -> WcRequestResponseResult { - let request = RequestParams::PairingPing(PairingPingRequest {}); - let irn_metadata = request.irn_metadata(); - let value = serde_json::to_value(request)?; - - Ok((value, irn_metadata)) -} - -pub(crate) async fn pairing_delete_request() -> WcRequestResponseResult { - let request = RequestParams::PairingDelete(PairingDeleteRequest { - code: 6000, - message: "Delete my pairing".to_string(), - }); - let irn_metadata = request.irn_metadata(); - let value = serde_json::to_value(request)?; - - Ok((value, irn_metadata)) -} - -pub(crate) async fn pairing_extend_request() -> WcRequestResponseResult { - let request = RequestParams::PairingExtend(PairingExtendRequest { - expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, - }); - let irn_metadata = request.irn_metadata(); - let value = serde_json::to_value(request)?; - - Ok((value, irn_metadata)) -} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs b/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs new file mode 100644 index 0000000000..543f47f21a --- /dev/null +++ b/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs @@ -0,0 +1,27 @@ +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::domain::Topic; +use serde::{Deserialize, Serialize}; + +use crate::{error::WalletConnectCtxError, session::delete::send_session_delete_request, WalletConnectCtx}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct DeleteConnectionResponse { + pub successful: bool, +} + +#[derive(Deserialize)] +pub struct DeleteConnectionRequest { + topic: Topic, +} + +/// `delete connection` RPC command implementation. +pub async fn delete_connection( + ctx: MmArc, + req: DeleteConnectionRequest, +) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + send_session_delete_request(&ctx, &req.topic).await?; + + Ok(DeleteConnectionResponse { successful: true }) +} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs b/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs new file mode 100644 index 0000000000..6c1e2e2f76 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs @@ -0,0 +1,20 @@ +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::MmResult; +use serde::Serialize; + +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + +use super::EmptyRpcRequst; + +#[derive(Debug, PartialEq, Serialize)] +pub struct GetChainIdResponse { + pub chain_id: String, +} + +/// `delete connection` RPC command implementation. +pub async fn get_chain_id(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let chain_id = ctx.get_active_chain_id().await; + + Ok(GetChainIdResponse { chain_id }) +} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs b/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs new file mode 100644 index 0000000000..8734f0d223 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs @@ -0,0 +1,19 @@ +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::MmResult; +use serde::Serialize; + +use super::EmptyRpcRequst; +use crate::{error::WalletConnectCtxError, session::Session, WalletConnectCtx}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct GetSessionResponse { + pub session: Option, +} + +/// `delete connection` RPC command implementation. +pub async fn get_session(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let session = ctx.get_session().await; + + Ok(GetSessionResponse { session }) +} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/mod.rs b/mm2src/kdf_walletconnect/src/rpc_commands/mod.rs new file mode 100644 index 0000000000..3ae7f66bfc --- /dev/null +++ b/mm2src/kdf_walletconnect/src/rpc_commands/mod.rs @@ -0,0 +1,15 @@ +mod delete_connection; +mod get_chain_id; +mod get_session; +mod new_connection; +mod ping; + +pub use delete_connection::delete_connection; +pub use get_chain_id::get_chain_id; +pub use get_session::get_session; +pub use new_connection::new_connection; +pub use ping::ping_session; +use serde::Deserialize; + +#[derive(Deserialize)] +pub struct EmptyRpcRequst {} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs b/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs new file mode 100644 index 0000000000..11b995381e --- /dev/null +++ b/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs @@ -0,0 +1,22 @@ +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::MmResult; +use serde::Serialize; + +use super::EmptyRpcRequst; +use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct CreateConnectionResponse { + pub url: String, +} + +/// `new_connection` RPC command implementation. +pub async fn new_connection( + ctx: MmArc, + _req: EmptyRpcRequst, +) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let url = ctx.new_connection(None).await?; + + Ok(CreateConnectionResponse { url }) +} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs b/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs new file mode 100644 index 0000000000..363bceacf7 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs @@ -0,0 +1,24 @@ +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::MmResult; +use relay_rpc::domain::Topic; +use serde::{Deserialize, Serialize}; + +use crate::{error::WalletConnectCtxError, session::ping::send_session_ping_request, WalletConnectCtx}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct SessionPingResponse { + pub successful: bool, +} + +#[derive(Deserialize)] +pub struct SessionPingRequest { + topic: Topic, +} + +/// `ping session` RPC command implementation. +pub async fn ping_session(ctx: MmArc, req: SessionPingRequest) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + send_session_ping_request(&ctx, &req.topic).await?; + + Ok(SessionPingResponse { successful: true }) +} diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/delete.rs index d1702bb5a2..d4baf5f180 100644 --- a/mm2src/kdf_walletconnect/src/session/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/delete.rs @@ -1,11 +1,12 @@ -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{error::{WalletConnectCtxError, USER_REQUESTED}, + WalletConnectCtx}; use common::log::debug; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session_delete::SessionDeleteRequest, ResponseParamsSuccess}}; + rpc::params::{session_delete::SessionDeleteRequest, RequestParams, ResponseParamsSuccess}}; -pub(crate) async fn process_session_delete_request( +pub(crate) async fn reply_session_delete_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, @@ -14,9 +15,22 @@ pub(crate) async fn process_session_delete_request( let param = ResponseParamsSuccess::SessionDelete(true); ctx.publish_response_ok(topic, param, message_id).await?; - session_delete_cleanup(ctx, topic).await?; + session_delete_cleanup(ctx, topic).await +} - Ok(()) +pub(crate) async fn send_session_delete_request( + ctx: &WalletConnectCtx, + session_topic: &Topic, +) -> MmResult<(), WalletConnectCtxError> { + let delete_request = SessionDeleteRequest { + code: USER_REQUESTED, + message: "User Disconnected".to_owned(), + }; + let param = RequestParams::SessionDelete(delete_request); + + ctx.publish_request(session_topic, param).await?; + + session_delete_cleanup(ctx, session_topic).await } async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectCtxError> { diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index eede3933dc..02a2db9b0f 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -65,7 +65,8 @@ impl SessionEvents { if namespace.chains.contains(&chain) { // TODO: Notify GUI about chain changed. // Update active chain_id - *ctx.active_chain_id.lock().await = chain_id.clone().to_owned(); + ctx.set_active_chain(chain_id.clone()).await; + let params = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(topic, params, message_id).await?; diff --git a/mm2src/kdf_walletconnect/src/session/extend.rs b/mm2src/kdf_walletconnect/src/session/extend.rs index e637008264..5e34cb0e69 100644 --- a/mm2src/kdf_walletconnect/src/session/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/extend.rs @@ -6,7 +6,7 @@ use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_extend::SessionExtendRequest, ResponseParamsSuccess}}; /// Process session extend request. -pub(crate) async fn process_session_extend_request( +pub(crate) async fn reply_session_extend_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, diff --git a/mm2src/kdf_walletconnect/src/session/ping.rs b/mm2src/kdf_walletconnect/src/session/ping.rs index 3da8d26d03..87ebdba0c8 100644 --- a/mm2src/kdf_walletconnect/src/session/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/ping.rs @@ -2,9 +2,9 @@ use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::ResponseParamsSuccess}; + rpc::params::{RequestParams, ResponseParamsSuccess}}; -pub(crate) async fn process_session_ping_request( +pub(crate) async fn reply_session_ping_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, @@ -14,3 +14,13 @@ pub(crate) async fn process_session_ping_request( Ok(()) } + +pub(crate) async fn send_session_ping_request( + ctx: &WalletConnectCtx, + topic: &Topic, +) -> MmResult<(), WalletConnectCtxError> { + let param = RequestParams::SessionPing(()); + ctx.publish_request(topic, param).await?; + + Ok(()) +} diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 80d40f7c18..bc233cc0e2 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -13,7 +13,7 @@ use relay_rpc::{domain::{MessageId, Topic}, Metadata, RequestParams, ResponseParamsSuccess}}; /// Creates a new session proposal form topic and metadata. -pub(crate) async fn send_proposal( +pub(crate) async fn send_proposal_request( ctx: &WalletConnectCtx, topic: Topic, required_namespaces: Option, @@ -35,7 +35,7 @@ pub(crate) async fn send_proposal( /// Process session proposal request /// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal -pub async fn process_proposal_request( +pub async fn reply_session_proposal_request( ctx: &WalletConnectCtx, proposal: SessionProposeRequest, topic: &Topic, diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index b9a851f300..09534c0103 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -36,7 +36,7 @@ pub(crate) async fn send_session_settle_request( } /// Process session settle request. -pub(crate) async fn process_session_settle_request( +pub(crate) async fn reply_session_settle_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index 842b23ce71..ba03417bc6 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -6,7 +6,7 @@ use relay_rpc::{domain::{MessageId, Topic}, // TODO: Handle properly when multi chain is supported. // Hanlding for only cosmos support. -pub(crate) async fn process_session_update_request( +pub(crate) async fn reply_session_update_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index ece20f9eda..c8abf7950b 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -1,4 +1,3 @@ -use super::lp_commands::{connect_to_peer, create_new_pairing}; use super::{DispatcherError, DispatcherResult, PUBLIC_METHODS}; use crate::lp_native_dex::init_hw::{cancel_init_trezor, init_trezor, init_trezor_status, init_trezor_user_action}; #[cfg(target_arch = "wasm32")] @@ -55,6 +54,7 @@ use common::log::{error, warn}; use common::HttpStatusCode; use futures::Future as Future03; use http::Response; +use kdf_walletconnect::rpc_commands::{delete_connection, get_chain_id, get_session, new_connection, ping_session}; use mm2_core::data_asker::send_asked_data_rpc; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -161,6 +161,9 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, account_balance).await, "active_swaps" => handle_mmrpc(ctx, request, active_swaps_rpc).await, @@ -168,8 +171,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, add_node_to_version_stat).await, "best_orders" => handle_mmrpc(ctx, request, best_orders_rpc_v2).await, "clear_nft_db" => handle_mmrpc(ctx, request, clear_nft_db).await, - "wc_connect_pairing" => handle_mmrpc(ctx, request, connect_to_peer).await, - "wc_create_pairing" => handle_mmrpc(ctx, request, create_new_pairing).await, "enable_bch_with_tokens" => handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await, "enable_slp" => handle_mmrpc(ctx, request, enable_token::).await, "enable_eth_with_tokens" => handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await, @@ -224,6 +225,11 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, set_swap_transaction_fee_policy).await, "send_asked_data" => handle_mmrpc(ctx, request, send_asked_data_rpc).await, "z_coin_tx_history" => handle_mmrpc(ctx, request, coins::my_tx_history_v2::z_coin_tx_history_rpc).await, + "wc_new_connection" => handle_mmrpc(ctx, request, new_connection).await, + "wc_delete_connection" => handle_mmrpc(ctx, request, delete_connection).await, + "wc_get_chain_id" => handle_mmrpc(ctx, request, get_chain_id).await, + "wc_get_session" => handle_mmrpc(ctx, request, get_session).await, + "wc_ping_session" => handle_mmrpc(ctx, request, ping_session).await, #[cfg(not(target_arch = "wasm32"))] native_only_methods => match native_only_methods { #[cfg(all(feature = "enable-solana", not(target_os = "ios"), not(target_os = "android")))] diff --git a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs index 39547af0c3..ae992c6d3e 100644 --- a/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs +++ b/mm2src/mm2_main/src/rpc/lp_commands/lp_commands.rs @@ -2,7 +2,6 @@ use common::HttpStatusCode; use crypto::{CryptoCtx, CryptoCtxError, HwConnectionStatus, HwPubkey}; use derive_more::Display; use http::StatusCode; -use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use rpc::v1::types::H160 as H160Json; @@ -115,58 +114,3 @@ pub async fn trezor_connection_status( status: hw_ctx.trezor_connection_status().await, }) } - -//////////// TESTING PURPOSES ///////////// -use serde::Serialize; - -#[derive(Deserialize)] -pub struct ConnectPairingRequest { - url: String, -} - -#[derive(Debug, PartialEq, Serialize)] -pub struct ConnectPairingResponse { - pub topic: String, -} - -/// `connect_to_peer` RPC command implementation. -pub async fn connect_to_peer( - ctx: MmArc, - req: ConnectPairingRequest, -) -> MmResult { - let walletconnect_ctx = - WalletConnectCtx::try_from_ctx_or_initialize(&ctx).expect("WalletConnectCtx should be initialized by now!"); - - let topic = walletconnect_ctx - .connect_to_pairing(&req.url, true) - .await - .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; - - Ok(ConnectPairingResponse { - topic: topic.to_string(), - }) -} - -#[derive(Debug, PartialEq, Serialize)] -pub struct CreatePairingResponse { - pub url: String, -} - -#[derive(Deserialize)] -pub struct CreatePairingRequest {} - -/// `create_new_pairing` RPC command implementation. -pub async fn create_new_pairing( - ctx: MmArc, - _req: CreatePairingRequest, -) -> MmResult { - let walletconnect_ctx = - WalletConnectCtx::try_from_ctx_or_initialize(&ctx).expect("WalletConnectCtx should be initialized by now!"); - - let url = walletconnect_ctx - .create_pairing(None) - .await - .map_err(|err| TrezorConnectionError::Internal(err.to_string()))?; - - Ok(CreatePairingResponse { url }) -} From 9d12079eb64ac803a323cba589f2a4db94804a1f Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 13:36:13 +0100 Subject: [PATCH 034/125] move walletconnect rpc to mm2_main rpc --- mm2src/kdf_walletconnect/src/lib.rs | 5 +-- mm2src/kdf_walletconnect/src/session.rs | 4 +- .../kdf_walletconnect/src/session/delete.rs | 2 +- mm2src/kdf_walletconnect/src/session/ping.rs | 5 +-- mm2src/mm2_main/src/rpc.rs | 1 + .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 5 +-- .../src/rpc/wc_commands/delete_connection.rs | 30 +++++++++++++++ .../src/rpc/wc_commands/get_chain_id.rs | 20 ++++++++++ .../src/rpc/wc_commands/get_session.rs | 20 ++++++++++ .../src/rpc/wc_commands/new_connection.rs | 26 +++++++++++++ mm2src/mm2_main/src/rpc/wc_commands/ping.rs | 27 ++++++++++++++ .../src/rpc/wc_commands/wc_commands.rs | 37 +++++++++++++++++++ 12 files changed, 168 insertions(+), 14 deletions(-) create mode 100644 mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs create mode 100644 mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs create mode 100644 mm2src/mm2_main/src/rpc/wc_commands/get_session.rs create mode 100644 mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs create mode 100644 mm2src/mm2_main/src/rpc/wc_commands/ping.rs create mode 100644 mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 8f1d07700d..f13d053cdf 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,12 +1,11 @@ pub mod chain; -#[allow(unused)] mod error; +#[allow(unused)] pub mod error; mod handler; mod inbound_message; mod metadata; #[allow(unused)] mod pairing; pub mod rpc_commands; - -mod session; +pub mod session; mod storage; use chain::{build_required_namespaces, diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index beeb14053f..f9683fe33b 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,7 +1,7 @@ -pub(crate) mod delete; +pub mod delete; pub(crate) mod event; pub(crate) mod extend; -pub(crate) mod ping; +pub mod ping; pub(crate) mod propose; pub(crate) mod settle; pub(crate) mod update; diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/delete.rs index d4baf5f180..7fcd944833 100644 --- a/mm2src/kdf_walletconnect/src/session/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/delete.rs @@ -18,7 +18,7 @@ pub(crate) async fn reply_session_delete_request( session_delete_cleanup(ctx, topic).await } -pub(crate) async fn send_session_delete_request( +pub async fn send_session_delete_request( ctx: &WalletConnectCtx, session_topic: &Topic, ) -> MmResult<(), WalletConnectCtxError> { diff --git a/mm2src/kdf_walletconnect/src/session/ping.rs b/mm2src/kdf_walletconnect/src/session/ping.rs index 87ebdba0c8..55ff2af13b 100644 --- a/mm2src/kdf_walletconnect/src/session/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/ping.rs @@ -15,10 +15,7 @@ pub(crate) async fn reply_session_ping_request( Ok(()) } -pub(crate) async fn send_session_ping_request( - ctx: &WalletConnectCtx, - topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { +pub async fn send_session_ping_request(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectCtxError> { let param = RequestParams::SessionPing(()); ctx.publish_request(topic, param).await?; diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index 389f81a8b8..97e7a0d07a 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -50,6 +50,7 @@ mod dispatcher_legacy; #[path = "rpc/lp_commands/lp_commands_legacy.rs"] pub mod lp_commands_legacy; mod rate_limiter; +#[path = "rpc/wc_commands/wc_commands.rs"] pub mod wc_commands; /// Lists the RPC method not requiring the "userpass" authentication. /// None is also public to skip auth and display proper error in case of method is missing diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index c8abf7950b..a9f5036086 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -7,6 +7,7 @@ use crate::lp_ordermatch::{best_orders_rpc_v2, orderbook_rpc_v2, start_simple_ma use crate::lp_swap::swap_v2_rpcs::{active_swaps_rpc, my_recent_swaps_rpc, my_swap_status_rpc}; use crate::lp_wallet::get_mnemonic_rpc; use crate::rpc::rate_limiter::{process_rate_limit, RateLimitContext}; +use crate::rpc::wc_commands::{delete_connection, get_chain_id, get_session, new_connection, ping_session}; use crate::{lp_stats::{add_node_to_version_stat, remove_node_from_version_stat, start_version_stat_collection, stop_version_stat_collection, update_version_stat_collection}, lp_swap::{get_locked_amount_rpc, max_maker_vol, recreate_swap_data, trade_preimage_rpc}, @@ -54,7 +55,6 @@ use common::log::{error, warn}; use common::HttpStatusCode; use futures::Future as Future03; use http::Response; -use kdf_walletconnect::rpc_commands::{delete_connection, get_chain_id, get_session, new_connection, ping_session}; use mm2_core::data_asker::send_asked_data_rpc; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -161,9 +161,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, account_balance).await, "active_swaps" => handle_mmrpc(ctx, request, active_swaps_rpc).await, diff --git a/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs new file mode 100644 index 0000000000..07118b6c4c --- /dev/null +++ b/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs @@ -0,0 +1,30 @@ +use kdf_walletconnect::{session::delete::send_session_delete_request, WalletConnectCtx}; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::*; +use serde::{Deserialize, Serialize}; + +use super::WalletConnectRpcError; + +#[derive(Debug, PartialEq, Serialize)] +pub struct DeleteConnectionResponse { + pub successful: bool, +} + +#[derive(Deserialize)] +pub struct DeleteConnectionRequest { + topic: String, +} + +/// `delete connection` RPC command implementation. +pub async fn delete_connection( + ctx: MmArc, + req: DeleteConnectionRequest, +) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) + .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + send_session_delete_request(&ctx, &req.topic.into()) + .await + .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; + + Ok(DeleteConnectionResponse { successful: true }) +} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs new file mode 100644 index 0000000000..4243167278 --- /dev/null +++ b/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs @@ -0,0 +1,20 @@ +use kdf_walletconnect::WalletConnectCtx; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::*; +use serde::Serialize; + +use super::{EmptyRpcRequst, WalletConnectRpcError}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct GetChainIdResponse { + pub chain_id: String, +} + +/// `delete connection` RPC command implementation. +pub async fn get_chain_id(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) + .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let chain_id = ctx.get_active_chain_id().await; + + Ok(GetChainIdResponse { chain_id }) +} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs new file mode 100644 index 0000000000..d5a34644ff --- /dev/null +++ b/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs @@ -0,0 +1,20 @@ +use kdf_walletconnect::{session::Session, WalletConnectCtx}; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::*; +use serde::Serialize; + +use super::{EmptyRpcRequst, WalletConnectRpcError}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct GetSessionResponse { + pub session: Option, +} + +/// `delete connection` RPC command implementation. +pub async fn get_session(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) + .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let session = ctx.get_session().await; + + Ok(GetSessionResponse { session }) +} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs new file mode 100644 index 0000000000..46b58d5988 --- /dev/null +++ b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs @@ -0,0 +1,26 @@ +use kdf_walletconnect::WalletConnectCtx; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::*; +use serde::Serialize; + +use super::{EmptyRpcRequst, WalletConnectRpcError}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct CreateConnectionResponse { + pub url: String, +} + +/// `new_connection` RPC command implementation. +pub async fn new_connection( + ctx: MmArc, + _req: EmptyRpcRequst, +) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) + .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let url = ctx + .new_connection(None) + .await + .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; + + Ok(CreateConnectionResponse { url }) +} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/ping.rs b/mm2src/mm2_main/src/rpc/wc_commands/ping.rs new file mode 100644 index 0000000000..a49e5d7d48 --- /dev/null +++ b/mm2src/mm2_main/src/rpc/wc_commands/ping.rs @@ -0,0 +1,27 @@ +use kdf_walletconnect::{session::ping::send_session_ping_request, WalletConnectCtx}; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::*; +use serde::{Deserialize, Serialize}; + +use super::WalletConnectRpcError; + +#[derive(Debug, PartialEq, Serialize)] +pub struct SessionPingResponse { + pub successful: bool, +} + +#[derive(Deserialize)] +pub struct SessionPingRequest { + topic: String, +} + +/// `ping session` RPC command implementation. +pub async fn ping_session(ctx: MmArc, req: SessionPingRequest) -> MmResult { + let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) + .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + send_session_ping_request(&ctx, &req.topic.into()) + .await + .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; + + Ok(SessionPingResponse { successful: true }) +} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs new file mode 100644 index 0000000000..ec63b4a60b --- /dev/null +++ b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs @@ -0,0 +1,37 @@ +mod delete_connection; +mod get_chain_id; +mod get_session; +mod new_connection; +mod ping; + +use common::HttpStatusCode; +pub use delete_connection::delete_connection; +use derive_more::Display; +pub use get_chain_id::get_chain_id; +pub use get_session::get_session; +use http::StatusCode; +pub use new_connection::new_connection; +pub use ping::ping_session; +use serde::Deserialize; + +#[derive(Deserialize)] +pub struct EmptyRpcRequst {} + +#[derive(Serialize, Display, SerializeErrorType)] +#[serde(tag = "error_type", content = "error_data")] +pub enum WalletConnectRpcError { + InternalError(String), + InitializationError(String), + SessionRequestError(String), +} + +impl HttpStatusCode for WalletConnectRpcError { + fn status_code(&self) -> StatusCode { + match self { + WalletConnectRpcError::InitializationError(_) => StatusCode::BAD_REQUEST, + WalletConnectRpcError::SessionRequestError(_) | WalletConnectRpcError::InternalError(_) => { + StatusCode::INTERNAL_SERVER_ERROR + }, + } + } +} From 03d9978d360336dcef80bbd43b5c7a11e0f41f02 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 13:45:07 +0100 Subject: [PATCH 035/125] remove mm2_test_helpers lock file --- mm2src/mm2_test_helpers/Cargo.lock | 4107 ---------------------------- 1 file changed, 4107 deletions(-) delete mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock deleted file mode 100644 index b7c1a47c49..0000000000 --- a/mm2src/mm2_test_helpers/Cargo.lock +++ /dev/null @@ -1,4107 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" - -[[package]] -name = "argon2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" -dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", - "zeroize", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.3.1", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" -dependencies = [ - "async-lock", - "cfg-if 1.0.0", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[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-process" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" -dependencies = [ - "async-channel 2.3.1", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if 1.0.0", - "event-listener 5.3.1", - "futures-lite", - "rustix", - "tracing", -] - -[[package]] -name = "async-signal" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if 1.0.0", - "futures-core", - "futures-io", - "rustix", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-std" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers 0.3.0", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.3.0", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "bip32" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" -dependencies = [ - "bs58", - "hkd32", - "hmac 0.11.0", - "ripemd160", - "secp256k1 0.20.3", - "sha2 0.9.9", - "subtle", - "zeroize", -] - -[[package]] -name = "bip39" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" -dependencies = [ - "bitcoin_hashes", - "rand_core 0.6.4", - "zeroize", -] - -[[package]] -name = "bitcoin" -version = "0.29.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" -dependencies = [ - "bech32", - "bitcoin_hashes", - "secp256k1 0.24.3", -] - -[[package]] -name = "bitcoin_hashes" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" - -[[package]] -name = "bitcrypto" -version = "0.1.0" -dependencies = [ - "groestl", - "primitives", - "ripemd160", - "serialization", - "sha-1", - "sha2 0.10.8", - "sha3 0.9.1", - "siphasher", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[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 = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding 0.2.1", - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel 2.3.1", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[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-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - -[[package]] -name = "bytes" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "cc" -version = "1.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07b1695e2c7e8fc85310cde85aeaab7e3097f593c91d209d3f9df76c928100f0" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chain" -version = "0.1.0" -dependencies = [ - "bitcoin", - "bitcrypto", - "primitives", - "rustc-hex", - "serialization", - "serialization_derive", -] - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets", -] - -[[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 = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "common" -version = "0.1.0" -dependencies = [ - "anyhow", - "arrayref", - "async-trait", - "backtrace", - "bytes 1.7.2", - "cc", - "cfg-if 1.0.0", - "chrono", - "crossbeam", - "derive_more", - "env_logger", - "findshlibs", - "fnv", - "futures 0.1.31", - "futures 0.3.30", - "futures-timer", - "gstuff", - "hex", - "http 0.2.12", - "http-body 0.1.0", - "hyper", - "hyper-rustls", - "instant", - "itertools", - "js-sys", - "lazy_static", - "libc", - "lightning", - "log", - "parking_lot", - "parking_lot_core 0.6.3", - "primitive-types", - "rand 0.7.3", - "regex", - "rustc-hash", - "ser_error", - "ser_error_derive", - "serde", - "serde-wasm-bindgen", - "serde_derive", - "serde_json", - "serde_repr", - "sha2 0.10.8", - "tokio", - "uuid", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", - "winapi", -] - -[[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_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto" -version = "1.0.0" -dependencies = [ - "aes", - "argon2", - "arrayref", - "async-trait", - "base64", - "bip32", - "bip39", - "bitcrypto", - "bs58", - "cbc", - "cfg-if 1.0.0", - "cipher", - "common", - "derive_more", - "enum-primitive-derive", - "enum_derives", - "futures 0.3.30", - "hex", - "hmac 0.12.1", - "http 0.2.12", - "hw_common", - "keys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_eth", - "mm2_metamask", - "num-traits", - "parking_lot", - "primitives", - "rpc", - "rpc_task", - "rustc-hex", - "secp256k1 0.20.3", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", - "serde_json", - "sha2 0.10.8", - "trezor", - "wasm-bindgen-test", - "web3", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "db_common" -version = "0.1.0" -dependencies = [ - "common", - "crossbeam-channel", - "futures 0.3.30", - "hex", - "log", - "rusqlite", - "sql-builder", - "tokio", - "uuid", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case", - "proc-macro2", - "quote 1.0.37", - "rustc_version 0.4.1", - "syn 2.0.77", -] - -[[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", - "crypto-common", - "subtle", -] - -[[package]] -name = "edit-distance" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "enum-primitive-derive" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" -dependencies = [ - "num-traits", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "enum_derives" -version = "0.1.0" -dependencies = [ - "itertools", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[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 = "ethabi" -version = "17.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3 0.10.8", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "ethcore-transaction" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "ethereum-types", - "ethkey", - "keccak-hash", - "rlp", - "rustc-hex", - "unexpected", -] - -[[package]] -name = "ethereum-types" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - -[[package]] -name = "ethkey" -version = "0.3.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "byteorder", - "edit-distance", - "ethereum-types", - "log", - "mem", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "tiny-keccak 1.4.4", -] - -[[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 = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - -[[package]] -name = "fastrand" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" - -[[package]] -name = "findshlibs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers 0.2.6", - "send_wrapper", -] - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures 0.1.31", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "groestl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "gstuff" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes 1.7.2", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.5.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" -dependencies = [ - "ahash", -] - -[[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 = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkd32" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" -dependencies = [ - "hmac 0.11.0", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[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.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -dependencies = [ - "bytes 0.4.12", - "fnv", - "itoa 0.4.8", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes 1.7.2", - "fnv", - "itoa 1.0.11", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "http 0.1.21", - "tokio-buf", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes 1.7.2", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" - -[[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 = "hw_common" -version = "0.1.0" -dependencies = [ - "async-trait", - "bip32", - "common", - "derive_more", - "futures 0.3.30", - "js-sys", - "mm2_err_handle", - "rusb", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes 1.7.2", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa 1.0.11", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "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", - "rustls", - "tokio", - "tokio-rustls", - "webpki-roots", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg 1.3.0", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" -dependencies = [ - "equivalent", - "hashbrown 0.14.5", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding 0.3.3", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipnet" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures 0.3.30", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "keccak-hash" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" -dependencies = [ - "primitive-types", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "keys" -version = "0.1.0" -dependencies = [ - "base58", - "bech32", - "bitcrypto", - "derive_more", - "lazy_static", - "primitives", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.159" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" - -[[package]] -name = "libsqlite3-sys" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "libusb1-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "lightning" -version = "0.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" -dependencies = [ - "bitcoin", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg 1.3.0", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -dependencies = [ - "value-bag", -] - -[[package]] -name = "mach2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" -dependencies = [ - "libc", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "mem" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "metrics" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash", - "metrics-macros", - "portable-atomic", -] - -[[package]] -name = "metrics-exporter-prometheus" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" -dependencies = [ - "base64", - "hyper", - "indexmap 1.9.3", - "ipnet", - "metrics", - "metrics-util", - "quanta", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "metrics-macros" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "metrics-util" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" -dependencies = [ - "aho-corasick", - "crossbeam-epoch", - "crossbeam-utils", - "hashbrown 0.13.1", - "indexmap 1.9.3", - "metrics", - "num_cpus", - "ordered-float", - "quanta", - "radix_trie", - "sketches-ddsketch", -] - -[[package]] -name = "minicov" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" -dependencies = [ - "cc", - "walkdir", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", -] - -[[package]] -name = "mm2_core" -version = "0.1.0" -dependencies = [ - "arrayref", - "async-std", - "async-trait", - "cfg-if 1.0.0", - "common", - "db_common", - "derive_more", - "futures 0.3.30", - "gstuff", - "hex", - "instant", - "lazy_static", - "mm2_err_handle", - "mm2_event_stream", - "mm2_metrics", - "mm2_rpc", - "primitives", - "rand 0.7.3", - "rustls", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "shared_ref_counter", - "tokio", - "uuid", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_err_handle" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.1.31", - "http 0.2.12", - "itertools", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_eth" -version = "0.1.0" -dependencies = [ - "ethabi", - "ethkey", - "hex", - "indexmap 1.9.3", - "itertools", - "mm2_err_handle", - "secp256k1 0.20.3", - "serde", - "serde_json", - "web3", -] - -[[package]] -name = "mm2_event_stream" -version = "0.1.0" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "common", - "futures 0.3.30", - "parking_lot", - "serde", - "tokio", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_io" -version = "0.1.0" -dependencies = [ - "async-std", - "common", - "derive_more", - "futures 0.3.30", - "gstuff", - "mm2_err_handle", - "rand 0.7.3", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_metamask" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.30", - "itertools", - "js-sys", - "jsonrpc-core", - "lazy_static", - "mm2_err_handle", - "mm2_eth", - "parking_lot", - "serde", - "serde_derive", - "serde_json", - "wasm-bindgen", - "wasm-bindgen-futures", - "web3", -] - -[[package]] -name = "mm2_metrics" -version = "0.1.0" -dependencies = [ - "base64", - "common", - "derive_more", - "futures 0.3.30", - "hyper", - "hyper-rustls", - "itertools", - "metrics", - "metrics-exporter-prometheus", - "metrics-util", - "mm2_err_handle", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "mm2_net" -version = "0.1.0" -dependencies = [ - "async-trait", - "base64", - "bytes 1.7.2", - "cfg-if 1.0.0", - "common", - "derive_more", - "ethkey", - "futures 0.3.30", - "futures-util", - "gstuff", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "hyper", - "js-sys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_state_machine", - "pin-project", - "prost", - "rand 0.7.3", - "rustls", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-rustls", - "tonic", - "tower-service", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "mm2_number" -version = "0.1.0" -dependencies = [ - "bigdecimal", - "num-bigint", - "num-rational", - "num-traits", - "paste", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_rpc" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.3.30", - "gstuff", - "http 0.2.12", - "mm2_err_handle", - "mm2_number", - "rpc", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "uuid", -] - -[[package]] -name = "mm2_state_machine" -version = "0.1.0" -dependencies = [ - "async-trait", -] - -[[package]] -name = "mm2_test_helpers" -version = "0.1.0" -dependencies = [ - "bytes 1.7.2", - "cfg-if 1.0.0", - "chrono", - "common", - "crypto", - "db_common", - "futures 0.3.30", - "gstuff", - "http 0.2.12", - "lazy_static", - "mm2_core", - "mm2_io", - "mm2_metrics", - "mm2_net", - "mm2_number", - "mm2_rpc", - "rand 0.7.3", - "regex", - "rpc", - "serde", - "serde_derive", - "serde_json", - "uuid", -] - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec 1.13.2", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "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", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg 1.3.0", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -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 = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec 0.7.6", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version 0.2.3", - "smallvec 0.6.14", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.5.6", - "smallvec 1.13.2", - "windows-targets", -] - -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" - -[[package]] -name = "polling" -version = "3.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" -dependencies = [ - "cfg-if 1.0.0", - "concurrent-queue", - "hermit-abi 0.4.0", - "pin-project-lite", - "rustix", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "portable-atomic" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d30538d42559de6b034bc76fd6dd4c38961b1ee5c6c56e3808c50128fdbc22ce" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "primitive-types" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "uint", -] - -[[package]] -name = "primitives" -version = "0.1.0" -dependencies = [ - "bitcoin_hashes", - "byteorder", - "rustc-hex", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes 1.7.2", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "quanta" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" -dependencies = [ - "crossbeam-utils", - "libc", - "mach2", - "once_cell", - "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", - "web-sys", - "winapi", -] - -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -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", - "wasm-bindgen", - "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -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-cpuid" -version = "10.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" -dependencies = [ - "bitflags 1.3.2", -] - -[[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.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "355ae415ccd3a04315d3f8246e86d67689ea74d88d915576e1589a351062a13b" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "regex" -version = "1.10.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if 1.0.0", - "getrandom 0.2.15", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes 1.7.2", - "rustc-hex", -] - -[[package]] -name = "rpc" -version = "0.1.0" -dependencies = [ - "chain", - "keys", - "log", - "primitives", - "rustc-hex", - "script", - "serde", - "serde_derive", - "serde_json", - "serialization", -] - -[[package]] -name = "rpc_task" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.30", - "mm2_err_handle", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", -] - -[[package]] -name = "rusb" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" -dependencies = [ - "libc", - "libusb1-sys", -] - -[[package]] -name = "rusqlite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec 1.13.2", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver 1.0.23", -] - -[[package]] -name = "rustix" -version = "0.38.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "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 = [ - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[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 = "script" -version = "0.1.0" -dependencies = [ - "bitcrypto", - "blake2b_simd", - "chain", - "keys", - "log", - "primitives", - "serde", - "serialization", -] - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "secp256k1" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" -dependencies = [ - "rand 0.6.5", - "secp256k1-sys 0.4.2", -] - -[[package]] -name = "secp256k1" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" -dependencies = [ - "bitcoin_hashes", - "secp256k1-sys 0.6.1", -] - -[[package]] -name = "secp256k1-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" -dependencies = [ - "cc", -] - -[[package]] -name = "secp256k1-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" -dependencies = [ - "cc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "ser_error" -version = "0.1.0" -dependencies = [ - "serde", -] - -[[package]] -name = "ser_error_derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "ser_error", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "serde_json" -version = "1.0.128" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "indexmap 2.5.0", - "itoa 1.0.11", - "memchr", - "ryu", - "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 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "serialization" -version = "0.1.0" -dependencies = [ - "byteorder", - "derive_more", - "primitives", - "test_helpers", -] - -[[package]] -name = "serialization_derive" -version = "0.1.0" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "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 1.0.0", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shared_ref_counter" -version = "0.1.0" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" - -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg 1.3.0", -] - -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "sql-builder" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" -dependencies = [ - "anyhow", - "thiserror", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.77" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test_helpers" -version = "0.1.0" -dependencies = [ - "hex", -] - -[[package]] -name = "thiserror" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "tiny-keccak" -version = "1.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" -dependencies = [ - "backtrace", - "bytes 1.7.2", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-buf" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" -dependencies = [ - "bytes 1.7.2", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap 2.5.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "base64", - "bytes 1.7.2", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "percent-encoding", - "pin-project", - "prost", - "tokio-stream", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "trezor" -version = "0.1.1" -dependencies = [ - "async-std", - "async-trait", - "bip32", - "byteorder", - "common", - "derive_more", - "ethcore-transaction", - "ethereum-types", - "ethkey", - "futures 0.3.30", - "hw_common", - "js-sys", - "lazy_static", - "mm2_err_handle", - "prost", - "rand 0.7.3", - "rpc_task", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unexpected" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "uuid" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" -dependencies = [ - "getrandom 0.2.15", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "value-bag" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote 1.0.37", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "wasm-bindgen-test" -version = "0.3.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68497a05fb21143a08a7d24fc81763384a3072ee43c44e86aad1744d6adef9d9" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "minicov", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "web-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web3" -version = "0.19.0" -source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" -dependencies = [ - "arrayvec 0.7.6", - "derive_more", - "ethabi", - "ethereum-types", - "futures 0.3.30", - "futures-timer", - "getrandom 0.2.15", - "hex", - "idna", - "js-sys", - "jsonrpc-core", - "log", - "parking_lot", - "pin-project", - "rand 0.8.5", - "rlp", - "serde", - "serde-wasm-bindgen", - "serde_json", - "tiny-keccak 2.0.2", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.77", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -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 1.0.37", - "syn 2.0.77", -] From 32e46d9f295caadc46918588b68085c14e75d881 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 13:51:44 +0100 Subject: [PATCH 036/125] format mm2_net cargo.toml --- mm2src/mm2_net/Cargo.toml | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/mm2src/mm2_net/Cargo.toml b/mm2src/mm2_net/Cargo.toml index c9718bd755..5d2aefb538 100644 --- a/mm2src/mm2_net/Cargo.toml +++ b/mm2src/mm2_net/Cargo.toml @@ -46,14 +46,7 @@ tower-service = "0.3" wasm-bindgen = "0.2.86" wasm-bindgen-test = { version = "0.3.2" } wasm-bindgen-futures = "0.4.21" -web-sys = { version = "0.3.55", features = ["console", "CloseEvent", "DomException", "ErrorEvent", "IdbDatabase", - "IdbCursor", "IdbCursorWithValue", "IdbFactory", "IdbIndex", "IdbIndexParameters", "IdbObjectStore", - "IdbObjectStoreParameters", "IdbOpenDbRequest", "IdbKeyRange", "IdbTransaction", "IdbTransactionMode", "Request", - "RequestInit", - "RequestMode", - "Response", - "Window","Headers", - "IdbVersionChangeEvent", "MessageEvent", "MessagePort", "ReadableStreamDefaultReader", "ReadableStream", "SharedWorker", "Url", "WebSocket"] } +web-sys = { version = "0.3.55", features = ["console", "CloseEvent", "DomException", "ErrorEvent", "IdbDatabase", "IdbCursor", "IdbCursorWithValue", "IdbFactory", "IdbIndex", "IdbIndexParameters", "IdbObjectStore", "IdbObjectStoreParameters", "IdbOpenDbRequest", "IdbKeyRange", "IdbTransaction", "IdbTransactionMode", "Request", "RequestInit", "RequestMode", "Response", "Window","Headers", "IdbVersionChangeEvent", "MessageEvent", "MessagePort", "ReadableStreamDefaultReader", "ReadableStream", "SharedWorker", "Url", "WebSocket"] } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] From 1e352b1ec2e6907401953005484c67e4e5e5355a Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 13:58:27 +0100 Subject: [PATCH 037/125] update storage session upon session settle response/request --- mm2src/kdf_walletconnect/src/lib.rs | 2 +- mm2src/kdf_walletconnect/src/session/settle.rs | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index f13d053cdf..8696096a55 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -419,7 +419,7 @@ impl WalletConnectCtx { /// WalletConnect can be usable in KDF. pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectCtxError> { // Initialized WalletConnectCtx - let wallet_connect = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let wallet_connect = WalletConnectCtx::try_from_ctx_or_initialize(ctx)?; // WalletConnectCtx is initialized, now we can connect to relayer client. wallet_connect.connect_client().await?; diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index 09534c0103..db59fd135b 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -1,10 +1,11 @@ use super::{Session, THIRTY_DAYS}; use crate::chain::{SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; +use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; use common::log::info; -use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::{MapMmError, MmResult}; use relay_rpc::rpc::params::session::{Namespace, SettleNamespaces}; use relay_rpc::rpc::params::RequestParams; use relay_rpc::{domain::{MessageId, Topic}, @@ -50,6 +51,13 @@ pub(crate) async fn reply_session_settle_request( session.relay = settle.relay.clone(); session.expiry = settle.expiry; + // Update storage session. + ctx.storage + .db + .update_session(session) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + info!("Session successfully settled for topic: {:?}", topic); } } From a30511beabceca36e165b433cf571c80aa72ecf5 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 16:07:30 +0100 Subject: [PATCH 038/125] add tokio to wc dependency list --- Cargo.lock | 1 + mm2src/kdf_walletconnect/Cargo.toml | 3 +++ mm2src/kdf_walletconnect/src/lib.rs | 2 +- mm2src/kdf_walletconnect/src/session/update.rs | 10 +++++++++- 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5a5079313b..036c3e9fd2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3575,6 +3575,7 @@ dependencies = [ "serde_json", "sha2 0.10.8", "thiserror", + "tokio", "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 23e8f02486..c6542a127a 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -33,6 +33,9 @@ serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } x25519-dalek = { version = "2.0", features = ["static_secrets"] } +[target.'cfg(not(target_arch = "wasm32"))'.dependencies] +tokio = { version = "1.20" } + [target.'cfg(target_arch = "wasm32")'.dependencies] mm2_db = { path = "../mm2_db" } mm2_test_helpers = { path = "../mm2_test_helpers" } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 8696096a55..8caf924099 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -111,7 +111,7 @@ impl WalletConnectCtx { let key = SigningKey::generate(&mut rand::thread_rng()); AuthToken::new(AUTH_TOKEN_SUB) .aud(RELAY_ADDRESS) - .ttl(Duration::from_secs(60 * 60)) + .ttl(Duration::from_secs(8 * 60 * 60)) .as_jwt(&key) .unwrap() }; diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index ba03417bc6..66929827d2 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -1,6 +1,7 @@ +use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; -use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_update::SessionUpdateRequest, ResponseParamsSuccess}}; @@ -16,6 +17,13 @@ pub(crate) async fn reply_session_update_request( let mut session = ctx.session.lock().await; if let Some(session) = session.as_mut() { session.namespaces = update.namespaces.0.clone(); + + // Update storage session. + ctx.storage + .db + .update_session(session) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; }; } From 341b18ec117597b10b5f82193c8dcc84c38580f9 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 26 Sep 2024 17:01:09 +0100 Subject: [PATCH 039/125] improve tenderming with_pubkey activation params --- .../src/tendermint_with_assets_activation.rs | 78 ++++++++++--------- .../kdf_walletconnect/src/storage/sqlite.rs | 6 +- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index d701aa4523..ead67e6ab1 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -40,7 +40,7 @@ impl RegisterTokenInfo for TendermintCoin { } } -#[derive(Clone, Default, Deserialize)] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct WalletConnectParams { #[serde(default)] pub account_index: u8, @@ -48,6 +48,19 @@ pub struct WalletConnectParams { pub enabled: bool, } +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "snake_case")] +pub enum TendermintPubkeyActivationParams { + /// Activation via public key + WithPubkey { + #[serde(deserialize_with = "deserialize_account_public_key")] + pubkey: TendermintPublicKey, + is_keplr_from_ledger: bool, + }, + /// Activation via WalletConnect + WalletConnect(WalletConnectParams), +} + #[derive(Clone, Deserialize)] pub struct TendermintActivationParams { nodes: Vec, @@ -60,15 +73,10 @@ pub struct TendermintActivationParams { #[serde(default)] pub path_to_address: HDPathAccountToAddressId, #[serde(default)] - #[serde(deserialize_with = "deserialize_account_public_key")] - with_pubkey: Option, - #[serde(default)] - is_keplr_from_ledger: bool, - #[serde(default)] - walletconnect: WalletConnectParams, + pub activation_params: Option, } -fn deserialize_account_public_key<'de, D>(deserializer: D) -> Result, D::Error> +fn deserialize_account_public_key<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { @@ -86,7 +94,7 @@ where .iter() .map(|i| i.as_u64().unwrap() as u8) .collect(); - Ok(Some(TendermintPublicKey::from_raw_ed25519(&value).unwrap())) + Ok(TendermintPublicKey::from_raw_ed25519(&value).unwrap()) }, Some("secp256k1") => { let value: Vec = value @@ -95,7 +103,7 @@ where .iter() .map(|i| i.as_u64().unwrap() as u8) .collect(); - Ok(Some(TendermintPublicKey::from_raw_secp256k1(&value).unwrap())) + Ok(TendermintPublicKey::from_raw_secp256k1(&value).unwrap()) }, _ => Err(serde::de::Error::custom( "Unsupported pubkey algorithm. Use one of ['ed25519', 'secp256k1']", @@ -285,35 +293,29 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { let conf = TendermintConf::try_from_json(&ticker, coin_conf)?; + let mut is_keplr_from_ledger = false; - let use_with_pubkey = activation_request.with_pubkey.is_some(); - let is_keplr_from_ledger = activation_request.is_keplr_from_ledger && use_with_pubkey; - let use_walletconnect = activation_request.walletconnect.enabled; - - if use_walletconnect && use_with_pubkey { - return MmError::err(TendermintInitError { - ticker: ticker.clone(), - kind: TendermintInitErrorKind::Internal("Can't activate tendermint in pubkey and WalletConnect mode enabled. Make sure only one is enabled.".to_string()), - }); - }; - - if (use_with_pubkey || use_walletconnect) && (ctx.is_watcher() || ctx.use_watchers()) { - return MmError::err(TendermintInitError { - ticker: ticker.clone(), - kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, - }); - }; - - let activation_policy = if let Some(pubkey) = activation_request.with_pubkey { - TendermintActivationPolicy::with_public_key(pubkey) - } else if use_walletconnect { - get_walletconnect_pubkey( - &ctx, - &activation_request.walletconnect, - protocol_conf.chain_id.as_ref(), - &ticker, - ) - .await? + let activation_policy = if let Some(params) = activation_request.activation_params { + println!("{params:?}"); + if ctx.is_watcher() || ctx.use_watchers() { + return MmError::err(TendermintInitError { + ticker: ticker.clone(), + kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, + }); + }; + + match params { + TendermintPubkeyActivationParams::WithPubkey { + pubkey, + is_keplr_from_ledger: temp, + } => { + is_keplr_from_ledger = temp; + TendermintActivationPolicy::with_public_key(pubkey) + }, + TendermintPubkeyActivationParams::WalletConnect(params) => { + get_walletconnect_pubkey(&ctx, ¶ms, protocol_conf.chain_id.as_ref(), &ticker).await? + }, + } } else { let private_key_policy = PrivKeyBuildPolicy::detect_priv_key_policy(&ctx).mm_err(|e| TendermintInitError { diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index bdad09c63c..fad3becbba 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -126,11 +126,11 @@ impl WalletConnectStorageOps for SqliteSessionStorage { .map_to_mm(AsyncConnError::from) } - async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { todo!() } + async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { Ok(None) } - async fn get_all_sessions(&self) -> MmResult, Self::Error> { todo!() } + async fn get_all_sessions(&self) -> MmResult, Self::Error> { Ok(vec![]) } async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { todo!() } - async fn update_session(&self, _session: &Session) -> MmResult<(), Self::Error> { todo!() } + async fn update_session(&self, _session: &Session) -> MmResult<(), Self::Error> { Ok(()) } } From 4c8e29926c598756d2085b32f734e695f6acc261 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 29 Sep 2024 14:21:36 +0100 Subject: [PATCH 040/125] minor changes --- mm2src/coins/Cargo.toml | 22 +++++++++---------- mm2src/kdf_walletconnect/src/session/event.rs | 2 +- .../kdf_walletconnect/src/session/propose.rs | 11 +++------- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index 4296e5dac9..715bb2f1af 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -7,19 +7,19 @@ edition = "2018" zhtlc-native-tests = [] # TODO enable-solana = [ - "dep:bincode", - "dep:ed25519-dalek-bip32", - "dep:solana-client", - "dep:solana-sdk", - "dep:solana-transaction-status", - "dep:spl-token", - "dep:spl-associated-token-account", - "dep:satomic-swap" + "dep:bincode", + "dep:ed25519-dalek-bip32", + "dep:solana-client", + "dep:solana-sdk", + "dep:solana-transaction-status", + "dep:spl-token", + "dep:spl-associated-token-account", + "dep:satomic-swap" ] enable-sia = [ - "dep:reqwest", - "dep:blake2b_simd", - "dep:sia-rust" + "dep:reqwest", + "dep:blake2b_simd", + "dep:sia-rust" ] default = [] run-docker-tests = [] diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index 02a2db9b0f..8ca92e5113 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -61,7 +61,7 @@ impl SessionEvents { ) -> MmResult<(), WalletConnectCtxError> { if ctx.is_chain_supported(chain_id) { if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { - if let Some(namespace) = ctx.namespaces.get(&key) { + if let Some(namespace) = ctx.session.lock().await.namespaces { if namespace.chains.contains(&chain) { // TODO: Notify GUI about chain changed. // Update active chain_id diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index bc233cc0e2..967845b5da 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -1,5 +1,6 @@ use super::{settle::send_session_settle_request, Session}; use crate::{error::WalletConnectCtxError, + metadata::generate_metadata, session::{SessionKey, SessionType, THIRTY_DAYS}, storage::WalletConnectStorageOps, WalletConnectCtx}; @@ -25,7 +26,7 @@ pub(crate) async fn send_proposal_request( let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], proposer, - required_namespaces: required_namespaces.unwrap_or(ctx.namespaces.clone()), + required_namespaces: required_namespaces.unwrap_or(generate_metadata()), }); ctx.publish_request(&topic, session_proposal).await?; @@ -78,13 +79,9 @@ pub async fn reply_session_proposal_request( let mut old_session = ctx.session.lock().await; *old_session = Some(session.clone()); - let mut subs = ctx.subscriptions.lock().await; - subs.push(session_topic.clone()); } - { - send_session_settle_request(ctx, &session).await?; - }; + send_session_settle_request(ctx, &session).await?; // Respond to incoming session propose. let param = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { @@ -141,8 +138,6 @@ pub(crate) async fn process_session_propose_response( let mut old_session = ctx.session.lock().await; *old_session = Some(session); - let mut subs = ctx.subscriptions.lock().await; - subs.push(session_topic.clone()); }; // Activate pairing_topic From 73d8315541226ed9c5c11d58c99c432107c6a22d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 29 Sep 2024 15:08:38 +0100 Subject: [PATCH 041/125] fix proposer mod --- Cargo.lock | 1 + mm2src/kdf_walletconnect/Cargo.toml | 1 + mm2src/kdf_walletconnect/src/session/event.rs | 19 +++++++----- .../kdf_walletconnect/src/session/propose.rs | 11 +++++-- .../src/storage/indexed_db.rs | 30 +++++++++++++++++++ 5 files changed, 51 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 036c3e9fd2..f0c0a593ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3562,6 +3562,7 @@ dependencies = [ "futures 0.3.28", "hex", "hkdf", + "js-sys", "mm2_core", "mm2_db", "mm2_err_handle", diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index c6542a127a..8e786df364 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -37,6 +37,7 @@ x25519-dalek = { version = "2.0", features = ["static_secrets"] } tokio = { version = "1.20" } [target.'cfg(target_arch = "wasm32")'.dependencies] +js-sys = { version = "0.3.27" } mm2_db = { path = "../mm2_db" } mm2_test_helpers = { path = "../mm2_test_helpers" } wasm-bindgen = "0.2.86" diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index 8ca92e5113..cd5e987695 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -61,16 +61,19 @@ impl SessionEvents { ) -> MmResult<(), WalletConnectCtxError> { if ctx.is_chain_supported(chain_id) { if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { - if let Some(namespace) = ctx.session.lock().await.namespaces { - if namespace.chains.contains(&chain) { - // TODO: Notify GUI about chain changed. - // Update active chain_id - ctx.set_active_chain(chain_id.clone()).await; + if let Some(session) = ctx.session.lock().await.as_ref() { + if let Some(namespace) = session.namespaces.get(&key) { + let chains = namespace.chains.clone().unwrap_or_default(); + if chains.contains(&chain) { + // TODO: Notify GUI about chain changed. + // Update active chain_id + ctx.set_active_chain(chain_id.clone()).await; - let params = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, params, message_id).await?; + let params = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, params, message_id).await?; - return Ok(()); + return Ok(()); + } } } } diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 967845b5da..bc233cc0e2 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -1,6 +1,5 @@ use super::{settle::send_session_settle_request, Session}; use crate::{error::WalletConnectCtxError, - metadata::generate_metadata, session::{SessionKey, SessionType, THIRTY_DAYS}, storage::WalletConnectStorageOps, WalletConnectCtx}; @@ -26,7 +25,7 @@ pub(crate) async fn send_proposal_request( let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], proposer, - required_namespaces: required_namespaces.unwrap_or(generate_metadata()), + required_namespaces: required_namespaces.unwrap_or(ctx.namespaces.clone()), }); ctx.publish_request(&topic, session_proposal).await?; @@ -79,9 +78,13 @@ pub async fn reply_session_proposal_request( let mut old_session = ctx.session.lock().await; *old_session = Some(session.clone()); + let mut subs = ctx.subscriptions.lock().await; + subs.push(session_topic.clone()); } - send_session_settle_request(ctx, &session).await?; + { + send_session_settle_request(ctx, &session).await?; + }; // Respond to incoming session propose. let param = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { @@ -138,6 +141,8 @@ pub(crate) async fn process_session_propose_response( let mut old_session = ctx.session.lock().await; *old_session = Some(session); + let mut subs = ctx.subscriptions.lock().await; + subs.push(session_topic.clone()); }; // Activate pairing_topic diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index 6496116785..2872fcac1a 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -117,3 +117,33 @@ impl WalletConnectStorageOps for IDBSessionStorage { async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { self.save_session(&session).await } } + +pub(crate) mod crypto { + use js_sys::{JsString, Object, Reflect, Uint8Array}; + + fn rsa_oaep_params() -> Object { + // Create a new empty JavaScript object + let rsa_oaep_params = Object::new(); + + // "name": "RSA-OAEP" + let _ = Reflect::set(&rsa_oaep_params, &JsString::from("name"), &JsString::from("RSA-OAEP")); + + // "modulusLength": 2048 + let _ = Reflect::set(&rsa_oaep_params, &JsString::from("modulusLength"), &2048.into()); + + // "publicExponent": new Uint8Array([0x01, 0x00, 0x01]) + let public_exponent = Uint8Array::new_with_length(3); + public_exponent.copy_from(&[0x01, 0x00, 0x01]); + + let _ = Reflect::set(&rsa_oaep_params, &JsString::from("publicExponent"), &public_exponent); + + // Create the "hash" sub-object + let hash_obj = Object::new(); + let _ = Reflect::set(&hash_obj, &JsString::from("name"), &JsString::from("SHA-256")); + + // "hash": {"name": "SHA-256"} + let _ = Reflect::set(&rsa_oaep_params, &JsString::from("hash"), &hash_obj); + + rsa_oaep_params + } +} From 7ab33d5f40c6482c564a3ba84e71e8088f59ab72 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 2 Oct 2024 13:11:24 +0100 Subject: [PATCH 042/125] implement walletconnect sign tx for tendermint - wip --- mm2src/coins/tendermint/tendermint_coin.rs | 73 +++++++++--- mm2src/coins/tendermint/tendermint_token.rs | 2 +- .../src/tendermint_with_assets_activation.rs | 15 ++- mm2src/kdf_walletconnect/src/chain/cosmos.rs | 105 +++++++++++++++++- mm2src/kdf_walletconnect/src/lib.rs | 16 ++- 5 files changed, 180 insertions(+), 31 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index d459e1499e..fa8fd70c68 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -30,6 +30,8 @@ use crate::{big_decimal_from_sat_unsigned, BalanceError, BalanceFut, BigDecimal, WatcherValidateTakerFeeInput, WithdrawError, WithdrawFee, WithdrawFut, WithdrawRequest}; use async_std::prelude::FutureExt as AsyncStdFutureExt; use async_trait::async_trait; +use base64::engine::general_purpose; +use base64::Engine; use bip32::DerivationPath; use bitcrypto::{dhash160, sha256}; use common::executor::{abortable_queue::AbortableQueue, AbortableSystem}; @@ -61,6 +63,7 @@ use futures01::Future; use hex::FromHexError; use instant::Duration; use itertools::Itertools; +use kdf_walletconnect::WalletConnectCtx; use keys::{KeyPair, Public}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_err_handle::prelude::*; @@ -354,6 +357,13 @@ impl RpcCommonOps for TendermintCoin { } } +#[derive(PartialEq)] +pub enum TendermintWalletConnectionType { + KeplrLedger, + WalletConnect, + Other, +} + pub struct TendermintCoinImpl { ticker: String, /// As seconds @@ -374,7 +384,7 @@ pub struct TendermintCoinImpl { client: TendermintRpcClient, pub(crate) chain_registry_name: Option, pub(crate) ctx: MmWeak, - pub(crate) is_keplr_from_ledger: bool, + pub(crate) wallet_connection_type: TendermintWalletConnectionType, } #[derive(Clone)] @@ -642,7 +652,7 @@ impl TendermintCoin { nodes: Vec, tx_history: bool, activation_policy: TendermintActivationPolicy, - is_keplr_from_ledger: bool, + wallet_connection_type: TendermintWalletConnectionType, ) -> MmResult { if nodes.is_empty() { return MmError::err(TendermintInitError { @@ -707,7 +717,7 @@ impl TendermintCoin { client: TendermintRpcClient(AsyncMutex::new(client_impl)), chain_registry_name: protocol_info.chain_registry_name, ctx: ctx.weak(), - is_keplr_from_ledger, + wallet_connection_type, }))) } @@ -907,32 +917,59 @@ impl TendermintCoin { let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); let account_info = try_tx_s!(self.account_info(&self.account_id).await); - let SerializedUnsignedTx { tx_json, body_bytes } = if self.is_keplr_from_ledger { + let SerializedUnsignedTx { tx_json, body_bytes } = if self.is_keplr_from_ledger() { try_tx_s!(self.any_to_legacy_amino_json(&account_info, tx_payload, fee, timeout_height, memo)) } else { try_tx_s!(self.any_to_serialized_sign_doc(&account_info, tx_payload, fee, timeout_height, memo)) }; let data: TxHashData = try_tx_s!(ctx - .ask_for_data(&format!("TX_HASH:{}", self.ticker()), tx_json, timeout) + .ask_for_data(&format!("TX_HASH:{}", self.ticker()), tx_json.clone(), timeout) .await .map_err(|e| ERRL!("{}", e))); - let tx = try_tx_s!(self.request_tx(data.hash.clone()).await.map_err(|e| ERRL!("{}", e))); - - let tx_raw_inner = TxRaw { - body_bytes: tx.body.as_ref().map(Message::encode_to_vec).unwrap_or_default(), - auth_info_bytes: tx.auth_info.as_ref().map(Message::encode_to_vec).unwrap_or_default(), - signatures: tx.signatures, + let tx_raw = match self.wallet_connection_type { + TendermintWalletConnectionType::WalletConnect => { + let wallet_connect = + try_tx_s!(WalletConnectCtx::try_from_ctx_or_initialize(&ctx).map_err(|e| ERRL!("{}", e))); + let my_address = try_tx_s!(self.my_address().map_err(|e| ERRL!("{}", e))); + let response = try_tx_s!( + wallet_connect + .cosmos_send_sign_tx_request(tx_json, &self.chain_id.to_string(), my_address) + .await + ); + let signature = try_tx_s!(general_purpose::STANDARD + .decode(response.signature.signature) + .map_err(|e| ERRL!("{}", e))); + let body_bytes = try_tx_s!(general_purpose::STANDARD + .decode(response.signed.body_bytes) + .map_err(|e| ERRL!("{}", e))); + let auth_info_bytes = try_tx_s!(general_purpose::STANDARD + .decode(response.signed.auth_info_bytes) + .map_err(|e| ERRL!("{}", e))); + TxRaw { + body_bytes, + auth_info_bytes, + signatures: vec![signature], + } + }, + _ => { + let tx = try_tx_s!(self.request_tx(data.hash.clone()).await.map_err(|e| ERRL!("{}", e))); + TxRaw { + body_bytes: tx.body.as_ref().map(Message::encode_to_vec).unwrap_or_default(), + auth_info_bytes: tx.auth_info.as_ref().map(Message::encode_to_vec).unwrap_or_default(), + signatures: tx.signatures, + } + }, }; - if body_bytes != tx_raw_inner.body_bytes { + if body_bytes != tx_raw.body_bytes { return Err(crate::TransactionErr::Plain(ERRL!( "Unsigned transaction don't match with the externally provided transaction." ))); } - Ok((data.hash, Raw::from(tx_raw_inner))) + Ok((data.hash, Raw::from(tx_raw))) } #[allow(deprecated)] @@ -1204,7 +1241,7 @@ impl TendermintCoin { hex::encode_upper(hash.as_slice()), )) } else { - let SerializedUnsignedTx { tx_json, .. } = if self.is_keplr_from_ledger { + let SerializedUnsignedTx { tx_json, .. } = if self.is_keplr_from_ledger() { self.any_to_legacy_amino_json(account_info, message, fee, timeout_height, memo) } else { self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo) @@ -2085,6 +2122,10 @@ impl TendermintCoin { None } + + pub fn is_keplr_from_ledger(&self) -> bool { + TendermintWalletConnectionType::KeplrLedger == self.wallet_connection_type + } } fn clients_from_urls(ctx: &MmArc, nodes: Vec) -> MmResult, TendermintInitErrorKind> { @@ -2169,7 +2210,7 @@ impl MmCoin for TendermintCoin { let coin_conf = crate::coin_conf(ctx, self.ticker()); let wallet_only_conf = coin_conf["wallet_only"].as_bool().unwrap_or(false); - wallet_only_conf || self.is_keplr_from_ledger + wallet_only_conf || self.is_keplr_from_ledger() } fn spawner(&self) -> CoinFutSpawner { CoinFutSpawner::new(&self.abortable_system) } @@ -2253,7 +2294,7 @@ impl MmCoin for TendermintCoin { ) .await?; - let fee_amount_u64 = if coin.is_keplr_from_ledger { + let fee_amount_u64 = if coin.is_keplr_from_ledger() { // When using `SIGN_MODE_LEGACY_AMINO_JSON`, Keplr ignores the fee we calculated // and calculates another one which is usually double what we calculate. // To make sure the transaction doesn't fail on the Keplr side (because if Keplr diff --git a/mm2src/coins/tendermint/tendermint_token.rs b/mm2src/coins/tendermint/tendermint_token.rs index 3e63589926..9af4cf77ee 100644 --- a/mm2src/coins/tendermint/tendermint_token.rs +++ b/mm2src/coins/tendermint/tendermint_token.rs @@ -476,7 +476,7 @@ impl MmCoin for TendermintToken { let coin_conf = crate::coin_conf(ctx, self.ticker()); let wallet_only_conf = coin_conf["wallet_only"].as_bool().unwrap_or(false); - wallet_only_conf || self.platform_coin.is_keplr_from_ledger + wallet_only_conf || self.platform_coin.is_keplr_from_ledger() } fn spawner(&self) -> CoinFutSpawner { CoinFutSpawner::new(&self.abortable_system) } diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index ead67e6ab1..33851c304d 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -14,7 +14,7 @@ use coins::tendermint::tendermint_tx_history_v2::tendermint_history_loop; use coins::tendermint::{tendermint_priv_key_policy, RpcNode, TendermintActivationPolicy, TendermintCoin, TendermintCommons, TendermintConf, TendermintInitError, TendermintInitErrorKind, TendermintProtocolInfo, TendermintPublicKey, TendermintToken, TendermintTokenActivationParams, - TendermintTokenInitError, TendermintTokenProtocolInfo}; + TendermintTokenInitError, TendermintTokenProtocolInfo, TendermintWalletConnectionType}; use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, MmCoinEnum, PrivKeyBuildPolicy}; use common::executor::{AbortSettings, SpawnAbortable}; use common::{true_f, Future01CompatExt}; @@ -293,10 +293,9 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { let conf = TendermintConf::try_from_json(&ticker, coin_conf)?; - let mut is_keplr_from_ledger = false; + let mut wallet_connectin_type = TendermintWalletConnectionType::Other; let activation_policy = if let Some(params) = activation_request.activation_params { - println!("{params:?}"); if ctx.is_watcher() || ctx.use_watchers() { return MmError::err(TendermintInitError { ticker: ticker.clone(), @@ -307,12 +306,16 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { match params { TendermintPubkeyActivationParams::WithPubkey { pubkey, - is_keplr_from_ledger: temp, + is_keplr_from_ledger, } => { - is_keplr_from_ledger = temp; + if is_keplr_from_ledger { + wallet_connectin_type = TendermintWalletConnectionType::KeplrLedger; + }; + TendermintActivationPolicy::with_public_key(pubkey) }, TendermintPubkeyActivationParams::WalletConnect(params) => { + wallet_connectin_type = TendermintWalletConnectionType::WalletConnect; get_walletconnect_pubkey(&ctx, ¶ms, protocol_conf.chain_id.as_ref(), &ticker).await? }, } @@ -337,7 +340,7 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { activation_request.nodes, activation_request.tx_history, activation_policy, - is_keplr_from_ledger, + wallet_connectin_type, ) .await } diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs index 356764aa40..e5faf3b212 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -7,7 +7,7 @@ use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::{session_request::{Request as SessionRequest, SessionRequestRequest}, RequestParams, ResponseParamsSuccess}; use serde::{Deserialize, Serialize}; -use serde_json::Value; +use serde_json::{json, Value}; use super::WcRequestMethods; @@ -69,7 +69,6 @@ where pub async fn cosmos_get_accounts_impl( ctx: &WalletConnectCtx, - chain: &str, chain_id: &str, ) -> MmResult, WalletConnectCtxError> { let account = ctx.get_account_for_chain_id(chain_id).await?; @@ -87,7 +86,7 @@ pub async fn cosmos_get_accounts_impl( }; let request = SessionRequestRequest { request, - chain_id: format!("{chain}:{chain_id}"), + chain_id: format!("cosmos:{chain_id}"), }; let session_request = RequestParams::SessionRequest(request); @@ -106,3 +105,103 @@ pub async fn cosmos_get_accounts_impl( MmError::err(WalletConnectCtxError::InvalidRequest) } + +#[derive(Debug, Serialize, Deserialize)] +pub struct CosmosTxSignedData { + pub signature: CosmosTxSignature, + pub signed: CosmosSignData, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CosmosTxSignature { + pub pub_key: CosmosTxPublicKey, + pub signature: String, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CosmosTxPublicKey { + #[serde(rename = "type")] + pub key_type: String, + pub value: String, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CosmosSignData { + pub chain_id: String, + pub account_number: String, + pub auth_info_bytes: String, + pub body_bytes: String, +} + +#[derive(Debug, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct CosmosTxSignParams { + pub signer_address: String, + pub sign_doc: CosmosSignData, +} + +pub async fn cosmos_sign_tx_direct_impl( + ctx: &WalletConnectCtx, + sign_doc: Value, + chain_id: &str, + signer_address: String, +) -> MmResult { + let session_topic = { + let session = ctx.session.lock().await; + session.as_ref().map(|s| s.topic.clone()) + }; + + // return not NotInitialized error if no session is found. + if session_topic.is_none() { + return MmError::err(WalletConnectCtxError::NotInitialized); + } + + let value = json!({ + "signer_address": signer_address, + "sign_doc": sign_doc + }); + + let request = SessionRequest { + method: WcRequestMethods::CosmosSignDirect.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: value, + }; + let request = SessionRequestRequest { + request, + chain_id: format!("cosmos:{chain_id}"), + }; + + let session_request = RequestParams::SessionRequest(request); + let topic = session_topic.unwrap(); + ctx.publish_request(&topic, session_request).await?; + + let mut session_handler = ctx.session_request_handler.lock().await; + if let Some((message_id, data)) = session_handler.next().await { + info!("Got cosmos sign response: {data:?}"); + let result = serde_json::from_value::(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&topic, response, &message_id).await?; + + return Ok(result); + } + + MmError::err(WalletConnectCtxError::InternalError( + "No response from wallet".to_string(), + )) +} + +//{ +// "id": 1, +// "jsonrpc": "2.0", +// "method": "cosmos_signDirect", +// "params": { +// "signerAddress": "cosmos1sguafvgmel6f880ryvq8efh9522p8zvmrzlcrq", +// "signDoc": { +// "chainId": "cosmoshub-4", +// "accountNumber": "1" +// "authInfoBytes": "CgoKABIECgIIARgBEhMKDQoFdWNvc20SBDIwMDAQwJoM", +// "bodyBytes": "CpABChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnAKLWNvc21vczFwa3B0cmU3ZmRrbDZnZnJ6bGVzamp2aHhobGMzcjRnbW1rOHJzNhItY29zbW9zMXF5cHF4cHE5cWNyc3N6ZzJwdnhxNnJzMHpxZzN5eWM1bHp2N3h1GhAKBXVjb3NtEgcxMjM0NTY3" +// } +// } +// } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 8caf924099..deb24ef4e4 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -9,7 +9,7 @@ pub mod session; mod storage; use chain::{build_required_namespaces, - cosmos::{cosmos_get_accounts_impl, CosmosAccount}, + cosmos::{cosmos_get_accounts_impl, cosmos_sign_tx_direct_impl, CosmosAccount, CosmosTxSignedData}, SUPPORTED_CHAINS}; use common::executor::SpawnFuture; use common::{executor::Timer, @@ -165,13 +165,11 @@ impl WalletConnectCtx { pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|chain| chain == &chain_id) } - /// Set active chain. pub async fn set_active_chain(&self, chain_id: &str) { let mut active_chain = self.active_chain_id.lock().await; *active_chain = chain_id.to_owned(); } - /// Get current active chain id. pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } pub async fn get_session(&self) -> Option { self.session.lock().await.clone() } @@ -211,10 +209,9 @@ impl WalletConnectCtx { pub async fn cosmos_get_account( &self, account_index: u8, - chain: &str, chain_id: &str, ) -> MmResult { - let accounts = cosmos_get_accounts_impl(self, chain, chain_id).await?; + let accounts = cosmos_get_accounts_impl(self, chain_id).await?; if accounts.is_empty() { return MmError::err(WalletConnectCtxError::EmptyAccount(chain_id.to_string())); @@ -227,6 +224,15 @@ impl WalletConnectCtx { Ok(accounts[account_index as usize].clone()) } + pub async fn cosmos_send_sign_tx_request( + &self, + sign_doc: Value, + chain_id: &str, + signer_address: String, + ) -> MmResult { + cosmos_sign_tx_direct_impl(self, sign_doc, chain_id, signer_address).await + } + async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { { let session = self.session.lock().await; From 0bcd41cbd75288872863f707bf5e7c8550778b20 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 2 Oct 2024 13:12:32 +0100 Subject: [PATCH 043/125] remove chain params from get cosmos account method --- .../coins_activation/src/tendermint_with_assets_activation.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 33851c304d..0d72a06124 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -254,7 +254,7 @@ async fn get_walletconnect_pubkey( WalletConnectCtx::try_from_ctx_or_initialize(ctx).expect("WalletConnectCtx should be initialized by now!"); let account = walletconnect_ctx - .cosmos_get_account(param.account_index, "cosmos", chain_id) + .cosmos_get_account(param.account_index, chain_id) .await .mm_err(|err| TendermintInitError { ticker: ticker.to_string(), From b2ec3095b3bd01f36dddbd655a6de3ca2ba18153 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 2 Oct 2024 19:46:05 +0100 Subject: [PATCH 044/125] tx impl - wip --- mm2src/coins/coin_errors.rs | 7 + .../tendermint/rpc/tendermint_native_rpc.rs | 2 +- mm2src/coins/tendermint/tendermint_coin.rs | 56 +- mm2src/coins/tendermint/tendermint_token.rs | 1 + mm2src/kdf_walletconnect/src/chain/cosmos.rs | 2 + mm2src/kdf_walletconnect/src/lib.rs | 2 +- .../kdf_walletconnect/src/session/propose.rs | 20 +- mm2src/mm2_test_helpers/Cargo.lock | 4116 +++++++++++++++++ 8 files changed, 4184 insertions(+), 22 deletions(-) create mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/mm2src/coins/coin_errors.rs b/mm2src/coins/coin_errors.rs index aead751eb0..7c96430a35 100644 --- a/mm2src/coins/coin_errors.rs +++ b/mm2src/coins/coin_errors.rs @@ -116,3 +116,10 @@ pub enum MyAddressError { UnexpectedDerivationMethod(String), InternalError(String), } + +impl std::error::Error for MyAddressError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + // This error doesn't wrap another error, so we return None + None + } +} diff --git a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs index 6b4dfb9ca4..e2dde73076 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs @@ -429,7 +429,7 @@ mod sealed { .await .map_err(|e| Error::client_internal(e.to_string()))?; let response_body = response_to_string(response).await?; - debug!("Incoming response: {}", response_body); + common::log::info!("Incoming response: {}", response_body); R::Response::from_string(&response_body) } } diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index fa8fd70c68..b53696debc 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -1186,6 +1186,7 @@ impl TendermintCoin { withdraw_from: Option, ) -> Result<(AccountId, Option), WithdrawError> { if let TendermintActivationPolicy::PublicKey(_) = self.activation_policy { + println!("inside pubkey"); return Ok((self.account_id.clone(), None)); } @@ -1222,7 +1223,7 @@ impl TendermintCoin { } } - pub(super) fn any_to_transaction_data( + pub(super) async fn any_to_transaction_data( &self, maybe_pk: Option, message: Any, @@ -1231,24 +1232,57 @@ impl TendermintCoin { timeout_height: u64, memo: String, ) -> Result { + println!("before maybe"); if let Some(priv_key) = maybe_pk { + println!("after maybe"); let tx_raw = self.any_to_signed_raw_tx(&priv_key, account_info, message, fee, timeout_height, memo)?; let tx_bytes = tx_raw.to_bytes()?; let hash = sha256(&tx_bytes); - Ok(TransactionData::new_signed( + return Ok(TransactionData::new_signed( tx_bytes.into(), hex::encode_upper(hash.as_slice()), - )) + )); + }; + + if let TendermintWalletConnectionType::WalletConnect = self.wallet_connection_type { + println!("inside wc"); + let ctx = MmArc::from_weak(&self.ctx) + .ok_or(MyAddressError::InternalError(ERRL!("ctx must be initialized already")))?; + let wallet_connect = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + + let SerializedUnsignedTx { tx_json, body_bytes } = + self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo)?; + + let my_address = self.my_address()?; + let response = wallet_connect + .cosmos_send_sign_tx_request(tx_json, &self.chain_id.to_string(), my_address) + .await?; + let signature = general_purpose::STANDARD.decode(response.signature.signature)?; + let body_bytes = general_purpose::STANDARD.decode(response.signed.body_bytes)?; + let auth_info_bytes = general_purpose::STANDARD.decode(response.signed.auth_info_bytes)?; + let tx_raw = TxRaw { + body_bytes, + auth_info_bytes, + signatures: vec![signature], + }; + let tx_raw: Raw = tx_raw.into(); + let tx_bytes = tx_raw.to_bytes()?; + let hash = sha256(&tx_bytes); + + return Ok(TransactionData::new_signed( + tx_bytes.into(), + hex::encode_upper(hash.as_slice()), + )); + }; + + let SerializedUnsignedTx { tx_json, .. } = if self.is_keplr_from_ledger() { + self.any_to_legacy_amino_json(account_info, message, fee, timeout_height, memo) } else { - let SerializedUnsignedTx { tx_json, .. } = if self.is_keplr_from_ledger() { - self.any_to_legacy_amino_json(account_info, message, fee, timeout_height, memo) - } else { - self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo) - }?; + self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo) + }?; - Ok(TransactionData::Unsigned(tx_json)) - } + Ok(TransactionData::Unsigned(tx_json)) } fn gen_create_htlc_tx( @@ -2348,8 +2382,10 @@ impl MmCoin for TendermintCoin { let account_info = coin.account_info(&account_id).await?; + println!("Before any_to_transaction_data"); let tx = coin .any_to_transaction_data(maybe_pk, msg_payload, &account_info, fee, timeout_height, memo.clone()) + .await .map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; let internal_id = { diff --git a/mm2src/coins/tendermint/tendermint_token.rs b/mm2src/coins/tendermint/tendermint_token.rs index 9af4cf77ee..5117e1774d 100644 --- a/mm2src/coins/tendermint/tendermint_token.rs +++ b/mm2src/coins/tendermint/tendermint_token.rs @@ -600,6 +600,7 @@ impl MmCoin for TendermintToken { let tx = platform .any_to_transaction_data(maybe_pk, msg_payload, &account_info, fee, timeout_height, memo.clone()) + .await .map_to_mm(|e| WithdrawError::InternalError(e.to_string()))?; let internal_id = { diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs index e5faf3b212..1e6de4bbde 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -162,6 +162,8 @@ pub async fn cosmos_sign_tx_direct_impl( "sign_doc": sign_doc }); + println!("VALUE: {:?}", value); + let request = SessionRequest { method: WcRequestMethods::CosmosSignDirect.as_ref().to_owned(), expiry: Some(Utc::now().timestamp() as u64 + 300), diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index deb24ef4e4..47b0cd1abb 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -437,7 +437,7 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect ctx.spawner().spawn(wallet_connect.clone().connection_live_watcher()); // load session from storage - wallet_connect.load_session_from_storage().await?; + // wallet_connect.load_session_from_storage().await?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index bc233cc0e2..b48a1eb777 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -70,11 +70,11 @@ pub async fn reply_session_proposal_request( { // save session to storage - ctx.storage - .db - .save_session(&session) - .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + //ctx.storage + // .db + // .save_session(&session) + // .await + // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; let mut old_session = ctx.session.lock().await; *old_session = Some(session.clone()); @@ -133,11 +133,11 @@ pub(crate) async fn process_session_propose_response( { // save session to storage - ctx.storage - .db - .save_session(&session) - .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + //ctx.storage + // .db + // .save_session(&session) + // .await + // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; let mut old_session = ctx.session.lock().await; *old_session = Some(session); diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock new file mode 100644 index 0000000000..62af3720d7 --- /dev/null +++ b/mm2src/mm2_test_helpers/Cargo.lock @@ -0,0 +1,4116 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" + +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", + "zeroize", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[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-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel 2.3.1", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if 1.0.0", + "event-listener 5.3.1", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if 1.0.0", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers 0.3.0", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.4.0", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bip32" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" +dependencies = [ + "bs58", + "hkd32", + "hmac 0.11.0", + "ripemd160", + "secp256k1 0.20.3", + "sha2 0.9.9", + "subtle", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "bitcoin" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" +dependencies = [ + "bech32", + "bitcoin_hashes", + "secp256k1 0.24.3", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitcrypto" +version = "0.1.0" +dependencies = [ + "groestl", + "primitives", + "ripemd160", + "serialization", + "sha-1", + "sha2 0.10.8", + "sha3 0.9.1", + "siphasher", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[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 = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding 0.2.1", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[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-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +dependencies = [ + "byteorder", + "iovec", +] + +[[package]] +name = "bytes" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chain" +version = "0.1.0" +dependencies = [ + "bitcoin", + "bitcrypto", + "primitives", + "rustc-hex", + "serialization", + "serialization_derive", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets", +] + +[[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 = "cloudabi" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "common" +version = "0.1.0" +dependencies = [ + "anyhow", + "arrayref", + "async-trait", + "backtrace", + "bytes 1.7.2", + "cc", + "cfg-if 1.0.0", + "chrono", + "crossbeam", + "derive_more", + "env_logger", + "findshlibs", + "fnv", + "futures 0.1.31", + "futures 0.3.30", + "futures-timer", + "gstuff", + "hex", + "http 0.2.12", + "http-body 0.1.0", + "hyper", + "hyper-rustls", + "instant", + "itertools", + "js-sys", + "lazy_static", + "libc", + "lightning", + "log", + "parking_lot", + "parking_lot_core 0.6.3", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hash", + "ser_error", + "ser_error_derive", + "serde", + "serde-wasm-bindgen", + "serde_derive", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "tokio", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", + "winapi", +] + +[[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_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto" +version = "1.0.0" +dependencies = [ + "aes", + "argon2", + "arrayref", + "async-trait", + "base64", + "bip32", + "bip39", + "bitcrypto", + "bs58", + "cbc", + "cfg-if 1.0.0", + "cipher", + "common", + "derive_more", + "enum-primitive-derive", + "enum_derives", + "futures 0.3.30", + "hex", + "hmac 0.12.1", + "http 0.2.12", + "hw_common", + "keys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_eth", + "mm2_metamask", + "num-traits", + "parking_lot", + "primitives", + "rpc", + "rpc_task", + "rustc-hex", + "secp256k1 0.20.3", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "trezor", + "wasm-bindgen-test", + "web3", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "db_common" +version = "0.1.0" +dependencies = [ + "common", + "crossbeam-channel", + "futures 0.3.30", + "hex", + "log", + "rusqlite", + "sql-builder", + "tokio", + "uuid", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote 1.0.37", + "rustc_version 0.4.1", + "syn 2.0.79", +] + +[[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", + "crypto-common", + "subtle", +] + +[[package]] +name = "edit-distance" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enum-primitive-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" +dependencies = [ + "num-traits", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "enum_derives" +version = "0.1.0" +dependencies = [ + "itertools", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[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 = "ethabi" +version = "17.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethcore-transaction" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "ethereum-types", + "ethkey", + "keccak-hash", + "rlp", + "rustc-hex", + "unexpected", +] + +[[package]] +name = "ethereum-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", +] + +[[package]] +name = "ethkey" +version = "0.3.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "byteorder", + "edit-distance", + "ethereum-types", + "log", + "mem", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "tiny-keccak 1.4.4", +] + +[[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 = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "findshlibs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers 0.2.6", + "send_wrapper", +] + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "groestl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "gstuff" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes 1.7.2", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +dependencies = [ + "ahash", +] + +[[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 = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkd32" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" +dependencies = [ + "hmac 0.11.0", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[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.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" +dependencies = [ + "bytes 0.4.12", + "fnv", + "itoa 0.4.8", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes 1.7.2", + "fnv", + "itoa 1.0.11", +] + +[[package]] +name = "http-body" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", + "http 0.1.21", + "tokio-buf", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes 1.7.2", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[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 = "hw_common" +version = "0.1.0" +dependencies = [ + "async-trait", + "bip32", + "common", + "derive_more", + "futures 0.3.30", + "js-sys", + "mm2_err_handle", + "rusb", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "hyper" +version = "0.14.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" +dependencies = [ + "bytes 1.7.2", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa 1.0.11", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "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", + "rustls", + "tokio", + "tokio-rustls", + "webpki-roots", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg 1.4.0", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.0", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding 0.3.3", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipnet" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures 0.3.30", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-hash" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" +dependencies = [ + "primitive-types", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "keys" +version = "0.1.0" +dependencies = [ + "base58", + "bech32", + "bitcrypto", + "derive_more", + "lazy_static", + "primitives", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.159" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" + +[[package]] +name = "libsqlite3-sys" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libusb1-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lightning" +version = "0.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" +dependencies = [ + "bitcoin", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg 1.4.0", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "mem" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "metrics" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" +dependencies = [ + "ahash", + "metrics-macros", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" +dependencies = [ + "base64", + "hyper", + "indexmap 1.9.3", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "metrics-util" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" +dependencies = [ + "aho-corasick", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.13.1", + "indexmap 1.9.3", + "metrics", + "num_cpus", + "ordered-float", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + +[[package]] +name = "minicov" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "mm2_core" +version = "0.1.0" +dependencies = [ + "arrayref", + "async-std", + "async-trait", + "cfg-if 1.0.0", + "common", + "db_common", + "derive_more", + "futures 0.3.30", + "gstuff", + "hex", + "instant", + "lazy_static", + "mm2_err_handle", + "mm2_event_stream", + "mm2_metrics", + "mm2_rpc", + "primitives", + "rand 0.7.3", + "rustls", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "shared_ref_counter", + "tokio", + "uuid", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_err_handle" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.1.31", + "http 0.2.12", + "itertools", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_eth" +version = "0.1.0" +dependencies = [ + "ethabi", + "ethkey", + "hex", + "indexmap 1.9.3", + "itertools", + "mm2_err_handle", + "secp256k1 0.20.3", + "serde", + "serde_json", + "web3", +] + +[[package]] +name = "mm2_event_stream" +version = "0.1.0" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "common", + "futures 0.3.30", + "parking_lot", + "serde", + "tokio", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_io" +version = "0.1.0" +dependencies = [ + "async-std", + "common", + "derive_more", + "futures 0.3.30", + "gstuff", + "mm2_err_handle", + "rand 0.7.3", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_metamask" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.30", + "itertools", + "js-sys", + "jsonrpc-core", + "lazy_static", + "mm2_err_handle", + "mm2_eth", + "parking_lot", + "serde", + "serde_derive", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "web3", +] + +[[package]] +name = "mm2_metrics" +version = "0.1.0" +dependencies = [ + "base64", + "common", + "derive_more", + "futures 0.3.30", + "hyper", + "hyper-rustls", + "itertools", + "metrics", + "metrics-exporter-prometheus", + "metrics-util", + "mm2_err_handle", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "mm2_net" +version = "0.1.0" +dependencies = [ + "async-trait", + "base64", + "bytes 1.7.2", + "cfg-if 1.0.0", + "common", + "derive_more", + "ethkey", + "futures 0.3.30", + "futures-util", + "gstuff", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "hyper", + "js-sys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_state_machine", + "pin-project", + "prost", + "rand 0.7.3", + "rustls", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-rustls", + "tonic", + "tower-service", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "mm2_number" +version = "0.1.0" +dependencies = [ + "bigdecimal", + "num-bigint", + "num-rational", + "num-traits", + "paste", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_rpc" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.3.30", + "gstuff", + "http 0.2.12", + "mm2_err_handle", + "mm2_number", + "rpc", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "mm2_state_machine" +version = "0.1.0" +dependencies = [ + "async-trait", +] + +[[package]] +name = "mm2_test_helpers" +version = "0.1.0" +dependencies = [ + "bytes 1.7.2", + "cfg-if 1.0.0", + "chrono", + "common", + "crypto", + "db_common", + "futures 0.3.30", + "gstuff", + "http 0.2.12", + "lazy_static", + "mm2_core", + "mm2_io", + "mm2_metrics", + "mm2_net", + "mm2_number", + "mm2_rpc", + "rand 0.7.3", + "regex", + "rpc", + "serde", + "serde_derive", + "serde_json", + "uuid", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec 1.13.2", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "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", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg 1.4.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "object" +version = "0.36.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "rustc_version 0.2.3", + "smallvec 0.6.14", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.5.7", + "smallvec 1.13.2", + "windows-targets", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if 1.0.0", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "uint", +] + +[[package]] +name = "primitives" +version = "0.1.0" +dependencies = [ + "bitcoin_hashes", + "byteorder", + "rustc-hex", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes 1.7.2", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "quanta" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" +dependencies = [ + "crossbeam-utils", + "libc", + "mach2", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg 0.2.1", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +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", + "wasm-bindgen", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +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-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[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.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom 0.2.15", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes 1.7.2", + "rustc-hex", +] + +[[package]] +name = "rpc" +version = "0.1.0" +dependencies = [ + "chain", + "keys", + "log", + "primitives", + "rustc-hex", + "script", + "serde", + "serde_derive", + "serde_json", + "serialization", +] + +[[package]] +name = "rpc_task" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.30", + "mm2_err_handle", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", +] + +[[package]] +name = "rusb" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" +dependencies = [ + "libc", + "libusb1-sys", +] + +[[package]] +name = "rusqlite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" +dependencies = [ + "bitflags 1.3.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec 1.13.2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "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 = [ + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[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 = "script" +version = "0.1.0" +dependencies = [ + "bitcrypto", + "blake2b_simd", + "chain", + "keys", + "log", + "primitives", + "serde", + "serialization", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "rand 0.6.5", + "secp256k1-sys 0.4.2", +] + +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "bitcoin_hashes", + "secp256k1-sys 0.6.1", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "ser_error" +version = "0.1.0" +dependencies = [ + "serde", +] + +[[package]] +name = "ser_error_derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "ser_error", + "syn 1.0.109", +] + +[[package]] +name = "serde" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.210" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "serde_json" +version = "1.0.128" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +dependencies = [ + "indexmap 2.6.0", + "itoa 1.0.11", + "memchr", + "ryu", + "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 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "serialization" +version = "0.1.0" +dependencies = [ + "byteorder", + "derive_more", + "primitives", + "test_helpers", +] + +[[package]] +name = "serialization_derive" +version = "0.1.0" +dependencies = [ + "quote 0.3.15", + "syn 0.11.11", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "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 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shared_ref_counter" +version = "0.1.0" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "siphasher" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" + +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg 1.4.0", +] + +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "sql-builder" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" +dependencies = [ + "anyhow", + "thiserror", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test_helpers" +version = "0.1.0" +dependencies = [ + "hex", +] + +[[package]] +name = "thiserror" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "tiny-keccak" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +dependencies = [ + "backtrace", + "bytes 1.7.2", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-buf" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes 1.7.2", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap 2.6.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "base64", + "bytes 1.7.2", + "futures-core", + "futures-util", + "http 0.2.12", + "http-body 0.4.6", + "percent-encoding", + "pin-project", + "prost", + "tokio-stream", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trezor" +version = "0.1.1" +dependencies = [ + "async-std", + "async-trait", + "bip32", + "byteorder", + "common", + "derive_more", + "ethcore-transaction", + "ethereum-types", + "ethkey", + "futures 0.3.30", + "hw_common", + "js-sys", + "lazy_static", + "mm2_err_handle", + "prost", + "rand 0.7.3", + "rpc_task", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unexpected" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "uuid" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" +dependencies = [ + "getrandom 0.2.15", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" +dependencies = [ + "quote 1.0.37", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68497a05fb21143a08a7d24fc81763384a3072ee43c44e86aad1744d6adef9d9" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "minicov", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "web-sys" +version = "0.3.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web3" +version = "0.19.0" +source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" +dependencies = [ + "arrayvec 0.7.6", + "derive_more", + "ethabi", + "ethereum-types", + "futures 0.3.30", + "futures-timer", + "getrandom 0.2.15", + "hex", + "idna", + "js-sys", + "jsonrpc-core", + "log", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rlp", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tiny-keccak 2.0.2", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.79", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +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 1.0.37", + "syn 2.0.79", +] From 2e25bde64789164ea9d5aab5849602fac7bf3c25 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 6 Oct 2024 10:28:46 +0100 Subject: [PATCH 045/125] save dev state --- mm2src/coins/tendermint/tendermint_coin.rs | 30 ++++++++++++++----- mm2src/kdf_walletconnect/src/chain/cosmos.rs | 21 ++++++------- .../kdf_walletconnect/src/inbound_message.rs | 6 ++-- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index b53696debc..ad50a66d0d 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -1370,14 +1370,28 @@ impl TendermintCoin { let auth_info = SignerInfo::single_direct(Some(pubkey), account_info.sequence).auth_info(fee); let sign_doc = SignDoc::new(&tx_body, &auth_info, &self.chain_id, account_info.account_number)?; - let tx_json = json!({ - "sign_doc": { - "body_bytes": sign_doc.body_bytes, - "auth_info_bytes": sign_doc.auth_info_bytes, - "chain_id": sign_doc.chain_id, - "account_number": sign_doc.account_number, - } - }); + let my_address = self.my_address().unwrap(); + let tx_json = if self.wallet_connection_type == TendermintWalletConnectionType::WalletConnect { + // convert body_bytes, auth_info_bytes to base64. + json!({ + "signerAddress": my_address, + "signDoc": { + "accountNumber": sign_doc.account_number.to_string(), + "chainId": sign_doc.chain_id, + "bodyBytes": &sign_doc.body_bytes, + "authInfoBytes": sign_doc.auth_info_bytes + } + }) + } else { + json!({ + "sign_doc": { + "body_bytes": sign_doc.body_bytes.clone(), + "auth_info_bytes": sign_doc.auth_info_bytes, + "chain_id": sign_doc.chain_id, + "account_number": sign_doc.account_number, + } + }) + }; Ok(SerializedUnsignedTx { tx_json, diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/cosmos.rs index 1e6de4bbde..e3f4d5f33b 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/cosmos.rs @@ -89,8 +89,10 @@ pub async fn cosmos_get_accounts_impl( chain_id: format!("cosmos:{chain_id}"), }; - let session_request = RequestParams::SessionRequest(request); - ctx.publish_request(&topic, session_request).await?; + { + let session_request = RequestParams::SessionRequest(request); + ctx.publish_request(&topic, session_request).await?; + }; let mut session_handler = ctx.session_request_handler.lock().await; if let Some((message_id, data)) = session_handler.next().await { @@ -157,26 +159,21 @@ pub async fn cosmos_sign_tx_direct_impl( return MmError::err(WalletConnectCtxError::NotInitialized); } - let value = json!({ - "signer_address": signer_address, - "sign_doc": sign_doc - }); - - println!("VALUE: {:?}", value); - let request = SessionRequest { method: WcRequestMethods::CosmosSignDirect.as_ref().to_owned(), expiry: Some(Utc::now().timestamp() as u64 + 300), - params: value, + params: sign_doc, }; let request = SessionRequestRequest { request, chain_id: format!("cosmos:{chain_id}"), }; - let session_request = RequestParams::SessionRequest(request); let topic = session_topic.unwrap(); - ctx.publish_request(&topic, session_request).await?; + { + let session_request = RequestParams::SessionRequest(request); + ctx.publish_request(&topic, session_request).await?; + } let mut session_handler = ctx.session_request_handler.lock().await; if let Some((message_id, data)) = session_handler.next().await { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index ae6e42be25..95bf51198b 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -43,6 +43,7 @@ pub(crate) async fn process_inbound_request( .await? }, Params::SessionRequest(_param) => { + println!("SessionRequest: {_param:?}"); // TODO: Implement when integrating KDF as a wallet. return MmError::err(WalletConnectCtxError::NotImplemented); }, @@ -94,20 +95,21 @@ pub(crate) async fn process_inbound_response( }, }, SuccessResponses::Other(value) => { + println!("Received: {value:?}"); ctx.session_request_sender .lock() .await .send((message_id, value)) .await .ok(); - println!("Sent"); Ok(()) }, } }, Response::Error(err) => { + // TODO: handle error properly println!("Error: {err:?}"); - todo!() + Ok(()) }, } } From 328bc76b0d6ae9dabb9139c5d00d886404557daa Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 6 Oct 2024 12:13:36 +0100 Subject: [PATCH 046/125] handle client connnection/reconnection efficiently and minor renaming --- .../tendermint/rpc/tendermint_native_rpc.rs | 4 +- mm2src/coins/tendermint/tendermint_coin.rs | 15 +- .../src/tendermint_with_assets_activation.rs | 5 +- mm2src/kdf_walletconnect/src/chain/mod.rs | 2 +- .../src/chain/{cosmos.rs => tendermint.rs} | 3 +- .../src/connection_handler.rs | 128 ++++++++++++++++++ mm2src/kdf_walletconnect/src/handler.rs | 57 -------- mm2src/kdf_walletconnect/src/lib.rs | 67 ++------- .../src/rpc_commands/delete_connection.rs | 2 +- .../src/rpc_commands/get_chain_id.rs | 2 +- .../src/rpc_commands/get_session.rs | 2 +- .../src/rpc_commands/new_connection.rs | 2 +- .../src/rpc_commands/ping.rs | 2 +- .../kdf_walletconnect/src/session/propose.rs | 1 - .../src/rpc/wc_commands/delete_connection.rs | 4 +- .../src/rpc/wc_commands/get_chain_id.rs | 4 +- .../src/rpc/wc_commands/get_session.rs | 4 +- .../src/rpc/wc_commands/new_connection.rs | 4 +- mm2src/mm2_main/src/rpc/wc_commands/ping.rs | 4 +- 19 files changed, 167 insertions(+), 145 deletions(-) rename mm2src/kdf_walletconnect/src/chain/{cosmos.rs => tendermint.rs} (99%) create mode 100644 mm2src/kdf_walletconnect/src/connection_handler.rs delete mode 100644 mm2src/kdf_walletconnect/src/handler.rs diff --git a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs index e2dde73076..58273f8041 100644 --- a/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs +++ b/mm2src/coins/tendermint/rpc/tendermint_native_rpc.rs @@ -429,7 +429,9 @@ mod sealed { .await .map_err(|e| Error::client_internal(e.to_string()))?; let response_body = response_to_string(response).await?; - common::log::info!("Incoming response: {}", response_body); + + debug!("Incoming response: {}", response_body); + R::Response::from_string(&response_body) } } diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index ad50a66d0d..e73aca6943 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -930,12 +930,10 @@ impl TendermintCoin { let tx_raw = match self.wallet_connection_type { TendermintWalletConnectionType::WalletConnect => { - let wallet_connect = - try_tx_s!(WalletConnectCtx::try_from_ctx_or_initialize(&ctx).map_err(|e| ERRL!("{}", e))); - let my_address = try_tx_s!(self.my_address().map_err(|e| ERRL!("{}", e))); + let wallet_connect = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); let response = try_tx_s!( wallet_connect - .cosmos_send_sign_tx_request(tx_json, &self.chain_id.to_string(), my_address) + .cosmos_send_sign_tx_request(tx_json, self.chain_id.as_ref()) .await ); let signature = try_tx_s!(general_purpose::STANDARD @@ -1249,14 +1247,13 @@ impl TendermintCoin { println!("inside wc"); let ctx = MmArc::from_weak(&self.ctx) .ok_or(MyAddressError::InternalError(ERRL!("ctx must be initialized already")))?; - let wallet_connect = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let wallet_connect = WalletConnectCtx::from_ctx(&ctx)?; - let SerializedUnsignedTx { tx_json, body_bytes } = + let SerializedUnsignedTx { tx_json, body_bytes: _ } = self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo)?; - let my_address = self.my_address()?; let response = wallet_connect - .cosmos_send_sign_tx_request(tx_json, &self.chain_id.to_string(), my_address) + .cosmos_send_sign_tx_request(tx_json, self.chain_id.as_ref()) .await?; let signature = general_purpose::STANDARD.decode(response.signature.signature)?; let body_bytes = general_purpose::STANDARD.decode(response.signed.body_bytes)?; @@ -1385,7 +1382,7 @@ impl TendermintCoin { } else { json!({ "sign_doc": { - "body_bytes": sign_doc.body_bytes.clone(), + "body_bytes": &sign_doc.body_bytes, "auth_info_bytes": sign_doc.auth_info_bytes, "chain_id": sign_doc.chain_id, "account_number": sign_doc.account_number, diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 0d72a06124..5ebaf0a5b7 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -18,7 +18,7 @@ use coins::tendermint::{tendermint_priv_key_policy, RpcNode, TendermintActivatio use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, MmCoinEnum, PrivKeyBuildPolicy}; use common::executor::{AbortSettings, SpawnAbortable}; use common::{true_f, Future01CompatExt}; -use kdf_walletconnect::chain::cosmos::CosmosAccountAlgo; +use kdf_walletconnect::chain::tendermint::CosmosAccountAlgo; use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -250,8 +250,7 @@ async fn get_walletconnect_pubkey( }); }; - let walletconnect_ctx = - WalletConnectCtx::try_from_ctx_or_initialize(ctx).expect("WalletConnectCtx should be initialized by now!"); + let walletconnect_ctx = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); let account = walletconnect_ctx .cosmos_get_account(param.account_index, chain_id) diff --git a/mm2src/kdf_walletconnect/src/chain/mod.rs b/mm2src/kdf_walletconnect/src/chain/mod.rs index 72053387b7..993444d200 100644 --- a/mm2src/kdf_walletconnect/src/chain/mod.rs +++ b/mm2src/kdf_walletconnect/src/chain/mod.rs @@ -1,4 +1,4 @@ -pub mod cosmos; +pub mod tendermint; use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; use std::collections::BTreeMap; diff --git a/mm2src/kdf_walletconnect/src/chain/cosmos.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs similarity index 99% rename from mm2src/kdf_walletconnect/src/chain/cosmos.rs rename to mm2src/kdf_walletconnect/src/chain/tendermint.rs index e3f4d5f33b..c780629b60 100644 --- a/mm2src/kdf_walletconnect/src/chain/cosmos.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -7,7 +7,7 @@ use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::{session_request::{Request as SessionRequest, SessionRequestRequest}, RequestParams, ResponseParamsSuccess}; use serde::{Deserialize, Serialize}; -use serde_json::{json, Value}; +use serde_json::Value; use super::WcRequestMethods; @@ -147,7 +147,6 @@ pub async fn cosmos_sign_tx_direct_impl( ctx: &WalletConnectCtx, sign_doc: Value, chain_id: &str, - signer_address: String, ) -> MmResult { let session_topic = { let session = ctx.session.lock().await; diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs new file mode 100644 index 0000000000..33b5e91d15 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -0,0 +1,128 @@ +use futures::StreamExt; +use std::sync::Arc; + +use common::{executor::Timer, + log::{error, info}}; +use futures::channel::mpsc::UnboundedSender; +use relay_client::{error::ClientError, + websocket::{CloseFrame, ConnectionHandler, PublishedMessage}}; + +use crate::WalletConnectCtx; + +pub struct Handler { + name: &'static str, + msg_sender: UnboundedSender, + conn_live_sender: UnboundedSender<()>, +} + +impl Handler { + pub fn new( + name: &'static str, + msg_sender: UnboundedSender, + conn_live_sender: UnboundedSender<()>, + ) -> Self { + Self { + name, + msg_sender, + conn_live_sender, + } + } +} + +impl ConnectionHandler for Handler { + fn connected(&mut self) { + info!("\n[{}] connection open", self.name); + } + + fn disconnected(&mut self, frame: Option>) { + info!("\n[{}] connection closed: frame={frame:?}", self.name); + + if let Err(e) = self.conn_live_sender.start_send(()) { + info!("\n[{}] failed to send to the receiver: {e}", self.name); + } + } + + fn message_received(&mut self, message: PublishedMessage) { + info!( + "\n[{}] inbound message: message_id={} topic={} tag={} message={}", + self.name, message.message_id, message.topic, message.tag, message.message, + ); + + if let Err(e) = self.msg_sender.start_send(message) { + info!("\n[{}] failed to send to the receiver: {e}", self.name); + } + } + + fn inbound_error(&mut self, error: ClientError) { + info!("\n[{}] inbound error: {error}", self.name); + } + + fn outbound_error(&mut self, error: ClientError) { + info!("\n[{}] outbound error: {error}", self.name); + } +} + +const INITIAL_RETRY_SECS: f64 = 5.0; +const RETRY_INCREMENT: f64 = 5.0; +const RECONNECT_DELAY: f64 = 5.0; + +pub(crate) async fn maintain_client_connection(this: Arc) { + initial_connection(&this).await; + handle_disconnections(&this).await; +} + +async fn initial_connection(this: &WalletConnectCtx) { + let mut retry_count = 0; + let mut retry_secs = INITIAL_RETRY_SECS; + + while let Err(err) = this.connect_client().await { + retry_count += 1; + error!( + "Error during initial connection attempt {}: {:?}. Retrying in {retry_secs} seconds...", + retry_count, err + ); + Timer::sleep(retry_secs).await; + retry_secs += RETRY_INCREMENT; + } + + info!("Successfully connected to client after {} attempt(s).", retry_count + 1); +} + +async fn handle_disconnections(this: &WalletConnectCtx) { + let mut recv = this.connection_live_handler.lock().await; + + while let Some(_msg) = recv.next().await { + info!("Connection disconnected. Attempting to reconnect..."); + reconnect(this).await; + resubscribe_to_topics(this).await; + info!("Reconnection process complete."); + } +} + +async fn reconnect(this: &WalletConnectCtx) { + let mut retry_count = 0; + + while let Err(err) = this.connect_client().await { + retry_count += 1; + error!( + "Error while reconnecting to client (attempt {}): {:?}. Retrying in {} seconds...", + retry_count, err, RECONNECT_DELAY + ); + Timer::sleep(RECONNECT_DELAY).await; + } + + info!( + "Successfully reconnected to client after {} attempt(s).", + retry_count + 1 + ); +} + +async fn resubscribe_to_topics(this: &WalletConnectCtx) { + let subs = this.subscriptions.lock().await; + for topic in &*subs { + match this.client.subscribe(topic.clone()).await { + Ok(_) => info!("Successfully reconnected to topic: {:?}", topic), + Err(err) => error!("Failed to subscribe to topic: {:?}. Error: {:?}", topic, err), + } + } +} diff --git a/mm2src/kdf_walletconnect/src/handler.rs b/mm2src/kdf_walletconnect/src/handler.rs deleted file mode 100644 index 2840ce4486..0000000000 --- a/mm2src/kdf_walletconnect/src/handler.rs +++ /dev/null @@ -1,57 +0,0 @@ -use common::log::info; -use futures::channel::mpsc::UnboundedSender; -use relay_client::{error::ClientError, - websocket::{CloseFrame, ConnectionHandler, PublishedMessage}}; - -pub struct Handler { - name: &'static str, - msg_sender: UnboundedSender, - conn_live_sender: UnboundedSender<()>, -} - -impl Handler { - pub fn new( - name: &'static str, - msg_sender: UnboundedSender, - conn_live_sender: UnboundedSender<()>, - ) -> Self { - Self { - name, - msg_sender, - conn_live_sender, - } - } -} - -impl ConnectionHandler for Handler { - fn connected(&mut self) { - info!("\n[{}] connection open", self.name); - } - - fn disconnected(&mut self, frame: Option>) { - info!("\n[{}] connection closed: frame={frame:?}", self.name); - - if let Err(e) = self.conn_live_sender.start_send(()) { - info!("\n[{}] failed to send to the receiver: {e}", self.name); - } - } - - fn message_received(&mut self, message: PublishedMessage) { - info!( - "\n[{}] inbound message: message_id={} topic={} tag={} message={}", - self.name, message.message_id, message.topic, message.tag, message.message, - ); - - if let Err(e) = self.msg_sender.start_send(message) { - info!("\n[{}] failed to send to the receiver: {e}", self.name); - } - } - - fn inbound_error(&mut self, error: ClientError) { - info!("\n[{}] inbound error: {error}", self.name); - } - - fn outbound_error(&mut self, error: ClientError) { - info!("\n[{}] outbound error: {error}", self.name); - } -} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 47b0cd1abb..2629c3b208 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,6 +1,6 @@ pub mod chain; +mod connection_handler; #[allow(unused)] pub mod error; -mod handler; mod inbound_message; mod metadata; #[allow(unused)] mod pairing; @@ -9,16 +9,15 @@ pub mod session; mod storage; use chain::{build_required_namespaces, - cosmos::{cosmos_get_accounts_impl, cosmos_sign_tx_direct_impl, CosmosAccount, CosmosTxSignedData}, + tendermint::{cosmos_get_accounts_impl, cosmos_sign_tx_direct_impl, CosmosAccount, CosmosTxSignedData}, SUPPORTED_CHAINS}; use common::executor::SpawnFuture; -use common::{executor::Timer, - log::{error, info}}; +use common::{executor::Timer, log::info}; +use connection_handler::{maintain_client_connection, Handler}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, lock::Mutex, StreamExt}; -use handler::Handler; use inbound_message::{process_inbound_request, process_inbound_response}; use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_core::mm_ctx::{from_ctx, MmArc}; @@ -99,7 +98,7 @@ impl WalletConnectCtx { }) } - pub fn try_from_ctx_or_initialize(ctx: &MmArc) -> MmResult, WalletConnectCtxError> { + pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectCtxError> { from_ctx(&ctx.wallet_connect, move || { Self::try_init(ctx).map_err(|err| err.to_string()) }) @@ -228,9 +227,8 @@ impl WalletConnectCtx { &self, sign_doc: Value, chain_id: &str, - signer_address: String, ) -> MmResult { - cosmos_sign_tx_direct_impl(self, sign_doc, chain_id, signer_address).await + cosmos_sign_tx_direct_impl(self, sign_doc, chain_id).await } async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { @@ -378,63 +376,20 @@ impl WalletConnectCtx { Ok(()) } - - async fn connection_live_watcher(self: Arc) { - let mut recv = self.connection_live_handler.lock().await; - let mut retry_count = 0; - - while let Some(_msg) = recv.next().await { - info!("Connection disconnected. Attempting to reconnect..."); - - // Try reconnecting - match self.connect_client().await { - Ok(_) => { - info!( - "Successfully reconnected to client after {} attempt(s).", - retry_count + 1 - ); - retry_count = 0; - }, - Err(err) => { - retry_count += 1; - common::log::error!( - "Error while reconnecting to client (attempt {}): {:?}. Retrying in 5 seconds...", - retry_count, - err - ); - Timer::sleep(5.).await; - continue; - }, - } - - // Subscribe to existing topics again after reconnecting - let subs = self.subscriptions.lock().await; - for topic in &*subs { - match self.client.subscribe(topic.clone()).await { - Ok(_) => info!("Successfully reconnected to topic: {:?}", topic), - Err(err) => error!("Failed to subscribe to topic: {:?}. Error: {:?}", topic, err), - } - } - - info!("Reconnection process complete."); - } - } } /// This function spwans related WalletConnect related tasks and needed initialization before /// WalletConnect can be usable in KDF. pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectCtxError> { // Initialized WalletConnectCtx - let wallet_connect = WalletConnectCtx::try_from_ctx_or_initialize(ctx)?; + let wallet_connect = WalletConnectCtx::from_ctx(ctx)?; - // WalletConnectCtx is initialized, now we can connect to relayer client. - wallet_connect.connect_client().await?; + // WalletConnectCtx is initialized, now we can connect to relayer client and spawn a watcher + // loop for disconnection. + ctx.spawner().spawn(maintain_client_connection(wallet_connect.clone())); // spawn message handler event loop - ctx.spawner().spawn(wallet_connect.clone().message_handler_event_loop()); - - // spawn WalletConnect client disconnect task - ctx.spawner().spawn(wallet_connect.clone().connection_live_watcher()); + ctx.spawner().spawn(wallet_connect.message_handler_event_loop()); // load session from storage // wallet_connect.load_session_from_storage().await?; diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs b/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs index 543f47f21a..2d8051f72f 100644 --- a/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs +++ b/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs @@ -20,7 +20,7 @@ pub async fn delete_connection( ctx: MmArc, req: DeleteConnectionRequest, ) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let ctx = WalletConnectCtx::from_ctx(&ctx)?; send_session_delete_request(&ctx, &req.topic).await?; Ok(DeleteConnectionResponse { successful: true }) diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs b/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs index 6c1e2e2f76..5eccb32801 100644 --- a/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs +++ b/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs @@ -13,7 +13,7 @@ pub struct GetChainIdResponse { /// `delete connection` RPC command implementation. pub async fn get_chain_id(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let ctx = WalletConnectCtx::from_ctx(&ctx)?; let chain_id = ctx.get_active_chain_id().await; Ok(GetChainIdResponse { chain_id }) diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs b/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs index 8734f0d223..f30b174592 100644 --- a/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs +++ b/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs @@ -12,7 +12,7 @@ pub struct GetSessionResponse { /// `delete connection` RPC command implementation. pub async fn get_session(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let ctx = WalletConnectCtx::from_ctx(&ctx)?; let session = ctx.get_session().await; Ok(GetSessionResponse { session }) diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs b/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs index 11b995381e..fa56c18d3d 100644 --- a/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs +++ b/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs @@ -15,7 +15,7 @@ pub async fn new_connection( ctx: MmArc, _req: EmptyRpcRequst, ) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let ctx = WalletConnectCtx::from_ctx(&ctx)?; let url = ctx.new_connection(None).await?; Ok(CreateConnectionResponse { url }) diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs b/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs index 363bceacf7..a2d43b5ba6 100644 --- a/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs +++ b/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs @@ -17,7 +17,7 @@ pub struct SessionPingRequest { /// `ping session` RPC command implementation. pub async fn ping_session(ctx: MmArc, req: SessionPingRequest) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx)?; + let ctx = WalletConnectCtx::from_ctx(&ctx)?; send_session_ping_request(&ctx, &req.topic).await?; Ok(SessionPingResponse { successful: true }) diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index b48a1eb777..9e13d43252 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -1,7 +1,6 @@ use super::{settle::send_session_settle_request, Session}; use crate::{error::WalletConnectCtxError, session::{SessionKey, SessionType, THIRTY_DAYS}, - storage::WalletConnectStorageOps, WalletConnectCtx}; use chrono::Utc; diff --git a/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs index 07118b6c4c..19cdad798b 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs @@ -20,8 +20,8 @@ pub async fn delete_connection( ctx: MmArc, req: DeleteConnectionRequest, ) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) - .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; send_session_delete_request(&ctx, &req.topic.into()) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs index 4243167278..0ec7dff5c0 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs @@ -12,8 +12,8 @@ pub struct GetChainIdResponse { /// `delete connection` RPC command implementation. pub async fn get_chain_id(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) - .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; let chain_id = ctx.get_active_chain_id().await; Ok(GetChainIdResponse { chain_id }) diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs index d5a34644ff..4b58c51fcf 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs @@ -12,8 +12,8 @@ pub struct GetSessionResponse { /// `delete connection` RPC command implementation. pub async fn get_session(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) - .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; let session = ctx.get_session().await; Ok(GetSessionResponse { session }) diff --git a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs index 46b58d5988..3dfbd218ab 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs @@ -15,8 +15,8 @@ pub async fn new_connection( ctx: MmArc, _req: EmptyRpcRequst, ) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) - .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; let url = ctx .new_connection(None) .await diff --git a/mm2src/mm2_main/src/rpc/wc_commands/ping.rs b/mm2src/mm2_main/src/rpc/wc_commands/ping.rs index a49e5d7d48..f3e630bd07 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/ping.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/ping.rs @@ -17,8 +17,8 @@ pub struct SessionPingRequest { /// `ping session` RPC command implementation. pub async fn ping_session(ctx: MmArc, req: SessionPingRequest) -> MmResult { - let ctx = WalletConnectCtx::try_from_ctx_or_initialize(&ctx) - .mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; send_session_ping_request(&ctx, &req.topic.into()) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; From 9b20d7f869c2ca194be7161b7a0959f8893282f5 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 6 Oct 2024 13:10:51 +0100 Subject: [PATCH 047/125] minor changes --- .../src/tendermint_with_assets_activation.rs | 2 +- mm2src/kdf_walletconnect/src/error.rs | 4 +- mm2src/kdf_walletconnect/src/lib.rs | 77 ++++++++++--------- 3 files changed, 45 insertions(+), 38 deletions(-) diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 5ebaf0a5b7..8654e44146 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -43,7 +43,7 @@ impl RegisterTokenInfo for TendermintCoin { #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct WalletConnectParams { #[serde(default)] - pub account_index: u8, + pub account_index: usize, #[serde(default)] pub enabled: bool, } diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 1c3104bd47..b9fb7fa353 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -75,13 +75,15 @@ pub enum WalletConnectCtxError { #[error("Account not found for chain_id: {0}")] NoAccountFound(String), #[error("Account not found for index: {0}")] - NoAccountFoundForIndex(u8), + NoAccountFoundForIndex(usize), #[error("Empty account approved for chain_id: {0}")] EmptyAccount(String), #[error("WalletConnect is not initaliazed yet!")] NotInitialized, #[error("Storage Error: {0}")] StorageError(String), + #[error("ChainId mismatch")] + ChainIdMismatch, } impl From> for WalletConnectCtxError { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 2629c3b208..b861a48c2f 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -12,7 +12,7 @@ use chain::{build_required_namespaces, tendermint::{cosmos_get_accounts_impl, cosmos_sign_tx_direct_impl, CosmosAccount, CosmosTxSignedData}, SUPPORTED_CHAINS}; use common::executor::SpawnFuture; -use common::{executor::Timer, log::info}; +use common::log::info; use connection_handler::{maintain_client_connection, Handler}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, @@ -26,7 +26,7 @@ use mm2_err_handle::prelude::*; use pairing_api::PairingClient; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; -use relay_rpc::rpc::params::{RelayProtocolMetadata, RequestParams}; +use relay_rpc::rpc::params::{session::Namespace, RelayProtocolMetadata, RequestParams}; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, rpc::{params::{session::ProposeNamespaces, IrnMetadata, Metadata, Relay, ResponseParamsError, @@ -118,8 +118,6 @@ impl WalletConnectCtx { self.client.connect(&opts).await?; - info!("WC connected"); - Ok(()) } @@ -173,41 +171,49 @@ impl WalletConnectCtx { pub async fn get_session(&self) -> Option { self.session.lock().await.clone() } - /// Get available accounts for a given chain_id. + /// Retrieves the available account for a given chain ID. pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { - let active_chain_id = self.active_chain_id.lock().await; - if *active_chain_id == chain_id { - let session = self.session.lock().await; - if let Some(session) = session.as_ref() { - // Iterate through namespaces to find the matching chain_id - for (namespace_key, namespace) in &session.namespaces { - if let Some(chains) = &namespace.chains { - let key = format!("{namespace_key}:{chain_id}"); - // Check if the chain_id exists within the namespace chains - if chains.contains(&key) { - if let Some(accounts) = &namespace.accounts { - // Loop through the accounts and extract the account for the correct chain - for account_name in accounts { - // "cosmos:cosmoshub-4:cosmos1fg2nemunucn496fewakqfe0mllcqfulrmjnj77" - let account_vec = account_name.split(':').collect::>(); - if account_vec.len() >= 3 { - return Ok(account_vec[2].to_owned()); - } - } - } - } - } - } - } + let active_chain_id = self.get_active_chain_id().await; + if active_chain_id != chain_id { + return MmError::err(WalletConnectCtxError::ChainIdMismatch); + } + + let session = self.session.lock().await; + let session = session.as_ref().ok_or(WalletConnectCtxError::NoAccountFound( + "No active session found".to_owned(), + ))?; + + session + .namespaces + .iter() + .find_map(|(key, namespace)| self.find_account_in_namespace(namespace, key, chain_id)) + .ok_or(MmError::new(WalletConnectCtxError::NoAccountFound( + chain_id.to_string(), + ))) + } + + fn find_account_in_namespace(&self, namespace: &Namespace, namespace_key: &str, chain_id: &str) -> Option { + let chains = namespace.chains.as_ref()?; + let key = format!("{namespace_key}:{chain_id}"); + + if !chains.contains(&key) { + return None; } - // If the chain doesn't match, or no valid account is found, return an error - MmError::err(WalletConnectCtxError::NoAccountFound(chain_id.to_string())) + let accounts = namespace.accounts.as_ref()?; + accounts.iter().find_map(|account_name| { + let parts: Vec<&str> = account_name.split(':').collect(); + if parts.len() >= 3 && parts[1] == chain_id { + Some(parts[2].to_string()) + } else { + None + } + }) } pub async fn cosmos_get_account( &self, - account_index: u8, + account_index: usize, chain_id: &str, ) -> MmResult { let accounts = cosmos_get_accounts_impl(self, chain_id).await?; @@ -216,11 +222,11 @@ impl WalletConnectCtx { return MmError::err(WalletConnectCtxError::EmptyAccount(chain_id.to_string())); }; - if accounts.len() < account_index as usize + 1 { + if accounts.len() < account_index + 1 { return MmError::err(WalletConnectCtxError::NoAccountFoundForIndex(account_index)); }; - Ok(accounts[account_index as usize].clone()) + Ok(accounts[account_index].clone()) } pub async fn cosmos_send_sign_tx_request( @@ -260,7 +266,7 @@ impl WalletConnectCtx { self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; - info!("Otbound request sent!\n"); + info!("Outbound request sent!\n"); Ok(()) } @@ -330,7 +336,6 @@ impl WalletConnectCtx { let selfi = self.clone(); let mut recv = self.inbound_message_handler.lock().await; while let Some(msg) = recv.next().await { - info!("received message"); if let Err(e) = selfi.handle_published_message(msg).await { info!("Error processing message: {:?}", e); } From ca2e19c60fb57725a63bf840e3503dd9312e3762 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 8 Oct 2024 14:19:33 +0100 Subject: [PATCH 048/125] implement multi session management --- Cargo.lock | 118 ++++++++++++------ mm2src/kdf_walletconnect/Cargo.toml | 1 + .../kdf_walletconnect/src/chain/tendermint.rs | 75 +++++------ mm2src/kdf_walletconnect/src/lib.rs | 68 +++++----- .../src/rpc_commands/delete_connection.rs | 27 ---- .../src/rpc_commands/get_chain_id.rs | 20 --- .../src/rpc_commands/get_session.rs | 19 --- .../kdf_walletconnect/src/rpc_commands/mod.rs | 15 --- .../src/rpc_commands/new_connection.rs | 22 ---- .../src/rpc_commands/ping.rs | 24 ---- mm2src/kdf_walletconnect/src/session.rs | 113 ++++++++++++++++- .../kdf_walletconnect/src/session/delete.rs | 2 +- mm2src/kdf_walletconnect/src/session/event.rs | 21 ++-- .../kdf_walletconnect/src/session/extend.rs | 7 +- .../kdf_walletconnect/src/session/propose.rs | 12 +- .../kdf_walletconnect/src/session/settle.rs | 6 +- .../kdf_walletconnect/src/session/update.rs | 21 ++-- .../src/rpc/wc_commands/get_session.rs | 2 +- 18 files changed, 296 insertions(+), 277 deletions(-) delete mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs delete mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs delete mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs delete mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/mod.rs delete mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs delete mode 100644 mm2src/kdf_walletconnect/src/rpc_commands/ping.rs diff --git a/Cargo.lock b/Cargo.lock index f0c0a593ff..ea326db9c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1785,6 +1785,20 @@ dependencies = [ "rayon", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils 0.8.16", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.10", +] + [[package]] name = "data-encoding" version = "2.4.0" @@ -3556,6 +3570,7 @@ dependencies = [ "cfg-if 1.0.0", "chrono", "common", + "dashmap 6.1.0", "db_common", "derive_more", "enum_derives", @@ -4247,10 +4262,11 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "lock_api" -version = "0.4.6" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88943dd7ef4a2e5a4bfa2753aaab3013e34ce2533d1996fb18ef591e315e2b3b" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ + "autocfg 1.1.0", "scopeguard", ] @@ -5456,7 +5472,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" dependencies = [ "lock_api", - "parking_lot_core 0.9.1", + "parking_lot_core 0.9.10", ] [[package]] @@ -5491,15 +5507,15 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.1" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28141e0cc4143da2443301914478dc976a61ffdb3f043058310c70df2fed8954" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if 1.0.0", "libc", - "redox_syscall 0.2.10", + "redox_syscall 0.5.7", "smallvec 1.6.1", - "windows-sys 0.32.0", + "windows-targets 0.52.6", ] [[package]] @@ -6297,6 +6313,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "redox_users" version = "0.3.4" @@ -7857,7 +7882,7 @@ dependencies = [ "byteorder", "bzip2", "crossbeam-channel 0.5.1", - "dashmap", + "dashmap 4.0.2", "dir-diff", "flate2", "fnv", @@ -9691,19 +9716,6 @@ dependencies = [ "windows_x86_64_msvc 0.34.0", ] -[[package]] -name = "windows-sys" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3df6e476185f92a12c072be4a189a0210dcdcf512a1891d6dff9edb874deadc6" -dependencies = [ - "windows_aarch64_msvc 0.32.0", - "windows_i686_gnu 0.32.0", - "windows_i686_msvc 0.32.0", - "windows_x86_64_gnu 0.32.0", - "windows_x86_64_msvc 0.32.0", -] - [[package]] name = "windows-sys" version = "0.42.0" @@ -9767,6 +9779,22 @@ dependencies = [ "windows_x86_64_msvc 0.48.0", ] +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.1" @@ -9780,10 +9808,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" [[package]] -name = "windows_aarch64_msvc" -version = "0.32.0" +name = "windows_aarch64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8e92753b1c443191654ec532f14c199742964a061be25d77d7a96f09db20bf5" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -9804,10 +9832,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" [[package]] -name = "windows_i686_gnu" -version = "0.32.0" +name = "windows_aarch64_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a711c68811799e017b6038e0922cb27a5e2f43a2ddb609fe0b6f3eeda9de615" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -9828,10 +9856,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" [[package]] -name = "windows_i686_msvc" -version = "0.32.0" +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146c11bb1a02615db74680b32a68e2d61f553cc24c4eb5b4ca10311740e44172" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -9852,10 +9886,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" [[package]] -name = "windows_x86_64_gnu" -version = "0.32.0" +name = "windows_i686_msvc" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c912b12f7454c6620635bbff3450962753834be2a594819bd5e945af18ec64bc" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -9875,6 +9909,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.1" @@ -9888,10 +9928,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" [[package]] -name = "windows_x86_64_msvc" -version = "0.32.0" +name = "windows_x86_64_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504a2476202769977a040c6364301a3f65d0cc9e3fb08600b2bda150a0488316" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -9911,6 +9951,12 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + [[package]] name = "winreg" version = "0.7.0" diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 8e786df364..895ba7b6dc 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -18,6 +18,7 @@ futures = { version = "0.3", package = "futures", features = [ ] } hex = "0.4.2" hkdf = "0.12.4" +dashmap = "6.1.0" mm2_core = { path = "../mm2_core" } mm2_db = { path = "../mm2_db" } mm2_err_handle = { path = "../mm2_err_handle" } diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index c780629b60..92c4556030 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -73,39 +73,42 @@ pub async fn cosmos_get_accounts_impl( ) -> MmResult, WalletConnectCtxError> { let account = ctx.get_account_for_chain_id(chain_id).await?; - let session_topic = { - let session = ctx.session.lock().await; - session.as_ref().map(|s| s.topic.clone()) + let topic = { + let session = ctx.session.get_session_active().await; + // return not NotInitialized error if no session is found. + if session.is_none() { + return MmError::err(WalletConnectCtxError::NotInitialized); + }; + + session.unwrap().topic }; - if let Some(topic) = session_topic { - let request = SessionRequest { - method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: serde_json::to_value(&account).unwrap(), - }; - let request = SessionRequestRequest { - request, - chain_id: format!("cosmos:{chain_id}"), - }; + let request = SessionRequest { + method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: serde_json::to_value(&account).unwrap(), + }; + let request = SessionRequestRequest { + request, + chain_id: format!("cosmos:{chain_id}"), + }; - { - let session_request = RequestParams::SessionRequest(request); - ctx.publish_request(&topic, session_request).await?; - }; + { + let session_request = RequestParams::SessionRequest(request); + ctx.publish_request(&topic, session_request).await?; + }; - let mut session_handler = ctx.session_request_handler.lock().await; - if let Some((message_id, data)) = session_handler.next().await { - info!("Got cosmos account: {data:?}"); - let result = serde_json::from_value::>(data)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&topic, response, &message_id).await?; + let mut session_handler = ctx.session_request_handler.lock().await; + if let Some((message_id, data)) = session_handler.next().await { + info!("Got cosmos account: {data:?}"); + let result = serde_json::from_value::>(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&topic, response, &message_id).await?; - return Ok(result); - } - } + return Ok(result); + }; - MmError::err(WalletConnectCtxError::InvalidRequest) + MmError::err(WalletConnectCtxError::NoAccountFound(chain_id.to_owned())) } #[derive(Debug, Serialize, Deserialize)] @@ -148,15 +151,15 @@ pub async fn cosmos_sign_tx_direct_impl( sign_doc: Value, chain_id: &str, ) -> MmResult { - let session_topic = { - let session = ctx.session.lock().await; - session.as_ref().map(|s| s.topic.clone()) - }; + let topic = { + let session = ctx.session.get_session_active().await; + // return not NotInitialized error if no session is found. + if session.is_none() { + return MmError::err(WalletConnectCtxError::NotInitialized); + }; - // return not NotInitialized error if no session is found. - if session_topic.is_none() { - return MmError::err(WalletConnectCtxError::NotInitialized); - } + session.unwrap().topic + }; let request = SessionRequest { method: WcRequestMethods::CosmosSignDirect.as_ref().to_owned(), @@ -167,8 +170,6 @@ pub async fn cosmos_sign_tx_direct_impl( request, chain_id: format!("cosmos:{chain_id}"), }; - - let topic = session_topic.unwrap(); { let session_request = RequestParams::SessionRequest(request); ctx.publish_request(&topic, session_request).await?; diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index b861a48c2f..9204548506 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -4,7 +4,6 @@ mod connection_handler; mod inbound_message; mod metadata; #[allow(unused)] mod pairing; -pub mod rpc_commands; pub mod session; mod storage; @@ -26,16 +25,17 @@ use mm2_err_handle::prelude::*; use pairing_api::PairingClient; use relay_client::{websocket::{Client, PublishedMessage}, ConnectionOptions, MessageIdGenerator}; -use relay_rpc::rpc::params::{session::Namespace, RelayProtocolMetadata, RequestParams}; +use relay_rpc::rpc::params::{session::{Namespace, SettleNamespaces}, + RelayProtocolMetadata, RequestParams}; use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, domain::{MessageId, Topic}, rpc::{params::{session::ProposeNamespaces, IrnMetadata, Metadata, Relay, ResponseParamsError, ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; use serde_json::Value; -use session::{propose::send_proposal_request, Session, SymKeyPair}; +use session::{propose::send_proposal_request, SessionManagement, SymKeyPair}; use std::{sync::Arc, time::Duration}; -use storage::{SessionStorageDb, WalletConnectStorageOps}; +use storage::SessionStorageDb; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; @@ -46,7 +46,7 @@ type SessionEventMessage = (MessageId, Value); pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, - pub session: Arc>>, + pub session: SessionManagement, pub active_chain_id: Arc>, pub(crate) key_pair: SymKeyPair, @@ -54,7 +54,8 @@ pub struct WalletConnectCtx { relay: Relay, metadata: Metadata, - namespaces: ProposeNamespaces, + namespaces: Arc>, + required_namespaces: ProposeNamespaces, subscriptions: Arc>>, inbound_message_handler: Arc>>, connection_live_handler: Arc>>, @@ -83,10 +84,11 @@ impl WalletConnectCtx { Ok(Self { client, pairing, - session: Default::default(), + session: SessionManagement::new(), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), relay, - namespaces: required, + namespaces: Default::default(), + required_namespaces: required, metadata: generate_metadata(), key_pair: SymKeyPair::new(), storage, @@ -169,8 +171,6 @@ impl WalletConnectCtx { pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } - pub async fn get_session(&self) -> Option { self.session.lock().await.clone() } - /// Retrieves the available account for a given chain ID. pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { let active_chain_id = self.get_active_chain_id().await; @@ -178,13 +178,8 @@ impl WalletConnectCtx { return MmError::err(WalletConnectCtxError::ChainIdMismatch); } - let session = self.session.lock().await; - let session = session.as_ref().ok_or(WalletConnectCtxError::NoAccountFound( - "No active session found".to_owned(), - ))?; - - session - .namespaces + let namespaces = self.namespaces.lock().await; + namespaces .iter() .find_map(|(key, namespace)| self.find_account_in_namespace(namespace, key, chain_id)) .ok_or(MmError::new(WalletConnectCtxError::NoAccountFound( @@ -239,11 +234,8 @@ impl WalletConnectCtx { async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { { - let session = self.session.lock().await; - if let Some(session) = session.as_ref() { - if &session.topic == topic { - return Ok(session.session_key.symmetric_key().to_vec()); - } + if let Some(key) = self.session.sym_key(topic) { + return Ok(key); } } @@ -362,22 +354,22 @@ impl WalletConnectCtx { } async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectCtxError> { - let sessions = self - .storage - .db - .get_all_sessions() - .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; - if let Some(session) = sessions.first() { - info!("Session found! activating :{}", session.topic); - - let mut ctx_session = self.session.lock().await; - *ctx_session = Some(session.clone()); - - // subcribe to session topics - self.client.subscribe(session.topic.clone()).await?; - self.client.subscribe(session.pairing_topic.clone()).await?; - } + //let sessions = self + // .storage + // .db + // .get_all_sessions() + // .await + // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + //if let Some(session) = sessions.first() { + // info!("Session found! activating :{}", session.topic); + // + // let mut ctx_session = self.session.lock().await; + // *ctx_session = Some(session.clone()); + // + // // subcribe to session topics + // self.client.subscribe(session.topic.clone()).await?; + //self.client.subscribe(session.pairing_topic.clone()).await?; + //} Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs b/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs deleted file mode 100644 index 2d8051f72f..0000000000 --- a/mm2src/kdf_walletconnect/src/rpc_commands/delete_connection.rs +++ /dev/null @@ -1,27 +0,0 @@ -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::MmResult; -use relay_rpc::domain::Topic; -use serde::{Deserialize, Serialize}; - -use crate::{error::WalletConnectCtxError, session::delete::send_session_delete_request, WalletConnectCtx}; - -#[derive(Debug, PartialEq, Serialize)] -pub struct DeleteConnectionResponse { - pub successful: bool, -} - -#[derive(Deserialize)] -pub struct DeleteConnectionRequest { - topic: Topic, -} - -/// `delete connection` RPC command implementation. -pub async fn delete_connection( - ctx: MmArc, - req: DeleteConnectionRequest, -) -> MmResult { - let ctx = WalletConnectCtx::from_ctx(&ctx)?; - send_session_delete_request(&ctx, &req.topic).await?; - - Ok(DeleteConnectionResponse { successful: true }) -} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs b/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs deleted file mode 100644 index 5eccb32801..0000000000 --- a/mm2src/kdf_walletconnect/src/rpc_commands/get_chain_id.rs +++ /dev/null @@ -1,20 +0,0 @@ -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::MmResult; -use serde::Serialize; - -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; - -use super::EmptyRpcRequst; - -#[derive(Debug, PartialEq, Serialize)] -pub struct GetChainIdResponse { - pub chain_id: String, -} - -/// `delete connection` RPC command implementation. -pub async fn get_chain_id(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = WalletConnectCtx::from_ctx(&ctx)?; - let chain_id = ctx.get_active_chain_id().await; - - Ok(GetChainIdResponse { chain_id }) -} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs b/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs deleted file mode 100644 index f30b174592..0000000000 --- a/mm2src/kdf_walletconnect/src/rpc_commands/get_session.rs +++ /dev/null @@ -1,19 +0,0 @@ -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::MmResult; -use serde::Serialize; - -use super::EmptyRpcRequst; -use crate::{error::WalletConnectCtxError, session::Session, WalletConnectCtx}; - -#[derive(Debug, PartialEq, Serialize)] -pub struct GetSessionResponse { - pub session: Option, -} - -/// `delete connection` RPC command implementation. -pub async fn get_session(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = WalletConnectCtx::from_ctx(&ctx)?; - let session = ctx.get_session().await; - - Ok(GetSessionResponse { session }) -} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/mod.rs b/mm2src/kdf_walletconnect/src/rpc_commands/mod.rs deleted file mode 100644 index 3ae7f66bfc..0000000000 --- a/mm2src/kdf_walletconnect/src/rpc_commands/mod.rs +++ /dev/null @@ -1,15 +0,0 @@ -mod delete_connection; -mod get_chain_id; -mod get_session; -mod new_connection; -mod ping; - -pub use delete_connection::delete_connection; -pub use get_chain_id::get_chain_id; -pub use get_session::get_session; -pub use new_connection::new_connection; -pub use ping::ping_session; -use serde::Deserialize; - -#[derive(Deserialize)] -pub struct EmptyRpcRequst {} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs b/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs deleted file mode 100644 index fa56c18d3d..0000000000 --- a/mm2src/kdf_walletconnect/src/rpc_commands/new_connection.rs +++ /dev/null @@ -1,22 +0,0 @@ -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::MmResult; -use serde::Serialize; - -use super::EmptyRpcRequst; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; - -#[derive(Debug, PartialEq, Serialize)] -pub struct CreateConnectionResponse { - pub url: String, -} - -/// `new_connection` RPC command implementation. -pub async fn new_connection( - ctx: MmArc, - _req: EmptyRpcRequst, -) -> MmResult { - let ctx = WalletConnectCtx::from_ctx(&ctx)?; - let url = ctx.new_connection(None).await?; - - Ok(CreateConnectionResponse { url }) -} diff --git a/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs b/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs deleted file mode 100644 index a2d43b5ba6..0000000000 --- a/mm2src/kdf_walletconnect/src/rpc_commands/ping.rs +++ /dev/null @@ -1,24 +0,0 @@ -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::MmResult; -use relay_rpc::domain::Topic; -use serde::{Deserialize, Serialize}; - -use crate::{error::WalletConnectCtxError, session::ping::send_session_ping_request, WalletConnectCtx}; - -#[derive(Debug, PartialEq, Serialize)] -pub struct SessionPingResponse { - pub successful: bool, -} - -#[derive(Deserialize)] -pub struct SessionPingRequest { - topic: Topic, -} - -/// `ping session` RPC command implementation. -pub async fn ping_session(ctx: MmArc, req: SessionPingRequest) -> MmResult { - let ctx = WalletConnectCtx::from_ctx(&ctx)?; - send_session_ping_request(&ctx, &req.topic).await?; - - Ok(SessionPingResponse { successful: true }) -} diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index f9683fe33b..91a6c482bf 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -10,7 +10,10 @@ use crate::error::SessionError; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; -use mm2_err_handle::prelude::MmResult; +use dashmap::mapref::one::RefMut; +use dashmap::DashMap; +use futures::lock::Mutex; +use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::IrnMetadata; @@ -19,6 +22,7 @@ use relay_rpc::{domain::{SubscriptionId, Topic}, use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::BTreeMap; +use std::sync::Arc; use x25519_dalek::{SharedSecret, StaticSecret}; use {hkdf::Hkdf, rand::{rngs::OsRng, CryptoRng, RngCore}, @@ -188,7 +192,7 @@ impl Session { controller, namespaces: BTreeMap::new(), proposer, - propose_namespaces: ctx.namespaces.clone(), + propose_namespaces: ctx.required_namespaces.clone(), relay: ctx.relay.clone(), expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, pairing_topic, @@ -196,6 +200,8 @@ impl Session { topic: session_topic, } } + + pub(crate) fn extend(&mut self, till: u64) { self.expiry = till; } } pub(crate) struct SymKeyPair { @@ -213,3 +219,106 @@ impl SymKeyPair { } } } + +struct SessionManagementImpl { + active_topic: Mutex>, + sessions: DashMap, +} + +pub struct SessionManagement(Arc); + +impl Default for SessionManagement { + fn default() -> Self { Self::new() } +} + +#[allow(unused)] +impl SessionManagement { + pub fn new() -> Self { + let impl_ = SessionManagementImpl { + active_topic: Default::default(), + sessions: Default::default(), + }; + + Self(Arc::new(impl_)) + } + + pub(crate) async fn add_session(&self, session: Session) { + // set active session topic. + *self.0.active_topic.lock().await = Some(session.topic.clone()); + + // insert session + self.0.sessions.insert(session.topic.clone(), session); + } + + pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { + let mut active_topic = self.0.active_topic.lock().await; + + if let Some(ref topic_) = *active_topic { + if topic_ == topic { + *active_topic = None; + }; + }; + + self.0.sessions.remove(topic).map(|(_, session)| session) + } + + pub(crate) fn get_session(&self, topic: &Topic) -> Option { + self.0.sessions.get(topic).map(|session| session.clone()) + } + + pub(crate) async fn get_session_mut(&self, topic: &Topic) -> Option> { + self.0.sessions.get_mut(topic) + } + + pub async fn get_session_active(&self) -> Option { + let active_topic = self.0.active_topic.lock().await; + if let Some(ref topic) = *active_topic { + self.get_session(topic) + } else { + None + } + } + + pub(crate) fn get_sessions(&self) -> Vec { + self.0 + .sessions + .clone() + .into_iter() + .map(|(_, session)| session) + .collect() + } + + pub(crate) fn extend_session(&self, topic: &Topic, till: u64) { + if let Some(mut session) = self.0.sessions.get_mut(topic) { + session.extend(till); + } + } + + pub(crate) async fn extend_active_session(&self, till: u64) { + let active_topic = self.0.active_topic.lock().await; + if let Some(ref topic) = *active_topic { + self.extend_session(topic, till); + } + } + + pub(crate) async fn delete_expired_sessions(&self) -> Vec { + let now = Utc::now().timestamp() as u64; + let mut expired_sessions = Vec::new(); + + // Collect session arcs for processing + for session in self.0.sessions.iter() { + if session.expiry <= now { + // Remove the session from the map + if let Some(session) = self.delete_session(&session.topic).await { + expired_sessions.push(session); + } + } + } + + expired_sessions + } + + pub(crate) fn sym_key(&self, topic: &Topic) -> Option> { + self.get_session(topic).map(|k| k.session_key.symmetric_key().to_vec()) + } +} diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/delete.rs index 7fcd944833..0f6235a9fc 100644 --- a/mm2src/kdf_walletconnect/src/session/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/delete.rs @@ -38,7 +38,7 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu ctx.client.unsubscribe(topic.clone()).await?; }; - if let Some(session) = ctx.session.lock().await.as_mut().take() { + if let Some(session) = ctx.session.delete_session(topic).await { debug!( "No active sessions left for pairing {}, disconnecting", session.pairing_topic diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/event.rs index cd5e987695..3053cab5f3 100644 --- a/mm2src/kdf_walletconnect/src/session/event.rs +++ b/mm2src/kdf_walletconnect/src/session/event.rs @@ -61,19 +61,18 @@ impl SessionEvents { ) -> MmResult<(), WalletConnectCtxError> { if ctx.is_chain_supported(chain_id) { if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { - if let Some(session) = ctx.session.lock().await.as_ref() { - if let Some(namespace) = session.namespaces.get(&key) { - let chains = namespace.chains.clone().unwrap_or_default(); - if chains.contains(&chain) { - // TODO: Notify GUI about chain changed. - // Update active chain_id - ctx.set_active_chain(chain_id.clone()).await; + let namespaces = ctx.namespaces.lock().await; + if let Some(namespace) = namespaces.get(&key) { + let chains = namespace.chains.clone().unwrap_or_default(); + if chains.contains(&chain) { + // TODO: Notify GUI about chain changed. + // Update active chain_id + ctx.set_active_chain(chain_id.clone()).await; - let params = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, params, message_id).await?; + let params = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, params, message_id).await?; - return Ok(()); - } + return Ok(()); } } } diff --git a/mm2src/kdf_walletconnect/src/session/extend.rs b/mm2src/kdf_walletconnect/src/session/extend.rs index 5e34cb0e69..e187dc4c24 100644 --- a/mm2src/kdf_walletconnect/src/session/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/extend.rs @@ -1,6 +1,5 @@ use crate::{error::WalletConnectCtxError, WalletConnectCtx}; -use common::log::info; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_extend::SessionExtendRequest, ResponseParamsSuccess}}; @@ -12,11 +11,7 @@ pub(crate) async fn reply_session_extend_request( message_id: &MessageId, extend: SessionExtendRequest, ) -> MmResult<(), WalletConnectCtxError> { - let mut session = ctx.session.lock().await; - if let Some(session) = session.as_mut() { - session.expiry = extend.expiry; - info!("Updated extended, info: {:?}", session); - } + ctx.session.extend_session(topic, extend.expiry); let param = ResponseParamsSuccess::SessionExtend(true); ctx.publish_response_ok(topic, param, message_id).await?; diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/propose.rs index 9e13d43252..dee7fbaeba 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/propose.rs @@ -24,7 +24,7 @@ pub(crate) async fn send_proposal_request( let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], proposer, - required_namespaces: required_namespaces.unwrap_or(ctx.namespaces.clone()), + required_namespaces: required_namespaces.unwrap_or(ctx.required_namespaces.clone()), }); ctx.publish_request(&topic, session_proposal).await?; @@ -75,8 +75,9 @@ pub async fn reply_session_proposal_request( // .await // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; - let mut old_session = ctx.session.lock().await; - *old_session = Some(session.clone()); + // Add session to session lists + ctx.session.add_session(session.clone()).await; + // Add topic to subscription list let mut subs = ctx.subscriptions.lock().await; subs.push(session_topic.clone()); } @@ -138,8 +139,9 @@ pub(crate) async fn process_session_propose_response( // .await // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; - let mut old_session = ctx.session.lock().await; - *old_session = Some(session); + // Add session to session lists + ctx.session.add_session(session.clone()).await; + // Add topic to subscription list let mut subs = ctx.subscriptions.lock().await; subs.push(session_topic.clone()); }; diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/settle.rs index db59fd135b..ad3a38c1f0 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/settle.rs @@ -44,8 +44,8 @@ pub(crate) async fn reply_session_settle_request( settle: SessionSettleRequest, ) -> MmResult<(), WalletConnectCtxError> { { - let mut session = ctx.session.lock().await; - if let Some(session) = session.as_mut() { + let session = ctx.session.get_session_mut(topic).await; + if let Some(mut session) = session { session.namespaces = settle.namespaces.0.clone(); session.controller = settle.controller.clone(); session.relay = settle.relay.clone(); @@ -54,7 +54,7 @@ pub(crate) async fn reply_session_settle_request( // Update storage session. ctx.storage .db - .update_session(session) + .update_session(&session) .await .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/update.rs index 66929827d2..b9722ed07f 100644 --- a/mm2src/kdf_walletconnect/src/session/update.rs +++ b/mm2src/kdf_walletconnect/src/session/update.rs @@ -1,6 +1,6 @@ -use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use common::log::info; use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_update::SessionUpdateRequest, ResponseParamsSuccess}}; @@ -14,16 +14,17 @@ pub(crate) async fn reply_session_update_request( update: SessionUpdateRequest, ) -> MmResult<(), WalletConnectCtxError> { { - let mut session = ctx.session.lock().await; - if let Some(session) = session.as_mut() { - session.namespaces = update.namespaces.0.clone(); - + if let Some(mut session) = ctx.session.get_session_mut(topic).await { + let mut ctx_ns = ctx.namespaces.lock().await; + *ctx_ns = update.namespaces.clone(); + session.namespaces = update.namespaces.0; + info!("Updated extended, info: {:?}", session); // Update storage session. - ctx.storage - .db - .update_session(session) - .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + //ctx.storage + //.db + //.update_session(session) + //.await + //.mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; }; } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs index 4b58c51fcf..0dc757f117 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs @@ -14,7 +14,7 @@ pub struct GetSessionResponse { pub async fn get_session(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let session = ctx.get_session().await; + let session = ctx.session.get_session_active().await; Ok(GetSessionResponse { session }) } From 481f1c33b5aa6ce863fe2242856bf8e07c8bd5be Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 8 Oct 2024 14:38:47 +0100 Subject: [PATCH 049/125] remove mm2_test_helpers lock file --- mm2src/mm2_test_helpers/Cargo.lock | 4116 ---------------------------- 1 file changed, 4116 deletions(-) delete mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock deleted file mode 100644 index 62af3720d7..0000000000 --- a/mm2src/mm2_test_helpers/Cargo.lock +++ /dev/null @@ -1,4116 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures", -] - -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" - -[[package]] -name = "argon2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" -dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", - "zeroize", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-executor" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.3.1", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" -dependencies = [ - "async-lock", - "cfg-if 1.0.0", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[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-process" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" -dependencies = [ - "async-channel 2.3.1", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if 1.0.0", - "event-listener 5.3.1", - "futures-lite", - "rustix", - "tracing", -] - -[[package]] -name = "async-signal" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if 1.0.0", - "futures-core", - "futures-io", - "rustix", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-std" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers 0.3.0", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.4.0", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets", -] - -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - -[[package]] -name = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "bip32" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" -dependencies = [ - "bs58", - "hkd32", - "hmac 0.11.0", - "ripemd160", - "secp256k1 0.20.3", - "sha2 0.9.9", - "subtle", - "zeroize", -] - -[[package]] -name = "bip39" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" -dependencies = [ - "bitcoin_hashes", - "rand_core 0.6.4", - "zeroize", -] - -[[package]] -name = "bitcoin" -version = "0.29.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" -dependencies = [ - "bech32", - "bitcoin_hashes", - "secp256k1 0.24.3", -] - -[[package]] -name = "bitcoin_hashes" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" - -[[package]] -name = "bitcrypto" -version = "0.1.0" -dependencies = [ - "groestl", - "primitives", - "ripemd160", - "serialization", - "sha-1", - "sha2 0.10.8", - "sha3 0.9.1", - "siphasher", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[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 = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding 0.2.1", - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel 2.3.1", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[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-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - -[[package]] -name = "bytes" -version = "1.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "cc" -version = "1.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chain" -version = "0.1.0" -dependencies = [ - "bitcoin", - "bitcrypto", - "primitives", - "rustc-hex", - "serialization", - "serialization_derive", -] - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets", -] - -[[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 = "cloudabi" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" -dependencies = [ - "bitflags 1.3.2", -] - -[[package]] -name = "common" -version = "0.1.0" -dependencies = [ - "anyhow", - "arrayref", - "async-trait", - "backtrace", - "bytes 1.7.2", - "cc", - "cfg-if 1.0.0", - "chrono", - "crossbeam", - "derive_more", - "env_logger", - "findshlibs", - "fnv", - "futures 0.1.31", - "futures 0.3.30", - "futures-timer", - "gstuff", - "hex", - "http 0.2.12", - "http-body 0.1.0", - "hyper", - "hyper-rustls", - "instant", - "itertools", - "js-sys", - "lazy_static", - "libc", - "lightning", - "log", - "parking_lot", - "parking_lot_core 0.6.3", - "primitive-types", - "rand 0.7.3", - "regex", - "rustc-hash", - "ser_error", - "ser_error_derive", - "serde", - "serde-wasm-bindgen", - "serde_derive", - "serde_json", - "serde_repr", - "sha2 0.10.8", - "tokio", - "uuid", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", - "winapi", -] - -[[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_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto" -version = "1.0.0" -dependencies = [ - "aes", - "argon2", - "arrayref", - "async-trait", - "base64", - "bip32", - "bip39", - "bitcrypto", - "bs58", - "cbc", - "cfg-if 1.0.0", - "cipher", - "common", - "derive_more", - "enum-primitive-derive", - "enum_derives", - "futures 0.3.30", - "hex", - "hmac 0.12.1", - "http 0.2.12", - "hw_common", - "keys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_eth", - "mm2_metamask", - "num-traits", - "parking_lot", - "primitives", - "rpc", - "rpc_task", - "rustc-hex", - "secp256k1 0.20.3", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", - "serde_json", - "sha2 0.10.8", - "trezor", - "wasm-bindgen-test", - "web3", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "db_common" -version = "0.1.0" -dependencies = [ - "common", - "crossbeam-channel", - "futures 0.3.30", - "hex", - "log", - "rusqlite", - "sql-builder", - "tokio", - "uuid", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case", - "proc-macro2", - "quote 1.0.37", - "rustc_version 0.4.1", - "syn 2.0.79", -] - -[[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", - "crypto-common", - "subtle", -] - -[[package]] -name = "edit-distance" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "enum-primitive-derive" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" -dependencies = [ - "num-traits", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "enum_derives" -version = "0.1.0" -dependencies = [ - "itertools", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[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 = "ethabi" -version = "17.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3 0.10.8", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "ethcore-transaction" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "ethereum-types", - "ethkey", - "keccak-hash", - "rlp", - "rustc-hex", - "unexpected", -] - -[[package]] -name = "ethereum-types" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - -[[package]] -name = "ethkey" -version = "0.3.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "byteorder", - "edit-distance", - "ethereum-types", - "log", - "mem", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "tiny-keccak 1.4.4", -] - -[[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 = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - -[[package]] -name = "fastrand" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" - -[[package]] -name = "findshlibs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - -[[package]] -name = "futures" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" - -[[package]] -name = "futures-executor" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite", -] - -[[package]] -name = "futures-macro" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "futures-sink" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" - -[[package]] -name = "futures-task" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" - -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers 0.2.6", - "send_wrapper", -] - -[[package]] -name = "futures-util" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" -dependencies = [ - "futures 0.1.31", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "gimli" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "groestl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "gstuff" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes 1.7.2", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.6.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" -dependencies = [ - "ahash", -] - -[[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 = "hashbrown" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hkd32" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" -dependencies = [ - "hmac 0.11.0", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[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.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -dependencies = [ - "bytes 0.4.12", - "fnv", - "itoa 0.4.8", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes 1.7.2", - "fnv", - "itoa 1.0.11", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "http 0.1.21", - "tokio-buf", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes 1.7.2", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "httparse" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" - -[[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 = "hw_common" -version = "0.1.0" -dependencies = [ - "async-trait", - "bip32", - "common", - "derive_more", - "futures 0.3.30", - "js-sys", - "mm2_err_handle", - "rusb", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "hyper" -version = "0.14.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" -dependencies = [ - "bytes 1.7.2", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa 1.0.11", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", - "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", - "rustls", - "tokio", - "tokio-rustls", - "webpki-roots", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg 1.4.0", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" -dependencies = [ - "equivalent", - "hashbrown 0.15.0", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding 0.3.3", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipnet" -version = "2.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" - -[[package]] -name = "itertools" -version = "0.10.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures 0.3.30", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "keccak-hash" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" -dependencies = [ - "primitive-types", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "keys" -version = "0.1.0" -dependencies = [ - "base58", - "bech32", - "bitcrypto", - "derive_more", - "lazy_static", - "primitives", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.159" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" - -[[package]] -name = "libsqlite3-sys" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "libusb1-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "lightning" -version = "0.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" -dependencies = [ - "bitcoin", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg 1.4.0", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -dependencies = [ - "value-bag", -] - -[[package]] -name = "mach2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" -dependencies = [ - "libc", -] - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "mem" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "metrics" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash", - "metrics-macros", - "portable-atomic", -] - -[[package]] -name = "metrics-exporter-prometheus" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" -dependencies = [ - "base64", - "hyper", - "indexmap 1.9.3", - "ipnet", - "metrics", - "metrics-util", - "quanta", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "metrics-macros" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "metrics-util" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" -dependencies = [ - "aho-corasick", - "crossbeam-epoch", - "crossbeam-utils", - "hashbrown 0.13.1", - "indexmap 1.9.3", - "metrics", - "num_cpus", - "ordered-float", - "quanta", - "radix_trie", - "sketches-ddsketch", -] - -[[package]] -name = "minicov" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c71e683cd655513b99affab7d317deb690528255a0d5f717f1024093c12b169" -dependencies = [ - "cc", - "walkdir", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", -] - -[[package]] -name = "mm2_core" -version = "0.1.0" -dependencies = [ - "arrayref", - "async-std", - "async-trait", - "cfg-if 1.0.0", - "common", - "db_common", - "derive_more", - "futures 0.3.30", - "gstuff", - "hex", - "instant", - "lazy_static", - "mm2_err_handle", - "mm2_event_stream", - "mm2_metrics", - "mm2_rpc", - "primitives", - "rand 0.7.3", - "rustls", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "shared_ref_counter", - "tokio", - "uuid", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_err_handle" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.1.31", - "http 0.2.12", - "itertools", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_eth" -version = "0.1.0" -dependencies = [ - "ethabi", - "ethkey", - "hex", - "indexmap 1.9.3", - "itertools", - "mm2_err_handle", - "secp256k1 0.20.3", - "serde", - "serde_json", - "web3", -] - -[[package]] -name = "mm2_event_stream" -version = "0.1.0" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "common", - "futures 0.3.30", - "parking_lot", - "serde", - "tokio", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_io" -version = "0.1.0" -dependencies = [ - "async-std", - "common", - "derive_more", - "futures 0.3.30", - "gstuff", - "mm2_err_handle", - "rand 0.7.3", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_metamask" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.30", - "itertools", - "js-sys", - "jsonrpc-core", - "lazy_static", - "mm2_err_handle", - "mm2_eth", - "parking_lot", - "serde", - "serde_derive", - "serde_json", - "wasm-bindgen", - "wasm-bindgen-futures", - "web3", -] - -[[package]] -name = "mm2_metrics" -version = "0.1.0" -dependencies = [ - "base64", - "common", - "derive_more", - "futures 0.3.30", - "hyper", - "hyper-rustls", - "itertools", - "metrics", - "metrics-exporter-prometheus", - "metrics-util", - "mm2_err_handle", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "mm2_net" -version = "0.1.0" -dependencies = [ - "async-trait", - "base64", - "bytes 1.7.2", - "cfg-if 1.0.0", - "common", - "derive_more", - "ethkey", - "futures 0.3.30", - "futures-util", - "gstuff", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "hyper", - "js-sys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_state_machine", - "pin-project", - "prost", - "rand 0.7.3", - "rustls", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-rustls", - "tonic", - "tower-service", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "mm2_number" -version = "0.1.0" -dependencies = [ - "bigdecimal", - "num-bigint", - "num-rational", - "num-traits", - "paste", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_rpc" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.3.30", - "gstuff", - "http 0.2.12", - "mm2_err_handle", - "mm2_number", - "rpc", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "uuid", -] - -[[package]] -name = "mm2_state_machine" -version = "0.1.0" -dependencies = [ - "async-trait", -] - -[[package]] -name = "mm2_test_helpers" -version = "0.1.0" -dependencies = [ - "bytes 1.7.2", - "cfg-if 1.0.0", - "chrono", - "common", - "crypto", - "db_common", - "futures 0.3.30", - "gstuff", - "http 0.2.12", - "lazy_static", - "mm2_core", - "mm2_io", - "mm2_metrics", - "mm2_net", - "mm2_number", - "mm2_rpc", - "rand 0.7.3", - "regex", - "rpc", - "serde", - "serde_derive", - "serde_json", - "uuid", -] - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec 1.13.2", -] - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "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", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg 1.4.0", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "object" -version = "0.36.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" -dependencies = [ - "portable-atomic", -] - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec 0.7.6", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version 0.2.3", - "smallvec 0.6.14", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.5.7", - "smallvec 1.13.2", - "windows-targets", -] - -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "pin-project-lite" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkg-config" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" - -[[package]] -name = "polling" -version = "3.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" -dependencies = [ - "cfg-if 1.0.0", - "concurrent-queue", - "hermit-abi 0.4.0", - "pin-project-lite", - "rustix", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "primitive-types" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "uint", -] - -[[package]] -name = "primitives" -version = "0.1.0" -dependencies = [ - "bitcoin_hashes", - "byteorder", - "rustc-hex", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro2" -version = "1.0.86" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prost" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" -dependencies = [ - "bytes 1.7.2", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.11.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" -dependencies = [ - "anyhow", - "itertools", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "quanta" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" -dependencies = [ - "crossbeam-utils", - "libc", - "mach2", - "once_cell", - "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", - "web-sys", - "winapi", -] - -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -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", - "wasm-bindgen", - "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -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-cpuid" -version = "10.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" -dependencies = [ - "bitflags 1.3.2", -] - -[[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.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "regex" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if 1.0.0", - "getrandom 0.2.15", - "libc", - "spin", - "untrusted", - "windows-sys 0.52.0", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes 1.7.2", - "rustc-hex", -] - -[[package]] -name = "rpc" -version = "0.1.0" -dependencies = [ - "chain", - "keys", - "log", - "primitives", - "rustc-hex", - "script", - "serde", - "serde_derive", - "serde_json", - "serialization", -] - -[[package]] -name = "rpc_task" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.30", - "mm2_err_handle", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", -] - -[[package]] -name = "rusb" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" -dependencies = [ - "libc", - "libusb1-sys", -] - -[[package]] -name = "rusqlite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec 1.13.2", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver 1.0.23", -] - -[[package]] -name = "rustix" -version = "0.38.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "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 = [ - "ring", - "rustls-webpki", - "sct", -] - -[[package]] -name = "rustls-webpki" -version = "0.101.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[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 = "script" -version = "0.1.0" -dependencies = [ - "bitcrypto", - "blake2b_simd", - "chain", - "keys", - "log", - "primitives", - "serde", - "serialization", -] - -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring", - "untrusted", -] - -[[package]] -name = "secp256k1" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" -dependencies = [ - "rand 0.6.5", - "secp256k1-sys 0.4.2", -] - -[[package]] -name = "secp256k1" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" -dependencies = [ - "bitcoin_hashes", - "secp256k1-sys 0.6.1", -] - -[[package]] -name = "secp256k1-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" -dependencies = [ - "cc", -] - -[[package]] -name = "secp256k1-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" -dependencies = [ - "cc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "ser_error" -version = "0.1.0" -dependencies = [ - "serde", -] - -[[package]] -name = "ser_error_derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "ser_error", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_derive" -version = "1.0.210" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "serde_json" -version = "1.0.128" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" -dependencies = [ - "indexmap 2.6.0", - "itoa 1.0.11", - "memchr", - "ryu", - "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 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "serialization" -version = "0.1.0" -dependencies = [ - "byteorder", - "derive_more", - "primitives", - "test_helpers", -] - -[[package]] -name = "serialization_derive" -version = "0.1.0" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "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 1.0.0", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shared_ref_counter" -version = "0.1.0" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "siphasher" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" - -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg 1.4.0", -] - -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "socket2" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "sql-builder" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" -dependencies = [ - "anyhow", - "thiserror", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.79" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test_helpers" -version = "0.1.0" -dependencies = [ - "hex", -] - -[[package]] -name = "thiserror" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.64" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "tiny-keccak" -version = "1.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.40.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" -dependencies = [ - "backtrace", - "bytes 1.7.2", - "libc", - "mio", - "pin-project-lite", - "socket2", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-buf" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls", - "tokio", -] - -[[package]] -name = "tokio-stream" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" -dependencies = [ - "futures-core", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" -dependencies = [ - "bytes 1.7.2", - "futures-core", - "futures-sink", - "pin-project-lite", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap 2.6.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" -dependencies = [ - "async-trait", - "base64", - "bytes 1.7.2", - "futures-core", - "futures-util", - "http 0.2.12", - "http-body 0.4.6", - "percent-encoding", - "pin-project", - "prost", - "tokio-stream", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "trezor" -version = "0.1.1" -dependencies = [ - "async-std", - "async-trait", - "bip32", - "byteorder", - "common", - "derive_more", - "ethcore-transaction", - "ethereum-types", - "ethkey", - "futures 0.3.30", - "hw_common", - "js-sys", - "lazy_static", - "mm2_err_handle", - "prost", - "rand 0.7.3", - "rpc_task", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unexpected" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "uuid" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81dfa00651efa65069b0b6b651f4aaa31ba9e3c3ce0137aaad053604ee7e0314" -dependencies = [ - "getrandom 0.2.15", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "value-bag" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" -dependencies = [ - "quote 1.0.37", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.93" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" - -[[package]] -name = "wasm-bindgen-test" -version = "0.3.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68497a05fb21143a08a7d24fc81763384a3072ee43c44e86aad1744d6adef9d9" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "minicov", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8220be1fa9e4c889b30fd207d4906657e7e90b12e0e6b0c8b8d8709f5de021" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "web-sys" -version = "0.3.70" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web3" -version = "0.19.0" -source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" -dependencies = [ - "arrayvec 0.7.6", - "derive_more", - "ethabi", - "ethereum-types", - "futures 0.3.30", - "futures-timer", - "getrandom 0.2.15", - "hex", - "idna", - "js-sys", - "jsonrpc-core", - "log", - "parking_lot", - "pin-project", - "rand 0.8.5", - "rlp", - "serde", - "serde-wasm-bindgen", - "serde_json", - "tiny-keccak 2.0.2", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.79", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -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 1.0.37", - "syn 2.0.79", -] From 0c00710ab659e3ed3849654393eb59708548a369 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 8 Oct 2024 16:07:51 +0100 Subject: [PATCH 050/125] refactoring and unit tests --- Cargo.lock | 5 +- mm2src/coins/tendermint/tendermint_coin.rs | 26 ++- .../src/tendermint_with_assets_activation.rs | 2 +- mm2src/kdf_walletconnect/Cargo.toml | 1 + .../kdf_walletconnect/src/inbound_message.rs | 14 +- mm2src/kdf_walletconnect/src/lib.rs | 2 +- mm2src/kdf_walletconnect/src/session.rs | 142 +++---------- mm2src/kdf_walletconnect/src/session/key.rs | 189 ++++++++++++++++++ .../src/session/{ => rpc}/delete.rs | 0 .../src/session/{ => rpc}/event.rs | 0 .../src/session/{ => rpc}/extend.rs | 0 .../kdf_walletconnect/src/session/rpc/mod.rs | 7 + .../src/session/{ => rpc}/ping.rs | 0 .../src/session/{ => rpc}/propose.rs | 8 +- .../src/session/{ => rpc}/settle.rs | 2 +- .../src/session/{ => rpc}/update.rs | 0 mm2src/kdf_walletconnect/src/storage/mod.rs | 4 +- .../src/rpc/wc_commands/delete_connection.rs | 3 +- mm2src/mm2_main/src/rpc/wc_commands/ping.rs | 3 +- 19 files changed, 262 insertions(+), 146 deletions(-) create mode 100644 mm2src/kdf_walletconnect/src/session/key.rs rename mm2src/kdf_walletconnect/src/session/{ => rpc}/delete.rs (100%) rename mm2src/kdf_walletconnect/src/session/{ => rpc}/event.rs (100%) rename mm2src/kdf_walletconnect/src/session/{ => rpc}/extend.rs (100%) create mode 100644 mm2src/kdf_walletconnect/src/session/rpc/mod.rs rename mm2src/kdf_walletconnect/src/session/{ => rpc}/ping.rs (100%) rename mm2src/kdf_walletconnect/src/session/{ => rpc}/propose.rs (94%) rename mm2src/kdf_walletconnect/src/session/{ => rpc}/settle.rs (98%) rename mm2src/kdf_walletconnect/src/session/{ => rpc}/update.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index ea326db9c5..04f3cb190e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "argon2" @@ -3565,6 +3565,7 @@ dependencies = [ name = "kdf_walletconnect" version = "0.1.0" dependencies = [ + "anyhow", "async-trait", "base64 0.21.7", "cfg-if 1.0.0", diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index e73aca6943..2d9a0893ca 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -364,6 +364,10 @@ pub enum TendermintWalletConnectionType { Other, } +impl Default for TendermintWalletConnectionType { + fn default() -> Self { Self::Other } +} + pub struct TendermintCoinImpl { ticker: String, /// As seconds @@ -652,7 +656,7 @@ impl TendermintCoin { nodes: Vec, tx_history: bool, activation_policy: TendermintActivationPolicy, - wallet_connection_type: TendermintWalletConnectionType, + wallet_connection_type: Option, ) -> MmResult { if nodes.is_empty() { return MmError::err(TendermintInitError { @@ -717,7 +721,7 @@ impl TendermintCoin { client: TendermintRpcClient(AsyncMutex::new(client_impl)), chain_registry_name: protocol_info.chain_registry_name, ctx: ctx.weak(), - wallet_connection_type, + wallet_connection_type: wallet_connection_type.unwrap_or_default(), }))) } @@ -3506,7 +3510,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -3632,7 +3636,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -3695,7 +3699,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -3769,7 +3773,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -3956,7 +3960,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -4039,7 +4043,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -4115,7 +4119,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -4187,7 +4191,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); @@ -4242,7 +4246,7 @@ pub mod tendermint_coin_tests { nodes, false, activation_policy, - false, + None, )) .unwrap(); diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 8654e44146..fa4b282b4d 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -339,7 +339,7 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { activation_request.nodes, activation_request.tx_history, activation_policy, - wallet_connectin_type, + Some(wallet_connectin_type), ) .await } diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 895ba7b6dc..2bcdac1be6 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] +anyhow = "1.0.89" async-trait = "0.1.52" base64 = "0.21.2" chrono = { version = "0.4.23", "features" = ["serde"] } diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 95bf51198b..180a482a1c 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -8,13 +8,13 @@ use serde_json::Value; use crate::{error::WalletConnectCtxError, pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, - session::{delete::reply_session_delete_request, - event::SessionEvents, - extend::reply_session_extend_request, - ping::reply_session_ping_request, - propose::{process_session_propose_response, reply_session_proposal_request}, - settle::reply_session_settle_request, - update::reply_session_update_request}, + session::rpc::{delete::reply_session_delete_request, + event::SessionEvents, + extend::reply_session_extend_request, + ping::reply_session_ping_request, + propose::{process_session_propose_response, reply_session_proposal_request}, + settle::reply_session_settle_request, + update::reply_session_update_request}, WalletConnectCtx}; #[derive(Debug, Serialize, Deserialize)] diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 9204548506..355b662698 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -33,7 +33,7 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; use serde_json::Value; -use session::{propose::send_proposal_request, SessionManagement, SymKeyPair}; +use session::{key::SymKeyPair, rpc::propose::send_proposal_request, SessionManagement}; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 91a6c482bf..1b4dd202e5 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,19 +1,14 @@ -pub mod delete; -pub(crate) mod event; -pub(crate) mod extend; -pub mod ping; -pub(crate) mod propose; -pub(crate) mod settle; -pub(crate) mod update; +pub(crate) mod key; +pub mod rpc; -use crate::error::SessionError; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; use dashmap::mapref::one::RefMut; use dashmap::DashMap; use futures::lock::Mutex; -use mm2_err_handle::prelude::{MmError, MmResult}; +use key::SessionKey; +use mm2_err_handle::prelude::MmResult; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::IrnMetadata; @@ -22,96 +17,14 @@ use relay_rpc::{domain::{SubscriptionId, Topic}, use serde::{Deserialize, Serialize}; use serde_json::Value; use std::collections::BTreeMap; +use std::fmt::Debug; use std::sync::Arc; -use x25519_dalek::{SharedSecret, StaticSecret}; -use {hkdf::Hkdf, - rand::{rngs::OsRng, CryptoRng, RngCore}, - sha2::{Digest, Sha256}, - std::fmt::Debug, - x25519_dalek::PublicKey}; pub(crate) const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; -#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] -pub struct SessionKey { - pub(crate) sym_key: [u8; 32], - pub(crate) public_key: [u8; 32], -} - -impl std::fmt::Debug for SessionKey { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("SessionKey") - .field("sym_key", &"*******") - .field("public_key", &self.public_key) - .finish() - } -} - -impl SessionKey { - /// Creates a new SessionKey with a given public key and empty symmetric key. - pub fn new(public_key: PublicKey) -> Self { - Self { - sym_key: [0u8; 32], - public_key: public_key.to_bytes(), - } - } - - /// Creates new session key from `osrng`. - pub fn from_osrng(other_public_key: &[u8; 32]) -> Result { - SessionKey::diffie_hellman(OsRng, other_public_key) - } - /// Performs Diffie-Hellman symmetric key derivation. - pub fn diffie_hellman(csprng: T, other_public_key: &[u8; 32]) -> Result - where - T: RngCore + CryptoRng, - { - let static_private_key = StaticSecret::random_from_rng(csprng); - let public_key = PublicKey::from(&static_private_key); - let shared_secret = static_private_key.diffie_hellman(&PublicKey::from(*other_public_key)); - - let mut session_key = Self { - sym_key: [0u8; 32], - public_key: public_key.to_bytes(), - }; - session_key.derive_symmetric_key(&shared_secret)?; - - Ok(session_key) - } - - /// Generates the symmetric key given the ephemeral secret and the peer's public key. - pub fn generate_symmetric_key( - &mut self, - static_secret: &StaticSecret, - peer_public_key: &[u8; 32], - ) -> Result<(), SessionError> { - let shared_secret = static_secret.diffie_hellman(&PublicKey::from(*peer_public_key)); - self.derive_symmetric_key(&shared_secret) - } - - /// Derives the symmetric key from a shared secret. - fn derive_symmetric_key(&mut self, shared_secret: &SharedSecret) -> Result<(), SessionError> { - let hk = Hkdf::::new(None, shared_secret.as_bytes()); - hk.expand(&[], &mut self.sym_key) - .map_err(|e| SessionError::SymKeyGeneration(e.to_string())) - } - - /// Gets symmetic key reference. - pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } - - /// Gets "our" public key used in symmetric key derivation. - pub fn diffie_public_key(&self) -> &[u8; 32] { &self.public_key } - - /// Generates new session topic. - pub fn generate_topic(&self) -> String { - let mut hasher = Sha256::new(); - hasher.update(self.sym_key); - hex::encode(hasher.finalize()) - } -} - /// In the WalletConnect protocol, a session involves two parties: a controller /// (typically a wallet) and a proposer (typically a dApp). This enum is used /// to distinguish between these two roles. @@ -204,24 +117,12 @@ impl Session { pub(crate) fn extend(&mut self, till: u64) { self.expiry = till; } } -pub(crate) struct SymKeyPair { - pub(crate) secret: StaticSecret, - pub(crate) public_key: PublicKey, -} - -impl SymKeyPair { - pub(crate) fn new() -> Self { - let static_secret = StaticSecret::random_from_rng(OsRng); - let public_key = PublicKey::from(&static_secret); - Self { - secret: static_secret, - public_key, - } - } -} - +/// Internal implementation of session management. +#[derive(Default, Debug)] struct SessionManagementImpl { + /// The currently active session topic. active_topic: Mutex>, + /// A thread-safe map of sessions indexed by topic. sessions: DashMap, } @@ -233,15 +134,10 @@ impl Default for SessionManagement { #[allow(unused)] impl SessionManagement { - pub fn new() -> Self { - let impl_ = SessionManagementImpl { - active_topic: Default::default(), - sessions: Default::default(), - }; - - Self(Arc::new(impl_)) - } + pub fn new() -> Self { Self(Default::default()) } + /// Inserts the provided `Session` into the session store, associated with the specified topic. + /// If a session with the same topic already exists, it will be overwritten. pub(crate) async fn add_session(&self, session: Session) { // set active session topic. *self.0.active_topic.lock().await = Some(session.topic.clone()); @@ -250,6 +146,8 @@ impl SessionManagement { self.0.sessions.insert(session.topic.clone(), session); } + /// Removes the session corresponding to the specified topic from the session store. + /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { let mut active_topic = self.0.active_topic.lock().await; @@ -262,14 +160,17 @@ impl SessionManagement { self.0.sessions.remove(topic).map(|(_, session)| session) } + /// Retrieves a cloned session associated with a given topic. pub(crate) fn get_session(&self, topic: &Topic) -> Option { self.0.sessions.get(topic).map(|session| session.clone()) } + /// Retrieves a mutable reference to the session associated with a given topic. pub(crate) async fn get_session_mut(&self, topic: &Topic) -> Option> { self.0.sessions.get_mut(topic) } + /// Returns an `Option` containing the active session if it exists; otherwise, returns `None`. pub async fn get_session_active(&self) -> Option { let active_topic = self.0.active_topic.lock().await; if let Some(ref topic) = *active_topic { @@ -279,6 +180,7 @@ impl SessionManagement { } } + /// Retrieves all sessions(active and inactive) pub(crate) fn get_sessions(&self) -> Vec { self.0 .sessions @@ -288,12 +190,16 @@ impl SessionManagement { .collect() } + /// Updates the expiry time of the session associated with the given topic to the specified timestamp. + /// If the session does not exist, this method does nothing. pub(crate) fn extend_session(&self, topic: &Topic, till: u64) { if let Some(mut session) = self.0.sessions.get_mut(topic) { session.extend(till); } } + /// Updates the expiry time of the currently active session to the specified timestamp. + /// If there is no active session, this method does nothing. pub(crate) async fn extend_active_session(&self, till: u64) { let active_topic = self.0.active_topic.lock().await; if let Some(ref topic) = *active_topic { @@ -301,6 +207,9 @@ impl SessionManagement { } } + /// This method checks all sessions for expiration based on the current time. + /// Expired sessions are removed from the session store and returned. + /// If the active session is expired, it is also removed, and the active session is set to `None`. pub(crate) async fn delete_expired_sessions(&self) -> Vec { let now = Utc::now().timestamp() as u64; let mut expired_sessions = Vec::new(); @@ -318,6 +227,7 @@ impl SessionManagement { expired_sessions } + /// Retrieves the symmetric key associated with a given topic. pub(crate) fn sym_key(&self, topic: &Topic) -> Option> { self.get_session(topic).map(|k| k.session_key.symmetric_key().to_vec()) } diff --git a/mm2src/kdf_walletconnect/src/session/key.rs b/mm2src/kdf_walletconnect/src/session/key.rs new file mode 100644 index 0000000000..3ca3bc314d --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/key.rs @@ -0,0 +1,189 @@ +use crate::error::SessionError; + +use serde::{Deserialize, Serialize}; +use x25519_dalek::{PublicKey, SharedSecret, StaticSecret}; +use {hkdf::Hkdf, + rand::{rngs::OsRng, CryptoRng, RngCore}, + sha2::Sha256}; + +pub(crate) struct SymKeyPair { + pub(crate) secret: StaticSecret, + pub(crate) public_key: PublicKey, +} + +impl SymKeyPair { + pub(crate) fn new() -> Self { + let static_secret = StaticSecret::random_from_rng(OsRng); + let public_key = PublicKey::from(&static_secret); + Self { + secret: static_secret, + public_key, + } + } +} + +#[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SessionKey { + pub(crate) sym_key: [u8; 32], + pub(crate) public_key: [u8; 32], +} + +impl std::fmt::Debug for SessionKey { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("SessionKey") + .field("sym_key", &"*******") + .field("public_key", &self.public_key) + .finish() + } +} + +impl SessionKey { + /// Creates a new `SessionKey` with the given public key and an empty symmetric key. + pub fn new(public_key: PublicKey) -> Self { + Self { + sym_key: [0u8; 32], + public_key: public_key.to_bytes(), + } + } + + /// Creates a new `SessionKey` using a random number generator and a peer's public key. + pub fn from_osrng(other_public_key: &[u8; 32]) -> Result { + SessionKey::diffie_hellman(OsRng, other_public_key) + } + + /// Performs Diffie-Hellman key exchange to derive a symmetric key. + pub fn diffie_hellman(csprng: T, other_public_key: &[u8; 32]) -> Result + where + T: RngCore + CryptoRng, + { + let static_private_key = StaticSecret::random_from_rng(csprng); + let public_key = PublicKey::from(&static_private_key); + let shared_secret = static_private_key.diffie_hellman(&PublicKey::from(*other_public_key)); + + let mut session_key = Self { + sym_key: [0u8; 32], + public_key: public_key.to_bytes(), + }; + session_key.derive_symmetric_key(&shared_secret)?; + + Ok(session_key) + } + + /// Generates the symmetric key using the static secret and the peer's public key. + pub fn generate_symmetric_key( + &mut self, + static_secret: &StaticSecret, + peer_public_key: &[u8; 32], + ) -> Result<(), SessionError> { + let shared_secret = static_secret.diffie_hellman(&PublicKey::from(*peer_public_key)); + self.derive_symmetric_key(&shared_secret) + } + + /// Derives the symmetric key from a shared secret. + fn derive_symmetric_key(&mut self, shared_secret: &SharedSecret) -> Result<(), SessionError> { + let hk = Hkdf::::new(None, shared_secret.as_bytes()); + hk.expand(b"SessionKey Derivation", &mut self.sym_key) + .map_err(|e| SessionError::SymKeyGeneration(e.to_string())) + } + + /// Gets symmetic key reference. + pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } + + /// Gets "our" public key used in symmetric key derivation. + pub fn diffie_public_key(&self) -> &[u8; 32] { &self.public_key } +} + +#[cfg(test)] +mod session_key_tests { + use super::*; + use anyhow::Result; + use rand::rngs::OsRng; + use x25519_dalek::{PublicKey, StaticSecret}; + + #[test] + fn test_diffie_hellman_key_exchange() -> Result<()> { + // Alice's key pair + let alice_static_secret = StaticSecret::random_from_rng(OsRng); + let alice_public_key = PublicKey::from(&alice_static_secret); + + // Bob's key pair + let bob_static_secret = StaticSecret::random_from_rng(OsRng); + let bob_public_key = PublicKey::from(&bob_static_secret); + + // Alice computes shared secret and session key + let alice_shared_secret = alice_static_secret.diffie_hellman(&bob_public_key); + let mut alice_session_key = SessionKey::new(alice_public_key); + alice_session_key.derive_symmetric_key(&alice_shared_secret)?; + + // Bob computes shared secret and session key + let bob_shared_secret = bob_static_secret.diffie_hellman(&alice_public_key); + let mut bob_session_key = SessionKey::new(bob_public_key); + bob_session_key.derive_symmetric_key(&bob_shared_secret)?; + + // Both symmetric keys should be the same + assert_eq!(alice_session_key.symmetric_key(), bob_session_key.symmetric_key()); + + // Ensure public keys are different + assert_ne!(alice_session_key.public_key, bob_session_key.public_key); + + Ok(()) + } + + #[test] + fn test_generate_symmetric_key() -> Result<()> { + // Alice's key pair + let alice_static_secret = StaticSecret::random_from_rng(OsRng); + let alice_public_key = PublicKey::from(&alice_static_secret); + + // Bob's public key + let bob_static_secret = StaticSecret::random_from_rng(OsRng); + let bob_public_key = PublicKey::from(&bob_static_secret); + + // Alice initializes session key + let mut alice_session_key = SessionKey::new(alice_public_key); + + // Alice generates symmetric key using Bob's public key + alice_session_key.generate_symmetric_key(&alice_static_secret, &bob_public_key.to_bytes())?; + + // Bob computes shared secret and session key + let bob_shared_secret = bob_static_secret.diffie_hellman(&alice_public_key); + let mut bob_session_key = SessionKey::new(bob_public_key); + bob_session_key.derive_symmetric_key(&bob_shared_secret)?; + + // Both symmetric keys should be the same + assert_eq!(alice_session_key.symmetric_key(), bob_session_key.symmetric_key()); + + Ok(()) + } + + #[test] + fn test_from_osrng() -> Result<()> { + // Bob's public key + let bob_static_secret = StaticSecret::random_from_rng(OsRng); + let bob_public_key = PublicKey::from(&bob_static_secret); + + // Alice creates session key using from_osrng + let alice_session_key = SessionKey::from_osrng(&bob_public_key.to_bytes())?; + + // Bob computes shared secret and session key + let bob_shared_secret = bob_static_secret.diffie_hellman(&PublicKey::from(alice_session_key.public_key)); + let mut bob_session_key = SessionKey::new(bob_public_key); + bob_session_key.derive_symmetric_key(&bob_shared_secret)?; + + // Both symmetric keys should be the same + assert_eq!(alice_session_key.symmetric_key(), bob_session_key.symmetric_key()); + + Ok(()) + } + + #[test] + fn test_debug_trait() { + let static_secret = StaticSecret::random_from_rng(OsRng); + let public_key = PublicKey::from(&static_secret); + let session_key = SessionKey::new(public_key); + + let debug_str = format!("{:?}", session_key); + assert!(debug_str.contains("SessionKey")); + assert!(debug_str.contains("sym_key: \"*******\"")); + } +} diff --git a/mm2src/kdf_walletconnect/src/session/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs similarity index 100% rename from mm2src/kdf_walletconnect/src/session/delete.rs rename to mm2src/kdf_walletconnect/src/session/rpc/delete.rs diff --git a/mm2src/kdf_walletconnect/src/session/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs similarity index 100% rename from mm2src/kdf_walletconnect/src/session/event.rs rename to mm2src/kdf_walletconnect/src/session/rpc/event.rs diff --git a/mm2src/kdf_walletconnect/src/session/extend.rs b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs similarity index 100% rename from mm2src/kdf_walletconnect/src/session/extend.rs rename to mm2src/kdf_walletconnect/src/session/rpc/extend.rs diff --git a/mm2src/kdf_walletconnect/src/session/rpc/mod.rs b/mm2src/kdf_walletconnect/src/session/rpc/mod.rs new file mode 100644 index 0000000000..83aeef1f76 --- /dev/null +++ b/mm2src/kdf_walletconnect/src/session/rpc/mod.rs @@ -0,0 +1,7 @@ +pub mod delete; +pub(crate) mod event; +pub(crate) mod extend; +pub mod ping; +pub(crate) mod propose; +pub(crate) mod settle; +pub(crate) mod update; diff --git a/mm2src/kdf_walletconnect/src/session/ping.rs b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs similarity index 100% rename from mm2src/kdf_walletconnect/src/session/ping.rs rename to mm2src/kdf_walletconnect/src/session/rpc/ping.rs diff --git a/mm2src/kdf_walletconnect/src/session/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs similarity index 94% rename from mm2src/kdf_walletconnect/src/session/propose.rs rename to mm2src/kdf_walletconnect/src/session/rpc/propose.rs index dee7fbaeba..185ae02aad 100644 --- a/mm2src/kdf_walletconnect/src/session/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,6 +1,6 @@ -use super::{settle::send_session_settle_request, Session}; +use super::settle::send_session_settle_request; use crate::{error::WalletConnectCtxError, - session::{SessionKey, SessionType, THIRTY_DAYS}, + session::{Session, SessionKey, SessionType, THIRTY_DAYS}, WalletConnectCtx}; use chrono::Utc; @@ -46,7 +46,7 @@ pub async fn reply_session_proposal_request( .unwrap(); let session_key = SessionKey::from_osrng(&sender_public_key)?; - let session_topic: Topic = session_key.generate_topic().into(); + let session_topic = Topic::generate(); let subscription_id = ctx .client .subscribe(session_topic.clone()) @@ -111,7 +111,7 @@ pub(crate) async fn process_session_propose_response( let mut session_key = SessionKey::new(ctx.key_pair.public_key); session_key.generate_symmetric_key(&ctx.key_pair.secret, &other_public_key)?; - let session_topic: Topic = session_key.generate_topic().into(); + let session_topic = Topic::generate(); let subscription_id = ctx .client .subscribe(session_topic.clone()) diff --git a/mm2src/kdf_walletconnect/src/session/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs similarity index 98% rename from mm2src/kdf_walletconnect/src/session/settle.rs rename to mm2src/kdf_walletconnect/src/session/rpc/settle.rs index ad3a38c1f0..3bca459db9 100644 --- a/mm2src/kdf_walletconnect/src/session/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -1,5 +1,5 @@ -use super::{Session, THIRTY_DAYS}; use crate::chain::{SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; +use crate::session::{Session, THIRTY_DAYS}; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; diff --git a/mm2src/kdf_walletconnect/src/session/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs similarity index 100% rename from mm2src/kdf_walletconnect/src/session/update.rs rename to mm2src/kdf_walletconnect/src/session/rpc/update.rs diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 1bd3247181..112e1d114f 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -43,6 +43,7 @@ impl SessionStorageDb { } } +#[cfg(ignore)] #[cfg(test)] pub(crate) mod session_storage_tests { @@ -56,7 +57,8 @@ pub(crate) mod session_storage_tests { use relay_rpc::{domain::{SubscriptionId, Topic}, rpc::params::Metadata}; - use crate::{session::{Session, SessionKey, SessionType}, + use crate::{session::key::SessionKey, + session::{Session, SessionType}, WalletConnectCtx}; use super::WalletConnectStorageOps; diff --git a/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs index 19cdad798b..266dde7233 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs @@ -1,4 +1,5 @@ -use kdf_walletconnect::{session::delete::send_session_delete_request, WalletConnectCtx}; +use kdf_walletconnect::session::rpc::delete::send_session_delete_request; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use serde::{Deserialize, Serialize}; diff --git a/mm2src/mm2_main/src/rpc/wc_commands/ping.rs b/mm2src/mm2_main/src/rpc/wc_commands/ping.rs index f3e630bd07..8f8c2d2f95 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/ping.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/ping.rs @@ -1,4 +1,5 @@ -use kdf_walletconnect::{session::ping::send_session_ping_request, WalletConnectCtx}; +use kdf_walletconnect::session::rpc::ping::send_session_ping_request; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use serde::{Deserialize, Serialize}; From e5e215089bd3657ffa0e219da48d5a63ec401264 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 8 Oct 2024 23:15:23 +0100 Subject: [PATCH 051/125] fix session topic generation bug --- mm2src/coins/tendermint/tendermint_coin.rs | 8 ++++---- mm2src/kdf_walletconnect/src/lib.rs | 8 ++++++-- mm2src/kdf_walletconnect/src/session/key.rs | 11 +++++++++-- mm2src/kdf_walletconnect/src/session/rpc/propose.rs | 11 ++++++----- mm2src/kdf_walletconnect/src/session/rpc/settle.rs | 8 +++++--- 5 files changed, 30 insertions(+), 16 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 2d9a0893ca..0188387366 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -1373,14 +1373,14 @@ impl TendermintCoin { let my_address = self.my_address().unwrap(); let tx_json = if self.wallet_connection_type == TendermintWalletConnectionType::WalletConnect { - // convert body_bytes, auth_info_bytes to base64. + //TODO:: maybe convert body_bytes, auth_info_bytes to base64. json!({ "signerAddress": my_address, "signDoc": { "accountNumber": sign_doc.account_number.to_string(), "chainId": sign_doc.chain_id, - "bodyBytes": &sign_doc.body_bytes, - "authInfoBytes": sign_doc.auth_info_bytes + "bodyBytes": general_purpose::STANDARD.encode(sign_doc.body_bytes.clone()), + "authInfoBytes": general_purpose::STANDARD.encode(sign_doc.auth_info_bytes) } }) } else { @@ -3407,7 +3407,7 @@ fn parse_expected_sequence_number(e: &str) -> MmResult Option { + fn find_account_in_namespace(&self, namespace_key: &str, namespace: &Namespace, chain_id: &str) -> Option { let chains = namespace.chains.as_ref()?; let key = format!("{namespace_key}:{chain_id}"); + println!("chains: {chains:?}"); + if !chains.contains(&key) { return None; } let accounts = namespace.accounts.as_ref()?; + accounts.iter().find_map(|account_name| { let parts: Vec<&str> = account_name.split(':').collect(); if parts.len() >= 3 && parts[1] == chain_id { diff --git a/mm2src/kdf_walletconnect/src/session/key.rs b/mm2src/kdf_walletconnect/src/session/key.rs index 3ca3bc314d..01f067d424 100644 --- a/mm2src/kdf_walletconnect/src/session/key.rs +++ b/mm2src/kdf_walletconnect/src/session/key.rs @@ -4,7 +4,7 @@ use serde::{Deserialize, Serialize}; use x25519_dalek::{PublicKey, SharedSecret, StaticSecret}; use {hkdf::Hkdf, rand::{rngs::OsRng, CryptoRng, RngCore}, - sha2::Sha256}; + sha2::{Digest, Sha256}}; pub(crate) struct SymKeyPair { pub(crate) secret: StaticSecret, @@ -82,7 +82,7 @@ impl SessionKey { /// Derives the symmetric key from a shared secret. fn derive_symmetric_key(&mut self, shared_secret: &SharedSecret) -> Result<(), SessionError> { let hk = Hkdf::::new(None, shared_secret.as_bytes()); - hk.expand(b"SessionKey Derivation", &mut self.sym_key) + hk.expand(&[], &mut self.sym_key) .map_err(|e| SessionError::SymKeyGeneration(e.to_string())) } @@ -91,6 +91,13 @@ impl SessionKey { /// Gets "our" public key used in symmetric key derivation. pub fn diffie_public_key(&self) -> &[u8; 32] { &self.public_key } + + /// Generates new session topic. + pub fn generate_topic(&self) -> String { + let mut hasher = Sha256::new(); + hasher.update(self.sym_key); + hex::encode(hasher.finalize()) + } } #[cfg(test)] diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 185ae02aad..f65526c7cf 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,5 +1,6 @@ use super::settle::send_session_settle_request; use crate::{error::WalletConnectCtxError, + metadata::generate_metadata, session::{Session, SessionKey, SessionType, THIRTY_DAYS}, WalletConnectCtx}; @@ -46,7 +47,7 @@ pub async fn reply_session_proposal_request( .unwrap(); let session_key = SessionKey::from_osrng(&sender_public_key)?; - let session_topic = Topic::generate(); + let session_topic: Topic = session_key.generate_topic().into(); let subscription_id = ctx .client .subscribe(session_topic.clone()) @@ -79,7 +80,7 @@ pub async fn reply_session_proposal_request( ctx.session.add_session(session.clone()).await; // Add topic to subscription list let mut subs = ctx.subscriptions.lock().await; - subs.push(session_topic.clone()); + subs.push(session_topic); } { @@ -111,7 +112,7 @@ pub(crate) async fn process_session_propose_response( let mut session_key = SessionKey::new(ctx.key_pair.public_key); session_key.generate_symmetric_key(&ctx.key_pair.secret, &other_public_key)?; - let session_topic = Topic::generate(); + let session_topic: Topic = session_key.generate_topic().into(); let subscription_id = ctx .client .subscribe(session_topic.clone()) @@ -124,8 +125,8 @@ pub(crate) async fn process_session_propose_response( subscription_id, session_key, pairing_topic.clone(), - Metadata::default(), - SessionType::Controller, + generate_metadata(), + SessionType::Proposer, ); session.relay = response.relay; session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 3bca459db9..5a171ceb2e 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -50,18 +50,20 @@ pub(crate) async fn reply_session_settle_request( session.controller = settle.controller.clone(); session.relay = settle.relay.clone(); session.expiry = settle.expiry; - // Update storage session. ctx.storage .db .update_session(&session) .await .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; - - info!("Session successfully settled for topic: {:?}", topic); } } + let mut ctx_ns = ctx.namespaces.lock().await; + *ctx_ns = settle.namespaces; + + info!("Session successfully settled for topic: {:?}", topic); + let param = ResponseParamsSuccess::SessionSettle(true); ctx.publish_response_ok(topic, param, message_id).await?; From 8d749dedfa8adc30a0038d2bf202beaef9f7639f Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 9 Oct 2024 13:55:54 +0100 Subject: [PATCH 052/125] tendermint sign tx impl fixes --- mm2src/coins/tendermint/tendermint_coin.rs | 15 ++++------ .../kdf_walletconnect/src/chain/tendermint.rs | 28 ++++++++++--------- .../kdf_walletconnect/src/inbound_message.rs | 3 +- 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 0188387366..30842f0427 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -1188,7 +1188,6 @@ impl TendermintCoin { withdraw_from: Option, ) -> Result<(AccountId, Option), WithdrawError> { if let TendermintActivationPolicy::PublicKey(_) = self.activation_policy { - println!("inside pubkey"); return Ok((self.account_id.clone(), None)); } @@ -1234,9 +1233,7 @@ impl TendermintCoin { timeout_height: u64, memo: String, ) -> Result { - println!("before maybe"); if let Some(priv_key) = maybe_pk { - println!("after maybe"); let tx_raw = self.any_to_signed_raw_tx(&priv_key, account_info, message, fee, timeout_height, memo)?; let tx_bytes = tx_raw.to_bytes()?; let hash = sha256(&tx_bytes); @@ -1248,7 +1245,6 @@ impl TendermintCoin { }; if let TendermintWalletConnectionType::WalletConnect = self.wallet_connection_type { - println!("inside wc"); let ctx = MmArc::from_weak(&self.ctx) .ok_or(MyAddressError::InternalError(ERRL!("ctx must be initialized already")))?; let wallet_connect = WalletConnectCtx::from_ctx(&ctx)?; @@ -1260,8 +1256,8 @@ impl TendermintCoin { .cosmos_send_sign_tx_request(tx_json, self.chain_id.as_ref()) .await?; let signature = general_purpose::STANDARD.decode(response.signature.signature)?; - let body_bytes = general_purpose::STANDARD.decode(response.signed.body_bytes)?; - let auth_info_bytes = general_purpose::STANDARD.decode(response.signed.auth_info_bytes)?; + let body_bytes = response.signed.body_bytes; + let auth_info_bytes = response.signed.auth_info_bytes; let tx_raw = TxRaw { body_bytes, auth_info_bytes, @@ -1373,14 +1369,14 @@ impl TendermintCoin { let my_address = self.my_address().unwrap(); let tx_json = if self.wallet_connection_type == TendermintWalletConnectionType::WalletConnect { - //TODO:: maybe convert body_bytes, auth_info_bytes to base64. + //todo:: maybe convert body_bytes, auth_info_bytes to base64. json!({ "signerAddress": my_address, "signDoc": { "accountNumber": sign_doc.account_number.to_string(), "chainId": sign_doc.chain_id, - "bodyBytes": general_purpose::STANDARD.encode(sign_doc.body_bytes.clone()), - "authInfoBytes": general_purpose::STANDARD.encode(sign_doc.auth_info_bytes) + "bodyBytes": hex::encode(&sign_doc.body_bytes), + "authInfoBytes": hex::encode(&sign_doc.auth_info_bytes) } }) } else { @@ -2397,7 +2393,6 @@ impl MmCoin for TendermintCoin { let account_info = coin.account_info(&account_id).await?; - println!("Before any_to_transaction_data"); let tx = coin .any_to_transaction_data(maybe_pk, msg_payload, &account_info, fee, timeout_height, memo.clone()) .await diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index 92c4556030..26966a9b67 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -1,3 +1,5 @@ +use std::collections::HashMap; + use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use base64::{engine::general_purpose, Engine}; use chrono::Utc; @@ -6,7 +8,7 @@ use futures::StreamExt; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::{session_request::{Request as SessionRequest, SessionRequestRequest}, RequestParams, ResponseParamsSuccess}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use super::WcRequestMethods; @@ -22,12 +24,12 @@ pub enum CosmosAccountAlgo { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct CosmosAccount { pub address: String, - #[serde(deserialize_with = "deserialize_pubkey")] + #[serde(deserialize_with = "deserialize_vec_field")] pub pubkey: Vec, pub algo: CosmosAccountAlgo, } -fn deserialize_pubkey<'de, D>(deserializer: D) -> Result, D::Error> +fn deserialize_vec_field<'de, D>(deserializer: D) -> Result, D::Error> where D: serde::Deserializer<'de>, { @@ -75,7 +77,6 @@ pub async fn cosmos_get_accounts_impl( let topic = { let session = ctx.session.get_session_active().await; - // return not NotInitialized error if no session is found. if session.is_none() { return MmError::err(WalletConnectCtxError::NotInitialized); }; @@ -100,7 +101,6 @@ pub async fn cosmos_get_accounts_impl( let mut session_handler = ctx.session_request_handler.lock().await; if let Some((message_id, data)) = session_handler.next().await { - info!("Got cosmos account: {data:?}"); let result = serde_json::from_value::>(data)?; let response = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(&topic, response, &message_id).await?; @@ -134,16 +134,18 @@ pub struct CosmosTxPublicKey { #[serde(rename_all = "camelCase")] pub struct CosmosSignData { pub chain_id: String, - pub account_number: String, - pub auth_info_bytes: String, - pub body_bytes: String, + pub account_number: AccountNumber, + #[serde(deserialize_with = "deserialize_vec_field")] + pub auth_info_bytes: Vec, + #[serde(deserialize_with = "deserialize_vec_field")] + pub body_bytes: Vec, } #[derive(Debug, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct CosmosTxSignParams { - pub signer_address: String, - pub sign_doc: CosmosSignData, +pub struct AccountNumber { + low: u64, + high: u64, + unsigned: bool, } pub async fn cosmos_sign_tx_direct_impl( @@ -177,7 +179,7 @@ pub async fn cosmos_sign_tx_direct_impl( let mut session_handler = ctx.session_request_handler.lock().await; if let Some((message_id, data)) = session_handler.next().await { - info!("Got cosmos sign response: {data:?}"); + println!("DATA: {data:?}"); let result = serde_json::from_value::(data)?; let response = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(&topic, response, &message_id).await?; diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 180a482a1c..d0a01255ef 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -43,8 +43,7 @@ pub(crate) async fn process_inbound_request( .await? }, Params::SessionRequest(_param) => { - println!("SessionRequest: {_param:?}"); - // TODO: Implement when integrating KDF as a wallet. + // TODO: Implement when integrating KDF as a Dapp. return MmError::err(WalletConnectCtxError::NotImplemented); }, From 8b1b6c3f6791088b97958089a40e566a1488dd4d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 9 Oct 2024 16:19:31 +0100 Subject: [PATCH 053/125] improve wc tx_signing codes --- mm2src/coins/tendermint/tendermint_coin.rs | 162 +++++++++++------- .../kdf_walletconnect/src/chain/tendermint.rs | 44 +++-- mm2src/kdf_walletconnect/src/lib.rs | 6 +- .../src/session/rpc/propose.rs | 2 +- 4 files changed, 125 insertions(+), 89 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 30842f0427..3f3a4f7917 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -861,6 +861,14 @@ impl TendermintCoin { ) }, TendermintActivationPolicy::PublicKey(_) => { + if let TendermintWalletConnectionType::WalletConnect = self.wallet_connection_type { + return try_tx_s!( + self.seq_safe_send_raw_tx_bytes(tx_payload, fee, timeout_height, memo) + .timeout(expiration) + .await + ); + }; + try_tx_s!( self.send_unsigned_tx_externally(tx_payload, fee, timeout_height, memo, expiration) .timeout(expiration) @@ -870,6 +878,58 @@ impl TendermintCoin { } } + async fn request_wc_tx_signing(&self, tx_json: serde_json::Value) -> Result { + let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); + let wallet_connect = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); + + let response = try_tx_s!( + wallet_connect + .cosmos_send_sign_tx_request(tx_json, self.chain_id.as_ref()) + .await + ); + let signature = try_tx_s!(general_purpose::STANDARD + .decode(response.signature.signature) + .map_err(|e| ERRL!("{}", e))); + + Ok(TxRaw { + body_bytes: response.signed.body_bytes, + auth_info_bytes: response.signed.auth_info_bytes, + signatures: vec![signature], + } + .into()) + } + + async fn get_tx_raw( + &self, + account_info: &BaseAccount, + tx_payload: Any, + fee: Fee, + timeout_height: u64, + memo: String, + ) -> Result { + match self.wallet_connection_type { + TendermintWalletConnectionType::WalletConnect => { + // Handle WalletConnect signing + let SerializedUnsignedTx { tx_json, body_bytes: _ } = + try_tx_s!(self.any_to_serialized_sign_doc(&account_info, tx_payload, fee, timeout_height, memo)); + + self.request_wc_tx_signing(tx_json).await + }, + _ => { + // Handle local signing + let tx_raw = try_tx_s!(self.any_to_signed_raw_tx( + try_tx_s!(self.activation_policy.activated_key_or_err()), + &account_info, + tx_payload, + fee, + timeout_height, + memo, + )); + Ok(tx_raw) + }, + } + } + async fn seq_safe_send_raw_tx_bytes( &self, tx_payload: Any, @@ -878,31 +938,36 @@ impl TendermintCoin { memo: String, ) -> Result<(String, Raw), TransactionErr> { let mut account_info = try_tx_s!(self.account_info(&self.account_id).await); - let (tx_id, tx_raw) = loop { - let tx_raw = try_tx_s!(self.any_to_signed_raw_tx( - try_tx_s!(self.activation_policy.activated_key_or_err()), - &account_info, - tx_payload.clone(), - fee.clone(), - timeout_height, - memo.clone(), - )); - match self.send_raw_tx_bytes(&try_tx_s!(tx_raw.to_bytes())).compat().await { - Ok(tx_id) => break (tx_id, tx_raw), + loop { + let tx_raw = try_tx_s!( + self.get_tx_raw( + &account_info, + tx_payload.clone(), + fee.clone(), + timeout_height, + memo.clone(), + ) + .await + ); + + // Attempt to send the transaction bytes + match self.send_raw_tx_bytes(try_tx_s!(&tx_raw.to_bytes())).compat().await { + Ok(tx_id) => { + return Ok((tx_id, tx_raw)); + }, Err(e) => { + // Handle sequence number mismatch and retry if e.contains(ACCOUNT_SEQUENCE_ERR) { account_info.sequence = try_tx_s!(parse_expected_sequence_number(&e)); - debug!("Got wrong account sequence, trying again."); + debug!("Account sequence mismatch, retrying..."); continue; } - return Err(crate::TransactionErr::Plain(ERRL!("{}", e))); + return Err(TransactionErr::Plain(ERRL!("Transaction failed: {}", e))); }, - }; - }; - - Ok((tx_id, tx_raw)) + } + } } async fn send_unsigned_tx_externally( @@ -932,37 +997,12 @@ impl TendermintCoin { .await .map_err(|e| ERRL!("{}", e))); - let tx_raw = match self.wallet_connection_type { - TendermintWalletConnectionType::WalletConnect => { - let wallet_connect = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); - let response = try_tx_s!( - wallet_connect - .cosmos_send_sign_tx_request(tx_json, self.chain_id.as_ref()) - .await - ); - let signature = try_tx_s!(general_purpose::STANDARD - .decode(response.signature.signature) - .map_err(|e| ERRL!("{}", e))); - let body_bytes = try_tx_s!(general_purpose::STANDARD - .decode(response.signed.body_bytes) - .map_err(|e| ERRL!("{}", e))); - let auth_info_bytes = try_tx_s!(general_purpose::STANDARD - .decode(response.signed.auth_info_bytes) - .map_err(|e| ERRL!("{}", e))); - TxRaw { - body_bytes, - auth_info_bytes, - signatures: vec![signature], - } - }, - _ => { - let tx = try_tx_s!(self.request_tx(data.hash.clone()).await.map_err(|e| ERRL!("{}", e))); - TxRaw { - body_bytes: tx.body.as_ref().map(Message::encode_to_vec).unwrap_or_default(), - auth_info_bytes: tx.auth_info.as_ref().map(Message::encode_to_vec).unwrap_or_default(), - signatures: tx.signatures, - } - }, + let tx = try_tx_s!(self.request_tx(data.hash.clone()).await.map_err(|e| ERRL!("{}", e))); + + let tx_raw = TxRaw { + body_bytes: tx.body.as_ref().map(Message::encode_to_vec).unwrap_or_default(), + auth_info_bytes: tx.auth_info.as_ref().map(Message::encode_to_vec).unwrap_or_default(), + signatures: tx.signatures, }; if body_bytes != tx_raw.body_bytes { @@ -1368,9 +1408,18 @@ impl TendermintCoin { let sign_doc = SignDoc::new(&tx_body, &auth_info, &self.chain_id, account_info.account_number)?; let my_address = self.my_address().unwrap(); - let tx_json = if self.wallet_connection_type == TendermintWalletConnectionType::WalletConnect { - //todo:: maybe convert body_bytes, auth_info_bytes to base64. - json!({ + let mut tx_json = json!({ + "sign_doc": { + "body_bytes": &sign_doc.body_bytes, + "auth_info_bytes": sign_doc.auth_info_bytes, + "chain_id": sign_doc.chain_id, + "account_number": sign_doc.account_number, + } + }); + + // if wallet_connection_type is WalletConnect, update tx_json to use WalletConnect type. + if self.wallet_connection_type == TendermintWalletConnectionType::WalletConnect { + tx_json = json!({ "signerAddress": my_address, "signDoc": { "accountNumber": sign_doc.account_number.to_string(), @@ -1379,16 +1428,7 @@ impl TendermintCoin { "authInfoBytes": hex::encode(&sign_doc.auth_info_bytes) } }) - } else { - json!({ - "sign_doc": { - "body_bytes": &sign_doc.body_bytes, - "auth_info_bytes": sign_doc.auth_info_bytes, - "chain_id": sign_doc.chain_id, - "account_number": sign_doc.account_number, - } - }) - }; + } Ok(SerializedUnsignedTx { tx_json, diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index 26966a9b67..028ff6e1ce 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -1,6 +1,5 @@ -use std::collections::HashMap; - use crate::{error::WalletConnectCtxError, WalletConnectCtx}; + use base64::{engine::general_purpose, Engine}; use chrono::Utc; use common::log::info; @@ -8,7 +7,7 @@ use futures::StreamExt; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::{session_request::{Request as SessionRequest, SessionRequestRequest}, RequestParams, ResponseParamsSuccess}; -use serde::{Deserialize, Deserializer, Serialize}; +use serde::{Deserialize, Serialize}; use serde_json::Value; use super::WcRequestMethods; @@ -60,15 +59,28 @@ where }) .collect(), Value::String(data) => { - let data = general_purpose::STANDARD - .decode(data) - .map_err(|err| serde::de::Error::custom(err.to_string()))?; + let data = decode_data(&data).map_err(|err| serde::de::Error::custom(err.to_string()))?; Ok(data) }, _ => Err(serde::de::Error::custom("Pubkey must be an string, object or array")), } } +fn decode_data(encoded: &str) -> Result, &'static str> { + // Check if the string is base64 or hex + if encoded.contains('=') || encoded.contains('/') || encoded.contains('+') { + // Try to decode as base64 + general_purpose::STANDARD + .decode(encoded) + .map_err(|_| "Invalid base64 encoding") + } else if encoded.chars().all(|c| c.is_ascii_hexdigit()) && encoded.len() % 2 == 0 { + // Try to decode as hex + hex::decode(encoded).map_err(|_| "Invalid hex encoding") + } else { + Err("Unknown encoding format") + } +} + pub async fn cosmos_get_accounts_impl( ctx: &WalletConnectCtx, chain_id: &str, @@ -134,7 +146,7 @@ pub struct CosmosTxPublicKey { #[serde(rename_all = "camelCase")] pub struct CosmosSignData { pub chain_id: String, - pub account_number: AccountNumber, + pub account_number: String, #[serde(deserialize_with = "deserialize_vec_field")] pub auth_info_bytes: Vec, #[serde(deserialize_with = "deserialize_vec_field")] @@ -148,7 +160,7 @@ pub struct AccountNumber { unsigned: bool, } -pub async fn cosmos_sign_tx_direct_impl( +pub async fn cosmos_sign_direct_impl( ctx: &WalletConnectCtx, sign_doc: Value, chain_id: &str, @@ -179,7 +191,6 @@ pub async fn cosmos_sign_tx_direct_impl( let mut session_handler = ctx.session_request_handler.lock().await; if let Some((message_id, data)) = session_handler.next().await { - println!("DATA: {data:?}"); let result = serde_json::from_value::(data)?; let response = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(&topic, response, &message_id).await?; @@ -191,18 +202,3 @@ pub async fn cosmos_sign_tx_direct_impl( "No response from wallet".to_string(), )) } - -//{ -// "id": 1, -// "jsonrpc": "2.0", -// "method": "cosmos_signDirect", -// "params": { -// "signerAddress": "cosmos1sguafvgmel6f880ryvq8efh9522p8zvmrzlcrq", -// "signDoc": { -// "chainId": "cosmoshub-4", -// "accountNumber": "1" -// "authInfoBytes": "CgoKABIECgIIARgBEhMKDQoFdWNvc20SBDIwMDAQwJoM", -// "bodyBytes": "CpABChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnAKLWNvc21vczFwa3B0cmU3ZmRrbDZnZnJ6bGVzamp2aHhobGMzcjRnbW1rOHJzNhItY29zbW9zMXF5cHF4cHE5cWNyc3N6ZzJwdnhxNnJzMHpxZzN5eWM1bHp2N3h1GhAKBXVjb3NtEgcxMjM0NTY3" -// } -// } -// } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index fc00a0d1a8..6031308fdf 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -8,7 +8,7 @@ pub mod session; mod storage; use chain::{build_required_namespaces, - tendermint::{cosmos_get_accounts_impl, cosmos_sign_tx_direct_impl, CosmosAccount, CosmosTxSignedData}, + tendermint::{cosmos_get_accounts_impl, cosmos_sign_direct_impl, CosmosAccount, CosmosTxSignedData}, SUPPORTED_CHAINS}; use common::executor::SpawnFuture; use common::log::info; @@ -233,7 +233,7 @@ impl WalletConnectCtx { sign_doc: Value, chain_id: &str, ) -> MmResult { - cosmos_sign_tx_direct_impl(self, sign_doc, chain_id).await + cosmos_sign_direct_impl(self, sign_doc, chain_id).await } async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { @@ -262,7 +262,7 @@ impl WalletConnectCtx { self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; - info!("Outbound request sent!\n"); + deb!("Outbound request sent!\n"); Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index f65526c7cf..fc32585a46 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -10,7 +10,7 @@ use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session::ProposeNamespaces, session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, - Metadata, RequestParams, ResponseParamsSuccess}}; + RequestParams, ResponseParamsSuccess}}; /// Creates a new session proposal form topic and metadata. pub(crate) async fn send_proposal_request( From 42029502ee66d784fd8b5216e0e27aa217368013 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 9 Oct 2024 16:38:10 +0100 Subject: [PATCH 054/125] minor fix --- mm2src/kdf_walletconnect/src/lib.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 6031308fdf..d4dd3fd602 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -179,7 +179,6 @@ impl WalletConnectCtx { } let namespaces = self.namespaces.lock().await; - println!("namespaces: {namespaces:?}"); namespaces .iter() .find_map(|(key, namespace)| self.find_account_in_namespace(key, namespace, chain_id)) @@ -192,8 +191,6 @@ impl WalletConnectCtx { let chains = namespace.chains.as_ref()?; let key = format!("{namespace_key}:{chain_id}"); - println!("chains: {chains:?}"); - if !chains.contains(&key) { return None; } @@ -262,7 +259,7 @@ impl WalletConnectCtx { self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; - deb!("Outbound request sent!\n"); + info!("Outbound request sent!\n"); Ok(()) } From d440ed988efe5ad86b14925bbfb9dec998fb098a Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 10 Oct 2024 15:53:07 +0100 Subject: [PATCH 055/125] add more session rpc endpoint --- mm2src/coins/tendermint/tendermint_coin.rs | 4 +- .../kdf_walletconnect/src/chain/tendermint.rs | 24 +++--- .../kdf_walletconnect/src/inbound_message.rs | 8 +- mm2src/kdf_walletconnect/src/session.rs | 75 ++++++++++++++----- .../src/session/rpc/delete.rs | 6 +- .../src/session/rpc/event.rs | 35 +++++---- .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 5 +- .../src/rpc/wc_commands/get_session.rs | 20 ----- .../mm2_main/src/rpc/wc_commands/sessions.rs | 57 ++++++++++++++ .../src/rpc/wc_commands/wc_commands.rs | 7 +- 10 files changed, 161 insertions(+), 80 deletions(-) delete mode 100644 mm2src/mm2_main/src/rpc/wc_commands/get_session.rs create mode 100644 mm2src/mm2_main/src/rpc/wc_commands/sessions.rs diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 3f3a4f7917..4cba2c391c 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -911,7 +911,7 @@ impl TendermintCoin { TendermintWalletConnectionType::WalletConnect => { // Handle WalletConnect signing let SerializedUnsignedTx { tx_json, body_bytes: _ } = - try_tx_s!(self.any_to_serialized_sign_doc(&account_info, tx_payload, fee, timeout_height, memo)); + try_tx_s!(self.any_to_serialized_sign_doc(account_info, tx_payload, fee, timeout_height, memo)); self.request_wc_tx_signing(tx_json).await }, @@ -919,7 +919,7 @@ impl TendermintCoin { // Handle local signing let tx_raw = try_tx_s!(self.any_to_signed_raw_tx( try_tx_s!(self.activation_policy.activated_key_or_err()), - &account_info, + account_info, tx_payload, fee, timeout_height, diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index 028ff6e1ce..00dbaa4bbb 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -2,7 +2,6 @@ use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use base64::{engine::general_purpose, Engine}; use chrono::Utc; -use common::log::info; use futures::StreamExt; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::{session_request::{Request as SessionRequest, SessionRequestRequest}, @@ -45,7 +44,7 @@ where return Err(serde::de::Error::custom("Invalid byte value")); } } else { - return Err(serde::de::Error::custom("Invalid pubkey format")); + return Err(serde::de::Error::custom("Invalid format")); } } Ok(vec) @@ -88,12 +87,10 @@ pub async fn cosmos_get_accounts_impl( let account = ctx.get_account_for_chain_id(chain_id).await?; let topic = { - let session = ctx.session.get_session_active().await; - if session.is_none() { - return MmError::err(WalletConnectCtxError::NotInitialized); - }; - - session.unwrap().topic + match ctx.session.get_session_active().await { + Some(session) => session.topic.into(), + None => return MmError::err(WalletConnectCtxError::NotInitialized), + } }; let request = SessionRequest { @@ -166,13 +163,10 @@ pub async fn cosmos_sign_direct_impl( chain_id: &str, ) -> MmResult { let topic = { - let session = ctx.session.get_session_active().await; - // return not NotInitialized error if no session is found. - if session.is_none() { - return MmError::err(WalletConnectCtxError::NotInitialized); - }; - - session.unwrap().topic + match ctx.session.get_session_active().await { + Some(session) => session.topic.into(), + None => return MmError::err(WalletConnectCtxError::NotInitialized), + } }; let request = SessionRequest { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index d0a01255ef..4504175992 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -9,7 +9,7 @@ use serde_json::Value; use crate::{error::WalletConnectCtxError, pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, session::rpc::{delete::reply_session_delete_request, - event::SessionEvents, + event::reply_session_event_request, extend::reply_session_extend_request, ping::reply_session_ping_request, propose::{process_session_propose_response, reply_session_proposal_request}, @@ -37,11 +37,7 @@ pub(crate) async fn process_inbound_request( Params::SessionPing(()) => reply_session_ping_request(ctx, topic, &message_id).await?, Params::SessionSettle(param) => reply_session_settle_request(ctx, topic, &message_id, param).await?, Params::SessionUpdate(param) => reply_session_update_request(ctx, topic, &message_id, param).await?, - Params::SessionEvent(param) => { - SessionEvents::from_events(param)? - .handle_session_event(ctx, topic, &message_id) - .await? - }, + Params::SessionEvent(param) => reply_session_event_request(ctx, topic, &message_id, param).await?, Params::SessionRequest(_param) => { // TODO: Implement when integrating KDF as a Dapp. return MmError::err(WalletConnectCtxError::NotImplemented); diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 1b4dd202e5..bba4679717 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -4,15 +4,18 @@ pub mod rpc; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; +use common::log::debug; use dashmap::mapref::one::RefMut; use dashmap::DashMap; use futures::lock::Mutex; use key::SessionKey; use mm2_err_handle::prelude::MmResult; +use relay_client::websocket::Client; +use relay_rpc::domain::Topic; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::IrnMetadata; -use relay_rpc::{domain::{SubscriptionId, Topic}, +use relay_rpc::{domain::SubscriptionId, rpc::params::{session::ProposeNamespaces, session_settle::Controller, Metadata, Relay}}; use serde::{Deserialize, Serialize}; use serde_json::Value; @@ -45,11 +48,21 @@ impl ToString for SessionType { } } +#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] +pub struct SessionRpcInfo { + pub topic: String, + pub metadata: Metadata, + pub peer_pubkey: String, + pub pairing_topic: String, + pub namespaces: BTreeMap, + pub subscription_id: SubscriptionId, +} + /// This struct is typically used in the core session management logic of a WalletConnect /// implementation. It's used to store, retrieve, and update session information throughout /// the lifecycle of a WalletConnect connection. #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] -pub struct Session { +pub(crate) struct Session { /// Session topic pub topic: Topic, /// Pairing subscription id. @@ -149,6 +162,7 @@ impl SessionManagement { /// Removes the session corresponding to the specified topic from the session store. /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { + debug!("Deleting session with topic: {topic}"); let mut active_topic = self.0.active_topic.lock().await; if let Some(ref topic_) = *active_topic { @@ -157,12 +171,28 @@ impl SessionManagement { }; }; - self.0.sessions.remove(topic).map(|(_, session)| session) + let removed_session = self.0.sessions.remove(topic).map(|(_, session)| session); + + // Update active session + if active_topic.is_none() {} + if let Some(session) = self.0.sessions.iter().next() { + debug!("New session with topic: {} activated!", session.topic); + *active_topic = Some(session.topic.clone()); + } + + removed_session } /// Retrieves a cloned session associated with a given topic. - pub(crate) fn get_session(&self, topic: &Topic) -> Option { - self.0.sessions.get(topic).map(|session| session.clone()) + pub fn get_session(&self, topic: &Topic) -> Option { + self.0.sessions.get(topic).map(|(session)| SessionRpcInfo { + topic: topic.to_string(), + metadata: session.controller.metadata.clone(), + peer_pubkey: session.controller.public_key.clone(), + pairing_topic: session.pairing_topic.to_string(), + namespaces: session.namespaces.clone(), + subscription_id: session.subscription_id.clone(), + }) } /// Retrieves a mutable reference to the session associated with a given topic. @@ -171,7 +201,7 @@ impl SessionManagement { } /// Returns an `Option` containing the active session if it exists; otherwise, returns `None`. - pub async fn get_session_active(&self) -> Option { + pub async fn get_session_active(&self) -> Option { let active_topic = self.0.active_topic.lock().await; if let Some(ref topic) = *active_topic { self.get_session(topic) @@ -181,32 +211,31 @@ impl SessionManagement { } /// Retrieves all sessions(active and inactive) - pub(crate) fn get_sessions(&self) -> Vec { + pub fn get_sessions(&self) -> Vec { self.0 .sessions .clone() .into_iter() - .map(|(_, session)| session) + .map(|(topic, session)| SessionRpcInfo { + topic: topic.to_string(), + metadata: session.controller.metadata.clone(), + peer_pubkey: session.controller.public_key.clone(), + pairing_topic: session.pairing_topic.to_string(), + namespaces: session.namespaces.clone(), + subscription_id: session.subscription_id, + }) .collect() } /// Updates the expiry time of the session associated with the given topic to the specified timestamp. /// If the session does not exist, this method does nothing. pub(crate) fn extend_session(&self, topic: &Topic, till: u64) { + debug!("Extending session with topic: {topic}"); if let Some(mut session) = self.0.sessions.get_mut(topic) { session.extend(till); } } - /// Updates the expiry time of the currently active session to the specified timestamp. - /// If there is no active session, this method does nothing. - pub(crate) async fn extend_active_session(&self, till: u64) { - let active_topic = self.0.active_topic.lock().await; - if let Some(ref topic) = *active_topic { - self.extend_session(topic, till); - } - } - /// This method checks all sessions for expiration based on the current time. /// Expired sessions are removed from the session store and returned. /// If the active session is expired, it is also removed, and the active session is set to `None`. @@ -229,6 +258,16 @@ impl SessionManagement { /// Retrieves the symmetric key associated with a given topic. pub(crate) fn sym_key(&self, topic: &Topic) -> Option> { - self.get_session(topic).map(|k| k.session_key.symmetric_key().to_vec()) + self.0 + .sessions + .get(topic) + .map(|k| k.session_key.symmetric_key().to_vec()) + } + + pub async fn disconnect_session(&self, topic: &Topic, client: &Client) -> MmResult<(), WalletConnectCtxError> { + client.unsubscribe(topic.clone()).await?; + self.delete_session(topic).await; + + Ok(()) } } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 0f6235a9fc..87b3cd3333 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -43,10 +43,10 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu "No active sessions left for pairing {}, disconnecting", session.pairing_topic ); + //Attempt to unsubscribe from topic + ctx.client.unsubscribe(session.pairing_topic.clone()).await?; // Attempt to disconnect the pairing - ctx.pairing - .disconnect(session.pairing_topic.as_ref(), &ctx.client) - .await?; + ctx.pairing.delete(session.pairing_topic.as_ref()).await; } Ok(()) diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 3053cab5f3..7e08973a08 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -1,26 +1,37 @@ use crate::{error::{WalletConnectCtxError, INVALID_EVENT, UNSUPPORTED_CHAINS}, WalletConnectCtx}; -use mm2_err_handle::prelude::{MmError, MmResult}; +use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, rpc::{params::{session_event::SessionEventRequest, ResponseParamsError, ResponseParamsSuccess}, ErrorData}}; -pub enum SessionEvents { +pub enum SessionEvent { ChainChanged(String), AccountsChanged(String, Vec), Unknown(String), } -impl SessionEvents { - pub fn from_events(event: SessionEventRequest) -> MmResult { +pub(crate) async fn reply_session_event_request( + ctx: &WalletConnectCtx, + topic: &Topic, + message_id: &MessageId, + event: SessionEventRequest, +) -> MmResult<(), WalletConnectCtxError> { + SessionEvent::from_event(event)? + .handle_session_event(ctx, topic, message_id) + .await +} + +impl SessionEvent { + pub fn from_event(event: SessionEventRequest) -> MmResult { match event.event.name.as_str() { - "chainChanged" => Ok(SessionEvents::ChainChanged(event.chain_id)), + "chainChanged" => Ok(SessionEvent::ChainChanged(event.chain_id)), "accountsChanged" => { let data = serde_json::from_value::>(event.event.data)?; - Ok(SessionEvents::AccountsChanged(event.chain_id, data)) + Ok(SessionEvent::AccountsChanged(event.chain_id, data)) }, - _ => Ok(SessionEvents::Unknown(event.event.name)), + _ => Ok(SessionEvent::Unknown(event.event.name)), } } @@ -31,13 +42,13 @@ impl SessionEvents { message_id: &MessageId, ) -> MmResult<(), WalletConnectCtxError> { match &self { - SessionEvents::ChainChanged(chain_id) => { + SessionEvent::ChainChanged(chain_id) => { Self::handle_chain_changed_event(ctx, chain_id, topic, message_id).await }, - SessionEvents::AccountsChanged(chain_id, data) => { + SessionEvent::AccountsChanged(chain_id, data) => { Self::handle_accounts_changed_event(ctx, chain_id, data, topic, message_id).await }, - SessionEvents::Unknown(name) => { + SessionEvent::Unknown(name) => { let error_data = ErrorData { code: INVALID_EVENT, message: format!("Received an invalid/unsupported session event: {name}"), @@ -46,9 +57,7 @@ impl SessionEvents { ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) .await?; - MmError::err(WalletConnectCtxError::SessionError(format!( - "Unsupported session event" - ))) + Ok(()) }, } } diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index d1a5bca19c..f89479ccf7 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -1,3 +1,4 @@ +use super::wc_commands::{disconnect_session, get_all_sessions, get_session}; use super::{DispatcherError, DispatcherResult, PUBLIC_METHODS}; use crate::lp_native_dex::init_hw::{cancel_init_trezor, init_trezor, init_trezor_status, init_trezor_user_action}; #[cfg(target_arch = "wasm32")] @@ -7,7 +8,7 @@ use crate::lp_ordermatch::{best_orders_rpc_v2, orderbook_rpc_v2, start_simple_ma use crate::lp_swap::swap_v2_rpcs::{active_swaps_rpc, my_recent_swaps_rpc, my_swap_status_rpc}; use crate::lp_wallet::{get_mnemonic_rpc, get_wallet_names_rpc}; use crate::rpc::rate_limiter::{process_rate_limit, RateLimitContext}; -use crate::rpc::wc_commands::{delete_connection, get_chain_id, get_session, new_connection, ping_session}; +use crate::rpc::wc_commands::{delete_connection, get_chain_id, new_connection, ping_session}; use crate::{lp_stats::{add_node_to_version_stat, remove_node_from_version_stat, start_version_stat_collection, stop_version_stat_collection, update_version_stat_collection}, lp_swap::{get_locked_amount_rpc, max_maker_vol, recreate_swap_data, trade_preimage_rpc}, @@ -227,6 +228,8 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, delete_connection).await, "wc_get_chain_id" => handle_mmrpc(ctx, request, get_chain_id).await, "wc_get_session" => handle_mmrpc(ctx, request, get_session).await, + "wc_get_sessions" => handle_mmrpc(ctx, request, get_all_sessions).await, + "wc_disconnect_session" => handle_mmrpc(ctx, request, disconnect_session).await, "wc_ping_session" => handle_mmrpc(ctx, request, ping_session).await, #[cfg(not(target_arch = "wasm32"))] native_only_methods => match native_only_methods { diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs deleted file mode 100644 index 0dc757f117..0000000000 --- a/mm2src/mm2_main/src/rpc/wc_commands/get_session.rs +++ /dev/null @@ -1,20 +0,0 @@ -use kdf_walletconnect::{session::Session, WalletConnectCtx}; -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::*; -use serde::Serialize; - -use super::{EmptyRpcRequst, WalletConnectRpcError}; - -#[derive(Debug, PartialEq, Serialize)] -pub struct GetSessionResponse { - pub session: Option, -} - -/// `delete connection` RPC command implementation. -pub async fn get_session(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = - WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let session = ctx.session.get_session_active().await; - - Ok(GetSessionResponse { session }) -} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs new file mode 100644 index 0000000000..6f95cf718a --- /dev/null +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -0,0 +1,57 @@ +use kdf_walletconnect::{session::SessionRpcInfo, WalletConnectCtx}; +use mm2_core::mm_ctx::MmArc; +use mm2_err_handle::prelude::*; +use serde::Serialize; + +use super::{EmptyRpcRequst, EmptyRpcResponse, WalletConnectRpcError}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct GetSessionsResponse { + pub sessions: Vec, +} + +/// `Get all sessions connection` RPC command implementation. +pub async fn get_all_sessions( + ctx: MmArc, + _req: EmptyRpcRequst, +) -> MmResult { + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let sessions = ctx.session.get_sessions(); + + Ok(GetSessionsResponse { sessions }) +} + +#[derive(Debug, Serialize)] +pub struct GetSessionResponse { + pub session: Option, +} + +#[derive(Deserialize)] +pub struct GetSessionRequest { + topic: String, +} + +/// `Get all sessions connection` RPC command implementation. +pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let session = ctx.session.get_session(&req.topic.into()); + + Ok(GetSessionResponse { session }) +} + +/// `Get all sessions connection` RPC command implementation. +pub async fn disconnect_session( + ctx: MmArc, + req: GetSessionRequest, +) -> MmResult { + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + ctx.session + .disconnect_session(&req.topic.into(), &ctx.client) + .await + .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; + + Ok(EmptyRpcResponse {}) +} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs index ec63b4a60b..9a96ae4225 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs @@ -1,22 +1,25 @@ mod delete_connection; mod get_chain_id; -mod get_session; mod new_connection; mod ping; +mod sessions; use common::HttpStatusCode; pub use delete_connection::delete_connection; use derive_more::Display; pub use get_chain_id::get_chain_id; -pub use get_session::get_session; use http::StatusCode; pub use new_connection::new_connection; pub use ping::ping_session; use serde::Deserialize; +pub use sessions::*; #[derive(Deserialize)] pub struct EmptyRpcRequst {} +#[derive(Debug, Serialize)] +pub struct EmptyRpcResponse {} + #[derive(Serialize, Display, SerializeErrorType)] #[serde(tag = "error_type", content = "error_data")] pub enum WalletConnectRpcError { From f3cf28bfaca2d006d2f04980983a1f1127172e7d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 10 Oct 2024 16:32:31 +0100 Subject: [PATCH 056/125] update wc deps --- Cargo.lock | 17 +++++++++++++++-- mm2src/kdf_walletconnect/Cargo.toml | 6 +++--- mm2src/kdf_walletconnect/src/lib.rs | 1 + mm2src/kdf_walletconnect/src/storage/sqlite.rs | 4 ++-- .../tests/docker_tests/swap_watcher_tests.rs | 2 +- 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 04f3cb190e..ca0c0c9a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3596,7 +3596,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", - "wc_common", + "wc_common 0.1.0", "web-sys", "x25519-dalek 2.0.1", ] @@ -5369,6 +5369,7 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" dependencies = [ "anyhow", "chrono", @@ -5385,7 +5386,7 @@ dependencies = [ "thiserror", "tokio", "url", - "wc_common", + "wc_common 0.1.0 (git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api)", ] [[package]] @@ -6384,6 +6385,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "relay_client" version = "0.1.0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" dependencies = [ "chrono", "data-encoding", @@ -6411,6 +6413,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" dependencies = [ "anyhow", "bs58 0.4.0", @@ -9570,6 +9573,16 @@ dependencies = [ "thiserror", ] +[[package]] +name = "wc_common" +version = "0.1.0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" +dependencies = [ + "base64 0.21.7", + "chacha20poly1305", + "thiserror", +] + [[package]] name = "web-sys" version = "0.3.55" diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 2bcdac1be6..72115527b0 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -23,10 +23,10 @@ dashmap = "6.1.0" mm2_core = { path = "../mm2_core" } mm2_db = { path = "../mm2_db" } mm2_err_handle = { path = "../mm2_err_handle" } -pairing_api = { path = "../../../kdf-wc/pairing_api" } +pairing_api = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } rand = "0.8" -relay_client = { path = "../../../kdf-wc/relay_client" } -relay_rpc = { path = "../../../kdf-wc/relay_rpc" } +relay_client = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } +relay_rpc = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } sha2 = "0.10.8" thiserror = "1.0.40" wc_common = { path = "../../../kdf-wc/wc_common" } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d4dd3fd602..2202ea3d5b 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -354,6 +354,7 @@ impl WalletConnectCtx { Ok(()) } + #[allow(unused)] async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectCtxError> { //let sessions = self // .storage diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index fad3becbba..3dcd13577c 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -126,11 +126,11 @@ impl WalletConnectStorageOps for SqliteSessionStorage { .map_to_mm(AsyncConnError::from) } - async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { Ok(None) } + async fn get_session(&self, _topic: &Topic) -> MmResult, Self::Error> { Ok(None) } async fn get_all_sessions(&self) -> MmResult, Self::Error> { Ok(vec![]) } - async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { todo!() } + async fn delete_session(&self, _topic: &Topic) -> MmResult<(), Self::Error> { todo!() } async fn update_session(&self, _session: &Session) -> MmResult<(), Self::Error> { Ok(()) } } diff --git a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs index aadda99709..f2bbe554b0 100644 --- a/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/swap_watcher_tests.rs @@ -3301,5 +3301,5 @@ fn test_watcher_reward() { let watcher_reward = block_on(utxo_coin.get_maker_watcher_reward(&MmCoinEnum::UtxoCoin(utxo_coin.clone()), None, timeout)).unwrap(); - assert!(matches!(watcher_reward, None)); + assert!(watcher_reward.is_none()); } From e56f8d784302b907fbba827324b374e37f72e192 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 10 Oct 2024 16:38:17 +0100 Subject: [PATCH 057/125] update wc_common deps --- Cargo.lock | 13 ++----------- mm2src/kdf_walletconnect/Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ca0c0c9a51..a3bfe7b8fe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3596,7 +3596,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", - "wc_common 0.1.0", + "wc_common", "web-sys", "x25519-dalek 2.0.1", ] @@ -5386,7 +5386,7 @@ dependencies = [ "thiserror", "tokio", "url", - "wc_common 0.1.0 (git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api)", + "wc_common", ] [[package]] @@ -9564,15 +9564,6 @@ dependencies = [ "quote 1.0.37", ] -[[package]] -name = "wc_common" -version = "0.1.0" -dependencies = [ - "base64 0.21.7", - "chacha20poly1305", - "thiserror", -] - [[package]] name = "wc_common" version = "0.1.0" diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 72115527b0..1a9118d6cc 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -29,7 +29,7 @@ relay_client = { git = "https://github.com/komodoplatform/walletconnectrust", br relay_rpc = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } sha2 = "0.10.8" thiserror = "1.0.40" -wc_common = { path = "../../../kdf-wc/wc_common" } +wc_common = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } secp256k1 = { version = "0.20" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } From a4983811469a5db59787b36ebf18c54db5ef102e Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 10 Oct 2024 22:42:13 +0100 Subject: [PATCH 058/125] use rustls --- Cargo.lock | 205 +++++++++++++--------------- mm2src/kdf_walletconnect/Cargo.toml | 2 +- 2 files changed, 96 insertions(+), 111 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c0c95d4cc4..8e1470c440 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -392,6 +392,15 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" +[[package]] +name = "base64" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" +dependencies = [ + "byteorder", +] + [[package]] name = "base64" version = "0.11.0" @@ -492,7 +501,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ "bitcoin_hashes", - "rand_core 0.6.4", + "rand_core 0.4.2", "zeroize", ] @@ -522,7 +531,7 @@ dependencies = [ "ripemd160", "serialization", "sha-1", - "sha2 0.10.8", + "sha2 0.10.7", "sha3 0.9.1", "siphasher", ] @@ -1094,7 +1103,7 @@ dependencies = [ "serde_with", "serialization", "serialization_derive", - "sha2 0.10.8", + "sha2 0.10.7", "sha3 0.9.1", "sia-rust", "solana-client", @@ -1209,7 +1218,7 @@ dependencies = [ "serde_derive", "serde_json", "serde_repr", - "sha2 0.10.8", + "sha2 0.10.7", "shared_ref_counter", "tokio", "uuid 1.2.2", @@ -1546,7 +1555,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", "tokio", "trezor", "wasm-bindgen-test", @@ -2082,7 +2091,7 @@ dependencies = [ "ed25519 2.2.3", "rand_core 0.6.4", "serde", - "sha2 0.10.8", + "sha2 0.10.7", "subtle", "zeroize", ] @@ -2109,7 +2118,7 @@ dependencies = [ "derivation-path 0.2.0", "ed25519-dalek 1.0.1", "hmac 0.12.1", - "sha2 0.10.8", + "sha2 0.10.7", ] [[package]] @@ -2492,21 +2501,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.0.1" @@ -2654,7 +2648,7 @@ checksum = "e01fe9932a224b72b45336d96040aa86386d674a31d0af27d800ea7bc8ca97fe" dependencies = [ "futures-io", "rustls 0.20.4", - "webpki", + "webpki 0.22.0", ] [[package]] @@ -3557,7 +3551,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "once_cell", - "sha2 0.10.8", + "sha2 0.10.7", "signature 2.2.0", ] @@ -3590,7 +3584,7 @@ dependencies = [ "secp256k1 0.20.3", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", "thiserror", "tokio", "wasm-bindgen", @@ -3824,7 +3818,7 @@ dependencies = [ "quick-protobuf-codec", "rand 0.8.4", "regex", - "sha2 0.10.8", + "sha2 0.10.7", "smallvec 1.6.1", "unsigned-varint", "void", @@ -3865,7 +3859,7 @@ dependencies = [ "multihash", "quick-protobuf", "rand 0.8.4", - "sha2 0.10.8", + "sha2 0.10.7", "thiserror", "zeroize", ] @@ -3922,7 +3916,7 @@ dependencies = [ "once_cell", "quick-protobuf", "rand 0.8.4", - "sha2 0.10.8", + "sha2 0.10.7", "snow", "static_assertions", "thiserror", @@ -4888,7 +4882,7 @@ dependencies = [ "secp256k1 0.20.3", "serde", "serde_bytes", - "sha2 0.10.8", + "sha2 0.10.7", "smallvec 1.6.1", "syn 2.0.77", "tokio", @@ -5031,23 +5025,6 @@ dependencies = [ "unsigned-varint", ] -[[package]] -name = "native-tls" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" -dependencies = [ - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "netlink-packet-core" version = "0.4.2" @@ -5280,50 +5257,12 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.66" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" -dependencies = [ - "bitflags 2.6.0", - "cfg-if 1.0.0", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2 1.0.86", - "quote 1.0.37", - "syn 2.0.77", -] - [[package]] name = "openssl-probe" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-sys" -version = "0.9.103" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f9e8deee91df40a943c71b917e5874b951d32a802526c85721ce3b776c929d6" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - [[package]] name = "ordered-float" version = "3.7.0" @@ -5370,7 +5309,7 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" dependencies = [ "anyhow", "chrono", @@ -6386,7 +6325,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" dependencies = [ "chrono", "data-encoding", @@ -6402,6 +6341,7 @@ dependencies = [ "serde_qs", "thiserror", "tokio", + "tokio-rustls 0.10.3", "tokio-tungstenite-wasm 0.1.1-alpha.0 (git+https://github.com/KomodoPlatform/tokio-tungstenite-wasm.git?rev=8fc7e2f)", "tokio-util", "url", @@ -6414,7 +6354,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" dependencies = [ "anyhow", "bs58 0.4.0", @@ -6431,7 +6371,7 @@ dependencies = [ "serde", "serde-aux", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", "strum", "thiserror", "url", @@ -6740,6 +6680,19 @@ dependencies = [ "windows-sys 0.45.0", ] +[[package]] +name = "rustls" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" +dependencies = [ + "base64 0.10.1", + "log", + "ring 0.16.20", + "sct 0.6.1", + "webpki 0.21.4", +] + [[package]] name = "rustls" version = "0.20.4" @@ -6748,8 +6701,8 @@ checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" dependencies = [ "log", "ring 0.16.20", - "sct", - "webpki", + "sct 0.7.0", + "webpki 0.22.0", ] [[package]] @@ -6761,7 +6714,7 @@ dependencies = [ "log", "ring 0.17.3", "rustls-webpki 0.101.7", - "sct", + "sct 0.7.0", ] [[package]] @@ -6918,6 +6871,16 @@ dependencies = [ "serialization", ] +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + [[package]] name = "sct" version = "0.7.0" @@ -7251,9 +7214,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" dependencies = [ "cfg-if 1.0.0", "cpufeatures", @@ -7416,7 +7379,7 @@ dependencies = [ "rand_core 0.6.4", "ring 0.17.3", "rustc_version 0.4.0", - "sha2 0.10.8", + "sha2 0.10.7", "subtle", ] @@ -8273,7 +8236,7 @@ dependencies = [ "serde", "serde_json", "serialization", - "sha2 0.10.8", + "sha2 0.10.7", "test_helpers", ] @@ -8542,7 +8505,7 @@ dependencies = [ "serde_bytes", "serde_json", "serde_repr", - "sha2 0.10.8", + "sha2 0.10.7", "signature 2.2.0", "subtle", "subtle-encoding", @@ -8651,7 +8614,7 @@ dependencies = [ "rand 0.8.4", "serde", "serde_json", - "sha2 0.10.8", + "sha2 0.10.7", ] [[package]] @@ -8802,6 +8765,17 @@ dependencies = [ "futures 0.1.29", ] +[[package]] +name = "tokio-io" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.29", + "log", +] + [[package]] name = "tokio-io-timeout" version = "1.2.0" @@ -8824,13 +8798,17 @@ dependencies = [ ] [[package]] -name = "tokio-native-tls" -version = "0.3.1" +name = "tokio-rustls" +version = "0.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +checksum = "2d7cf08f990090abd6c6a73cab46fed62f85e8aef8b99e4b918a9f4a637f0676" dependencies = [ - "native-tls", - "tokio", + "bytes 0.4.12", + "futures 0.1.29", + "iovec", + "rustls 0.16.0", + "tokio-io", + "webpki 0.21.4", ] [[package]] @@ -8841,7 +8819,7 @@ checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" dependencies = [ "rustls 0.20.4", "tokio", - "webpki", + "webpki 0.22.0", ] [[package]] @@ -8873,14 +8851,12 @@ checksum = "e80b39df6afcc12cdf752398ade96a6b9e99c903dfdc36e53ad10b9c366bca72" dependencies = [ "futures-util", "log", - "native-tls", "rustls 0.20.4", "rustls-native-certs", "tokio", - "tokio-native-tls", "tokio-rustls 0.23.2", "tungstenite", - "webpki", + "webpki 0.22.0", ] [[package]] @@ -9173,14 +9149,13 @@ dependencies = [ "http 0.2.12", "httparse", "log", - "native-tls", "rand 0.8.4", "rustls 0.20.4", "sha-1", "thiserror", "url", "utf-8", - "webpki", + "webpki 0.22.0", "webpki-roots 0.22.3", ] @@ -9568,7 +9543,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#9836e93fc788504318927a3ea8d3f5c7052c2e8f" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" dependencies = [ "base64 0.21.7", "chacha20poly1305", @@ -9619,6 +9594,16 @@ dependencies = [ "wasm-bindgen-futures", ] +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + [[package]] name = "webpki" version = "0.22.0" @@ -9635,7 +9620,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" dependencies = [ - "webpki", + "webpki 0.22.0", ] [[package]] diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 1a9118d6cc..9850057fd9 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -27,7 +27,7 @@ pairing_api = { git = "https://github.com/komodoplatform/walletconnectrust", bra rand = "0.8" relay_client = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } relay_rpc = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } -sha2 = "0.10.8" +sha2 = "0.10.7" thiserror = "1.0.40" wc_common = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } secp256k1 = { version = "0.20" } From c7b41a8ee302ce8ddb70ab4d3441922d65cf8612 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 11 Oct 2024 10:29:13 +0100 Subject: [PATCH 059/125] update bip39 deps --- Cargo.lock | 40 +++++++++++++++++++++++++++++++--------- mm2src/crypto/Cargo.toml | 2 +- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8e1470c440..0fbea80c27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -496,12 +496,12 @@ dependencies = [ [[package]] name = "bip39" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" dependencies = [ - "bitcoin_hashes", - "rand_core 0.4.2", + "bitcoin_hashes 0.13.0", + "rand_core 0.6.4", "zeroize", ] @@ -512,16 +512,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" dependencies = [ "bech32", - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "secp256k1 0.24.3", ] +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + [[package]] name = "bitcoin_hashes" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + [[package]] name = "bitcrypto" version = "0.1.0" @@ -1014,7 +1030,7 @@ dependencies = [ "bincode", "bip32", "bitcoin", - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "bitcrypto", "blake2b_simd", "byteorder", @@ -2969,6 +2985,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-conservative" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + [[package]] name = "hex_fmt" version = "0.3.0" @@ -4200,7 +4222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9680857590c3529cf8c7d32b04501f215f2bf1e029fdfa22f4112f66c1741e4" dependencies = [ "bech32", - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "lightning", "num-traits", "secp256k1 0.24.3", @@ -5680,7 +5702,7 @@ dependencies = [ name = "primitives" version = "0.1.0" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "byteorder", "rustc-hex", "uint", @@ -6921,7 +6943,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "secp256k1-sys 0.6.1", ] diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index dd3bbec752..c5636ed80e 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -13,7 +13,7 @@ arrayref = "0.3" async-trait = "0.1" base64 = "0.21.2" bip32 = { version = "0.2.2", default-features = false, features = ["alloc", "secp256k1-ffi"] } -bip39 = { version = "2.0.0", features = ["rand_core", "zeroize"], default-features = false } +bip39 = { version = "2.1.0", features = ["rand_core", "zeroize"], default-features = false } bitcrypto = { path = "../mm2_bitcoin/crypto" } bs58 = "0.4.0" cbc = "0.1.2" From 8fc7620595ef55840a6826c79be82848b15aaa1c Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 11 Oct 2024 10:43:51 +0100 Subject: [PATCH 060/125] fix wasm clippy --- .../src/storage/indexed_db.rs | 39 ++----------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index 2872fcac1a..64f1a8ac99 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -55,11 +55,10 @@ impl IDBSessionStorage { } async fn lock_db(&self) -> MmResult, WcIndexedDbError> { - Ok(self - .0 + self.0 .get_or_initialize() .await - .mm_err(|err| WcIndexedDbError::InternalError(err.to_string()))?) + .mm_err(|err| WcIndexedDbError::InternalError(err.to_string())) } } @@ -76,7 +75,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; session_table - .replace_item_by_unique_index("topic", session.topic.clone(), &session) + .replace_item_by_unique_index("topic", session.topic.clone(), session) .await?; Ok(()) @@ -115,35 +114,5 @@ impl WalletConnectStorageOps for IDBSessionStorage { Ok(()) } - async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { self.save_session(&session).await } -} - -pub(crate) mod crypto { - use js_sys::{JsString, Object, Reflect, Uint8Array}; - - fn rsa_oaep_params() -> Object { - // Create a new empty JavaScript object - let rsa_oaep_params = Object::new(); - - // "name": "RSA-OAEP" - let _ = Reflect::set(&rsa_oaep_params, &JsString::from("name"), &JsString::from("RSA-OAEP")); - - // "modulusLength": 2048 - let _ = Reflect::set(&rsa_oaep_params, &JsString::from("modulusLength"), &2048.into()); - - // "publicExponent": new Uint8Array([0x01, 0x00, 0x01]) - let public_exponent = Uint8Array::new_with_length(3); - public_exponent.copy_from(&[0x01, 0x00, 0x01]); - - let _ = Reflect::set(&rsa_oaep_params, &JsString::from("publicExponent"), &public_exponent); - - // Create the "hash" sub-object - let hash_obj = Object::new(); - let _ = Reflect::set(&hash_obj, &JsString::from("name"), &JsString::from("SHA-256")); - - // "hash": {"name": "SHA-256"} - let _ = Reflect::set(&rsa_oaep_params, &JsString::from("hash"), &hash_obj); - - rsa_oaep_params - } + async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { self.save_session(session).await } } From 2d5240453f0e76eabac2fc9302c4d0f1d8fc2184 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 11 Oct 2024 12:00:50 +0100 Subject: [PATCH 061/125] add chains/tendermint test --- .../kdf_walletconnect/src/chain/tendermint.rs | 201 ++++++++++++------ 1 file changed, 135 insertions(+), 66 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index 00dbaa4bbb..375582dbae 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -11,7 +11,7 @@ use serde_json::Value; use super::WcRequestMethods; -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum CosmosAccountAlgo { #[serde(rename = "secp256k1")] Secp256k1, @@ -19,7 +19,7 @@ pub enum CosmosAccountAlgo { TendermintSecp256k1, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CosmosAccount { pub address: String, #[serde(deserialize_with = "deserialize_vec_field")] @@ -27,59 +27,6 @@ pub struct CosmosAccount { pub algo: CosmosAccountAlgo, } -fn deserialize_vec_field<'de, D>(deserializer: D) -> Result, D::Error> -where - D: serde::Deserializer<'de>, -{ - let value = Value::deserialize(deserializer)?; - - match value { - Value::Object(map) => { - let mut vec = Vec::new(); - for i in 0..map.len() { - if let Some(Value::Number(num)) = map.get(&i.to_string()) { - if let Some(byte) = num.as_u64() { - vec.push(byte as u8); - } else { - return Err(serde::de::Error::custom("Invalid byte value")); - } - } else { - return Err(serde::de::Error::custom("Invalid format")); - } - } - Ok(vec) - }, - Value::Array(arr) => arr - .into_iter() - .map(|v| { - v.as_u64() - .ok_or_else(|| serde::de::Error::custom("Invalid byte value")) - .map(|n| n as u8) - }) - .collect(), - Value::String(data) => { - let data = decode_data(&data).map_err(|err| serde::de::Error::custom(err.to_string()))?; - Ok(data) - }, - _ => Err(serde::de::Error::custom("Pubkey must be an string, object or array")), - } -} - -fn decode_data(encoded: &str) -> Result, &'static str> { - // Check if the string is base64 or hex - if encoded.contains('=') || encoded.contains('/') || encoded.contains('+') { - // Try to decode as base64 - general_purpose::STANDARD - .decode(encoded) - .map_err(|_| "Invalid base64 encoding") - } else if encoded.chars().all(|c| c.is_ascii_hexdigit()) && encoded.len() % 2 == 0 { - // Try to decode as hex - hex::decode(encoded).map_err(|_| "Invalid hex encoding") - } else { - Err("Unknown encoding format") - } -} - pub async fn cosmos_get_accounts_impl( ctx: &WalletConnectCtx, chain_id: &str, @@ -120,26 +67,26 @@ pub async fn cosmos_get_accounts_impl( MmError::err(WalletConnectCtxError::NoAccountFound(chain_id.to_owned())) } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct CosmosTxSignedData { pub signature: CosmosTxSignature, pub signed: CosmosSignData, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct CosmosTxSignature { pub pub_key: CosmosTxPublicKey, pub signature: String, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct CosmosTxPublicKey { #[serde(rename = "type")] pub key_type: String, pub value: String, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] pub struct CosmosSignData { pub chain_id: String, @@ -150,13 +97,6 @@ pub struct CosmosSignData { pub body_bytes: Vec, } -#[derive(Debug, Serialize, Deserialize)] -pub struct AccountNumber { - low: u64, - high: u64, - unsigned: bool, -} - pub async fn cosmos_sign_direct_impl( ctx: &WalletConnectCtx, sign_doc: Value, @@ -196,3 +136,132 @@ pub async fn cosmos_sign_direct_impl( "No response from wallet".to_string(), )) } + +fn deserialize_vec_field<'de, D>(deserializer: D) -> Result, D::Error> +where + D: serde::Deserializer<'de>, +{ + let value = Value::deserialize(deserializer)?; + + match value { + Value::Object(map) => { + let mut vec = Vec::new(); + for i in 0..map.len() { + if let Some(Value::Number(num)) = map.get(&i.to_string()) { + if let Some(byte) = num.as_u64() { + vec.push(byte as u8); + } else { + return Err(serde::de::Error::custom("Invalid byte value")); + } + } else { + return Err(serde::de::Error::custom("Invalid format")); + } + } + Ok(vec) + }, + Value::Array(arr) => arr + .into_iter() + .map(|v| { + v.as_u64() + .ok_or_else(|| serde::de::Error::custom("Invalid byte value")) + .map(|n| n as u8) + }) + .collect(), + Value::String(data) => { + let data = decode_data(&data).map_err(|err| serde::de::Error::custom(err.to_string()))?; + Ok(data) + }, + _ => Err(serde::de::Error::custom("Pubkey must be an string, object or array")), + } +} + +fn decode_data(encoded: &str) -> Result, &'static str> { + // Check if the string is base64 or hex + if encoded.contains('=') || encoded.contains('/') || encoded.contains('+') { + // Try to decode as base64 + general_purpose::STANDARD + .decode(encoded) + .map_err(|_| "Invalid base64 encoding") + } else if encoded.chars().all(|c| c.is_ascii_hexdigit()) && encoded.len() % 2 == 0 { + // Try to decode as hex + hex::decode(encoded).map_err(|_| "Invalid hex encoding") + } else { + Err("Unknown encoding format") + } +} + +#[cfg(test)] +mod test_cosmos_walletconnect { + use serde_json::json; + + use crate::chain::tendermint::{decode_data, CosmosSignData, CosmosTxPublicKey, CosmosTxSignature, + CosmosTxSignedData}; + + #[test] + fn test_decode_base64() { + let base64_data = "SGVsbG8gd29ybGQ="; // "Hello world" in base64 + let expected = b"Hello world".to_vec(); + let result = decode_data(base64_data); + assert_eq!(result.unwrap(), expected, "Base64 decoding failed"); + } + + #[test] + fn test_decode_hex() { + let hex_data = "48656c6c6f20776f726c64"; // "Hello world" in hex + let expected = b"Hello world".to_vec(); + let result = decode_data(hex_data); + assert_eq!(result.unwrap(), expected, "Hex decoding failed"); + } + + #[test] + fn test_deserialize_sign_message_response() { + let json = json!({ + "signature": { + "signature": "eGrmDGKTmycxJO56yTQORDzTFjBEBgyBmHc8ey6FbHh9WytzgsJilYBywz5uludhyKePZdRwznamg841fXw50Q==", + "pub_key": { + "type": "tendermint/PubKeySecp256k1", + "value": "AjqZ1rq/EsPAb4SA6l0qjpVMHzqXotYXz23D5kOceYYu" + } + }, + "signed": { + "chainId": "cosmoshub-4", + "authInfoBytes": "0a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a21023a99d6babf12c3c06f8480ea5d2a8e954c1f3a97a2d617cf6dc3e6439c79862e12040a020801180212140a0e0a057561746f6d1205313837353010c8d007", + "bodyBytes": "0a8e010a1c2f636f736d6f732e62616e6b2e763162657461312e4d736753656e64126e0a2d636f736d6f7331376c386432737973646e3667683636786d366664666b6575333634703836326a68396c6e6667122d636f736d6f7331376c386432737973646e3667683636786d366664666b6575333634703836326a68396c6e66671a0e0a057561746f6d12053430303030189780e00a", + "accountNumber": "2934714" + } + }); + let expected_tx = CosmosTxSignedData { + signature: CosmosTxSignature { + pub_key: CosmosTxPublicKey { + key_type: "tendermint/PubKeySecp256k1".to_owned(), + value: "AjqZ1rq/EsPAb4SA6l0qjpVMHzqXotYXz23D5kOceYYu".to_owned(), + }, + signature: "eGrmDGKTmycxJO56yTQORDzTFjBEBgyBmHc8ey6FbHh9WytzgsJilYBywz5uludhyKePZdRwznamg841fXw50Q==" + .to_owned(), + }, + signed: CosmosSignData { + chain_id: "cosmoshub-4".to_owned(), + account_number: "2934714".to_owned(), + auth_info_bytes: vec![ + 10, 80, 10, 70, 10, 31, 47, 99, 111, 115, 109, 111, 115, 46, 99, 114, 121, 112, 116, 111, 46, 115, + 101, 99, 112, 50, 53, 54, 107, 49, 46, 80, 117, 98, 75, 101, 121, 18, 35, 10, 33, 2, 58, 153, 214, + 186, 191, 18, 195, 192, 111, 132, 128, 234, 93, 42, 142, 149, 76, 31, 58, 151, 162, 214, 23, 207, + 109, 195, 230, 67, 156, 121, 134, 46, 18, 4, 10, 2, 8, 1, 24, 2, 18, 20, 10, 14, 10, 5, 117, 97, + 116, 111, 109, 18, 5, 49, 56, 55, 53, 48, 16, 200, 208, 7, + ], + body_bytes: vec![ + 10, 142, 1, 10, 28, 47, 99, 111, 115, 109, 111, 115, 46, 98, 97, 110, 107, 46, 118, 49, 98, 101, + 116, 97, 49, 46, 77, 115, 103, 83, 101, 110, 100, 18, 110, 10, 45, 99, 111, 115, 109, 111, 115, 49, + 55, 108, 56, 100, 50, 115, 121, 115, 100, 110, 54, 103, 104, 54, 54, 120, 109, 54, 102, 100, 102, + 107, 101, 117, 51, 54, 52, 112, 56, 54, 50, 106, 104, 57, 108, 110, 102, 103, 18, 45, 99, 111, 115, + 109, 111, 115, 49, 55, 108, 56, 100, 50, 115, 121, 115, 100, 110, 54, 103, 104, 54, 54, 120, 109, + 54, 102, 100, 102, 107, 101, 117, 51, 54, 52, 112, 56, 54, 50, 106, 104, 57, 108, 110, 102, 103, + 26, 14, 10, 5, 117, 97, 116, 111, 109, 18, 5, 52, 48, 48, 48, 48, 24, 151, 128, 224, 10, + ], + }, + }; + + let actual_tx = serde_json::from_value::(json).unwrap(); + assert_eq!(expected_tx, actual_tx); + } +} From 4cbd2fa0ecf3aff220543d5db79d6f610dceb5b0 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 14 Oct 2024 01:41:37 +0100 Subject: [PATCH 062/125] minor changes, improve api --- Cargo.lock | 153 +++++------------- mm2src/coins/tendermint/tendermint_coin.rs | 33 ++-- mm2src/crypto/Cargo.toml | 1 + .../kdf_walletconnect/src/chain/tendermint.rs | 25 ++- mm2src/kdf_walletconnect/src/lib.rs | 41 ++--- mm2src/kdf_walletconnect/src/session.rs | 87 +++++++--- .../src/session/rpc/settle.rs | 8 +- .../mm2_main/src/rpc/wc_commands/sessions.rs | 7 +- 8 files changed, 154 insertions(+), 201 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0fbea80c27..0cc889a471 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -392,15 +392,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" -[[package]] -name = "base64" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" -dependencies = [ - "byteorder", -] - [[package]] name = "base64" version = "0.11.0" @@ -1562,6 +1553,7 @@ dependencies = [ "num-traits", "parking_lot 0.12.0", "primitives", + "rand 0.8.5", "rpc", "rpc_task", "rustc-hex", @@ -2478,7 +2470,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" dependencies = [ "byteorder", - "rand 0.8.4", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -2664,7 +2656,7 @@ checksum = "e01fe9932a224b72b45336d96040aa86386d674a31d0af27d800ea7bc8ca97fe" dependencies = [ "futures-io", "rustls 0.20.4", - "webpki 0.22.0", + "webpki", ] [[package]] @@ -3600,7 +3592,7 @@ dependencies = [ "mm2_err_handle", "mm2_test_helpers", "pairing_api", - "rand 0.8.4", + "rand 0.8.5", "relay_client", "relay_rpc", "secp256k1 0.20.3", @@ -3773,7 +3765,7 @@ dependencies = [ "parking_lot 0.12.0", "pin-project", "quick-protobuf", - "rand 0.8.4", + "rand 0.8.5", "rw-stream-sink", "smallvec 1.6.1", "thiserror", @@ -3810,7 +3802,7 @@ dependencies = [ "log", "quick-protobuf", "quick-protobuf-codec", - "rand 0.8.4", + "rand 0.8.5", "smallvec 1.6.1", "thiserror", ] @@ -3838,7 +3830,7 @@ dependencies = [ "prometheus-client", "quick-protobuf", "quick-protobuf-codec", - "rand 0.8.4", + "rand 0.8.5", "regex", "sha2 0.10.7", "smallvec 1.6.1", @@ -3880,7 +3872,7 @@ dependencies = [ "log", "multihash", "quick-protobuf", - "rand 0.8.4", + "rand 0.8.5", "sha2 0.10.7", "thiserror", "zeroize", @@ -3898,7 +3890,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "log", - "rand 0.8.4", + "rand 0.8.5", "smallvec 1.6.1", "socket2 0.5.3", "tokio", @@ -3937,7 +3929,7 @@ dependencies = [ "multihash", "once_cell", "quick-protobuf", - "rand 0.8.4", + "rand 0.8.5", "sha2 0.10.7", "snow", "static_assertions", @@ -3959,7 +3951,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "log", - "rand 0.8.4", + "rand 0.8.5", "void", ] @@ -3975,7 +3967,7 @@ dependencies = [ "libp2p-identity", "libp2p-swarm", "log", - "rand 0.8.4", + "rand 0.8.5", "smallvec 1.6.1", "void", ] @@ -3996,7 +3988,7 @@ dependencies = [ "log", "multistream-select", "once_cell", - "rand 0.8.4", + "rand 0.8.5", "smallvec 1.6.1", "tokio", "void", @@ -4108,7 +4100,7 @@ dependencies = [ "libsecp256k1-core 0.3.0", "libsecp256k1-gen-ecmult 0.3.0", "libsecp256k1-gen-genmult 0.3.0", - "rand 0.8.4", + "rand 0.8.5", "serde", "sha2 0.9.9", "typenum", @@ -5331,14 +5323,14 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" dependencies = [ "anyhow", "chrono", "hex", "lazy_static", "paste", - "rand 0.8.4", + "rand 0.8.5", "regex", "relay_client", "relay_rpc", @@ -6044,14 +6036,13 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha 0.3.1", "rand_core 0.6.4", - "rand_hc 0.3.1", ] [[package]] @@ -6135,15 +6126,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_hc" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "rand_isaac" version = "0.1.1" @@ -6347,7 +6329,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" dependencies = [ "chrono", "data-encoding", @@ -6363,7 +6345,6 @@ dependencies = [ "serde_qs", "thiserror", "tokio", - "tokio-rustls 0.10.3", "tokio-tungstenite-wasm 0.1.1-alpha.0 (git+https://github.com/KomodoPlatform/tokio-tungstenite-wasm.git?rev=8fc7e2f)", "tokio-util", "url", @@ -6376,7 +6357,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" dependencies = [ "anyhow", "bs58 0.4.0", @@ -6388,7 +6369,7 @@ dependencies = [ "jsonwebtoken", "once_cell", "paste", - "rand 0.8.4", + "rand 0.8.5", "regex", "serde", "serde-aux", @@ -6702,19 +6683,6 @@ dependencies = [ "windows-sys 0.45.0", ] -[[package]] -name = "rustls" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e" -dependencies = [ - "base64 0.10.1", - "log", - "ring 0.16.20", - "sct 0.6.1", - "webpki 0.21.4", -] - [[package]] name = "rustls" version = "0.20.4" @@ -6723,8 +6691,8 @@ checksum = "4fbfeb8d0ddb84706bc597a5574ab8912817c52a397f819e5b614e2265206921" dependencies = [ "log", "ring 0.16.20", - "sct 0.7.0", - "webpki 0.22.0", + "sct", + "webpki", ] [[package]] @@ -6736,7 +6704,7 @@ dependencies = [ "log", "ring 0.17.3", "rustls-webpki 0.101.7", - "sct 0.7.0", + "sct", ] [[package]] @@ -6893,16 +6861,6 @@ dependencies = [ "serialization", ] -[[package]] -name = "sct" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "sct" version = "0.7.0" @@ -7447,7 +7405,7 @@ dependencies = [ "futures 0.3.28", "httparse", "log", - "rand 0.8.4", + "rand 0.8.5", "sha-1", ] @@ -8633,7 +8591,7 @@ dependencies = [ "hex", "hmac 0.12.1", "log", - "rand 0.8.4", + "rand 0.8.5", "serde", "serde_json", "sha2 0.10.7", @@ -8787,17 +8745,6 @@ dependencies = [ "futures 0.1.29", ] -[[package]] -name = "tokio-io" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fc868aae093479e3131e3d165c93b1c7474109d13c90ec0dda2a1bbfff0674" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.29", - "log", -] - [[package]] name = "tokio-io-timeout" version = "1.2.0" @@ -8819,20 +8766,6 @@ dependencies = [ "syn 2.0.77", ] -[[package]] -name = "tokio-rustls" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d7cf08f990090abd6c6a73cab46fed62f85e8aef8b99e4b918a9f4a637f0676" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.29", - "iovec", - "rustls 0.16.0", - "tokio-io", - "webpki 0.21.4", -] - [[package]] name = "tokio-rustls" version = "0.23.2" @@ -8841,7 +8774,7 @@ checksum = "a27d5f2b839802bd8267fa19b0530f5a08b9c08cd417976be2a65d130fe1c11b" dependencies = [ "rustls 0.20.4", "tokio", - "webpki 0.22.0", + "webpki", ] [[package]] @@ -8878,7 +8811,7 @@ dependencies = [ "tokio", "tokio-rustls 0.23.2", "tungstenite", - "webpki 0.22.0", + "webpki", ] [[package]] @@ -8995,7 +8928,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite 0.2.9", - "rand 0.8.4", + "rand 0.8.5", "slab", "tokio", "tokio-util", @@ -9123,7 +9056,7 @@ dependencies = [ "idna", "ipnet", "lazy_static", - "rand 0.8.4", + "rand 0.8.5", "smallvec 1.6.1", "socket2 0.4.9", "thiserror", @@ -9171,13 +9104,13 @@ dependencies = [ "http 0.2.12", "httparse", "log", - "rand 0.8.4", + "rand 0.8.5", "rustls 0.20.4", "sha-1", "thiserror", "url", "utf-8", - "webpki 0.22.0", + "webpki", "webpki-roots 0.22.3", ] @@ -9349,7 +9282,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "422ee0de9031b5b948b97a8fc04e3aa35230001a722ddd27943e0be31564ce4c" dependencies = [ "getrandom 0.2.9", - "rand 0.8.4", + "rand 0.8.5", "serde", ] @@ -9565,7 +9498,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#81753315dee132d53eac1ad6b6b18467a267a314" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" dependencies = [ "base64 0.21.7", "chacha20poly1305", @@ -9604,7 +9537,7 @@ dependencies = [ "log", "parking_lot 0.12.0", "pin-project", - "rand 0.8.4", + "rand 0.8.5", "reqwest", "rlp", "serde", @@ -9616,16 +9549,6 @@ dependencies = [ "wasm-bindgen-futures", ] -[[package]] -name = "webpki" -version = "0.21.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - [[package]] name = "webpki" version = "0.22.0" @@ -9642,7 +9565,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" dependencies = [ - "webpki 0.22.0", + "webpki", ] [[package]] @@ -10046,7 +9969,7 @@ dependencies = [ "nohash-hasher", "parking_lot 0.12.0", "pin-project", - "rand 0.8.4", + "rand 0.8.5", "static_assertions", ] @@ -10062,7 +9985,7 @@ dependencies = [ "nohash-hasher", "parking_lot 0.12.0", "pin-project", - "rand 0.8.4", + "rand 0.8.5", "static_assertions", ] diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 4cba2c391c..b2910be057 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -359,13 +359,14 @@ impl RpcCommonOps for TendermintCoin { #[derive(PartialEq)] pub enum TendermintWalletConnectionType { + Wc, + WcWithLedger, KeplrLedger, - WalletConnect, - Other, + Internal, } impl Default for TendermintWalletConnectionType { - fn default() -> Self { Self::Other } + fn default() -> Self { Self::Internal } } pub struct TendermintCoinImpl { @@ -388,7 +389,7 @@ pub struct TendermintCoinImpl { client: TendermintRpcClient, pub(crate) chain_registry_name: Option, pub(crate) ctx: MmWeak, - pub(crate) wallet_connection_type: TendermintWalletConnectionType, + pub(crate) wallet_type: TendermintWalletConnectionType, } #[derive(Clone)] @@ -656,7 +657,7 @@ impl TendermintCoin { nodes: Vec, tx_history: bool, activation_policy: TendermintActivationPolicy, - wallet_connection_type: Option, + wallet_type: Option, ) -> MmResult { if nodes.is_empty() { return MmError::err(TendermintInitError { @@ -721,7 +722,7 @@ impl TendermintCoin { client: TendermintRpcClient(AsyncMutex::new(client_impl)), chain_registry_name: protocol_info.chain_registry_name, ctx: ctx.weak(), - wallet_connection_type: wallet_connection_type.unwrap_or_default(), + wallet_type: wallet_type.unwrap_or_default(), }))) } @@ -861,7 +862,7 @@ impl TendermintCoin { ) }, TendermintActivationPolicy::PublicKey(_) => { - if let TendermintWalletConnectionType::WalletConnect = self.wallet_connection_type { + if let TendermintWalletConnectionType::Wc = self.wallet_type { return try_tx_s!( self.seq_safe_send_raw_tx_bytes(tx_payload, fee, timeout_height, memo) .timeout(expiration) @@ -907,8 +908,8 @@ impl TendermintCoin { timeout_height: u64, memo: String, ) -> Result { - match self.wallet_connection_type { - TendermintWalletConnectionType::WalletConnect => { + match self.wallet_type { + TendermintWalletConnectionType::Wc => { // Handle WalletConnect signing let SerializedUnsignedTx { tx_json, body_bytes: _ } = try_tx_s!(self.any_to_serialized_sign_doc(account_info, tx_payload, fee, timeout_height, memo)); @@ -1284,7 +1285,7 @@ impl TendermintCoin { )); }; - if let TendermintWalletConnectionType::WalletConnect = self.wallet_connection_type { + if let TendermintWalletConnectionType::Wc = self.wallet_type { let ctx = MmArc::from_weak(&self.ctx) .ok_or(MyAddressError::InternalError(ERRL!("ctx must be initialized already")))?; let wallet_connect = WalletConnectCtx::from_ctx(&ctx)?; @@ -1417,15 +1418,15 @@ impl TendermintCoin { } }); - // if wallet_connection_type is WalletConnect, update tx_json to use WalletConnect type. - if self.wallet_connection_type == TendermintWalletConnectionType::WalletConnect { + // if wallet_type is WalletConnect, update tx_json to use WalletConnect type. + if self.wallet_type == TendermintWalletConnectionType::Wc { tx_json = json!({ "signerAddress": my_address, "signDoc": { "accountNumber": sign_doc.account_number.to_string(), "chainId": sign_doc.chain_id, - "bodyBytes": hex::encode(&sign_doc.body_bytes), - "authInfoBytes": hex::encode(&sign_doc.auth_info_bytes) + "bodyBytes": general_purpose::STANDARD.encode(&sign_doc.body_bytes), + "authInfoBytes": general_purpose::STANDARD.encode(&sign_doc.auth_info_bytes) } }) } @@ -2208,9 +2209,7 @@ impl TendermintCoin { None } - pub fn is_keplr_from_ledger(&self) -> bool { - TendermintWalletConnectionType::KeplrLedger == self.wallet_connection_type - } + pub fn is_keplr_from_ledger(&self) -> bool { TendermintWalletConnectionType::KeplrLedger == self.wallet_type } } fn clients_from_urls(ctx: &MmArc, nodes: Vec) -> MmResult, TendermintInitErrorKind> { diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index c5636ed80e..72e2c0e884 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -34,6 +34,7 @@ mm2_err_handle = { path = "../mm2_err_handle" } num-traits = "0.2" parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } +rand = "0.8.5" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } rustc-hex = "2" diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index 375582dbae..7a9a48e075 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -33,11 +33,9 @@ pub async fn cosmos_get_accounts_impl( ) -> MmResult, WalletConnectCtxError> { let account = ctx.get_account_for_chain_id(chain_id).await?; - let topic = { - match ctx.session.get_session_active().await { - Some(session) => session.topic.into(), - None => return MmError::err(WalletConnectCtxError::NotInitialized), - } + let topic = match ctx.session.get_session_active().await { + Some(session) => session.topic.clone(), + None => return MmError::err(WalletConnectCtxError::NotInitialized), }; let request = SessionRequest { @@ -102,11 +100,9 @@ pub async fn cosmos_sign_direct_impl( sign_doc: Value, chain_id: &str, ) -> MmResult { - let topic = { - match ctx.session.get_session_active().await { - Some(session) => session.topic.into(), - None => return MmError::err(WalletConnectCtxError::NotInitialized), - } + let topic = match ctx.session.get_session_active().await { + Some(session) => session.topic.clone(), + None => return MmError::err(WalletConnectCtxError::NotInitialized), }; let request = SessionRequest { @@ -176,15 +172,12 @@ where } fn decode_data(encoded: &str) -> Result, &'static str> { - // Check if the string is base64 or hex - if encoded.contains('=') || encoded.contains('/') || encoded.contains('+') { - // Try to decode as base64 + if encoded.chars().all(|c| c.is_ascii_hexdigit()) && encoded.len() % 2 == 0 { + hex::decode(encoded).map_err(|_| "Invalid hex encoding") + } else if encoded.contains('=') || encoded.contains('/') || encoded.contains('+') || encoded.len() % 4 == 0 { general_purpose::STANDARD .decode(encoded) .map_err(|_| "Invalid base64 encoding") - } else if encoded.chars().all(|c| c.is_ascii_hexdigit()) && encoded.len() % 2 == 0 { - // Try to decode as hex - hex::decode(encoded).map_err(|_| "Invalid hex encoding") } else { Err("Unknown encoding format") } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 2202ea3d5b..7f17175b84 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -20,7 +20,6 @@ use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, use inbound_message::{process_inbound_request, process_inbound_response}; use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_core::mm_ctx::{from_ctx, MmArc}; -use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; use pairing_api::PairingClient; use relay_client::{websocket::{Client, PublishedMessage}, @@ -33,11 +32,13 @@ use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, ResponseParamsSuccess}, ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; use serde_json::Value; -use session::{key::SymKeyPair, rpc::propose::send_proposal_request, SessionManagement}; +use session::{key::SymKeyPair, SessionManagement}; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; +use crate::session::rpc::propose::send_proposal_request; + pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; // tendermint e.g ATOM @@ -146,20 +147,17 @@ impl WalletConnectCtx { Ok(url) } - /// Connect to a WalletConnect pairing url. - pub async fn connect_to_pairing(&self, url: &str, activate: bool) -> MmResult { - let topic = self.pairing.pair(url, activate).await?; - - info!("Subscribing to topic: {topic:?}"); - self.client.subscribe(topic.clone()).await?; - info!("Subscribed to topic: {topic:?}"); - - { - let mut subs = self.subscriptions.lock().await; - subs.push(topic.clone()); - }; - - Ok(topic) + pub async fn is_keplr_from_ledger(&self) -> bool { + self.session + .get_session_active() + .await + .map(|session| { + session + .session_properties + .as_ref() + .map(|props| props.keys.first().map(|key| key.is_nano_ledger)) + }) + .is_some() } pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|chain| chain == &chain_id) } @@ -181,20 +179,13 @@ impl WalletConnectCtx { let namespaces = self.namespaces.lock().await; namespaces .iter() - .find_map(|(key, namespace)| self.find_account_in_namespace(key, namespace, chain_id)) + .find_map(|(_key, namespace)| self.find_account_in_namespace(namespace, chain_id)) .ok_or(MmError::new(WalletConnectCtxError::NoAccountFound( chain_id.to_string(), ))) } - fn find_account_in_namespace(&self, namespace_key: &str, namespace: &Namespace, chain_id: &str) -> Option { - let chains = namespace.chains.as_ref()?; - let key = format!("{namespace_key}:{chain_id}"); - - if !chains.contains(&key) { - return None; - } - + fn find_account_in_namespace(&self, namespace: &Namespace, chain_id: &str) -> Option { let accounts = namespace.accounts.as_ref()?; accounts.iter().find_map(|account_name| { diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index bba4679717..ceb61d8c38 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -5,7 +5,7 @@ use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use chrono::Utc; use common::log::debug; -use dashmap::mapref::one::RefMut; +use dashmap::mapref::one::{Ref, RefMut}; use dashmap::DashMap; use futures::lock::Mutex; use key::SessionKey; @@ -17,7 +17,7 @@ use relay_rpc::rpc::params::session_propose::Proposer; use relay_rpc::rpc::params::IrnMetadata; use relay_rpc::{domain::SubscriptionId, rpc::params::{session::ProposeNamespaces, session_settle::Controller, Metadata, Relay}}; -use serde::{Deserialize, Serialize}; +use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::collections::BTreeMap; use std::fmt::Debug; @@ -56,13 +56,42 @@ pub struct SessionRpcInfo { pub pairing_topic: String, pub namespaces: BTreeMap, pub subscription_id: SubscriptionId, + pub properties: Option, +} + +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] +#[serde(rename_all = "camelCase")] +pub struct KeyInfo { + pub chain_id: String, + pub name: String, + pub algo: String, + pub pub_key: String, + pub address: String, + pub bech32_address: String, + pub ethereum_hex_address: String, + pub is_nano_ledger: bool, + pub is_keystone: bool, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +pub struct SessionProperties { + #[serde(deserialize_with = "deserialize_keys_from_string")] + pub keys: Vec, +} + +fn deserialize_keys_from_string<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + let key_string = String::deserialize(deserializer)?; + serde_json::from_str(&key_string).map_err(serde::de::Error::custom) } /// This struct is typically used in the core session management logic of a WalletConnect /// implementation. It's used to store, retrieve, and update session information throughout /// the lifecycle of a WalletConnect connection. #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] -pub(crate) struct Session { +pub struct Session { /// Session topic pub topic: Topic, /// Pairing subscription id. @@ -85,6 +114,7 @@ pub(crate) struct Session { pub pairing_topic: Topic, /// Indicates whether this session info represents a Controller or Proposer perspective. pub session_type: SessionType, + pub session_properties: Option, } impl Session { @@ -124,6 +154,7 @@ impl Session { pairing_topic, session_type, topic: session_topic, + session_properties: None, } } @@ -145,6 +176,20 @@ impl Default for SessionManagement { fn default() -> Self { Self::new() } } +impl From for SessionRpcInfo { + fn from(value: Session) -> Self { + Self { + topic: value.topic.to_string(), + metadata: value.controller.metadata, + peer_pubkey: value.controller.public_key, + pairing_topic: value.pairing_topic.to_string(), + namespaces: value.namespaces, + subscription_id: value.subscription_id, + properties: value.session_properties, + } + } +} + #[allow(unused)] impl SessionManagement { pub fn new() -> Self { Self(Default::default()) } @@ -165,35 +210,26 @@ impl SessionManagement { debug!("Deleting session with topic: {topic}"); let mut active_topic = self.0.active_topic.lock().await; - if let Some(ref topic_) = *active_topic { - if topic_ == topic { - *active_topic = None; - }; - }; - + // Remove the session and get the removed session (if any) let removed_session = self.0.sessions.remove(topic).map(|(_, session)| session); - // Update active session - if active_topic.is_none() {} - if let Some(session) = self.0.sessions.iter().next() { - debug!("New session with topic: {} activated!", session.topic); - *active_topic = Some(session.topic.clone()); + // Update active topic if necessary + if active_topic.as_ref() == Some(topic) { + // If the deleted session was the active one, find a new active session + *active_topic = self.0.sessions.iter().next().map(|session| session.topic.clone()); + + if let Some(new_active_topic) = active_topic.as_ref() { + debug!("New session with topic: {} activated!", new_active_topic); + } else { + debug!("No active sessions remaining"); + } } removed_session } /// Retrieves a cloned session associated with a given topic. - pub fn get_session(&self, topic: &Topic) -> Option { - self.0.sessions.get(topic).map(|(session)| SessionRpcInfo { - topic: topic.to_string(), - metadata: session.controller.metadata.clone(), - peer_pubkey: session.controller.public_key.clone(), - pairing_topic: session.pairing_topic.to_string(), - namespaces: session.namespaces.clone(), - subscription_id: session.subscription_id.clone(), - }) - } + pub fn get_session(&self, topic: &Topic) -> Option> { self.0.sessions.get(topic) } /// Retrieves a mutable reference to the session associated with a given topic. pub(crate) async fn get_session_mut(&self, topic: &Topic) -> Option> { @@ -201,7 +237,7 @@ impl SessionManagement { } /// Returns an `Option` containing the active session if it exists; otherwise, returns `None`. - pub async fn get_session_active(&self) -> Option { + pub async fn get_session_active(&self) -> Option> { let active_topic = self.0.active_topic.lock().await; if let Some(ref topic) = *active_topic { self.get_session(topic) @@ -223,6 +259,7 @@ impl SessionManagement { pairing_topic: session.pairing_topic.to_string(), namespaces: session.namespaces.clone(), subscription_id: session.subscription_id, + properties: session.session_properties, }) .collect() } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 5a171ceb2e..d7a9a3cd11 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -1,5 +1,5 @@ use crate::chain::{SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; -use crate::session::{Session, THIRTY_DAYS}; +use crate::session::{Session, SessionProperties, THIRTY_DAYS}; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; @@ -29,6 +29,7 @@ pub(crate) async fn send_session_settle_request( controller: session_info.controller.clone(), namespaces: SettleNamespaces(settled_namespaces), expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, + session_properties: None, }); ctx.publish_request(&session_info.topic, request).await?; @@ -50,6 +51,11 @@ pub(crate) async fn reply_session_settle_request( session.controller = settle.controller.clone(); session.relay = settle.relay.clone(); session.expiry = settle.expiry; + + if let Some(value) = settle.session_properties { + let session_properties = serde_json::from_str::(&value.to_string())?; + session.session_properties = Some(session_properties); + } // Update storage session. ctx.storage .db diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 6f95cf718a..cb8f9684cf 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -17,7 +17,7 @@ pub async fn get_all_sessions( ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let sessions = ctx.session.get_sessions(); + let sessions = ctx.session.get_sessions().map(|s| SessionRpcInfo::from(s)); Ok(GetSessionsResponse { sessions }) } @@ -36,7 +36,10 @@ pub struct GetSessionRequest { pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let session = ctx.session.get_session(&req.topic.into()); + let session = ctx + .session + .get_session(&req.topic.into()) + .map(|s| SessionRpcInfo::from(s)); Ok(GetSessionResponse { session }) } From a57495d6559918c9b12db3e91b6eaa0fd9d8d472 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 14 Oct 2024 10:51:58 +0100 Subject: [PATCH 063/125] remove subscription on session delete --- mm2src/kdf_walletconnect/src/chain/tendermint.rs | 4 ++-- mm2src/kdf_walletconnect/src/session/rpc/delete.rs | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index 7a9a48e075..f9b8b8474e 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -33,8 +33,8 @@ pub async fn cosmos_get_accounts_impl( ) -> MmResult, WalletConnectCtxError> { let account = ctx.get_account_for_chain_id(chain_id).await?; - let topic = match ctx.session.get_session_active().await { - Some(session) => session.topic.clone(), + let topic = match ctx.sessin.get_session_active().await { + Some(session) => session.topic.clonse(;), None => return MmError::err(WalletConnectCtxError::NotInitialized), }; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 87b3cd3333..740ddb1923 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -47,6 +47,10 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu ctx.client.unsubscribe(session.pairing_topic.clone()).await?; // Attempt to disconnect the pairing ctx.pairing.delete(session.pairing_topic.as_ref()).await; + // Remove subscriptions + let mut subs = ctx.subscriptions.lock().await; + subs.retain(|s| s != &session.topic); + subs.retain(|s| s != &session.pairing_topic); } Ok(()) From c7e7de61d47473c8e012a6fbefab975654214cc6 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 14 Oct 2024 11:45:58 +0100 Subject: [PATCH 064/125] improve ledger external wallet connection checks --- mm2src/coins/tendermint/tendermint_coin.rs | 64 +++++++++++-------- mm2src/coins/tendermint/tendermint_token.rs | 2 +- .../src/tendermint_with_assets_activation.rs | 25 ++++++-- .../kdf_walletconnect/src/chain/tendermint.rs | 4 +- mm2src/kdf_walletconnect/src/lib.rs | 2 +- .../mm2_main/src/rpc/wc_commands/sessions.rs | 9 ++- 6 files changed, 66 insertions(+), 40 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index b2910be057..551f2f446a 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -360,7 +360,7 @@ impl RpcCommonOps for TendermintCoin { #[derive(PartialEq)] pub enum TendermintWalletConnectionType { Wc, - WcWithLedger, + WcLedger, KeplrLedger, Internal, } @@ -987,7 +987,7 @@ impl TendermintCoin { let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); let account_info = try_tx_s!(self.account_info(&self.account_id).await); - let SerializedUnsignedTx { tx_json, body_bytes } = if self.is_keplr_from_ledger() { + let SerializedUnsignedTx { tx_json, body_bytes } = if self.is_ledger_connection() { try_tx_s!(self.any_to_legacy_amino_json(&account_info, tx_payload, fee, timeout_height, memo)) } else { try_tx_s!(self.any_to_serialized_sign_doc(&account_info, tx_payload, fee, timeout_height, memo)) @@ -1314,7 +1314,7 @@ impl TendermintCoin { )); }; - let SerializedUnsignedTx { tx_json, .. } = if self.is_keplr_from_ledger() { + let SerializedUnsignedTx { tx_json, .. } = if self.is_ledger_connection() { self.any_to_legacy_amino_json(account_info, message, fee, timeout_height, memo) } else { self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo) @@ -1408,28 +1408,31 @@ impl TendermintCoin { let auth_info = SignerInfo::single_direct(Some(pubkey), account_info.sequence).auth_info(fee); let sign_doc = SignDoc::new(&tx_body, &auth_info, &self.chain_id, account_info.account_number)?; - let my_address = self.my_address().unwrap(); - let mut tx_json = json!({ - "sign_doc": { - "body_bytes": &sign_doc.body_bytes, - "auth_info_bytes": sign_doc.auth_info_bytes, - "chain_id": sign_doc.chain_id, - "account_number": sign_doc.account_number, - } - }); - - // if wallet_type is WalletConnect, update tx_json to use WalletConnect type. - if self.wallet_type == TendermintWalletConnectionType::Wc { - tx_json = json!({ - "signerAddress": my_address, - "signDoc": { - "accountNumber": sign_doc.account_number.to_string(), - "chainId": sign_doc.chain_id, - "bodyBytes": general_purpose::STANDARD.encode(&sign_doc.body_bytes), - "authInfoBytes": general_purpose::STANDARD.encode(&sign_doc.auth_info_bytes) - } - }) - } + let tx_json = match self.wallet_type { + TendermintWalletConnectionType::Wc => { + // if wallet_type is WalletConnect, update tx_json to use WalletConnect type. + let my_address = self.my_address().unwrap(); + json!({ + "signerAddress": my_address, + "signDoc": { + "accountNumber": sign_doc.account_number.to_string(), + "chainId": sign_doc.chain_id, + "bodyBytes": general_purpose::STANDARD.encode(&sign_doc.body_bytes), + "authInfoBytes": general_purpose::STANDARD.encode(&sign_doc.auth_info_bytes) + } + }) + }, + _ => { + json!({ + "sign_doc": { + "body_bytes": &sign_doc.body_bytes, + "auth_info_bytes": sign_doc.auth_info_bytes, + "chain_id": sign_doc.chain_id, + "account_number": sign_doc.account_number, + } + }) + }, + }; Ok(SerializedUnsignedTx { tx_json, @@ -2209,7 +2212,12 @@ impl TendermintCoin { None } - pub fn is_keplr_from_ledger(&self) -> bool { TendermintWalletConnectionType::KeplrLedger == self.wallet_type } + pub fn is_ledger_connection(&self) -> bool { + matches!( + self.wallet_type, + TendermintWalletConnectionType::WcLedger | TendermintWalletConnectionType::KeplrLedger + ) + } } fn clients_from_urls(ctx: &MmArc, nodes: Vec) -> MmResult, TendermintInitErrorKind> { @@ -2294,7 +2302,7 @@ impl MmCoin for TendermintCoin { let coin_conf = crate::coin_conf(ctx, self.ticker()); let wallet_only_conf = coin_conf["wallet_only"].as_bool().unwrap_or(false); - wallet_only_conf || self.is_keplr_from_ledger() + wallet_only_conf || self.is_ledger_connection() } fn spawner(&self) -> CoinFutSpawner { CoinFutSpawner::new(&self.abortable_system) } @@ -2378,7 +2386,7 @@ impl MmCoin for TendermintCoin { ) .await?; - let fee_amount_u64 = if coin.is_keplr_from_ledger() { + let fee_amount_u64 = if coin.is_ledger_connection() { // When using `SIGN_MODE_LEGACY_AMINO_JSON`, Keplr ignores the fee we calculated // and calculates another one which is usually double what we calculate. // To make sure the transaction doesn't fail on the Keplr side (because if Keplr diff --git a/mm2src/coins/tendermint/tendermint_token.rs b/mm2src/coins/tendermint/tendermint_token.rs index 5117e1774d..65a2c61248 100644 --- a/mm2src/coins/tendermint/tendermint_token.rs +++ b/mm2src/coins/tendermint/tendermint_token.rs @@ -476,7 +476,7 @@ impl MmCoin for TendermintToken { let coin_conf = crate::coin_conf(ctx, self.ticker()); let wallet_only_conf = coin_conf["wallet_only"].as_bool().unwrap_or(false); - wallet_only_conf || self.platform_coin.is_keplr_from_ledger() + wallet_only_conf || self.platform_coin.is_ledger_connection() } fn spawner(&self) -> CoinFutSpawner { CoinFutSpawner::new(&self.abortable_system) } diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index fa4b282b4d..c79fc8db6c 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -55,7 +55,7 @@ pub enum TendermintPubkeyActivationParams { WithPubkey { #[serde(deserialize_with = "deserialize_account_public_key")] pubkey: TendermintPublicKey, - is_keplr_from_ledger: bool, + is_ledger_connection: bool, }, /// Activation via WalletConnect WalletConnect(WalletConnectParams), @@ -242,6 +242,7 @@ async fn get_walletconnect_pubkey( param: &WalletConnectParams, chain_id: &str, ticker: &str, + wallet_type: &mut TendermintWalletConnectionType, ) -> MmResult { if ctx.is_watcher() || ctx.use_watchers() { return MmError::err(TendermintInitError { @@ -270,6 +271,12 @@ async fn get_walletconnect_pubkey( kind: TendermintInitErrorKind::Internal(e), })?; + if walletconnect_ctx.is_ledger_connection().await { + *wallet_type = TendermintWalletConnectionType::WcLedger; + } else { + *wallet_type = TendermintWalletConnectionType::Wc; + }; + Ok(TendermintActivationPolicy::with_public_key(pubkey)) } @@ -292,7 +299,7 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { let conf = TendermintConf::try_from_json(&ticker, coin_conf)?; - let mut wallet_connectin_type = TendermintWalletConnectionType::Other; + let mut wallet_connectin_type = TendermintWalletConnectionType::Internal; let activation_policy = if let Some(params) = activation_request.activation_params { if ctx.is_watcher() || ctx.use_watchers() { @@ -305,17 +312,23 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { match params { TendermintPubkeyActivationParams::WithPubkey { pubkey, - is_keplr_from_ledger, + is_ledger_connection, } => { - if is_keplr_from_ledger { + if is_ledger_connection { wallet_connectin_type = TendermintWalletConnectionType::KeplrLedger; }; TendermintActivationPolicy::with_public_key(pubkey) }, TendermintPubkeyActivationParams::WalletConnect(params) => { - wallet_connectin_type = TendermintWalletConnectionType::WalletConnect; - get_walletconnect_pubkey(&ctx, ¶ms, protocol_conf.chain_id.as_ref(), &ticker).await? + get_walletconnect_pubkey( + &ctx, + ¶ms, + protocol_conf.chain_id.as_ref(), + &ticker, + &mut wallet_connectin_type, + ) + .await? }, } } else { diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/kdf_walletconnect/src/chain/tendermint.rs index f9b8b8474e..7a9a48e075 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/kdf_walletconnect/src/chain/tendermint.rs @@ -33,8 +33,8 @@ pub async fn cosmos_get_accounts_impl( ) -> MmResult, WalletConnectCtxError> { let account = ctx.get_account_for_chain_id(chain_id).await?; - let topic = match ctx.sessin.get_session_active().await { - Some(session) => session.topic.clonse(;), + let topic = match ctx.session.get_session_active().await { + Some(session) => session.topic.clone(), None => return MmError::err(WalletConnectCtxError::NotInitialized), }; diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 7f17175b84..ee5082a44a 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -147,7 +147,7 @@ impl WalletConnectCtx { Ok(url) } - pub async fn is_keplr_from_ledger(&self) -> bool { + pub async fn is_ledger_connection(&self) -> bool { self.session .get_session_active() .await diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index cb8f9684cf..809d9b307e 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -17,7 +17,12 @@ pub async fn get_all_sessions( ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let sessions = ctx.session.get_sessions().map(|s| SessionRpcInfo::from(s)); + let sessions = ctx + .session + .get_sessions() + .into_iter() + .map(SessionRpcInfo::from) + .collect::>(); Ok(GetSessionsResponse { sessions }) } @@ -39,7 +44,7 @@ pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult Date: Mon, 14 Oct 2024 12:15:50 +0100 Subject: [PATCH 065/125] wc tx handling for tendermint --- mm2src/coins/tendermint/tendermint_coin.rs | 26 +++++++++++----------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 551f2f446a..d76b4890c2 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -851,7 +851,10 @@ impl TendermintCoin { // As there wouldn't be enough time to process the data, to mitigate potential edge problems (such as attempting to send transaction // bytes half a second before expiration, which may take longer to send and result in the transaction amount being wasted due to a timeout), // reduce the expiration time by 5 seconds. - let expiration = timeout - Duration::from_secs(5); + const SAFETY_MARGIN: Duration = Duration::from_secs(5); + let expiration = try_tx_s!(timeout + .checked_sub(SAFETY_MARGIN) + .ok_or("Timeout duration is too short")); match self.activation_policy { TendermintActivationPolicy::PrivateKey(_) => { @@ -861,20 +864,17 @@ impl TendermintCoin { .await ) }, - TendermintActivationPolicy::PublicKey(_) => { - if let TendermintWalletConnectionType::Wc = self.wallet_type { - return try_tx_s!( - self.seq_safe_send_raw_tx_bytes(tx_payload, fee, timeout_height, memo) - .timeout(expiration) - .await - ); - }; - - try_tx_s!( + TendermintActivationPolicy::PublicKey(_) => match self.wallet_type { + TendermintWalletConnectionType::WcLedger | TendermintWalletConnectionType::Wc => try_tx_s!( + self.seq_safe_send_raw_tx_bytes(tx_payload, fee, timeout_height, memo) + .timeout(expiration) + .await + ), + _ => try_tx_s!( self.send_unsigned_tx_externally(tx_payload, fee, timeout_height, memo, expiration) .timeout(expiration) .await - ) + ), }, } } @@ -909,7 +909,7 @@ impl TendermintCoin { memo: String, ) -> Result { match self.wallet_type { - TendermintWalletConnectionType::Wc => { + TendermintWalletConnectionType::Wc | TendermintWalletConnectionType::WcLedger => { // Handle WalletConnect signing let SerializedUnsignedTx { tx_json, body_bytes: _ } = try_tx_s!(self.any_to_serialized_sign_doc(account_info, tx_payload, fee, timeout_height, memo)); From 5a574a6ecedfc5fa263180a113885b79d2197b73 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 15 Oct 2024 03:48:50 +0100 Subject: [PATCH 066/125] complete persistent session storage with unit test for native and wasm --- .../src/connection_handler.rs | 5 + mm2src/kdf_walletconnect/src/lib.rs | 58 ++++--- mm2src/kdf_walletconnect/src/session.rs | 86 ++++++++++- .../src/session/rpc/delete.rs | 11 +- .../src/session/rpc/propose.rs | 19 ++- .../src/session/rpc/settle.rs | 1 - mm2src/kdf_walletconnect/src/storage/mod.rs | 135 +++++++++++++---- .../kdf_walletconnect/src/storage/sqlite.rs | 142 +++++++++++------- 8 files changed, 335 insertions(+), 122 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 33b5e91d15..3c5c759232 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -86,6 +86,11 @@ async fn initial_connection(this: &WalletConnectCtx) { } info!("Successfully connected to client after {} attempt(s).", retry_count + 1); + + // load session from storage + if let Err(err) = this.load_session_from_storage().await { + error!("Unable to load session from storage: {err:?}"); + }; } async fn handle_disconnections(this: &WalletConnectCtx) { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index ee5082a44a..dd5349e5d0 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -35,6 +35,7 @@ use serde_json::Value; use session::{key::SymKeyPair, SessionManagement}; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; +use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; use crate::session::rpc::propose::send_proposal_request; @@ -64,6 +65,12 @@ pub struct WalletConnectCtx { session_request_handler: Arc>>, } +impl Drop for WalletConnectCtx { + fn drop(&mut self) { + println!("drop"); + } +} + impl WalletConnectCtx { pub fn try_init(ctx: &MmArc) -> MmResult { let (msg_sender, msg_receiver) = unbounded(); @@ -152,10 +159,12 @@ impl WalletConnectCtx { .get_session_active() .await .map(|session| { - session - .session_properties - .as_ref() - .map(|props| props.keys.first().map(|key| key.is_nano_ledger)) + session.session_properties.as_ref().map(|props| { + props + .keys + .as_ref() + .map(|keys| keys.first().map(|key| key.is_nano_ledger)) + }) }) .is_some() } @@ -347,22 +356,23 @@ impl WalletConnectCtx { #[allow(unused)] async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectCtxError> { - //let sessions = self - // .storage - // .db - // .get_all_sessions() - // .await - // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; - //if let Some(session) = sessions.first() { - // info!("Session found! activating :{}", session.topic); - // - // let mut ctx_session = self.session.lock().await; - // *ctx_session = Some(session.clone()); - // - // // subcribe to session topics - // self.client.subscribe(session.topic.clone()).await?; - //self.client.subscribe(session.pairing_topic.clone()).await?; - //} + let sessions = self + .storage + .get_all_sessions() + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + + for session in sessions { + let topic = session.topic.clone(); + let pairing_topic = session.pairing_topic.clone(); + + info!("Session found! activating :{}", topic); + self.session.add_session(session).await; + + // subcribe to session topics + self.client.subscribe(topic).await?; + self.client.subscribe(pairing_topic).await?; + } Ok(()) } @@ -371,9 +381,14 @@ impl WalletConnectCtx { /// This function spwans related WalletConnect related tasks and needed initialization before /// WalletConnect can be usable in KDF. pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectCtxError> { + info!("Initializing WalletConnect"); + // Initialized WalletConnectCtx let wallet_connect = WalletConnectCtx::from_ctx(ctx)?; + // Intialize storage. + wallet_connect.storage.init().await.unwrap(); + // WalletConnectCtx is initialized, now we can connect to relayer client and spawn a watcher // loop for disconnection. ctx.spawner().spawn(maintain_client_connection(wallet_connect.clone())); @@ -381,8 +396,7 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect // spawn message handler event loop ctx.spawner().spawn(wallet_connect.message_handler_event_loop()); - // load session from storage - // wallet_connect.load_session_from_storage().await?; + info!("WalletConnect initialization completed successfully"); Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index ceb61d8c38..ec4c9a0a28 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -75,16 +75,29 @@ pub struct KeyInfo { #[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct SessionProperties { - #[serde(deserialize_with = "deserialize_keys_from_string")] - pub keys: Vec, + #[serde(default, deserialize_with = "deserialize_keys_from_string")] + pub keys: Option>, } -fn deserialize_keys_from_string<'de, D>(deserializer: D) -> Result, D::Error> +fn deserialize_keys_from_string<'de, D>(deserializer: D) -> Result>, D::Error> where D: Deserializer<'de>, { - let key_string = String::deserialize(deserializer)?; - serde_json::from_str(&key_string).map_err(serde::de::Error::custom) + #[derive(Deserialize)] + #[serde(untagged)] + enum KeysField { + String(String), + Vec(Vec), + None, + } + + match KeysField::deserialize(deserializer)? { + KeysField::String(key_string) => serde_json::from_str(&key_string) + .map(Some) + .map_err(serde::de::Error::custom), + KeysField::Vec(keys) => Ok(Some(keys)), + KeysField::None => Ok(None), + } } /// This struct is typically used in the core session management logic of a WalletConnect @@ -308,3 +321,66 @@ impl SessionManagement { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + + fn create_sample_key_info() -> KeyInfo { + KeyInfo { + chain_id: "test-chain".to_string(), + name: "Test Key".to_string(), + algo: "secp256k1".to_string(), + pub_key: "0123456789ABCDEF".to_string(), + address: "test_address".to_string(), + bech32_address: "bech32_test_address".to_string(), + ethereum_hex_address: "0xtest_eth_address".to_string(), + is_nano_ledger: false, + is_keystone: false, + } + } + + #[test] + fn test_deserialize_keys_from_string() { + let key_info = create_sample_key_info(); + let key_json = serde_json::to_string(&vec![key_info.clone()]).unwrap(); + let json = format!(r#"{{"keys": "{}"}}"#, key_json.replace('\"', "\\\"")); + let session: SessionProperties = serde_json::from_str(&json).unwrap(); + assert!(session.keys.is_some()); + assert_eq!(session.keys.unwrap(), vec![key_info]); + } + + #[test] + fn test_deserialize_keys_from_vec() { + let key_info = create_sample_key_info(); + let json = format!(r#"{{"keys": [{}]}}"#, serde_json::to_string(&key_info).unwrap()); + let session: SessionProperties = serde_json::from_str(&json).unwrap(); + assert!(session.keys.is_some()); + assert_eq!(session.keys.unwrap(), vec![key_info]); + } + + #[test] + fn test_deserialize_empty_keys() { + let json = r#"{"keys": []}"#; + let session: SessionProperties = serde_json::from_str(json).unwrap(); + assert_eq!(session.keys, Some(vec![])); + } + + #[test] + fn test_deserialize_no_keys() { + let json = r#"{}"#; + let session: SessionProperties = serde_json::from_str(json).unwrap(); + assert_eq!(session.keys, None); + } + + #[test] + fn test_serialize_deserialize_roundtrip() { + let key_info = create_sample_key_info(); + let original = SessionProperties { + keys: Some(vec![key_info]), + }; + let serialized = serde_json::to_string(&original).unwrap(); + let deserialized: SessionProperties = serde_json::from_str(&serialized).unwrap(); + assert_eq!(original, deserialized); + } +} diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 740ddb1923..19b1f203f6 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -1,8 +1,9 @@ use crate::{error::{WalletConnectCtxError, USER_REQUESTED}, + storage::WalletConnectStorageOps, WalletConnectCtx}; use common::log::debug; -use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::{MapMmError, MmResult}; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_delete::SessionDeleteRequest, RequestParams, ResponseParamsSuccess}}; @@ -51,7 +52,13 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu let mut subs = ctx.subscriptions.lock().await; subs.retain(|s| s != &session.topic); subs.retain(|s| s != &session.pairing_topic); - } + }; + + // delete session from storage as well. + ctx.storage + .delete_session(topic) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index fc32585a46..bac64457e7 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,4 +1,5 @@ use super::settle::send_session_settle_request; +use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectCtxError, metadata::generate_metadata, session::{Session, SessionKey, SessionType, THIRTY_DAYS}, @@ -70,11 +71,10 @@ pub async fn reply_session_proposal_request( { // save session to storage - //ctx.storage - // .db - // .save_session(&session) - // .await - // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + ctx.storage + .save_session(&session) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; // Add session to session lists ctx.session.add_session(session.clone()).await; @@ -134,11 +134,10 @@ pub(crate) async fn process_session_propose_response( { // save session to storage - //ctx.storage - // .db - // .save_session(&session) - // .await - // .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + ctx.storage + .save_session(&session) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; // Add session to session lists ctx.session.add_session(session.clone()).await; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index d7a9a3cd11..927f2f07b0 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -58,7 +58,6 @@ pub(crate) async fn reply_session_settle_request( } // Update storage session. ctx.storage - .db .update_session(&session) .await .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 112e1d114f..aed78b8893 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -1,3 +1,5 @@ +use std::ops::Deref; + use async_trait::async_trait; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::MmResult; @@ -22,40 +24,39 @@ pub(crate) trait WalletConnectStorageOps { async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error>; } -pub(crate) struct SessionStorageDb { - #[cfg(target_arch = "wasm32")] - pub(crate) db: indexed_db::IDBSessionStorage, - #[cfg(not(target_arch = "wasm32"))] - pub(crate) db: sqlite::SqliteSessionStorage, +#[cfg(target_arch = "wasm32")] +type DB = indexed_db::IDBSessionStorage; +#[cfg(not(target_arch = "wasm32"))] +type DB = sqlite::SqliteSessionStorage; + +pub(crate) struct SessionStorageDb(DB); + +impl Deref for SessionStorageDb { + type Target = DB; + fn deref(&self) -> &Self::Target { &self.0 } } impl SessionStorageDb { pub(crate) fn init(ctx: &MmArc) -> MmResult { - let selfi = SessionStorageDb { - #[cfg(target_arch = "wasm32")] - db: indexed_db::IDBSessionStorage::new(ctx) - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?, - #[cfg(not(target_arch = "wasm32"))] - db: sqlite::SqliteSessionStorage::new(ctx).mm_err(WalletConnectCtxError::StorageError)?, - }; + #[cfg(target_arch = "wasm32")] + let db = indexed_db::IDBSessionStorage::new(ctx) + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + #[cfg(not(target_arch = "wasm32"))] + let db = sqlite::SqliteSessionStorage::new(ctx).mm_err(WalletConnectCtxError::StorageError)?; - Ok(selfi) + Ok(SessionStorageDb(db)) } } -#[cfg(ignore)] #[cfg(test)] pub(crate) mod session_storage_tests { - - #[cfg(target_arch = "wasm32")] common::cfg_wasm32! { use wasm_bindgen_test::*; wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); } use common::cross_test; use mm2_test_helpers::for_tests::mm_ctx_with_custom_async_db; - use relay_rpc::{domain::{SubscriptionId, Topic}, - rpc::params::Metadata}; + use relay_rpc::{domain::SubscriptionId, rpc::params::Metadata}; use crate::{session::key::SessionKey, session::{Session, SessionType}, @@ -63,9 +64,7 @@ pub(crate) mod session_storage_tests { use super::WalletConnectStorageOps; - cross_test!(save_session_impl, { - let mm_ctx = mm_ctx_with_custom_async_db().await; - let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); + fn sample_test_session(wc_ctx: &WalletConnectCtx) -> Session { let session_key = SessionKey { sym_key: [ 115, 159, 247, 31, 199, 84, 88, 59, 158, 252, 98, 225, 51, 125, 201, 239, 142, 34, 9, 201, 128, 114, @@ -77,21 +76,99 @@ pub(crate) mod session_storage_tests { ], }; - let session = Session::new( - &wc_ctx, - Topic::generate(), + Session::new( + wc_ctx, + "bb89e3bae8cb89e5549f4d9bcc5a1ac2aae6dd90ef37eb2f59d80c5773f36343".into(), SubscriptionId::generate(), session_key, - Topic::generate(), + "5af44bdf8d6b11f4635c964a15e9e2d50942534824791757b2c26528e8feef39".into(), Metadata::default(), SessionType::Controller, - ); + ) + } + + cross_test!(save_and_get_session_test, { + let mm_ctx = mm_ctx_with_custom_async_db().await; + let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); + wc_ctx.storage.init().await.unwrap(); + + let sample_session = sample_test_session(&wc_ctx); // try save session - wc_ctx.storage.db.save_session(&session).await.unwrap(); + wc_ctx.storage.save_session(&sample_session).await.unwrap(); // try get session - let db_session = wc_ctx.storage.db.get_session(&session.topic).await.unwrap(); - assert_eq!(session, db_session.unwrap()); + let db_session = wc_ctx.storage.get_session(&sample_session.topic).await.unwrap(); + assert_eq!(sample_session, db_session.unwrap()); + }); + + cross_test!(delete_session_test, { + let mm_ctx = mm_ctx_with_custom_async_db().await; + let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); + wc_ctx.storage.init().await.unwrap(); + + let sample_session = sample_test_session(&wc_ctx); + + // try save session + wc_ctx.storage.save_session(&sample_session).await.unwrap(); + + // try get session + let db_session = wc_ctx + .storage + .get_session(&sample_session.topic) + .await + .unwrap() + .unwrap(); + assert_eq!(sample_session, db_session); + + // try delete session + wc_ctx.storage.delete_session(&db_session.topic).await.unwrap(); + + // try get_session deleted again + let db_session = wc_ctx.storage.get_session(&db_session.topic).await; + assert!(db_session.is_err()); + }); + + cross_test!(update_session_test, { + let mm_ctx = mm_ctx_with_custom_async_db().await; + let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); + wc_ctx.storage.init().await.unwrap(); + + let sample_session = sample_test_session(&wc_ctx); + + // try save session + wc_ctx.storage.save_session(&sample_session).await.unwrap(); + + // try get session + let db_session = wc_ctx + .storage + .get_session(&sample_session.topic) + .await + .unwrap() + .unwrap(); + assert_eq!(sample_session, db_session); + + // modify sample_session + let mut modified_sample_session = sample_session.clone(); + modified_sample_session.expiry = 100; + + // assert that original session expiry isn't the same as our new expiry. + assert_ne!(sample_session.expiry, modified_sample_session.expiry); + + // try update session + wc_ctx.storage.update_session(&modified_sample_session).await.unwrap(); + + // try get_session again with new updated expiry + let db_session = wc_ctx + .storage + .get_session(&sample_session.topic) + .await + .unwrap() + .unwrap(); + assert_ne!(modified_sample_session, sample_session); + assert_ne!(sample_session.expiry, db_session.expiry); + + assert_eq!(modified_sample_session, db_session); + assert_eq!(100, db_session.expiry); }); } diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 3dcd13577c..2fdf06ba27 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -12,24 +12,16 @@ use std::sync::Arc; use super::WalletConnectStorageOps; use crate::session::Session; -const SESSION_TBALE_NAME: &str = "session"; +const SESSION_TABLE_NAME: &str = "wc_session"; /// Sessions table fn create_sessions_table() -> SqlResult { - validate_table_name(SESSION_TBALE_NAME)?; + validate_table_name(SESSION_TABLE_NAME)?; Ok(format!( - "CREATE TABLE IF NOT EXISTS {SESSION_TBALE_NAME} ( + "CREATE TABLE IF NOT EXISTS {SESSION_TABLE_NAME} ( topic VARCHAR(255) PRIMARY KEY, - subscription_id VARCHAR(255) NOT NULL, - session_key TEXT NOT NULL, - expiry BIGINT NOT NULL, - pairing_topic VARCHAR(255) NOT NULL, - session_type VARCHAR(50) NOT NULL, - proposer TEXT NOT NULL, - controller TEXT NOT NULL, - relay TEXT NOT NULL, - namespaces TEXT, - proposed_namespace TEXT + data TEXT NOT NULL, + expiry BIGINT NOT NULL );" )) } @@ -67,9 +59,10 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn is_initialized(&self) -> MmResult { let lock = self.lock_db().await; - validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?; + validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; + lock.call(move |conn| { - let initialized = query_single_row(conn, CHECK_TABLE_EXISTS_SQL, [SESSION_TBALE_NAME], string_from_row)?; + let initialized = query_single_row(conn, CHECK_TABLE_EXISTS_SQL, [SESSION_TABLE_NAME], string_from_row)?; Ok(initialized.is_some()) }) .await @@ -77,46 +70,21 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { + validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; - validate_table_name(SESSION_TBALE_NAME).map_err(AsyncConnError::from)?; - let sql = format!( - "INSERT INTO {} ( - topic, subscription_id, session_key, expiry, pairing_topic, session_type, proposer, controller, relay, namespace, propose_namespaces - ) VALUES ( - ?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11 - );", - SESSION_TBALE_NAME - ); let session = session.clone(); lock.call(move |conn| { + let sql = format!( + "INSERT INTO {} (topic, data, expiry) VALUES (?1, ?2, ?3);", + SESSION_TABLE_NAME + ); let transaction = conn.transaction()?; - //let session_key = - // serde_json::to_string(&session.session_key).map_err(|err| AsyncConnError::from(err.to_string()))?; - let relay = serde_json::to_string(&session.relay).map_err(|err| AsyncConnError::from(err.to_string()))?; - let proposer = - serde_json::to_string(&session.proposer).map_err(|err| AsyncConnError::from(err.to_string()))?; - let controller = - serde_json::to_string(&session.controller).map_err(|err| AsyncConnError::from(err.to_string()))?; - let namespaces = - serde_json::to_string(&session.namespaces).map_err(|err| AsyncConnError::from(err.to_string()))?; - let propose_namespaces = serde_json::to_string(&session.propose_namespaces) - .map_err(|err| AsyncConnError::from(err.to_string()))?; - - let params = [ - session.topic.to_string(), - session.subscription_id.to_string(), - "session_key".to_string(), - session.expiry.to_string(), - session.pairing_topic.to_string(), - session.session_type.to_string(), - proposer, - controller, - relay, - namespaces, - propose_namespaces, - ]; + let session_data = serde_json::to_string(&session).map_err(|err| AsyncConnError::from(err.to_string()))?; + + let params = [session.topic.to_string(), session_data, session.expiry.to_string()]; + transaction.execute(&sql, params)?; transaction.commit()?; @@ -126,11 +94,79 @@ impl WalletConnectStorageOps for SqliteSessionStorage { .map_to_mm(AsyncConnError::from) } - async fn get_session(&self, _topic: &Topic) -> MmResult, Self::Error> { Ok(None) } + async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { + validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; + let lock = self.lock_db().await; + let topic = topic.clone(); + let session_str = lock + .call(move |conn| { + let sql = format!("SELECT topic, data, expiry FROM {} WHERE topic=?1;", SESSION_TABLE_NAME); + let mut stmt = conn.prepare(&sql)?; + let session: String = stmt.query_row([topic.to_string()], |row| row.get::<_, String>(1))?; + Ok(session) + }) + .await + .map_to_mm(AsyncConnError::from)?; + + let session = serde_json::from_str(&session_str).map_to_mm(|err| AsyncConnError::from(err.to_string()))?; + Ok(session) + } + + async fn get_all_sessions(&self) -> MmResult, Self::Error> { + validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; + let lock = self.lock_db().await; + let sessions_str = lock + .call(move |conn| { + let sql = format!("SELECT topic, data, expiry FROM {};", SESSION_TABLE_NAME); + let mut stmt = conn.prepare(&sql)?; + let sessions = stmt.query_map([], |row| row.get::<_, String>(1))?.collect::>(); + Ok(sessions) + }) + .await + .map_to_mm(AsyncConnError::from)?; + + let mut sessions = Vec::with_capacity(sessions_str.len()); + for session in sessions_str { + let session = serde_json::from_str(&session.map_to_mm(AsyncConnError::from)?) + .map_to_mm(|err| AsyncConnError::from(err.to_string()))?; + sessions.push(session); + } + + Ok(sessions) + } + + async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { + validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; + let topic = topic.clone(); + let lock = self.lock_db().await; + lock.call(move |conn| { + let sql = format!("DELETE FROM {} WHERE topic = ?1", SESSION_TABLE_NAME); + let mut stmt = conn.prepare(&sql)?; + let _ = stmt.execute([topic.to_string()])?; - async fn get_all_sessions(&self) -> MmResult, Self::Error> { Ok(vec![]) } + Ok(()) + }) + .await + .map_to_mm(AsyncConnError::from) + } - async fn delete_session(&self, _topic: &Topic) -> MmResult<(), Self::Error> { todo!() } + async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { + validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; + let session = session.clone(); + let lock = self.lock_db().await; + lock.call(move |conn| { + let sql = format!( + "UPDATE {} SET data = ?1, expiry = ?2 WHERE topic = ?3", + SESSION_TABLE_NAME + ); + let session_data = serde_json::to_string(&session).map_err(|err| AsyncConnError::from(err.to_string()))?; + let params = [session_data, session.expiry.to_string(), session.topic.to_string()]; + let _row = conn.prepare(&sql)?.execute(params)?; + println!("{_row}"); - async fn update_session(&self, _session: &Session) -> MmResult<(), Self::Error> { Ok(()) } + Ok(()) + }) + .await + .map_to_mm(AsyncConnError::from) + } } From 81ebee73f4a50f9adea9e7387335770ec324f071 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 15 Oct 2024 18:00:02 +0100 Subject: [PATCH 067/125] minor changes --- mm2src/kdf_walletconnect/src/lib.rs | 1 - .../kdf_walletconnect/src/session/rpc/delete.rs | 16 ++++++++-------- .../kdf_walletconnect/src/session/rpc/update.rs | 16 ++++++++-------- mm2src/kdf_walletconnect/src/storage/mod.rs | 1 - mm2src/kdf_walletconnect/src/storage/sqlite.rs | 1 - 5 files changed, 16 insertions(+), 19 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index dd5349e5d0..9b1127bd00 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -354,7 +354,6 @@ impl WalletConnectCtx { Ok(()) } - #[allow(unused)] async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectCtxError> { let sessions = self .storage diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 19b1f203f6..2d2c18be9a 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -4,8 +4,8 @@ use crate::{error::{WalletConnectCtxError, USER_REQUESTED}, use common::log::debug; use mm2_err_handle::prelude::{MapMmError, MmResult}; -use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session_delete::SessionDeleteRequest, RequestParams, ResponseParamsSuccess}}; +use relay_rpc::domain::{MessageId, Topic}; +use relay_rpc::rpc::params::{session_delete::SessionDeleteRequest, RequestParams, ResponseParamsSuccess}; pub(crate) async fn reply_session_delete_request( ctx: &WalletConnectCtx, @@ -52,13 +52,13 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu let mut subs = ctx.subscriptions.lock().await; subs.retain(|s| s != &session.topic); subs.retain(|s| s != &session.pairing_topic); - }; - // delete session from storage as well. - ctx.storage - .delete_session(topic) - .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + // delete session from storage as well. + ctx.storage + .delete_session(topic) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + }; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index b9722ed07f..04bbcc7c3f 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -1,9 +1,10 @@ +use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectCtxError, WalletConnectCtx}; use common::log::info; use mm2_err_handle::prelude::*; -use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session_update::SessionUpdateRequest, ResponseParamsSuccess}}; +use relay_rpc::domain::{MessageId, Topic}; +use relay_rpc::rpc::params::{session_update::SessionUpdateRequest, ResponseParamsSuccess}; // TODO: Handle properly when multi chain is supported. // Hanlding for only cosmos support. @@ -19,12 +20,11 @@ pub(crate) async fn reply_session_update_request( *ctx_ns = update.namespaces.clone(); session.namespaces = update.namespaces.0; info!("Updated extended, info: {:?}", session); - // Update storage session. - //ctx.storage - //.db - //.update_session(session) - //.await - //.mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + // Update storage session. + ctx.storage + .update_session(&session) + .await + .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; }; } diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index aed78b8893..6ba4476de4 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -165,7 +165,6 @@ pub(crate) mod session_storage_tests { .await .unwrap() .unwrap(); - assert_ne!(modified_sample_session, sample_session); assert_ne!(sample_session.expiry, db_session.expiry); assert_eq!(modified_sample_session, db_session); diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 2fdf06ba27..96540ff845 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -162,7 +162,6 @@ impl WalletConnectStorageOps for SqliteSessionStorage { let session_data = serde_json::to_string(&session).map_err(|err| AsyncConnError::from(err.to_string()))?; let params = [session_data, session.expiry.to_string(), session.topic.to_string()]; let _row = conn.prepare(&sql)?.execute(params)?; - println!("{_row}"); Ok(()) }) From 46e3802fe3678079d193d4acf1d92826474e7694 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 17 Oct 2024 16:39:29 +0100 Subject: [PATCH 068/125] fix is ledger connection fn --- mm2src/kdf_walletconnect/src/lib.rs | 39 ++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 9b1127bd00..6cf95a5a11 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -10,8 +10,8 @@ mod storage; use chain::{build_required_namespaces, tendermint::{cosmos_get_accounts_impl, cosmos_sign_direct_impl, CosmosAccount, CosmosTxSignedData}, SUPPORTED_CHAINS}; -use common::executor::SpawnFuture; use common::log::info; +use common::{executor::SpawnFuture, log::error}; use connection_handler::{maintain_client_connection, Handler}; use error::WalletConnectCtxError; use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, @@ -158,15 +158,11 @@ impl WalletConnectCtx { self.session .get_session_active() .await - .map(|session| { - session.session_properties.as_ref().map(|props| { - props - .keys - .as_ref() - .map(|keys| keys.first().map(|key| key.is_nano_ledger)) - }) - }) - .is_some() + .and_then(|session| session.session_properties.clone()) + .and_then(|props| props.keys.as_ref().cloned()) + .and_then(|keys| keys.first().cloned()) + .map(|key| key.is_nano_ledger) + .unwrap_or(false) } pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|chain| chain == &chain_id) } @@ -185,7 +181,14 @@ impl WalletConnectCtx { return MmError::err(WalletConnectCtxError::ChainIdMismatch); } - let namespaces = self.namespaces.lock().await; + let namespaces = &self + .session + .get_session_active() + .await + .ok_or(MmError::new(WalletConnectCtxError::NoAccountFound( + chain_id.to_string(), + )))? + .namespaces; namespaces .iter() .find_map(|(_key, namespace)| self.find_account_in_namespace(namespace, chain_id)) @@ -355,13 +358,25 @@ impl WalletConnectCtx { } async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectCtxError> { - let sessions = self + let now = chrono::Utc::now().timestamp() as u64; + let mut sessions = self .storage .get_all_sessions() .await .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); + for session in sessions { + // delete expired session + if now > session.expiry { + info!("Session {} expired, trying to delete from storage", session.topic); + if let Err(err) = self.storage.delete_session(&session.topic).await { + error!("Unable to delete session: {:?} from storage", err); + } + continue; + }; + let topic = session.topic.clone(); let pairing_topic = session.pairing_topic.clone(); From 500cb87391033ca466d7ca54c81cf961b7fd7565 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 19 Oct 2024 21:48:15 +0100 Subject: [PATCH 069/125] module refactorings --- .../src/tendermint_with_assets_activation.rs | 2 +- mm2src/kdf_walletconnect/src/chain/mod.rs | 5 +- .../src/connection_handler.rs | 29 +++--- .../kdf_walletconnect/src/inbound_message.rs | 16 ++-- mm2src/kdf_walletconnect/src/lib.rs | 88 +++++++++---------- .../src/session/rpc/event.rs | 24 ++--- .../src/session/rpc/settle.rs | 3 - .../src/session/rpc/update.rs | 5 +- 8 files changed, 82 insertions(+), 90 deletions(-) diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index c79fc8db6c..0b70aeebef 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -18,7 +18,7 @@ use coins::tendermint::{tendermint_priv_key_policy, RpcNode, TendermintActivatio use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, MmCoinEnum, PrivKeyBuildPolicy}; use common::executor::{AbortSettings, SpawnAbortable}; use common::{true_f, Future01CompatExt}; -use kdf_walletconnect::chain::tendermint::CosmosAccountAlgo; +use kdf_walletconnect::chain::CosmosAccountAlgo; use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; diff --git a/mm2src/kdf_walletconnect/src/chain/mod.rs b/mm2src/kdf_walletconnect/src/chain/mod.rs index 993444d200..d813aae034 100644 --- a/mm2src/kdf_walletconnect/src/chain/mod.rs +++ b/mm2src/kdf_walletconnect/src/chain/mod.rs @@ -1,7 +1,10 @@ -pub mod tendermint; +pub(crate) mod tendermint; use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; use std::collections::BTreeMap; +pub use tendermint::CosmosAccountAlgo; +pub(crate) use tendermint::*; + pub(crate) const SUPPORTED_EVENTS: &[&str] = &[]; pub(crate) const SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 3c5c759232..67cf5a6608 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -1,13 +1,15 @@ -use futures::StreamExt; -use std::sync::Arc; +use crate::WalletConnectCtx; -use common::{executor::Timer, - log::{error, info}}; +use common::executor::Timer; +use common::log::{error, info}; use futures::channel::mpsc::UnboundedSender; -use relay_client::{error::ClientError, - websocket::{CloseFrame, ConnectionHandler, PublishedMessage}}; +use futures::StreamExt; +use relay_client::error::ClientError; +use relay_client::websocket::{CloseFrame, ConnectionHandler, PublishedMessage}; -use crate::WalletConnectCtx; +const INITIAL_RETRY_SECS: f64 = 5.0; +const RETRY_INCREMENT: f64 = 5.0; +const RECONNECT_DELAY: f64 = 5.0; pub struct Handler { name: &'static str, @@ -62,16 +64,7 @@ impl ConnectionHandler for Handler { } } -const INITIAL_RETRY_SECS: f64 = 5.0; -const RETRY_INCREMENT: f64 = 5.0; -const RECONNECT_DELAY: f64 = 5.0; - -pub(crate) async fn maintain_client_connection(this: Arc) { - initial_connection(&this).await; - handle_disconnections(&this).await; -} - -async fn initial_connection(this: &WalletConnectCtx) { +pub(crate) async fn initial_connection(this: &WalletConnectCtx) { let mut retry_count = 0; let mut retry_secs = INITIAL_RETRY_SECS; @@ -93,7 +86,7 @@ async fn initial_connection(this: &WalletConnectCtx) { }; } -async fn handle_disconnections(this: &WalletConnectCtx) { +pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { let mut recv = this.connection_live_handler.lock().await; while let Some(_msg) = recv.next().await { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 4504175992..cccf03a4e8 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,11 +1,3 @@ -use common::log::info; -use futures::SinkExt; -use mm2_err_handle::prelude::{MmError, MmResult}; -use relay_rpc::{domain::Topic, - rpc::{params::ResponseParamsSuccess, Params, Request, Response}}; -use serde::{Deserialize, Serialize}; -use serde_json::Value; - use crate::{error::WalletConnectCtxError, pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, session::rpc::{delete::reply_session_delete_request, @@ -17,6 +9,14 @@ use crate::{error::WalletConnectCtxError, update::reply_session_update_request}, WalletConnectCtx}; +use common::log::info; +use futures::sink::SinkExt; +use mm2_err_handle::prelude::{MmError, MmResult}; +use relay_rpc::domain::Topic; +use relay_rpc::rpc::{params::ResponseParamsSuccess, Params, Request, Response}; +use serde::{Deserialize, Serialize}; +use serde_json::Value; + #[derive(Debug, Serialize, Deserialize)] #[serde(untagged)] pub enum SuccessResponses { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 6cf95a5a11..ff99b409df 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -7,30 +7,28 @@ mod metadata; pub mod session; mod storage; -use chain::{build_required_namespaces, - tendermint::{cosmos_get_accounts_impl, cosmos_sign_direct_impl, CosmosAccount, CosmosTxSignedData}, - SUPPORTED_CHAINS}; +use chain::{build_required_namespaces, cosmos_get_accounts_impl, cosmos_sign_direct_impl, CosmosAccount, + CosmosTxSignedData, SUPPORTED_CHAINS}; use common::log::info; use common::{executor::SpawnFuture, log::error}; -use connection_handler::{maintain_client_connection, Handler}; +use connection_handler::Handler; use error::WalletConnectCtxError; -use futures::{channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}, - lock::Mutex, - StreamExt}; +use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; +use futures::lock::Mutex; +use futures::StreamExt; use inbound_message::{process_inbound_request, process_inbound_response}; use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_core::mm_ctx::{from_ctx, MmArc}; use mm2_err_handle::prelude::*; use pairing_api::PairingClient; -use relay_client::{websocket::{Client, PublishedMessage}, - ConnectionOptions, MessageIdGenerator}; -use relay_rpc::rpc::params::{session::{Namespace, SettleNamespaces}, - RelayProtocolMetadata, RequestParams}; -use relay_rpc::{auth::{ed25519_dalek::SigningKey, AuthToken}, - domain::{MessageId, Topic}, - rpc::{params::{session::ProposeNamespaces, IrnMetadata, Metadata, Relay, ResponseParamsError, - ResponseParamsSuccess}, - ErrorResponse, Payload, Request, Response, SuccessfulResponse}}; +use relay_client::websocket::{Client, PublishedMessage}; +use relay_client::{ConnectionOptions, MessageIdGenerator}; +use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; +use relay_rpc::domain::{MessageId, Topic}; +use relay_rpc::rpc::params::session::{Namespace, ProposeNamespaces}; +use relay_rpc::rpc::params::{IrnMetadata, Metadata, Relay, RelayProtocolMetadata, RequestParams, ResponseParamsError, + ResponseParamsSuccess}; +use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; use serde_json::Value; use session::{key::SymKeyPair, SessionManagement}; use std::{sync::Arc, time::Duration}; @@ -56,7 +54,6 @@ pub struct WalletConnectCtx { relay: Relay, metadata: Metadata, - namespaces: Arc>, required_namespaces: ProposeNamespaces, subscriptions: Arc>>, inbound_message_handler: Arc>>, @@ -95,7 +92,6 @@ impl WalletConnectCtx { session: SessionManagement::new(), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), relay, - namespaces: Default::default(), required_namespaces: required, metadata: generate_metadata(), key_pair: SymKeyPair::new(), @@ -191,25 +187,12 @@ impl WalletConnectCtx { .namespaces; namespaces .iter() - .find_map(|(_key, namespace)| self.find_account_in_namespace(namespace, chain_id)) + .find_map(|(_key, namespace)| find_account_in_namespace(namespace, chain_id)) .ok_or(MmError::new(WalletConnectCtxError::NoAccountFound( chain_id.to_string(), ))) } - fn find_account_in_namespace(&self, namespace: &Namespace, chain_id: &str) -> Option { - let accounts = namespace.accounts.as_ref()?; - - accounts.iter().find_map(|account_name| { - let parts: Vec<&str> = account_name.split(':').collect(); - if parts.len() >= 3 && parts[1] == chain_id { - Some(parts[2].to_string()) - } else { - None - } - }) - } - pub async fn cosmos_get_account( &self, account_index: usize, @@ -328,16 +311,6 @@ impl WalletConnectCtx { Ok(()) } - pub async fn message_handler_event_loop(self: Arc) { - let selfi = self.clone(); - let mut recv = self.inbound_message_handler.lock().await; - while let Some(msg) = recv.next().await { - if let Err(e) = selfi.handle_published_message(msg).await { - info!("Error processing message: {:?}", e); - } - } - } - async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectCtxError> { let message = { let key = self.sym_key(&msg.topic).await?; @@ -405,12 +378,39 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect // WalletConnectCtx is initialized, now we can connect to relayer client and spawn a watcher // loop for disconnection. - ctx.spawner().spawn(maintain_client_connection(wallet_connect.clone())); + ctx.spawner().spawn({ + let this = wallet_connect.clone(); + async move { + connection_handler::initial_connection(&this).await; + connection_handler::handle_disconnections(&this).await; + } + }); // spawn message handler event loop - ctx.spawner().spawn(wallet_connect.message_handler_event_loop()); + ctx.spawner().spawn(async move { + let selfi = wallet_connect.clone(); + let mut recv = wallet_connect.inbound_message_handler.lock().await; + while let Some(msg) = recv.next().await { + if let Err(e) = selfi.handle_published_message(msg).await { + info!("Error processing message: {:?}", e); + } + } + }); info!("WalletConnect initialization completed successfully"); Ok(()) } + +fn find_account_in_namespace(namespace: &Namespace, chain_id: &str) -> Option { + let accounts = namespace.accounts.as_ref()?; + + accounts.iter().find_map(|account_name| { + let parts: Vec<&str> = account_name.split(':').collect(); + if parts.len() >= 3 && parts[1] == chain_id { + Some(parts[2].to_string()) + } else { + None + } + }) +} diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 7e08973a08..26c116ac09 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -70,18 +70,18 @@ impl SessionEvent { ) -> MmResult<(), WalletConnectCtxError> { if ctx.is_chain_supported(chain_id) { if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { - let namespaces = ctx.namespaces.lock().await; - if let Some(namespace) = namespaces.get(&key) { - let chains = namespace.chains.clone().unwrap_or_default(); - if chains.contains(&chain) { - // TODO: Notify GUI about chain changed. - // Update active chain_id - ctx.set_active_chain(chain_id.clone()).await; - - let params = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, params, message_id).await?; - - return Ok(()); + if let Some(session) = ctx.session.get_session_active().await { + if let Some(namespace) = session.namespaces.get(&key) { + let chains = namespace.chains.clone().unwrap_or_default(); + if chains.contains(&chain) { + // TODO: Notify GUI about chain changed. + ctx.set_active_chain(chain_id.clone()).await; + + let params = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, params, message_id).await?; + + return Ok(()); + } } } } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 927f2f07b0..bf00eebbdf 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -64,9 +64,6 @@ pub(crate) async fn reply_session_settle_request( } } - let mut ctx_ns = ctx.namespaces.lock().await; - *ctx_ns = settle.namespaces; - info!("Session successfully settled for topic: {:?}", topic); let param = ResponseParamsSuccess::SessionSettle(true); diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index 04bbcc7c3f..7c3b94e4a9 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -16,15 +16,14 @@ pub(crate) async fn reply_session_update_request( ) -> MmResult<(), WalletConnectCtxError> { { if let Some(mut session) = ctx.session.get_session_mut(topic).await { - let mut ctx_ns = ctx.namespaces.lock().await; - *ctx_ns = update.namespaces.clone(); session.namespaces = update.namespaces.0; - info!("Updated extended, info: {:?}", session); // Update storage session. ctx.storage .update_session(&session) .await .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + + info!("Updated extended, info: {:?}", session); }; } From 1840ca843a7dd675d74828e3a303fe8f664f0105 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 21 Oct 2024 05:18:35 +0100 Subject: [PATCH 070/125] introduce WcRequstOps trait, untighten code and more --- mm2src/coins/Cargo.toml | 1 + mm2src/coins/tendermint/mod.rs | 2 + mm2src/coins/tendermint/tendermint_coin.rs | 32 +++- .../tendermint/wallet_connect.rs} | 167 +++++++++--------- .../src/tendermint_with_assets_activation.rs | 17 +- .../src/{chain/mod.rs => chain.rs} | 4 - mm2src/kdf_walletconnect/src/error.rs | 10 +- .../kdf_walletconnect/src/inbound_message.rs | 12 +- mm2src/kdf_walletconnect/src/lib.rs | 115 +++++------- mm2src/kdf_walletconnect/src/pairing.rs | 8 +- mm2src/kdf_walletconnect/src/session.rs | 23 ++- .../src/session/rpc/delete.rs | 10 +- .../src/session/rpc/event.rs | 12 +- .../src/session/rpc/extend.rs | 4 +- .../kdf_walletconnect/src/session/rpc/mod.rs | 2 + .../kdf_walletconnect/src/session/rpc/ping.rs | 6 +- .../src/session/rpc/propose.rs | 18 +- .../src/session/rpc/settle.rs | 8 +- .../src/session/rpc/update.rs | 6 +- mm2src/kdf_walletconnect/src/storage/mod.rs | 8 +- mm2src/mm2_main/src/rpc/wc_commands/ping.rs | 28 --- .../mm2_main/src/rpc/wc_commands/sessions.rs | 27 ++- .../src/rpc/wc_commands/wc_commands.rs | 2 - 23 files changed, 256 insertions(+), 266 deletions(-) rename mm2src/{kdf_walletconnect/src/chain/tendermint.rs => coins/tendermint/wallet_connect.rs} (79%) rename mm2src/kdf_walletconnect/src/{chain/mod.rs => chain.rs} (92%) delete mode 100644 mm2src/mm2_main/src/rpc/wc_commands/ping.rs diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index dc6c16e66d..563e41a71b 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -81,6 +81,7 @@ protobuf = "2.20" proxy_signature = { path = "../proxy_signature" } rand = { version = "0.7", features = ["std", "small_rng"] } regex = "1" +relay_rpc = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } reqwest = { version = "0.11.9", default-features = false, features = ["json"], optional = true } rlp = { version = "0.5" } rmp-serde = "0.14.3" diff --git a/mm2src/coins/tendermint/mod.rs b/mm2src/coins/tendermint/mod.rs index 78009b5db8..87943930f1 100644 --- a/mm2src/coins/tendermint/mod.rs +++ b/mm2src/coins/tendermint/mod.rs @@ -10,11 +10,13 @@ mod tendermint_balance_events; mod tendermint_coin; mod tendermint_token; pub mod tendermint_tx_history_v2; +pub mod wallet_connect; pub use cosmrs::tendermint::PublicKey as TendermintPublicKey; pub use cosmrs::AccountId; pub use tendermint_coin::*; pub use tendermint_token::*; +pub use wallet_connect::*; pub(crate) const TENDERMINT_COIN_PROTOCOL_TYPE: &str = "TENDERMINT"; pub(crate) const TENDERMINT_ASSET_PROTOCOL_TYPE: &str = "TENDERMINTTOKEN"; diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 9ab0240578..619c17745a 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -3,6 +3,7 @@ use super::htlc::{ClaimHtlcMsg, ClaimHtlcProto, CreateHtlcMsg, CreateHtlcProto, QueryHtlcResponse, TendermintHtlc, HTLC_STATE_COMPLETED, HTLC_STATE_OPEN, HTLC_STATE_REFUNDED}; use super::ibc::transfer_v1::MsgTransfer; use super::ibc::IBC_GAS_LIMIT_DEFAULT; +use super::wallet_connect::{cosmos_request_wc_signed_tx, CosmosTxSignedData}; use super::{rpc::*, TENDERMINT_COIN_PROTOCOL_TYPE}; use crate::coin_errors::{MyAddressError, ValidatePaymentError, ValidatePaymentResult}; use crate::hd_wallet::{HDPathAccountToAddressId, WithdrawFrom}; @@ -63,7 +64,8 @@ use futures01::Future; use hex::FromHexError; use instant::Duration; use itertools::Itertools; -use kdf_walletconnect::WalletConnectCtx; +use kdf_walletconnect::error::WalletConnectError; +use kdf_walletconnect::{WalletConnectCtx, WcRequestOps}; use keys::{KeyPair, Public}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_err_handle::prelude::*; @@ -865,6 +867,7 @@ impl TendermintCoin { ) }, TendermintActivationPolicy::PublicKey(_) => match self.wallet_type { + // TODO implement ledger tx signing for WC. TendermintWalletConnectionType::WcLedger | TendermintWalletConnectionType::Wc => try_tx_s!( self.seq_safe_send_raw_tx_bytes(tx_payload, fee, timeout_height, memo) .timeout(expiration) @@ -881,13 +884,9 @@ impl TendermintCoin { async fn request_wc_tx_signing(&self, tx_json: serde_json::Value) -> Result { let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); - let wallet_connect = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); + let wc = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); - let response = try_tx_s!( - wallet_connect - .cosmos_send_sign_tx_request(tx_json, self.chain_id.as_ref()) - .await - ); + let response = try_tx_s!(self.wc_request_sign_tx(&wc, self.chain_id.as_ref(), tx_json).await); let signature = try_tx_s!(general_purpose::STANDARD .decode(response.signature.signature) .map_err(|e| ERRL!("{}", e))); @@ -1293,8 +1292,8 @@ impl TendermintCoin { let SerializedUnsignedTx { tx_json, body_bytes: _ } = self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo)?; - let response = wallet_connect - .cosmos_send_sign_tx_request(tx_json, self.chain_id.as_ref()) + let response = self + .wc_request_sign_tx(&wallet_connect, self.chain_id.as_ref(), tx_json) .await?; let signature = general_purpose::STANDARD.decode(response.signature.signature)?; let body_bytes = response.signed.body_bytes; @@ -3448,6 +3447,21 @@ fn parse_expected_sequence_number(e: &str) -> MmResult; + type SignTxData = CosmosTxSignedData; + + async fn wc_request_sign_tx( + &self, + ctx: &WalletConnectCtx, + chain_id: &str, + tx_json: serde_json::Value, + ) -> Result { + cosmos_request_wc_signed_tx(ctx, tx_json, chain_id).await + } +} + #[cfg(test)] pub mod tendermint_falsecoin_tests { use super::*; diff --git a/mm2src/kdf_walletconnect/src/chain/tendermint.rs b/mm2src/coins/tendermint/wallet_connect.rs similarity index 79% rename from mm2src/kdf_walletconnect/src/chain/tendermint.rs rename to mm2src/coins/tendermint/wallet_connect.rs index 7a9a48e075..de59a47232 100644 --- a/mm2src/kdf_walletconnect/src/chain/tendermint.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -1,70 +1,16 @@ -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; - -use base64::{engine::general_purpose, Engine}; +use base64::engine::general_purpose; +use base64::Engine; use chrono::Utc; use futures::StreamExt; -use mm2_err_handle::prelude::{MmError, MmResult}; -use relay_rpc::rpc::params::{session_request::{Request as SessionRequest, SessionRequestRequest}, - RequestParams, ResponseParamsSuccess}; +use kdf_walletconnect::error::WalletConnectError; +use kdf_walletconnect::{chain::WcRequestMethods, WalletConnectCtx}; +use mm2_err_handle::prelude::*; +use relay_rpc::rpc::params::session_request::Request as SessionRequest; +use relay_rpc::rpc::params::session_request::SessionRequestRequest; +use relay_rpc::rpc::params::{RequestParams, ResponseParamsSuccess}; use serde::{Deserialize, Serialize}; use serde_json::Value; -use super::WcRequestMethods; - -#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] -pub enum CosmosAccountAlgo { - #[serde(rename = "secp256k1")] - Secp256k1, - #[serde(rename = "tendermint/PubKeySecp256k1")] - TendermintSecp256k1, -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct CosmosAccount { - pub address: String, - #[serde(deserialize_with = "deserialize_vec_field")] - pub pubkey: Vec, - pub algo: CosmosAccountAlgo, -} - -pub async fn cosmos_get_accounts_impl( - ctx: &WalletConnectCtx, - chain_id: &str, -) -> MmResult, WalletConnectCtxError> { - let account = ctx.get_account_for_chain_id(chain_id).await?; - - let topic = match ctx.session.get_session_active().await { - Some(session) => session.topic.clone(), - None => return MmError::err(WalletConnectCtxError::NotInitialized), - }; - - let request = SessionRequest { - method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: serde_json::to_value(&account).unwrap(), - }; - let request = SessionRequestRequest { - request, - chain_id: format!("cosmos:{chain_id}"), - }; - - { - let session_request = RequestParams::SessionRequest(request); - ctx.publish_request(&topic, session_request).await?; - }; - - let mut session_handler = ctx.session_request_handler.lock().await; - if let Some((message_id, data)) = session_handler.next().await { - let result = serde_json::from_value::>(data)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&topic, response, &message_id).await?; - - return Ok(result); - }; - - MmError::err(WalletConnectCtxError::NoAccountFound(chain_id.to_owned())) -} - #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct CosmosTxSignedData { pub signature: CosmosTxSignature, @@ -95,23 +41,24 @@ pub struct CosmosSignData { pub body_bytes: Vec, } -pub async fn cosmos_sign_direct_impl( +pub async fn cosmos_request_wc_signed_tx( ctx: &WalletConnectCtx, sign_doc: Value, chain_id: &str, -) -> MmResult { - let topic = match ctx.session.get_session_active().await { - Some(session) => session.topic.clone(), - None => return MmError::err(WalletConnectCtxError::NotInitialized), - }; +) -> MmResult { + let topic = ctx + .session + .get_session_active() + .await + .map(|session| session.topic.clone()) + .ok_or(WalletConnectError::NotInitialized)?; - let request = SessionRequest { - method: WcRequestMethods::CosmosSignDirect.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: sign_doc, - }; let request = SessionRequestRequest { - request, + request: SessionRequest { + method: WcRequestMethods::CosmosSignDirect.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: sign_doc, + }, chain_id: format!("cosmos:{chain_id}"), }; { @@ -128,9 +75,72 @@ pub async fn cosmos_sign_direct_impl( return Ok(result); } - MmError::err(WalletConnectCtxError::InternalError( - "No response from wallet".to_string(), - )) + MmError::err(WalletConnectError::InternalError("No response from wallet".to_string())) +} + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] +pub enum CosmosAccountAlgo { + #[serde(rename = "secp256k1")] + Secp256k1, + #[serde(rename = "tendermint/PubKeySecp256k1")] + TendermintSecp256k1, +} + +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct CosmosAccount { + pub address: String, + #[serde(deserialize_with = "deserialize_vec_field")] + pub pubkey: Vec, + pub algo: CosmosAccountAlgo, +} + +pub async fn cosmos_get_accounts_impl( + ctx: &WalletConnectCtx, + chain_id: &str, + account_index: Option, +) -> MmResult { + let account = ctx.get_account_for_chain_id(chain_id).await?; + + let topic = ctx + .session + .get_session_active() + .await + .map(|session| session.topic.clone()) + .ok_or(WalletConnectError::NotInitialized)?; + + let request = SessionRequestRequest { + request: SessionRequest { + method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: serde_json::to_value(&account).unwrap(), + }, + chain_id: format!("cosmos:{chain_id}"), + }; + + { + let session_request = RequestParams::SessionRequest(request); + ctx.publish_request(&topic, session_request).await?; + }; + + let mut session_handler = ctx.session_request_handler.lock().await; + if let Some((message_id, data)) = session_handler.next().await { + let accounts = serde_json::from_value::>(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&topic, response, &message_id).await?; + + if accounts.is_empty() { + return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); + }; + + let account_index = account_index.unwrap_or(0); + if accounts.len() < account_index + 1 { + return MmError::err(WalletConnectError::NoAccountFoundForIndex(account_index)); + }; + + return Ok(accounts[account_index].clone()); + }; + + MmError::err(WalletConnectError::NoAccountFound(chain_id.to_owned())) } fn deserialize_vec_field<'de, D>(deserializer: D) -> Result, D::Error> @@ -187,8 +197,7 @@ fn decode_data(encoded: &str) -> Result, &'static str> { mod test_cosmos_walletconnect { use serde_json::json; - use crate::chain::tendermint::{decode_data, CosmosSignData, CosmosTxPublicKey, CosmosTxSignature, - CosmosTxSignedData}; + use super::{decode_data, CosmosSignData, CosmosTxPublicKey, CosmosTxSignature, CosmosTxSignedData}; #[test] fn test_decode_base64() { diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 0b70aeebef..d221637d2a 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -11,14 +11,14 @@ use async_trait::async_trait; use coins::hd_wallet::HDPathAccountToAddressId; use coins::my_tx_history_v2::TxHistoryStorage; use coins::tendermint::tendermint_tx_history_v2::tendermint_history_loop; -use coins::tendermint::{tendermint_priv_key_policy, RpcNode, TendermintActivationPolicy, TendermintCoin, - TendermintCommons, TendermintConf, TendermintInitError, TendermintInitErrorKind, - TendermintProtocolInfo, TendermintPublicKey, TendermintToken, TendermintTokenActivationParams, - TendermintTokenInitError, TendermintTokenProtocolInfo, TendermintWalletConnectionType}; +use coins::tendermint::{cosmos_get_accounts_impl, tendermint_priv_key_policy, CosmosAccountAlgo, RpcNode, + TendermintActivationPolicy, TendermintCoin, TendermintCommons, TendermintConf, + TendermintInitError, TendermintInitErrorKind, TendermintProtocolInfo, TendermintPublicKey, + TendermintToken, TendermintTokenActivationParams, TendermintTokenInitError, + TendermintTokenProtocolInfo, TendermintWalletConnectionType}; use coins::{CoinBalance, CoinProtocol, MarketCoinOps, MmCoin, MmCoinEnum, PrivKeyBuildPolicy}; use common::executor::{AbortSettings, SpawnAbortable}; use common::{true_f, Future01CompatExt}; -use kdf_walletconnect::chain::CosmosAccountAlgo; use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -251,10 +251,9 @@ async fn get_walletconnect_pubkey( }); }; - let walletconnect_ctx = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); - let account = walletconnect_ctx - .cosmos_get_account(param.account_index, chain_id) + let account = cosmos_get_accounts_impl(&wc, chain_id, Some(param.account_index)) .await .mm_err(|err| TendermintInitError { ticker: ticker.to_string(), @@ -271,7 +270,7 @@ async fn get_walletconnect_pubkey( kind: TendermintInitErrorKind::Internal(e), })?; - if walletconnect_ctx.is_ledger_connection().await { + if wc.is_ledger_connection().await { *wallet_type = TendermintWalletConnectionType::WcLedger; } else { *wallet_type = TendermintWalletConnectionType::Wc; diff --git a/mm2src/kdf_walletconnect/src/chain/mod.rs b/mm2src/kdf_walletconnect/src/chain.rs similarity index 92% rename from mm2src/kdf_walletconnect/src/chain/mod.rs rename to mm2src/kdf_walletconnect/src/chain.rs index d813aae034..47d998dc2f 100644 --- a/mm2src/kdf_walletconnect/src/chain/mod.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -1,10 +1,6 @@ -pub(crate) mod tendermint; use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; use std::collections::BTreeMap; -pub use tendermint::CosmosAccountAlgo; -pub(crate) use tendermint::*; - pub(crate) const SUPPORTED_EVENTS: &[&str] = &[]; pub(crate) const SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index b9fb7fa353..1c1b260e97 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -41,7 +41,7 @@ pub(crate) const UNSUPPORTED_NAMESPACE_KEY: i32 = 5104; pub(crate) const USER_REQUESTED: i64 = 6000; #[derive(Debug, Serialize, Deserialize, EnumFromStringify, thiserror::Error)] -pub enum WalletConnectCtxError { +pub enum WalletConnectError { #[error("Pairing Error: {0}")] #[from_stringify("PairingClientError")] PairingError(String), @@ -86,12 +86,12 @@ pub enum WalletConnectCtxError { ChainIdMismatch, } -impl From> for WalletConnectCtxError { - fn from(error: Error) -> Self { WalletConnectCtxError::PublishError(format!("{error:?}")) } +impl From> for WalletConnectError { + fn from(error: Error) -> Self { WalletConnectError::PublishError(format!("{error:?}")) } } -impl From> for WalletConnectCtxError { - fn from(error: Error) -> Self { WalletConnectCtxError::SubscriptionError(format!("{error:?}")) } +impl From> for WalletConnectError { + fn from(error: Error) -> Self { WalletConnectError::SubscriptionError(format!("{error:?}")) } } /// Session key and topic derivation errors. diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index cccf03a4e8..68c3673b19 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,4 +1,4 @@ -use crate::{error::WalletConnectCtxError, +use crate::{error::WalletConnectError, pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, session::rpc::{delete::reply_session_delete_request, event::reply_session_event_request, @@ -28,7 +28,7 @@ pub(crate) async fn process_inbound_request( ctx: &WalletConnectCtx, request: Request, topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let message_id = request.id; match request.params { Params::SessionPropose(proposal) => reply_session_proposal_request(ctx, proposal, topic, &message_id).await?, @@ -40,7 +40,7 @@ pub(crate) async fn process_inbound_request( Params::SessionEvent(param) => reply_session_event_request(ctx, topic, &message_id, param).await?, Params::SessionRequest(_param) => { // TODO: Implement when integrating KDF as a Dapp. - return MmError::err(WalletConnectCtxError::NotImplemented); + return MmError::err(WalletConnectError::NotImplemented); }, Params::PairingPing(_param) => reply_pairing_ping_response(ctx, topic, &message_id).await?, @@ -48,7 +48,7 @@ pub(crate) async fn process_inbound_request( Params::PairingExtend(param) => reply_pairing_extend_response(ctx, topic, &message_id, param).await?, _ => { info!("Unknown request params received."); - return MmError::err(WalletConnectCtxError::InvalidRequest); + return MmError::err(WalletConnectError::InvalidRequest); }, }; @@ -59,7 +59,7 @@ pub(crate) async fn process_inbound_response( ctx: &WalletConnectCtx, response: Response, topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let message_id = response.id(); match response { @@ -81,7 +81,7 @@ pub(crate) async fn process_inbound_response( | ResponseParamsSuccess::PairingDelete(success) | ResponseParamsSuccess::PairingPing(success) => { if !success { - return MmError::err(WalletConnectCtxError::UnSuccessfulResponse(format!( + return MmError::err(WalletConnectError::UnSuccessfulResponse(format!( "Unsuccessful response={params:?}" ))); }; diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index ff99b409df..5eb812098d 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -7,12 +7,13 @@ mod metadata; pub mod session; mod storage; -use chain::{build_required_namespaces, cosmos_get_accounts_impl, cosmos_sign_direct_impl, CosmosAccount, - CosmosTxSignedData, SUPPORTED_CHAINS}; +use crate::session::rpc::propose::send_proposal_request; + +use chain::{build_required_namespaces, SUPPORTED_CHAINS}; use common::log::info; use common::{executor::SpawnFuture, log::error}; use connection_handler::Handler; -use error::WalletConnectCtxError; +use error::WalletConnectError; use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; use futures::lock::Mutex; use futures::StreamExt; @@ -30,23 +31,21 @@ use relay_rpc::rpc::params::{IrnMetadata, Metadata, Relay, RelayProtocolMetadata ResponseParamsSuccess}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; use serde_json::Value; -use session::{key::SymKeyPair, SessionManagement}; +use session::{key::SymKeyPair, SessionManager}; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; -use crate::session::rpc::propose::send_proposal_request; - pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; -const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; // tendermint e.g ATOM +const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; type SessionEventMessage = (MessageId, Value); pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, - pub session: SessionManagement, + pub session: SessionManager, pub active_chain_id: Arc>, pub(crate) key_pair: SymKeyPair, @@ -59,17 +58,11 @@ pub struct WalletConnectCtx { inbound_message_handler: Arc>>, connection_live_handler: Arc>>, session_request_sender: Arc>>, - session_request_handler: Arc>>, -} - -impl Drop for WalletConnectCtx { - fn drop(&mut self) { - println!("drop"); - } + pub session_request_handler: Arc>>, } impl WalletConnectCtx { - pub fn try_init(ctx: &MmArc) -> MmResult { + pub fn try_init(ctx: &MmArc) -> MmResult { let (msg_sender, msg_receiver) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); let (session_request_sender, session_request_receiver) = unbounded(); @@ -89,7 +82,7 @@ impl WalletConnectCtx { Ok(Self { client, pairing, - session: SessionManagement::new(), + session: SessionManager::new(), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), relay, required_namespaces: required, @@ -104,14 +97,14 @@ impl WalletConnectCtx { }) } - pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectCtxError> { + pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectError> { from_ctx(&ctx.wallet_connect, move || { Self::try_init(ctx).map_err(|err| err.to_string()) }) - .map_to_mm(WalletConnectCtxError::InternalError) + .map_to_mm(WalletConnectError::InternalError) } - pub async fn connect_client(&self) -> MmResult<(), WalletConnectCtxError> { + pub async fn connect_client(&self) -> MmResult<(), WalletConnectError> { let auth = { let key = SigningKey::generate(&mut rand::thread_rng()); AuthToken::new(AUTH_TOKEN_SUB) @@ -131,7 +124,7 @@ impl WalletConnectCtx { pub async fn new_connection( &self, required_namespaces: Option, - ) -> MmResult { + ) -> MmResult { let (topic, url) = self.pairing.create(self.metadata.clone(), None).await?; info!("Subscribing to topic: {topic:?}"); @@ -171,55 +164,25 @@ impl WalletConnectCtx { pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } /// Retrieves the available account for a given chain ID. - pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { + pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { let active_chain_id = self.get_active_chain_id().await; if active_chain_id != chain_id { - return MmError::err(WalletConnectCtxError::ChainIdMismatch); + return MmError::err(WalletConnectError::ChainIdMismatch); } let namespaces = &self .session .get_session_active() .await - .ok_or(MmError::new(WalletConnectCtxError::NoAccountFound( - chain_id.to_string(), - )))? + .ok_or(MmError::new(WalletConnectError::NoAccountFound(chain_id.to_string())))? .namespaces; namespaces .iter() .find_map(|(_key, namespace)| find_account_in_namespace(namespace, chain_id)) - .ok_or(MmError::new(WalletConnectCtxError::NoAccountFound( - chain_id.to_string(), - ))) + .ok_or(MmError::new(WalletConnectError::NoAccountFound(chain_id.to_string()))) } - pub async fn cosmos_get_account( - &self, - account_index: usize, - chain_id: &str, - ) -> MmResult { - let accounts = cosmos_get_accounts_impl(self, chain_id).await?; - - if accounts.is_empty() { - return MmError::err(WalletConnectCtxError::EmptyAccount(chain_id.to_string())); - }; - - if accounts.len() < account_index + 1 { - return MmError::err(WalletConnectCtxError::NoAccountFoundForIndex(account_index)); - }; - - Ok(accounts[account_index].clone()) - } - - pub async fn cosmos_send_sign_tx_request( - &self, - sign_doc: Value, - chain_id: &str, - ) -> MmResult { - cosmos_sign_direct_impl(self, sign_doc, chain_id).await - } - - async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectCtxError> { + async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectError> { { if let Some(key) = self.session.sym_key(topic) { return Ok(key); @@ -234,11 +197,11 @@ impl WalletConnectCtx { } } - MmError::err(WalletConnectCtxError::PairingError(format!("Topic not found:{topic}"))) + MmError::err(WalletConnectError::PairingError(format!("Topic not found:{topic}"))) } - /// Private function to publish a request. - async fn publish_request(&self, topic: &Topic, param: RequestParams) -> MmResult<(), WalletConnectCtxError> { + /// function to publish a request. + pub async fn publish_request(&self, topic: &Topic, param: RequestParams) -> MmResult<(), WalletConnectError> { let irn_metadata = param.irn_metadata(); let message_id = MessageIdGenerator::new().next(); let request = Request::new(message_id, param.into()); @@ -251,12 +214,12 @@ impl WalletConnectCtx { } /// Private function to publish a success request response. - async fn publish_response_ok( + pub async fn publish_response_ok( &self, topic: &Topic, result: ResponseParamsSuccess, message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { + ) -> MmResult<(), WalletConnectError> { let irn_metadata = result.irn_metadata(); let value = serde_json::to_value(result)?; let response = Response::Success(SuccessfulResponse::new(*message_id, value)); @@ -272,7 +235,7 @@ impl WalletConnectCtx { topic: &Topic, error_data: ResponseParamsError, message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { + ) -> MmResult<(), WalletConnectError> { let error = error_data.error(); let irn_metadata = error_data.irn_metadata(); let response = Response::Error(ErrorResponse::new(*message_id, error)); @@ -288,7 +251,7 @@ impl WalletConnectCtx { topic: &Topic, irn_metadata: IrnMetadata, payload: Payload, - ) -> MmResult<(), WalletConnectCtxError> { + ) -> MmResult<(), WalletConnectError> { let sym_key = self.sym_key(topic).await?; let payload = serde_json::to_string(&payload)?; @@ -311,7 +274,7 @@ impl WalletConnectCtx { Ok(()) } - async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectCtxError> { + async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectError> { let message = { let key = self.sym_key(&msg.topic).await?; decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() @@ -330,13 +293,13 @@ impl WalletConnectCtx { Ok(()) } - async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectCtxError> { + async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectError> { let now = chrono::Utc::now().timestamp() as u64; let mut sessions = self .storage .get_all_sessions() .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); @@ -367,7 +330,7 @@ impl WalletConnectCtx { /// This function spwans related WalletConnect related tasks and needed initialization before /// WalletConnect can be usable in KDF. -pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectCtxError> { +pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectError> { info!("Initializing WalletConnect"); // Initialized WalletConnectCtx @@ -388,17 +351,16 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect // spawn message handler event loop ctx.spawner().spawn(async move { - let selfi = wallet_connect.clone(); + let this = wallet_connect.clone(); let mut recv = wallet_connect.inbound_message_handler.lock().await; while let Some(msg) = recv.next().await { - if let Err(e) = selfi.handle_published_message(msg).await { + if let Err(e) = this.handle_published_message(msg).await { info!("Error processing message: {:?}", e); } } }); info!("WalletConnect initialization completed successfully"); - Ok(()) } @@ -414,3 +376,16 @@ fn find_account_in_namespace(namespace: &Namespace, chain_id: &str) -> Option Result; +} diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index 4838074e4f..9fc3973d57 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -1,5 +1,5 @@ use crate::session::{WcRequestResponseResult, THIRTY_DAYS}; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; use mm2_err_handle::prelude::MmResult; @@ -14,7 +14,7 @@ pub(crate) async fn reply_pairing_ping_response( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let param = ResponseParamsSuccess::PairingPing(true); ctx.publish_response_ok(topic, param, message_id).await?; @@ -26,7 +26,7 @@ pub(crate) async fn reply_pairing_extend_response( topic: &Topic, message_id: &MessageId, extend: PairingExtendRequest, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { { let mut pairings = ctx.pairing.pairings.lock().await; if let Some(pairing) = pairings.get_mut(topic.as_ref()) { @@ -46,7 +46,7 @@ pub(crate) async fn reply_pairing_delete_response( topic: &Topic, message_id: &MessageId, _delete: PairingDeleteRequest, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { { ctx.pairing.disconnect(topic.as_ref(), &ctx.client).await?; } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index ec4c9a0a28..2a8125ad2a 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,7 +1,7 @@ pub(crate) mod key; pub mod rpc; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; use common::log::debug; @@ -10,7 +10,6 @@ use dashmap::DashMap; use futures::lock::Mutex; use key::SessionKey; use mm2_err_handle::prelude::MmResult; -use relay_client::websocket::Client; use relay_rpc::domain::Topic; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; @@ -26,7 +25,7 @@ use std::sync::Arc; pub(crate) const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; -pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectCtxError>; +pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectError>; /// In the WalletConnect protocol, a session involves two parties: a controller /// (typically a wallet) and a proposer (typically a dApp). This enum is used @@ -176,16 +175,16 @@ impl Session { /// Internal implementation of session management. #[derive(Default, Debug)] -struct SessionManagementImpl { +struct SessionManagerImpl { /// The currently active session topic. active_topic: Mutex>, /// A thread-safe map of sessions indexed by topic. sessions: DashMap, } -pub struct SessionManagement(Arc); +pub struct SessionManager(Arc); -impl Default for SessionManagement { +impl Default for SessionManager { fn default() -> Self { Self::new() } } @@ -204,7 +203,7 @@ impl From for SessionRpcInfo { } #[allow(unused)] -impl SessionManagement { +impl SessionManager { pub fn new() -> Self { Self(Default::default()) } /// Inserts the provided `Session` into the session store, associated with the specified topic. @@ -314,14 +313,20 @@ impl SessionManagement { .map(|k| k.session_key.symmetric_key().to_vec()) } - pub async fn disconnect_session(&self, topic: &Topic, client: &Client) -> MmResult<(), WalletConnectCtxError> { - client.unsubscribe(topic.clone()).await?; + async fn disconnect_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { self.delete_session(topic).await; Ok(()) } } +pub async fn disconnect_session_rpc_rpc(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { + ctx.client.unsubscribe(topic.clone()).await?; + ctx.session.delete_session(topic).await; + + Ok(()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 2d2c18be9a..270ff078fc 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -1,4 +1,4 @@ -use crate::{error::{WalletConnectCtxError, USER_REQUESTED}, +use crate::{error::{WalletConnectError, USER_REQUESTED}, storage::WalletConnectStorageOps, WalletConnectCtx}; @@ -12,7 +12,7 @@ pub(crate) async fn reply_session_delete_request( topic: &Topic, message_id: &MessageId, _delete_params: SessionDeleteRequest, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let param = ResponseParamsSuccess::SessionDelete(true); ctx.publish_response_ok(topic, param, message_id).await?; @@ -22,7 +22,7 @@ pub(crate) async fn reply_session_delete_request( pub async fn send_session_delete_request( ctx: &WalletConnectCtx, session_topic: &Topic, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let delete_request = SessionDeleteRequest { code: USER_REQUESTED, message: "User Disconnected".to_owned(), @@ -34,7 +34,7 @@ pub async fn send_session_delete_request( session_delete_cleanup(ctx, session_topic).await } -async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectCtxError> { +async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { { ctx.client.unsubscribe(topic.clone()).await?; }; @@ -57,7 +57,7 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu ctx.storage .delete_session(topic) .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; }; Ok(()) diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 26c116ac09..869c3408a4 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -1,4 +1,4 @@ -use crate::{error::{WalletConnectCtxError, INVALID_EVENT, UNSUPPORTED_CHAINS}, +use crate::{error::{WalletConnectError, INVALID_EVENT, UNSUPPORTED_CHAINS}, WalletConnectCtx}; use mm2_err_handle::prelude::MmResult; @@ -17,14 +17,14 @@ pub(crate) async fn reply_session_event_request( topic: &Topic, message_id: &MessageId, event: SessionEventRequest, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { SessionEvent::from_event(event)? .handle_session_event(ctx, topic, message_id) .await } impl SessionEvent { - pub fn from_event(event: SessionEventRequest) -> MmResult { + pub fn from_event(event: SessionEventRequest) -> MmResult { match event.event.name.as_str() { "chainChanged" => Ok(SessionEvent::ChainChanged(event.chain_id)), "accountsChanged" => { @@ -40,7 +40,7 @@ impl SessionEvent { ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { + ) -> MmResult<(), WalletConnectError> { match &self { SessionEvent::ChainChanged(chain_id) => { Self::handle_chain_changed_event(ctx, chain_id, topic, message_id).await @@ -67,7 +67,7 @@ impl SessionEvent { chain_id: &str, topic: &Topic, message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { + ) -> MmResult<(), WalletConnectError> { if ctx.is_chain_supported(chain_id) { if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { if let Some(session) = ctx.session.get_session_active().await { @@ -104,7 +104,7 @@ impl SessionEvent { _data: &[String], topic: &Topic, message_id: &MessageId, - ) -> MmResult<(), WalletConnectCtxError> { + ) -> MmResult<(), WalletConnectError> { // TODO: Handle account change logic. //TODO: Notify about account changed. diff --git a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs index e187dc4c24..2b566755aa 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs @@ -1,4 +1,4 @@ -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtx}; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, @@ -10,7 +10,7 @@ pub(crate) async fn reply_session_extend_request( topic: &Topic, message_id: &MessageId, extend: SessionExtendRequest, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { ctx.session.extend_session(topic, extend.expiry); let param = ResponseParamsSuccess::SessionExtend(true); diff --git a/mm2src/kdf_walletconnect/src/session/rpc/mod.rs b/mm2src/kdf_walletconnect/src/session/rpc/mod.rs index 83aeef1f76..b94443c191 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/mod.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/mod.rs @@ -5,3 +5,5 @@ pub mod ping; pub(crate) mod propose; pub(crate) mod settle; pub(crate) mod update; + +pub use ping::*; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs index 55ff2af13b..8009b309e9 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs @@ -1,4 +1,4 @@ -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtx}; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, @@ -8,14 +8,14 @@ pub(crate) async fn reply_session_ping_request( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let param = ResponseParamsSuccess::SessionPing(true); ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) } -pub async fn send_session_ping_request(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectCtxError> { +pub async fn send_session_ping_request(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { let param = RequestParams::SessionPing(()); ctx.publish_request(topic, param).await?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index bac64457e7..4d31d530c1 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,6 +1,6 @@ use super::settle::send_session_settle_request; use crate::storage::WalletConnectStorageOps; -use crate::{error::WalletConnectCtxError, +use crate::{error::WalletConnectError, metadata::generate_metadata, session::{Session, SessionKey, SessionType, THIRTY_DAYS}, WalletConnectCtx}; @@ -18,7 +18,7 @@ pub(crate) async fn send_proposal_request( ctx: &WalletConnectCtx, topic: Topic, required_namespaces: Option, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let proposer = Proposer { metadata: ctx.metadata.clone(), public_key: hex::encode(ctx.key_pair.public_key.as_bytes()), @@ -41,7 +41,7 @@ pub async fn reply_session_proposal_request( proposal: SessionProposeRequest, topic: &Topic, message_id: &MessageId, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let sender_public_key = hex::decode(&proposal.proposer.public_key)? .as_slice() .try_into() @@ -53,7 +53,7 @@ pub async fn reply_session_proposal_request( .client .subscribe(session_topic.clone()) .await - .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + .map_to_mm(|err| WalletConnectError::SubscriptionError(err.to_string()))?; let session = Session::new( ctx, @@ -67,14 +67,14 @@ pub async fn reply_session_proposal_request( session .propose_namespaces .supported(&proposal.required_namespaces) - .map_to_mm(|err| WalletConnectCtxError::InternalError(err.to_string()))?; + .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))?; { // save session to storage ctx.storage .save_session(&session) .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Add session to session lists ctx.session.add_session(session.clone()).await; @@ -103,7 +103,7 @@ pub(crate) async fn process_session_propose_response( ctx: &WalletConnectCtx, pairing_topic: &Topic, response: SessionProposeResponse, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let other_public_key = hex::decode(&response.responder_public_key)? .as_slice() .try_into() @@ -117,7 +117,7 @@ pub(crate) async fn process_session_propose_response( .client .subscribe(session_topic.clone()) .await - .map_to_mm(|err| WalletConnectCtxError::SubscriptionError(err.to_string()))?; + .map_to_mm(|err| WalletConnectError::SubscriptionError(err.to_string()))?; let mut session = Session::new( ctx, @@ -137,7 +137,7 @@ pub(crate) async fn process_session_propose_response( ctx.storage .save_session(&session) .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Add session to session lists ctx.session.add_session(session.clone()).await; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index bf00eebbdf..009ba258bf 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -1,7 +1,7 @@ use crate::chain::{SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; use crate::session::{Session, SessionProperties, THIRTY_DAYS}; use crate::storage::WalletConnectStorageOps; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; use common::log::info; @@ -15,7 +15,7 @@ use std::collections::BTreeMap; pub(crate) async fn send_session_settle_request( ctx: &WalletConnectCtx, session_info: &Session, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { let mut settled_namespaces = BTreeMap::::new(); settled_namespaces.insert("eip155".to_string(), Namespace { chains: Some(SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect()), @@ -43,7 +43,7 @@ pub(crate) async fn reply_session_settle_request( topic: &Topic, message_id: &MessageId, settle: SessionSettleRequest, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { { let session = ctx.session.get_session_mut(topic).await; if let Some(mut session) = session { @@ -60,7 +60,7 @@ pub(crate) async fn reply_session_settle_request( ctx.storage .update_session(&session) .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; } } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index 7c3b94e4a9..bc77a63f43 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -1,5 +1,5 @@ use crate::storage::WalletConnectStorageOps; -use crate::{error::WalletConnectCtxError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtx}; use common::log::info; use mm2_err_handle::prelude::*; @@ -13,7 +13,7 @@ pub(crate) async fn reply_session_update_request( topic: &Topic, message_id: &MessageId, update: SessionUpdateRequest, -) -> MmResult<(), WalletConnectCtxError> { +) -> MmResult<(), WalletConnectError> { { if let Some(mut session) = ctx.session.get_session_mut(topic).await { session.namespaces = update.namespaces.0; @@ -21,7 +21,7 @@ pub(crate) async fn reply_session_update_request( ctx.storage .update_session(&session) .await - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; info!("Updated extended, info: {:?}", session); }; diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 6ba4476de4..6fa393d1a5 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -6,7 +6,7 @@ use mm2_err_handle::prelude::MmResult; use mm2_err_handle::prelude::*; use relay_rpc::domain::Topic; -use crate::{error::WalletConnectCtxError, session::Session}; +use crate::{error::WalletConnectError, session::Session}; #[cfg(target_arch = "wasm32")] pub(crate) mod indexed_db; #[cfg(not(target_arch = "wasm32"))] pub(crate) mod sqlite; @@ -37,12 +37,12 @@ impl Deref for SessionStorageDb { } impl SessionStorageDb { - pub(crate) fn init(ctx: &MmArc) -> MmResult { + pub(crate) fn init(ctx: &MmArc) -> MmResult { #[cfg(target_arch = "wasm32")] let db = indexed_db::IDBSessionStorage::new(ctx) - .mm_err(|err| WalletConnectCtxError::StorageError(err.to_string()))?; + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; #[cfg(not(target_arch = "wasm32"))] - let db = sqlite::SqliteSessionStorage::new(ctx).mm_err(WalletConnectCtxError::StorageError)?; + let db = sqlite::SqliteSessionStorage::new(ctx).mm_err(WalletConnectError::StorageError)?; Ok(SessionStorageDb(db)) } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/ping.rs b/mm2src/mm2_main/src/rpc/wc_commands/ping.rs deleted file mode 100644 index 8f8c2d2f95..0000000000 --- a/mm2src/mm2_main/src/rpc/wc_commands/ping.rs +++ /dev/null @@ -1,28 +0,0 @@ -use kdf_walletconnect::session::rpc::ping::send_session_ping_request; -use kdf_walletconnect::WalletConnectCtx; -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::*; -use serde::{Deserialize, Serialize}; - -use super::WalletConnectRpcError; - -#[derive(Debug, PartialEq, Serialize)] -pub struct SessionPingResponse { - pub successful: bool, -} - -#[derive(Deserialize)] -pub struct SessionPingRequest { - topic: String, -} - -/// `ping session` RPC command implementation. -pub async fn ping_session(ctx: MmArc, req: SessionPingRequest) -> MmResult { - let ctx = - WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - send_session_ping_request(&ctx, &req.topic.into()) - .await - .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; - - Ok(SessionPingResponse { successful: true }) -} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 809d9b307e..6b73d8246c 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -1,4 +1,6 @@ -use kdf_walletconnect::{session::SessionRpcInfo, WalletConnectCtx}; +use kdf_walletconnect::session::SessionRpcInfo; +use kdf_walletconnect::session::{disconnect_session_rpc_rpc, rpc::send_session_ping_request}; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; use serde::Serialize; @@ -37,7 +39,7 @@ pub struct GetSessionRequest { topic: String, } -/// `Get all sessions connection` RPC command implementation. +/// `Get session connection` RPC command implementation. pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; @@ -49,17 +51,32 @@ pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - ctx.session - .disconnect_session(&req.topic.into(), &ctx.client) + disconnect_session_rpc_rpc(&ctx, &req.topic.into()) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; Ok(EmptyRpcResponse {}) } + +#[derive(Debug, PartialEq, Serialize)] +pub struct SessionPingResponse { + pub successful: bool, +} + +/// `ping session` RPC command implementation. +pub async fn ping_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + send_session_ping_request(&ctx, &req.topic.into()) + .await + .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; + + Ok(SessionPingResponse { successful: true }) +} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs index 9a96ae4225..cd2ef9e7bd 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs @@ -1,7 +1,6 @@ mod delete_connection; mod get_chain_id; mod new_connection; -mod ping; mod sessions; use common::HttpStatusCode; @@ -10,7 +9,6 @@ use derive_more::Display; pub use get_chain_id::get_chain_id; use http::StatusCode; pub use new_connection::new_connection; -pub use ping::ping_session; use serde::Deserialize; pub use sessions::*; From 6501134d9ccc754efee794f94a8e0b2b1873382d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 21 Oct 2024 05:19:06 +0100 Subject: [PATCH 071/125] commit cargo.lock --- Cargo.lock | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.lock b/Cargo.lock index c4bef16cc0..c3ac18236f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -910,6 +910,7 @@ dependencies = [ "proxy_signature", "rand 0.7.3", "regex", + "relay_rpc", "reqwest", "rlp", "rmp-serde", From 38dadbe28356fd8417855a832ebe6dd7fadc9a68 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 21 Oct 2024 15:14:18 +0100 Subject: [PATCH 072/125] implement cosmos ledger amino sign support --- mm2src/coins/tendermint/tendermint_coin.rs | 68 +++++++++++++------ mm2src/coins/tendermint/wallet_connect.rs | 52 +++++++++++++- .../src/tendermint_with_assets_activation.rs | 14 ++-- mm2src/kdf_walletconnect/src/chain.rs | 3 + mm2src/kdf_walletconnect/src/lib.rs | 5 +- 5 files changed, 108 insertions(+), 34 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 619c17745a..d441ce244f 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -882,7 +882,7 @@ impl TendermintCoin { } } - async fn request_wc_tx_signing(&self, tx_json: serde_json::Value) -> Result { + async fn wc_signed_tx(&self, tx_json: serde_json::Value) -> Result { let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); let wc = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); @@ -910,10 +910,13 @@ impl TendermintCoin { match self.wallet_type { TendermintWalletConnectionType::Wc | TendermintWalletConnectionType::WcLedger => { // Handle WalletConnect signing - let SerializedUnsignedTx { tx_json, body_bytes: _ } = - try_tx_s!(self.any_to_serialized_sign_doc(account_info, tx_payload, fee, timeout_height, memo)); + let SerializedUnsignedTx { tx_json, .. } = if self.is_ledger_connection() { + try_tx_s!(self.any_to_legacy_amino_json(account_info, tx_payload, fee, timeout_height, memo)) + } else { + try_tx_s!(self.any_to_serialized_sign_doc(account_info, tx_payload, fee, timeout_height, memo)) + }; - self.request_wc_tx_signing(tx_json).await + self.wc_signed_tx(tx_json).await }, _ => { // Handle local signing @@ -1467,8 +1470,6 @@ impl TendermintCoin { let msg_send = MsgSend::from_any(&tx_payload)?; let timeout_height = u32::try_from(timeout_height)?; - let original_tx_type_url = tx_payload.type_url.clone(); - let body_bytes = tx::Body::new(vec![tx_payload], &memo, timeout_height).into_bytes()?; let amount: Vec = msg_send .amount @@ -1505,20 +1506,47 @@ impl TendermintCoin { }) .collect(); - let tx_json = serde_json::json!({ - "legacy_amino_json": { - "account_number": account_info.account_number.to_string(), - "chain_id": self.chain_id.to_string(), - "fee": { - "amount": fee_amount, - "gas": fee.gas_limit.to_string() - }, - "memo": memo, - "msgs": [msg], - "sequence": account_info.sequence.to_string(), + let (tx_json, body_bytes) = match self.wallet_type { + TendermintWalletConnectionType::WcLedger => { + let signer_address = self.my_address().unwrap(); + let body_bytes = tx::Body::new(vec![tx_payload], &memo, timeout_height).into_bytes()?; + let json = serde_json::json!({ + "signerAddress": signer_address, + "signDoc": { + "account_number": account_info.account_number.to_string(), + "chain_id": self.chain_id.to_string(), + "fee": { + "amount": fee_amount, + "gas": fee.gas_limit.to_string() + }, + "memo": memo, + "msgs": [msg], + "sequence": account_info.sequence.to_string(), + }, + }); + (json, body_bytes) }, - "original_tx_type_url": original_tx_type_url, - }); + TendermintWalletConnectionType::KeplrLedger => { + let original_tx_type_url = tx_payload.type_url.clone(); + let body_bytes = tx::Body::new(vec![tx_payload], &memo, timeout_height).into_bytes()?; + let json = serde_json::json!({ + "legacy_amino_json": { + "account_number": account_info.account_number.to_string(), + "chain_id": self.chain_id.to_string(), + "fee": { + "amount": fee_amount, + "gas": fee.gas_limit.to_string() + }, + "memo": memo, + "msgs": [msg], + "sequence": account_info.sequence.to_string(), + }, + "original_tx_type_url": original_tx_type_url, + }); + (json, body_bytes) + }, + _ => unreachable!(), + }; Ok(SerializedUnsignedTx { tx_json, body_bytes }) } @@ -3458,7 +3486,7 @@ impl WcRequestOps for TendermintCoin { chain_id: &str, tx_json: serde_json::Value, ) -> Result { - cosmos_request_wc_signed_tx(ctx, tx_json, chain_id).await + cosmos_request_wc_signed_tx(ctx, tx_json, chain_id, self.is_ledger_connection()).await } } diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index de59a47232..bc72356337 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -1,3 +1,5 @@ +use std::str::FromStr; + use base64::engine::general_purpose; use base64::Engine; use chrono::Utc; @@ -45,6 +47,7 @@ pub async fn cosmos_request_wc_signed_tx( ctx: &WalletConnectCtx, sign_doc: Value, chain_id: &str, + is_ledger_conn: bool, ) -> MmResult { let topic = ctx .session @@ -53,9 +56,14 @@ pub async fn cosmos_request_wc_signed_tx( .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; + let method = if is_ledger_conn { + WcRequestMethods::CosmosSignAmino + } else { + WcRequestMethods::CosmosSignDirect + }; let request = SessionRequestRequest { request: SessionRequest { - method: WcRequestMethods::CosmosSignDirect.as_ref().to_owned(), + method: method.as_ref().to_owned(), expiry: Some(Utc::now().timestamp() as u64 + 300), params: sign_doc, }, @@ -86,12 +94,26 @@ pub enum CosmosAccountAlgo { TendermintSecp256k1, } +impl FromStr for CosmosAccountAlgo { + type Err = String; + + fn from_str(s: &str) -> Result { + match s { + "secp256k1" => Ok(Self::Secp256k1), + "tendermint/PubKeySecp256k1" => Ok(Self::TendermintSecp256k1), + _ => Err(format!("Unknown pubkey type: {s}")), + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct CosmosAccount { pub address: String, #[serde(deserialize_with = "deserialize_vec_field")] pub pubkey: Vec, pub algo: CosmosAccountAlgo, + #[serde(default)] + pub is_ledger: Option, } pub async fn cosmos_get_accounts_impl( @@ -101,13 +123,37 @@ pub async fn cosmos_get_accounts_impl( ) -> MmResult { let account = ctx.get_account_for_chain_id(chain_id).await?; - let topic = ctx + let session = ctx .session .get_session_active() .await - .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; + // Check if existing session has session_properties and return wallet account; + if let Some(props) = &session.session_properties { + if let Some(keys) = &props.keys { + if let Some(key) = keys.iter().next() { + let pubkey = decode_data(&key.pub_key).map_to_mm(|err| { + WalletConnectError::PayloadError(format!("error decoding pubkey payload: {err:?}")) + })?; + let address = decode_data(&key.address).map_to_mm(|err| { + WalletConnectError::PayloadError(format!("error decoding address payload: {err:?}")) + })?; + let address = hex::encode(address); + let algo = CosmosAccountAlgo::from_str(&key.algo).map_to_mm(|err| { + WalletConnectError::PayloadError(format!("error decoding algo payload: {err:?}")) + })?; + + return Ok(CosmosAccount { + address, + pubkey, + algo, + is_ledger: Some(key.is_nano_ledger), + }); + } + } + } + let topic = session.topic.clone(); let request = SessionRequestRequest { request: SessionRequest { method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index d221637d2a..b54aad9370 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -244,13 +244,6 @@ async fn get_walletconnect_pubkey( ticker: &str, wallet_type: &mut TendermintWalletConnectionType, ) -> MmResult { - if ctx.is_watcher() || ctx.use_watchers() { - return MmError::err(TendermintInitError { - ticker: ticker.to_string(), - kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, - }); - }; - let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); let account = cosmos_get_accounts_impl(&wc, chain_id, Some(param.account_index)) @@ -320,6 +313,13 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { TendermintActivationPolicy::with_public_key(pubkey) }, TendermintPubkeyActivationParams::WalletConnect(params) => { + if ctx.is_watcher() || ctx.use_watchers() { + return MmError::err(TendermintInitError { + ticker: ticker.to_string(), + kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, + }); + }; + get_walletconnect_pubkey( &ctx, ¶ms, diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index 47d998dc2f..ebcc5b00f8 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -1,9 +1,12 @@ use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; use std::collections::BTreeMap; +pub(crate) const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; + pub(crate) const SUPPORTED_EVENTS: &[&str] = &[]; pub(crate) const SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; +pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; #[derive(Debug, Clone)] pub enum WcRequestMethods { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 5eb812098d..34f9df4428 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -9,7 +9,7 @@ mod storage; use crate::session::rpc::propose::send_proposal_request; -use chain::{build_required_namespaces, SUPPORTED_CHAINS}; +use chain::{build_required_namespaces, DEFAULT_CHAIN_ID, SUPPORTED_CHAINS, SUPPORTED_PROTOCOL}; use common::log::info; use common::{executor::SpawnFuture, log::error}; use connection_handler::Handler; @@ -37,9 +37,6 @@ use storage::SessionStorageDb; use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; -pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; -const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; - type SessionEventMessage = (MessageId, Value); pub struct WalletConnectCtx { From 301a5b0efc612cbf6dff9fc8a32f8993fc29ab40 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 21 Oct 2024 15:35:43 +0100 Subject: [PATCH 073/125] fix fmt --- mm2src/kdf_walletconnect/src/storage/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 6fa393d1a5..4ceba70965 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -39,8 +39,8 @@ impl Deref for SessionStorageDb { impl SessionStorageDb { pub(crate) fn init(ctx: &MmArc) -> MmResult { #[cfg(target_arch = "wasm32")] - let db = indexed_db::IDBSessionStorage::new(ctx) - .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; + let db = + indexed_db::IDBSessionStorage::new(ctx).mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; #[cfg(not(target_arch = "wasm32"))] let db = sqlite::SqliteSessionStorage::new(ctx).mm_err(WalletConnectError::StorageError)?; From 3cde05b7cd81a754fa2c2684b98fcfeca40390e0 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 22 Oct 2024 02:26:27 +0100 Subject: [PATCH 074/125] start eth pubkey mode impl --- mm2src/coins/eth.rs | 6 ++++++ mm2src/coins/eth/v2_activation.rs | 1 + mm2src/coins_activation/src/eth_with_token_activation.rs | 1 + 3 files changed, 8 insertions(+) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index a6cd170627..979b283a79 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -586,6 +586,12 @@ pub enum EthPrivKeyBuildPolicy { #[cfg(target_arch = "wasm32")] Metamask(MetamaskArc), Trezor, + PubKeyMode { + eth_account: Address, + eth_account_str: String, + /// Please note that this is a normal version of public key (uncompressed). + eth_account_pubkey: H520, + }, } impl EthPrivKeyBuildPolicy { diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 15af41b3c2..129a279395 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -157,6 +157,7 @@ pub enum EthPrivKeyActivationPolicy { Trezor, #[cfg(target_arch = "wasm32")] Metamask, + WalletConnect, } impl EthPrivKeyActivationPolicy { diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index 8cee5094f2..85cedeee0d 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -466,5 +466,6 @@ fn eth_priv_key_build_policy( Ok(EthPrivKeyBuildPolicy::Metamask(metamask_ctx)) }, EthPrivKeyActivationPolicy::Trezor => Ok(EthPrivKeyBuildPolicy::Trezor), + EthPrivKeyActivationPolicy::WalletConnect => todo!(), } } From 5eb3e4c8e923eaba98c49433a480a1c5ec27697f Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 22 Oct 2024 16:52:12 +0100 Subject: [PATCH 075/125] save progress - impl wc eth_personal sign --- mm2src/coins/eth.rs | 35 ++++++-- mm2src/coins/eth/eth_withdraw.rs | 3 + mm2src/coins/eth/v2_activation.rs | 8 +- mm2src/coins/eth/wallet_connect.rs | 93 ++++++++++++++++++++++ mm2src/coins/lp_coins.rs | 10 ++- mm2src/coins/tendermint/tendermint_coin.rs | 1 + mm2src/coins/utxo/utxo_common.rs | 5 ++ mm2src/coins/utxo/utxo_withdraw.rs | 5 ++ mm2src/kdf_walletconnect/src/chain.rs | 13 ++- 9 files changed, 160 insertions(+), 13 deletions(-) create mode 100644 mm2src/coins/eth/wallet_connect.rs diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 979b283a79..6c7c7c830d 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -76,6 +76,8 @@ use futures::future::{join, join_all, select_ok, try_join_all, Either, FutureExt use futures01::Future; use http::Uri; use instant::Instant; +use kdf_walletconnect::error::WalletConnectError; +use kdf_walletconnect::{WalletConnectCtx, WcRequestOps}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; use mm2_number::bigdecimal_custom::CheckedDivision; @@ -138,6 +140,7 @@ mod eth_rpc; #[cfg(target_arch = "wasm32")] mod eth_wasm_tests; #[cfg(any(test, target_arch = "wasm32"))] mod for_tests; pub(crate) mod nft_swap_v2; +mod wallet_connect; mod web3_transport; use web3_transport::{http_transport::HttpTransportNode, Web3Transport}; @@ -586,12 +589,7 @@ pub enum EthPrivKeyBuildPolicy { #[cfg(target_arch = "wasm32")] Metamask(MetamaskArc), Trezor, - PubKeyMode { - eth_account: Address, - eth_account_str: String, - /// Please note that this is a normal version of public key (uncompressed). - eth_account_pubkey: H520, - }, + WalletConnect, } impl EthPrivKeyBuildPolicy { @@ -1370,9 +1368,10 @@ impl SwapOps for EthCoin { activated_key: ref key_pair, .. } => key_pair_from_secret(key_pair.secret().as_bytes()).expect("valid key"), - EthPrivKeyPolicy::Trezor => todo!(), + EthPrivKeyPolicy::Trezor | EthPrivKeyPolicy::WalletConnect(_) => todo!(), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => todo!(), + EthPrivKeyPolicy::WalletConnect(_) => todo!(), } } @@ -1390,6 +1389,7 @@ impl SwapOps for EthCoin { EthPrivKeyPolicy::Trezor => todo!(), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(ref metamask_policy) => metamask_policy.public_key.as_bytes().to_vec(), + EthPrivKeyPolicy::WalletConnect(pubkey) => pubkey.to_bytes().to_vec(), } } @@ -2161,6 +2161,7 @@ impl MarketCoinOps for EthCoin { EthPrivKeyPolicy::Metamask(ref metamask_policy) => { Ok(format!("{:02x}", metamask_policy.public_key_uncompressed)) }, + EthPrivKeyPolicy::WalletConnect(_) => todo!(), } } @@ -2480,6 +2481,7 @@ impl MarketCoinOps for EthCoin { EthPrivKeyPolicy::Trezor => ERR!("'display_priv_key' is not supported for Hardware Wallets"), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => ERR!("'display_priv_key' is not supported for MetaMask"), + EthPrivKeyPolicy::WalletConnect(_) => todo!(), } } @@ -2690,6 +2692,9 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw EthPrivKeyPolicy::Trezor => MmError::err(RawTransactionError::InvalidParam( "sign raw eth tx not implemented for Trezor".into(), )), + EthPrivKeyPolicy::WalletConnect(_) => MmError::err(RawTransactionError::InvalidParam( + "sign raw eth tx not implemented for WalletConnect".into(), + )), } } @@ -3639,6 +3644,7 @@ impl EthCoin { EthPrivKeyPolicy::Metamask(_) => { sign_and_send_transaction_with_metamask(coin, value, action, data, gas).await }, + EthPrivKeyPolicy::WalletConnect(_) => todo!(), } }; Box::new(fut.boxed().compat()) @@ -7180,6 +7186,7 @@ impl CommonSwapOpsV2 for EthCoin { .expect("slice with incorrect length"); Public::from_slice(&pubkey_bytes) }, + EthPrivKeyPolicy::WalletConnect(pubkey) => pubkey, } } @@ -7224,3 +7231,17 @@ impl EthCoin { EthCoin(Arc::new(coin)) } } + +#[async_trait::async_trait] +impl WcRequestOps for EthCoin { + type Error = WalletConnectError; + type SignTxData = String; + async fn wc_request_sign_tx( + &self, + _ctx: &WalletConnectCtx, + _chain_id: &str, + _tx_json: serde_json::Value, + ) -> Result { + todo!() + } +} diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index b3de177a89..f9bf9b3b1e 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -139,6 +139,7 @@ where let bytes = rlp::encode(&signed); Ok((signed.tx_hash(), BytesJson::from(bytes.to_vec()))) }, + EthPrivKeyPolicy::WalletConnect(_) => todo!(), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => MmError::err(WithdrawError::InternalError("invalid policy".to_owned())), } @@ -181,6 +182,7 @@ where EthPrivKeyPolicy::Iguana(_) | EthPrivKeyPolicy::HDWallet { .. } | EthPrivKeyPolicy::Trezor => { MmError::err(WithdrawError::InternalError("invalid policy".to_owned())) }, + EthPrivKeyPolicy::WalletConnect(_) => todo!(), } } @@ -292,6 +294,7 @@ where }; self.send_withdraw_tx(&req, tx_to_send).await? }, + EthPrivKeyPolicy::WalletConnect(_) => todo!(), }; self.on_finishing()?; diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 129a279395..63a39033e9 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -162,6 +162,7 @@ pub enum EthPrivKeyActivationPolicy { impl EthPrivKeyActivationPolicy { pub fn is_hw_policy(&self) -> bool { matches!(self, EthPrivKeyActivationPolicy::Trezor) } + pub fn is_wc_policy(&self) -> bool { matches!(self, EthPrivKeyActivationPolicy::WalletConnect) } } #[derive(Clone, Debug, Deserialize, Serialize, Default)] @@ -596,7 +597,8 @@ pub async fn eth_coin_from_conf_and_request_v2( let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; let web3_instances = match (req.rpc_mode, &priv_key_policy) { (EthRpcMode::Default, EthPrivKeyPolicy::Iguana(_) | EthPrivKeyPolicy::HDWallet { .. }) - | (EthRpcMode::Default, EthPrivKeyPolicy::Trezor) => { + | (EthRpcMode::Default, EthPrivKeyPolicy::Trezor) + | (EthRpcMode::Default, EthPrivKeyPolicy::WalletConnect(_)) => { build_web3_instances(ctx, ticker.to_string(), req.nodes.clone()).await? }, #[cfg(target_arch = "wasm32")] @@ -779,6 +781,10 @@ pub(crate) async fn build_address_and_priv_key_policy( DerivationMethod::SingleAddress(address), )) }, + EthPrivKeyBuildPolicy::WalletConnect => { + // request walletconnect eth pubkey + todo!() + }, } } diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs new file mode 100644 index 0000000000..56e3db96e4 --- /dev/null +++ b/mm2src/coins/eth/wallet_connect.rs @@ -0,0 +1,93 @@ +use std::str::FromStr; + +use async_std::stream::StreamExt; +use chrono::Utc; +use derive_more::Display; +use ethereum_types::{Address, Public, H160, H256}; +use ethkey::{public_to_address, recover, Message, Signature}; +use kdf_walletconnect::{chain::{WcRequestMethods, ETH_CHAIN_ID}, + error::WalletConnectError, + WalletConnectCtx}; +use mm2_err_handle::prelude::*; +use relay_rpc::rpc::params::session_request::SessionRequestRequest; +use relay_rpc::rpc::params::{session_request::Request as SessionRequest, RequestParams, ResponseParamsSuccess}; +use web3::helpers; + +#[derive(Display, Debug)] +pub enum EthWalletConnectError { + InvalidSignature(String), + AccoountMisMatch(String), +} + +pub async fn eth_request_wc_personal( + ctx: &WalletConnectCtx, + chain_id: &str, +) -> MmResult<(Public, Address), WalletConnectError> { + let topic = ctx + .session + .get_session_active() + .await + .map(|session| session.topic.clone()) + .ok_or(WalletConnectError::NotInitialized)?; + + let full_chain_id = format!("{ETH_CHAIN_ID}:{chain_id}"); + + let account_str = ctx.get_account_for_chain_id(&full_chain_id).await?; + let account = helpers::serialize(&account_str); + let message_str = "KDF: Verify that this account is yours"; + let message = helpers::serialize(&message_str); + + let params = json!(&[&account, &message]); + + let request = SessionRequestRequest { + request: SessionRequest { + method: WcRequestMethods::PersonalSign.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params, + }, + chain_id: full_chain_id, + }; + { + let session_request = RequestParams::SessionRequest(request); + ctx.publish_request(&topic, session_request).await?; + } + + let mut session_handler = ctx.session_request_handler.lock().await; + if let Some((message_id, data)) = session_handler.next().await { + let result = serde_json::from_value::(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&topic, response, &message_id).await?; + + let hash = Message::from_str(&hex::encode(message_str)).expect("valid message hash"); + + return get_pubkey_from_signature(&result, &hash, &account_str) + .mm_err(|err| WalletConnectError::PayloadError(err.to_string())); + } + + MmError::err(WalletConnectError::InternalError("No response from wallet".to_string())) +} + +fn get_pubkey_from_signature( + signature: &str, + hash: &H256, + account: &str, +) -> MmResult<(Public, Address), EthWalletConnectError> { + let account = H160::from_str(account).expect("valid eth account"); + let signature = signature.strip_prefix("0x").unwrap_or(signature); + let signature = + Signature::from_str(signature).map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; + + let pubkey = recover(&signature, hash).map_to_mm(|_| { + let error = format!("Couldn't recover a public key from the signature: '{signature:?}'"); + EthWalletConnectError::InvalidSignature(error) + })?; + + let recovered_address = public_to_address(&pubkey); + + if account != recovered_address { + let error = format!("Recovered address '{recovered_address:?}' should be the same as '{account:?}'"); + return MmError::err(EthWalletConnectError::AccoountMisMatch(error)); + } + + Ok((pubkey, recovered_address)) +} diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 3e5f55ce41..16b1782b7b 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -54,6 +54,7 @@ use crypto::{derive_secp256k1_secret, Bip32Error, Bip44Chain, CryptoCtx, CryptoC Secp256k1ExtendedPublicKey, Secp256k1Secret, WithHwRpcError}; use derive_more::Display; use enum_derives::{EnumFromStringify, EnumFromTrait}; +use ethereum_types::Public as EthPublic; use ethereum_types::H256; use futures::compat::Future01CompatExt; use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; @@ -3902,6 +3903,8 @@ pub enum PrivKeyPolicy { /// with the Metamask extension, especially within web-based contexts. #[cfg(target_arch = "wasm32")] Metamask(EthMetamaskPolicy), + + WalletConnect(EthPublic), } #[cfg(target_arch = "wasm32")] @@ -3923,7 +3926,7 @@ impl PrivKeyPolicy { activated_key: activated_key_pair, .. } => Some(activated_key_pair), - PrivKeyPolicy::Trezor => None, + PrivKeyPolicy::WalletConnect(_) | PrivKeyPolicy::Trezor => None, #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => None, } @@ -3943,7 +3946,7 @@ impl PrivKeyPolicy { PrivKeyPolicy::HDWallet { bip39_secp_priv_key, .. } => Some(bip39_secp_priv_key), - PrivKeyPolicy::Iguana(_) | PrivKeyPolicy::Trezor => None, + PrivKeyPolicy::Iguana(_) | PrivKeyPolicy::Trezor | PrivKeyPolicy::WalletConnect(_) => None, #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => None, } @@ -3965,8 +3968,7 @@ impl PrivKeyPolicy { path_to_coin: derivation_path, .. } => Some(derivation_path), - PrivKeyPolicy::Trezor => None, - PrivKeyPolicy::Iguana(_) => None, + PrivKeyPolicy::Iguana(_) | PrivKeyPolicy::Trezor | PrivKeyPolicy::WalletConnect(_) => None, #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => None, } diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index d441ce244f..704e82cb41 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -281,6 +281,7 @@ impl TendermintActivationPolicy { #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => unreachable!(), + PrivKeyPolicy::WalletConnect(_) => unreachable!(), }, Self::PublicKey(account_public_key) => Ok(*account_public_key), } diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index 175454e1da..e90fc87bda 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -380,6 +380,9 @@ pub fn my_public_key(coin: &UtxoCoinFields) -> Result<&Public, MmError MmError::err(UnexpectedDerivationMethod::UnsupportedError( "`PrivKeyPolicy::Metamask` is not supported in this context".to_string(), )), + PrivKeyPolicy::WalletConnect(_) => MmError::err(UnexpectedDerivationMethod::UnsupportedError( + "`PrivKeyPolicy::WalletConnect` is not supported in this context".to_string(), + )), } } @@ -2954,6 +2957,7 @@ pub fn display_priv_key(coin: &UtxoCoinFields) -> Result { PrivKeyPolicy::Trezor => ERR!("'display_priv_key' is not supported for Hardware Wallets"), #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => ERR!("'display_priv_key' doesn't support Metamask"), + PrivKeyPolicy::WalletConnect(_) => ERR!("'display_priv_key' doesn't support WalletConnect"), } } @@ -4747,6 +4751,7 @@ pub fn derive_htlc_key_pair(coin: &UtxoCoinFields, _swap_unique_data: &[u8]) -> PrivKeyPolicy::Trezor => todo!(), #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => panic!("`PrivKeyPolicy::Metamask` is not supported for UTXO coins"), + PrivKeyPolicy::WalletConnect(_) => todo!(), } } diff --git a/mm2src/coins/utxo/utxo_withdraw.rs b/mm2src/coins/utxo/utxo_withdraw.rs index 8721a6a433..5700f90897 100644 --- a/mm2src/coins/utxo/utxo_withdraw.rs +++ b/mm2src/coins/utxo/utxo_withdraw.rs @@ -342,6 +342,11 @@ where "`PrivKeyPolicy::Metamask` is not supported for UTXO coins!".to_string(), )) }, + PrivKeyPolicy::WalletConnect(_) => { + return MmError::err(WithdrawError::UnsupportedError( + "`PrivKeyPolicy::WalletConnect` is not supported for UTXO coins!".to_string(), + )) + }, }; self.task_handle diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index ebcc5b00f8..457c3bd15c 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -2,9 +2,16 @@ use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; use std::collections::BTreeMap; pub(crate) const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; +pub const ETH_CHAIN_ID: &str = "eip155"; pub(crate) const SUPPORTED_EVENTS: &[&str] = &[]; -pub(crate) const SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; +pub(crate) const SUPPORTED_METHODS: &[&str] = &[ + "cosmos_getAccounts", + "cosmos_signDirect", + "cosmos_signAmino", + "eth_signTransaction", + "personal_sign", +]; pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; @@ -13,6 +20,8 @@ pub enum WcRequestMethods { CosmosSignDirect, CosmosSignAmino, CosmosGetAccounts, + EthSignTransaction, + PersonalSign, } impl AsRef for WcRequestMethods { @@ -21,6 +30,8 @@ impl AsRef for WcRequestMethods { Self::CosmosSignDirect => "cosmos_signDirect", Self::CosmosSignAmino => "cosmos_signAmino", Self::CosmosGetAccounts => "cosmos_getAccounts", + Self::EthSignTransaction => "eth_signTransaction", + Self::PersonalSign => "personal_sign", } } } From b35bd4a6a97dde747e6adf36e43f06e4328b6c75 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 23 Oct 2024 15:24:15 +0100 Subject: [PATCH 076/125] implement eth coin activation using walletconnect --- mm2src/coins/eth.rs | 26 +++++--- mm2src/coins/eth/eth_withdraw.rs | 10 +-- mm2src/coins/eth/v2_activation.rs | 12 ++-- mm2src/coins/eth/wallet_connect.rs | 64 +++++++++++-------- mm2src/coins/lp_coins.rs | 13 ++-- mm2src/coins/tendermint/tendermint_coin.rs | 2 +- mm2src/coins/utxo/utxo_common.rs | 6 +- mm2src/coins/utxo/utxo_withdraw.rs | 2 +- .../src/eth_with_token_activation.rs | 26 ++++++-- mm2src/kdf_walletconnect/src/chain.rs | 38 ++++++----- mm2src/kdf_walletconnect/src/lib.rs | 12 ++-- mm2src/kdf_walletconnect/src/session.rs | 19 +++++- .../src/session/rpc/settle.rs | 46 ++++++------- .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 3 +- .../mm2_main/src/rpc/wc_commands/sessions.rs | 33 ++++++++-- 15 files changed, 192 insertions(+), 120 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 6c7c7c830d..19d8106354 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -140,7 +140,7 @@ mod eth_rpc; #[cfg(target_arch = "wasm32")] mod eth_wasm_tests; #[cfg(any(test, target_arch = "wasm32"))] mod for_tests; pub(crate) mod nft_swap_v2; -mod wallet_connect; +pub mod wallet_connect; mod web3_transport; use web3_transport::{http_transport::HttpTransportNode, Web3Transport}; @@ -589,7 +589,10 @@ pub enum EthPrivKeyBuildPolicy { #[cfg(target_arch = "wasm32")] Metamask(MetamaskArc), Trezor, - WalletConnect, + WalletConnect { + address: Address, + pubkey: Public, + }, } impl EthPrivKeyBuildPolicy { @@ -1368,10 +1371,9 @@ impl SwapOps for EthCoin { activated_key: ref key_pair, .. } => key_pair_from_secret(key_pair.secret().as_bytes()).expect("valid key"), - EthPrivKeyPolicy::Trezor | EthPrivKeyPolicy::WalletConnect(_) => todo!(), + EthPrivKeyPolicy::Trezor | EthPrivKeyPolicy::WalletConnect { .. } => todo!(), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => todo!(), - EthPrivKeyPolicy::WalletConnect(_) => todo!(), } } @@ -1389,7 +1391,7 @@ impl SwapOps for EthCoin { EthPrivKeyPolicy::Trezor => todo!(), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(ref metamask_policy) => metamask_policy.public_key.as_bytes().to_vec(), - EthPrivKeyPolicy::WalletConnect(pubkey) => pubkey.to_bytes().to_vec(), + EthPrivKeyPolicy::WalletConnect { pubkey, .. } => pubkey.to_bytes().to_vec(), } } @@ -2161,7 +2163,11 @@ impl MarketCoinOps for EthCoin { EthPrivKeyPolicy::Metamask(ref metamask_policy) => { Ok(format!("{:02x}", metamask_policy.public_key_uncompressed)) }, - EthPrivKeyPolicy::WalletConnect(_) => todo!(), + EthPrivKeyPolicy::WalletConnect { address: _, pubkey } => { + let key = hex::encode(pubkey); + println!("Pubkey: {key}"); + Ok(format!("04{key}")) + }, } } @@ -2481,7 +2487,7 @@ impl MarketCoinOps for EthCoin { EthPrivKeyPolicy::Trezor => ERR!("'display_priv_key' is not supported for Hardware Wallets"), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => ERR!("'display_priv_key' is not supported for MetaMask"), - EthPrivKeyPolicy::WalletConnect(_) => todo!(), + EthPrivKeyPolicy::WalletConnect { .. } => ERR!("'display_priv_key' is not supported for MetaMask"), } } @@ -2692,7 +2698,7 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw EthPrivKeyPolicy::Trezor => MmError::err(RawTransactionError::InvalidParam( "sign raw eth tx not implemented for Trezor".into(), )), - EthPrivKeyPolicy::WalletConnect(_) => MmError::err(RawTransactionError::InvalidParam( + EthPrivKeyPolicy::WalletConnect { .. } => MmError::err(RawTransactionError::InvalidParam( "sign raw eth tx not implemented for WalletConnect".into(), )), } @@ -3644,7 +3650,7 @@ impl EthCoin { EthPrivKeyPolicy::Metamask(_) => { sign_and_send_transaction_with_metamask(coin, value, action, data, gas).await }, - EthPrivKeyPolicy::WalletConnect(_) => todo!(), + EthPrivKeyPolicy::WalletConnect { .. } => todo!(), } }; Box::new(fut.boxed().compat()) @@ -7186,7 +7192,7 @@ impl CommonSwapOpsV2 for EthCoin { .expect("slice with incorrect length"); Public::from_slice(&pubkey_bytes) }, - EthPrivKeyPolicy::WalletConnect(pubkey) => pubkey, + EthPrivKeyPolicy::WalletConnect { pubkey, .. } => pubkey, } } diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index f9bf9b3b1e..1baa2431d3 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -139,7 +139,7 @@ where let bytes = rlp::encode(&signed); Ok((signed.tx_hash(), BytesJson::from(bytes.to_vec()))) }, - EthPrivKeyPolicy::WalletConnect(_) => todo!(), + EthPrivKeyPolicy::WalletConnect { .. } => todo!(), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => MmError::err(WithdrawError::InternalError("invalid policy".to_owned())), } @@ -179,10 +179,12 @@ where .unwrap_or_default(); Ok((tx_hash, tx_hex)) }, - EthPrivKeyPolicy::Iguana(_) | EthPrivKeyPolicy::HDWallet { .. } | EthPrivKeyPolicy::Trezor => { + EthPrivKeyPolicy::Iguana(_) + | EthPrivKeyPolicy::HDWallet { .. } + | EthPrivKeyPolicy::Trezor + | EthPrivKeyPolicy::WalletConnect { .. } => { MmError::err(WithdrawError::InternalError("invalid policy".to_owned())) }, - EthPrivKeyPolicy::WalletConnect(_) => todo!(), } } @@ -294,7 +296,7 @@ where }; self.send_withdraw_tx(&req, tx_to_send).await? }, - EthPrivKeyPolicy::WalletConnect(_) => todo!(), + EthPrivKeyPolicy::WalletConnect { address: _, pubkey: _ } => todo!(), }; self.on_finishing()?; diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 63a39033e9..93825cdea0 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -551,6 +551,7 @@ pub async fn eth_coin_from_conf_and_request_v2( req: EthActivationV2Request, priv_key_build_policy: EthPrivKeyBuildPolicy, ) -> MmResult { + let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; if req.swap_contract_address == Address::default() { return Err(EthActivationV2Error::InvalidSwapContractAddr( "swap_contract_address can't be zero address".to_string(), @@ -594,11 +595,10 @@ pub async fn eth_coin_from_conf_and_request_v2( ) .await?; - let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; let web3_instances = match (req.rpc_mode, &priv_key_policy) { (EthRpcMode::Default, EthPrivKeyPolicy::Iguana(_) | EthPrivKeyPolicy::HDWallet { .. }) | (EthRpcMode::Default, EthPrivKeyPolicy::Trezor) - | (EthRpcMode::Default, EthPrivKeyPolicy::WalletConnect(_)) => { + | (EthRpcMode::Default, EthPrivKeyPolicy::WalletConnect { .. }) => { build_web3_instances(ctx, ticker.to_string(), req.nodes.clone()).await? }, #[cfg(target_arch = "wasm32")] @@ -781,10 +781,10 @@ pub(crate) async fn build_address_and_priv_key_policy( DerivationMethod::SingleAddress(address), )) }, - EthPrivKeyBuildPolicy::WalletConnect => { - // request walletconnect eth pubkey - todo!() - }, + EthPrivKeyBuildPolicy::WalletConnect { address, pubkey } => Ok(( + EthPrivKeyPolicy::WalletConnect { address, pubkey }, + DerivationMethod::SingleAddress(address), + )), } } diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 56e3db96e4..313af4bc9b 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -3,15 +3,17 @@ use std::str::FromStr; use async_std::stream::StreamExt; use chrono::Utc; use derive_more::Display; -use ethereum_types::{Address, Public, H160, H256}; -use ethkey::{public_to_address, recover, Message, Signature}; +use ethereum_types::{Address, Public, H160}; +use ethkey::{public_to_address, Message, Signature}; use kdf_walletconnect::{chain::{WcRequestMethods, ETH_CHAIN_ID}, error::WalletConnectError, WalletConnectCtx}; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session_request::SessionRequestRequest; use relay_rpc::rpc::params::{session_request::Request as SessionRequest, RequestParams, ResponseParamsSuccess}; -use web3::helpers; +use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, + Secp256k1}; +use web3::signing::hash_message; #[derive(Display, Debug)] pub enum EthWalletConnectError { @@ -19,9 +21,9 @@ pub enum EthWalletConnectError { AccoountMisMatch(String), } -pub async fn eth_request_wc_personal( +pub async fn eth_request_wc_personal_sign( ctx: &WalletConnectCtx, - chain_id: &str, + chain_id: u64, ) -> MmResult<(Public, Address), WalletConnectError> { let topic = ctx .session @@ -30,14 +32,10 @@ pub async fn eth_request_wc_personal( .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; - let full_chain_id = format!("{ETH_CHAIN_ID}:{chain_id}"); - - let account_str = ctx.get_account_for_chain_id(&full_chain_id).await?; - let account = helpers::serialize(&account_str); - let message_str = "KDF: Verify that this account is yours"; - let message = helpers::serialize(&message_str); - - let params = json!(&[&account, &message]); + let account_str = ctx.get_account_for_chain_id(&chain_id.to_string()).await?; + let message = "Hello World"; + let message_hex = format!("0x{}", hex::encode(message)); + let params = json!(&[&message_hex, &account_str]); let request = SessionRequestRequest { request: SessionRequest { @@ -45,7 +43,7 @@ pub async fn eth_request_wc_personal( expiry: Some(Utc::now().timestamp() as u64 + 300), params, }, - chain_id: full_chain_id, + chain_id: format!("{ETH_CHAIN_ID}:{chain_id}"), }; { let session_request = RequestParams::SessionRequest(request); @@ -58,27 +56,26 @@ pub async fn eth_request_wc_personal( let response = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(&topic, response, &message_id).await?; - let hash = Message::from_str(&hex::encode(message_str)).expect("valid message hash"); + let res = extract_pubkey_from_signature(&result, message, &account_str) + .mm_err(|err| WalletConnectError::PayloadError(err.to_string()))?; - return get_pubkey_from_signature(&result, &hash, &account_str) - .mm_err(|err| WalletConnectError::PayloadError(err.to_string())); + return Ok(res); } MmError::err(WalletConnectError::InternalError("No response from wallet".to_string())) } -fn get_pubkey_from_signature( - signature: &str, - hash: &H256, +fn extract_pubkey_from_signature( + signature_str: &str, + message: &str, account: &str, ) -> MmResult<(Public, Address), EthWalletConnectError> { - let account = H160::from_str(account).expect("valid eth account"); - let signature = signature.strip_prefix("0x").unwrap_or(signature); - let signature = - Signature::from_str(signature).map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; - - let pubkey = recover(&signature, hash).map_to_mm(|_| { - let error = format!("Couldn't recover a public key from the signature: '{signature:?}'"); + let message_hash = hash_message(message); + let account = H160::from_str(&account[2..]).expect("valid eth account"); + let signature = Signature::from_str(&signature_str[2..]) + .map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; + let pubkey = recover(&signature, &message_hash).map_to_mm(|err| { + let error = format!("Couldn't recover a public key from the signature: '{signature:?}, error: {err:?}'"); EthWalletConnectError::InvalidSignature(error) })?; @@ -88,6 +85,17 @@ fn get_pubkey_from_signature( let error = format!("Recovered address '{recovered_address:?}' should be the same as '{account:?}'"); return MmError::err(EthWalletConnectError::AccoountMisMatch(error)); } - Ok((pubkey, recovered_address)) } + +pub fn recover(signature: &Signature, message: &Message) -> Result { + let recovery_id = signature[64] as i32 - 27; + let recovery_id = RecoveryId::from_i32(recovery_id)?; + let sig = RecoverableSignature::from_compact(&signature[0..64], recovery_id)?; + let pubkey = Secp256k1::new().recover(&secp256k1::Message::from_slice(&message[..])?, &sig)?; + let serialized = pubkey.serialize_uncompressed(); + + let mut public = Public::default(); + public.as_mut().copy_from_slice(&serialized[1..65]); + Ok(public) +} diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 16b1782b7b..919c0728a0 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -55,7 +55,7 @@ use crypto::{derive_secp256k1_secret, Bip32Error, Bip44Chain, CryptoCtx, CryptoC use derive_more::Display; use enum_derives::{EnumFromStringify, EnumFromTrait}; use ethereum_types::Public as EthPublic; -use ethereum_types::H256; +use ethereum_types::{H160, H256}; use futures::compat::Future01CompatExt; use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use futures::{FutureExt, TryFutureExt}; @@ -3904,7 +3904,10 @@ pub enum PrivKeyPolicy { #[cfg(target_arch = "wasm32")] Metamask(EthMetamaskPolicy), - WalletConnect(EthPublic), + WalletConnect { + address: H160, + pubkey: EthPublic, + }, } #[cfg(target_arch = "wasm32")] @@ -3926,7 +3929,7 @@ impl PrivKeyPolicy { activated_key: activated_key_pair, .. } => Some(activated_key_pair), - PrivKeyPolicy::WalletConnect(_) | PrivKeyPolicy::Trezor => None, + PrivKeyPolicy::WalletConnect { .. } | PrivKeyPolicy::Trezor => None, #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => None, } @@ -3946,7 +3949,7 @@ impl PrivKeyPolicy { PrivKeyPolicy::HDWallet { bip39_secp_priv_key, .. } => Some(bip39_secp_priv_key), - PrivKeyPolicy::Iguana(_) | PrivKeyPolicy::Trezor | PrivKeyPolicy::WalletConnect(_) => None, + PrivKeyPolicy::Iguana(_) | PrivKeyPolicy::Trezor | PrivKeyPolicy::WalletConnect { .. } => None, #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => None, } @@ -3968,7 +3971,7 @@ impl PrivKeyPolicy { path_to_coin: derivation_path, .. } => Some(derivation_path), - PrivKeyPolicy::Iguana(_) | PrivKeyPolicy::Trezor | PrivKeyPolicy::WalletConnect(_) => None, + PrivKeyPolicy::Iguana(_) | PrivKeyPolicy::Trezor | PrivKeyPolicy::WalletConnect { .. } => None, #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => None, } diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 704e82cb41..60f9e6c123 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -281,7 +281,7 @@ impl TendermintActivationPolicy { #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => unreachable!(), - PrivKeyPolicy::WalletConnect(_) => unreachable!(), + PrivKeyPolicy::WalletConnect { .. } => unreachable!(), }, Self::PublicKey(account_public_key) => Ok(*account_public_key), } diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index e90fc87bda..c4d4c713fd 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -380,7 +380,7 @@ pub fn my_public_key(coin: &UtxoCoinFields) -> Result<&Public, MmError MmError::err(UnexpectedDerivationMethod::UnsupportedError( "`PrivKeyPolicy::Metamask` is not supported in this context".to_string(), )), - PrivKeyPolicy::WalletConnect(_) => MmError::err(UnexpectedDerivationMethod::UnsupportedError( + PrivKeyPolicy::WalletConnect { .. } => MmError::err(UnexpectedDerivationMethod::UnsupportedError( "`PrivKeyPolicy::WalletConnect` is not supported in this context".to_string(), )), } @@ -2957,7 +2957,7 @@ pub fn display_priv_key(coin: &UtxoCoinFields) -> Result { PrivKeyPolicy::Trezor => ERR!("'display_priv_key' is not supported for Hardware Wallets"), #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => ERR!("'display_priv_key' doesn't support Metamask"), - PrivKeyPolicy::WalletConnect(_) => ERR!("'display_priv_key' doesn't support WalletConnect"), + PrivKeyPolicy::WalletConnect { .. } => ERR!("'display_priv_key' doesn't support WalletConnect"), } } @@ -4751,7 +4751,7 @@ pub fn derive_htlc_key_pair(coin: &UtxoCoinFields, _swap_unique_data: &[u8]) -> PrivKeyPolicy::Trezor => todo!(), #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => panic!("`PrivKeyPolicy::Metamask` is not supported for UTXO coins"), - PrivKeyPolicy::WalletConnect(_) => todo!(), + PrivKeyPolicy::WalletConnect { .. } => todo!(), } } diff --git a/mm2src/coins/utxo/utxo_withdraw.rs b/mm2src/coins/utxo/utxo_withdraw.rs index 5700f90897..4d2e265b64 100644 --- a/mm2src/coins/utxo/utxo_withdraw.rs +++ b/mm2src/coins/utxo/utxo_withdraw.rs @@ -342,7 +342,7 @@ where "`PrivKeyPolicy::Metamask` is not supported for UTXO coins!".to_string(), )) }, - PrivKeyPolicy::WalletConnect(_) => { + PrivKeyPolicy::WalletConnect { .. } => { return MmError::err(WithdrawError::UnsupportedError( "`PrivKeyPolicy::WalletConnect` is not supported for UTXO coins!".to_string(), )) diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index 85cedeee0d..872675ad05 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -10,14 +10,16 @@ use crate::prelude::*; use async_trait::async_trait; use coins::coin_balance::{CoinBalanceReport, EnableCoinBalanceOps}; use coins::eth::v2_activation::{eth_coin_from_conf_and_request_v2, Erc20Protocol, Erc20TokenActivationRequest, - EthActivationV2Error, EthActivationV2Request, EthPrivKeyActivationPolicy}; -use coins::eth::v2_activation::{EthTokenActivationError, NftActivationRequest, NftProviderEnum}; + EthActivationV2Error, EthActivationV2Request, EthPrivKeyActivationPolicy, + EthTokenActivationError, NftActivationRequest, NftProviderEnum}; +use coins::eth::wallet_connect::eth_request_wc_personal_sign; use coins::eth::{Erc20TokenInfo, EthCoin, EthCoinType, EthPrivKeyBuildPolicy}; use coins::hd_wallet::RpcTaskXPubExtractor; use coins::my_tx_history_v2::TxHistoryStorage; use coins::nft::nft_structs::NftInfo; use coins::{CoinBalance, CoinBalanceMap, CoinProtocol, CoinWithDerivationMethod, DerivationMethod, MarketCoinOps, MmCoin, MmCoinEnum}; +use kdf_walletconnect::WalletConnectCtx; use crate::platform_coin_with_tokens::InitPlatformCoinWithTokensTask; use common::Future01CompatExt; @@ -271,7 +273,12 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { activation_request: Self::ActivationRequest, _protocol: Self::PlatformProtocolInfo, ) -> Result> { - let priv_key_policy = eth_priv_key_build_policy(&ctx, &activation_request.platform_request.priv_key_policy)?; + let priv_key_policy = eth_priv_key_build_policy( + &ctx, + &activation_request.platform_request.priv_key_policy, + platform_conf, + ) + .await?; let platform_coin = eth_coin_from_conf_and_request_v2( &ctx, @@ -452,9 +459,10 @@ impl PlatformCoinWithTokensActivationOps for EthCoin { } } -fn eth_priv_key_build_policy( +async fn eth_priv_key_build_policy( ctx: &MmArc, activation_policy: &EthPrivKeyActivationPolicy, + conf: &Json, ) -> MmResult { match activation_policy { EthPrivKeyActivationPolicy::ContextPrivKey => Ok(EthPrivKeyBuildPolicy::detect_priv_key_policy(ctx)?), @@ -466,6 +474,14 @@ fn eth_priv_key_build_policy( Ok(EthPrivKeyBuildPolicy::Metamask(metamask_ctx)) }, EthPrivKeyActivationPolicy::Trezor => Ok(EthPrivKeyBuildPolicy::Trezor), - EthPrivKeyActivationPolicy::WalletConnect => todo!(), + EthPrivKeyActivationPolicy::WalletConnect => { + let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; + let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + let (pubkey, address) = eth_request_wc_personal_sign(&wc, chain_id) + .await + .mm_err(|err| EthActivationV2Error::InternalError(err.to_string()))?; + + Ok(EthPrivKeyBuildPolicy::WalletConnect { address, pubkey }) + }, } } diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index 457c3bd15c..6f40aa4434 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -1,19 +1,19 @@ use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; -use std::collections::BTreeMap; +use std::collections::{BTreeMap, BTreeSet}; + +pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4", "eip155:1"]; +pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; + +pub const COSMOS_CHAIN_ID: &str = "cosmos"; +pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; +pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; -pub(crate) const DEFAULT_CHAIN_ID: &str = "cosmoshub-4"; pub const ETH_CHAIN_ID: &str = "eip155"; +pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "personal_sign"]; +pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1"]; +pub(crate) const ETH_SUPPORTED_EVENTS: &[&str] = &["accountsChanged", "chainChanged"]; -pub(crate) const SUPPORTED_EVENTS: &[&str] = &[]; -pub(crate) const SUPPORTED_METHODS: &[&str] = &[ - "cosmos_getAccounts", - "cosmos_signDirect", - "cosmos_signAmino", - "eth_signTransaction", - "personal_sign", -]; -pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; -pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; +pub(crate) const DEFAULT_CHAIN_ID: &str = "1"; #[derive(Debug, Clone)] pub enum WcRequestMethods { @@ -38,10 +38,16 @@ impl AsRef for WcRequestMethods { pub(crate) fn build_required_namespaces() -> ProposeNamespaces { let mut required = BTreeMap::new(); - required.insert("cosmos".to_string(), ProposeNamespace { - chains: SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), + required.insert(COSMOS_CHAIN_ID.to_string(), ProposeNamespace { + events: BTreeSet::new(), + chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + }); + + required.insert(ETH_CHAIN_ID.to_string(), ProposeNamespace { + events: ETH_SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), + chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), }); ProposeNamespaces(required) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 34f9df4428..41c1350fe7 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -151,7 +151,7 @@ impl WalletConnectCtx { .unwrap_or(false) } - pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|chain| chain == &chain_id) } + pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|&chain| chain == chain_id) } pub async fn set_active_chain(&self, chain_id: &str) { let mut active_chain = self.active_chain_id.lock().await; @@ -162,16 +162,13 @@ impl WalletConnectCtx { /// Retrieves the available account for a given chain ID. pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { - let active_chain_id = self.get_active_chain_id().await; - if active_chain_id != chain_id { - return MmError::err(WalletConnectError::ChainIdMismatch); - } - let namespaces = &self .session .get_session_active() .await - .ok_or(MmError::new(WalletConnectError::NoAccountFound(chain_id.to_string())))? + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active WalletConnect session found".to_string(), + )))? .namespaces; namespaces .iter() @@ -364,6 +361,7 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect fn find_account_in_namespace(namespace: &Namespace, chain_id: &str) -> Option { let accounts = namespace.accounts.as_ref()?; + println!("ACCOUNTS: {accounts:?}"); accounts.iter().find_map(|account_name| { let parts: Vec<&str> = account_name.split(':').collect(); if parts.len() >= 3 && parts[1] == chain_id { diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 2a8125ad2a..b32d7ac602 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -9,7 +9,7 @@ use dashmap::mapref::one::{Ref, RefMut}; use dashmap::DashMap; use futures::lock::Mutex; use key::SessionKey; -use mm2_err_handle::prelude::MmResult; +use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::domain::Topic; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; @@ -240,6 +240,23 @@ impl SessionManager { removed_session } + /// Retrieves a cloned session associated with a given topic. + pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { + let mut active_topic = self.0.active_topic.lock().await; + if let Some(this) = active_topic.as_mut() { + if topic == this { + return Ok(()); + }; + } + + if let Some(session) = self.get_session(topic) { + *active_topic = Some(session.topic.clone()); + return Ok(()); + } + + MmError::err(WalletConnectError::SessionError("Session not found".to_owned())) + } + /// Retrieves a cloned session associated with a given topic. pub fn get_session(&self, topic: &Topic) -> Option> { self.0.sessions.get(topic) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 009ba258bf..9507222d86 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -1,38 +1,34 @@ -use crate::chain::{SUPPORTED_CHAINS, SUPPORTED_EVENTS, SUPPORTED_METHODS}; -use crate::session::{Session, SessionProperties, THIRTY_DAYS}; +use crate::session::{Session, SessionProperties}; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, WalletConnectCtx}; -use chrono::Utc; use common::log::info; use mm2_err_handle::prelude::{MapMmError, MmResult}; -use relay_rpc::rpc::params::session::{Namespace, SettleNamespaces}; -use relay_rpc::rpc::params::RequestParams; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_settle::SessionSettleRequest, ResponseParamsSuccess}}; -use std::collections::BTreeMap; pub(crate) async fn send_session_settle_request( - ctx: &WalletConnectCtx, - session_info: &Session, + _ctx: &WalletConnectCtx, + _session_info: &Session, ) -> MmResult<(), WalletConnectError> { - let mut settled_namespaces = BTreeMap::::new(); - settled_namespaces.insert("eip155".to_string(), Namespace { - chains: Some(SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect()), - methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), - accounts: None, - }); - - let request = RequestParams::SessionSettle(SessionSettleRequest { - relay: session_info.relay.clone(), - controller: session_info.controller.clone(), - namespaces: SettleNamespaces(settled_namespaces), - expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, - session_properties: None, - }); - - ctx.publish_request(&session_info.topic, request).await?; + // let mut settled_namespaces = BTreeMap::::new(); + // let nam + // settled_namespaces.insert("eip155".to_string(), Namespace { + // chains: Some(SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect()), + // methods: SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + // events: SUPPORTED_EVENTS.iter().map(|e| e.to_string()).collect(), + // accounts: None, + // }); + // + // let request = RequestParams::SessionSettle(SessionSettleRequest { + // relay: session_info.relay.clone(), + // controller: session_info.controller.clone(), + // namespaces: SettleNamespaces(settled_namespaces), + // expiry: Utc::now().timestamp() as u64 + THIRTY_DAYS, + // session_properties: None, + // }); + // + // ctx.publish_request(&session_info.topic, request).await?; Ok(()) } diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index 5bfa1761d6..a84c2848ff 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -1,4 +1,4 @@ -use super::wc_commands::{disconnect_session, get_all_sessions, get_session}; +use super::wc_commands::{disconnect_session, get_all_sessions, get_session, set_active_session}; use super::{DispatcherError, DispatcherResult, PUBLIC_METHODS}; use crate::lp_healthcheck::peer_connection_healthcheck_rpc; use crate::lp_native_dex::init_hw::{cancel_init_trezor, init_trezor, init_trezor_status, init_trezor_user_action}; @@ -225,6 +225,7 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, get_session).await, "wc_get_sessions" => handle_mmrpc(ctx, request, get_all_sessions).await, "wc_disconnect_session" => handle_mmrpc(ctx, request, disconnect_session).await, + "wc_set_active_session" => handle_mmrpc(ctx, request, set_active_session).await, "wc_ping_session" => handle_mmrpc(ctx, request, ping_session).await, #[cfg(not(target_arch = "wasm32"))] native_only_methods => match native_only_methods { diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 6b73d8246c..645d8dee9e 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -7,6 +7,11 @@ use serde::Serialize; use super::{EmptyRpcRequst, EmptyRpcResponse, WalletConnectRpcError}; +#[derive(Debug, PartialEq, Serialize)] +pub struct SessionResponse { + pub result: String, +} + #[derive(Debug, PartialEq, Serialize)] pub struct GetSessionsResponse { pub sessions: Vec, @@ -51,6 +56,23 @@ pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult MmResult { + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + ctx.session + .set_active_session(&req.topic.into()) + .await + .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; + + Ok(SessionResponse { + result: "active session updated!".to_owned(), + }) +} + /// `Delete session connection` RPC command implementation. pub async fn disconnect_session( ctx: MmArc, @@ -65,18 +87,15 @@ pub async fn disconnect_session( Ok(EmptyRpcResponse {}) } -#[derive(Debug, PartialEq, Serialize)] -pub struct SessionPingResponse { - pub successful: bool, -} - /// `ping session` RPC command implementation. -pub async fn ping_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { +pub async fn ping_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; send_session_ping_request(&ctx, &req.topic.into()) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; - Ok(SessionPingResponse { successful: true }) + Ok(SessionResponse { + result: "Ping successful".to_owned(), + }) } From 337154cdbec010c1559ae9900feeb723e8907008 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 24 Oct 2024 06:12:18 +0100 Subject: [PATCH 077/125] eth walletconnect coin activation and message handler code improvements --- mm2src/coins/eth.rs | 10 +--- mm2src/coins/eth/v2_activation.rs | 9 ++- mm2src/coins/eth/wallet_connect.rs | 10 ++-- mm2src/coins/tendermint/wallet_connect.rs | 13 ++--- .../src/eth_with_token_activation.rs | 12 +++- .../src/tendermint_with_assets_activation.rs | 5 +- mm2src/kdf_walletconnect/src/chain.rs | 42 +++++++++----- .../kdf_walletconnect/src/inbound_message.rs | 56 +++++-------------- mm2src/kdf_walletconnect/src/lib.rs | 26 ++++----- mm2src/kdf_walletconnect/src/session.rs | 22 +++++++- .../src/session/rpc/propose.rs | 28 ++++++---- .../src/rpc/wc_commands/new_connection.rs | 2 +- .../mm2_main/src/rpc/wc_commands/sessions.rs | 4 +- 13 files changed, 122 insertions(+), 117 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 19d8106354..5a5d5394ba 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2163,11 +2163,7 @@ impl MarketCoinOps for EthCoin { EthPrivKeyPolicy::Metamask(ref metamask_policy) => { Ok(format!("{:02x}", metamask_policy.public_key_uncompressed)) }, - EthPrivKeyPolicy::WalletConnect { address: _, pubkey } => { - let key = hex::encode(pubkey); - println!("Pubkey: {key}"); - Ok(format!("04{key}")) - }, + EthPrivKeyPolicy::WalletConnect { address: _, pubkey } => Ok(format!("04{}", hex::encode(pubkey))), } } @@ -2698,9 +2694,7 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw EthPrivKeyPolicy::Trezor => MmError::err(RawTransactionError::InvalidParam( "sign raw eth tx not implemented for Trezor".into(), )), - EthPrivKeyPolicy::WalletConnect { .. } => MmError::err(RawTransactionError::InvalidParam( - "sign raw eth tx not implemented for WalletConnect".into(), - )), + EthPrivKeyPolicy::WalletConnect { .. } => todo!(), } } diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 93825cdea0..686b57c6a2 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -20,7 +20,9 @@ use std::sync::atomic::Ordering; use url::Url; use web3_transport::websocket_transport::WebsocketTransport; -#[derive(Clone, Debug, Deserialize, Display, EnumFromTrait, PartialEq, Serialize, SerializeErrorType)] +#[derive( + Clone, Debug, Deserialize, Display, EnumFromTrait, EnumFromStringify, PartialEq, Serialize, SerializeErrorType, +)] #[serde(tag = "error_type", content = "error_data")] pub enum EthActivationV2Error { InvalidPayload(String), @@ -62,6 +64,8 @@ pub enum EthActivationV2Error { HwError(HwRpcError), #[display(fmt = "Hardware wallet must be called within rpc task framework")] InvalidHardwareWalletCall, + #[from_stringify("WalletConnectError")] + WalletConnectError(String), } impl From for EthActivationV2Error { @@ -162,7 +166,6 @@ pub enum EthPrivKeyActivationPolicy { impl EthPrivKeyActivationPolicy { pub fn is_hw_policy(&self) -> bool { matches!(self, EthPrivKeyActivationPolicy::Trezor) } - pub fn is_wc_policy(&self) -> bool { matches!(self, EthPrivKeyActivationPolicy::WalletConnect) } } #[derive(Clone, Debug, Deserialize, Serialize, Default)] @@ -305,6 +308,8 @@ pub enum EthTokenActivationParams { #[derive(Clone, Deserialize)] pub struct Erc20TokenActivationRequest { pub required_confirmations: Option, + // #[serde(default)] + // pub use_walletconnect: Option, } /// Holds ERC-20 token-specific activation parameters when using the task manager for activation. diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 313af4bc9b..1c082409f0 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -5,8 +5,9 @@ use chrono::Utc; use derive_more::Display; use ethereum_types::{Address, Public, H160}; use ethkey::{public_to_address, Message, Signature}; -use kdf_walletconnect::{chain::{WcRequestMethods, ETH_CHAIN_ID}, +use kdf_walletconnect::{chain::{WcChain, WcRequestMethods}, error::WalletConnectError, + inbound_message::WcResponse, WalletConnectCtx}; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session_request::SessionRequestRequest; @@ -43,16 +44,15 @@ pub async fn eth_request_wc_personal_sign( expiry: Some(Utc::now().timestamp() as u64 + 300), params, }, - chain_id: format!("{ETH_CHAIN_ID}:{chain_id}"), + chain_id: format!("{}:{chain_id}", WcChain::Eip155.as_ref()), }; { let session_request = RequestParams::SessionRequest(request); ctx.publish_request(&topic, session_request).await?; } - let mut session_handler = ctx.session_request_handler.lock().await; - if let Some((message_id, data)) = session_handler.next().await { - let result = serde_json::from_value::(data)?; + if let Some((message_id, WcResponse::Other(response))) = ctx.session_request_handler.lock().await.next().await { + let result = serde_json::from_value::(response)?; let response = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(&topic, response, &message_id).await?; diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index bc72356337..ad2782e246 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -5,6 +5,7 @@ use base64::Engine; use chrono::Utc; use futures::StreamExt; use kdf_walletconnect::error::WalletConnectError; +use kdf_walletconnect::inbound_message::WcResponse; use kdf_walletconnect::{chain::WcRequestMethods, WalletConnectCtx}; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session_request::Request as SessionRequest; @@ -74,9 +75,8 @@ pub async fn cosmos_request_wc_signed_tx( ctx.publish_request(&topic, session_request).await?; } - let mut session_handler = ctx.session_request_handler.lock().await; - if let Some((message_id, data)) = session_handler.next().await { - let result = serde_json::from_value::(data)?; + if let Some((message_id, WcResponse::Other(response))) = ctx.session_request_handler.lock().await.next().await { + let result = serde_json::from_value::(response)?; let response = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(&topic, response, &message_id).await?; @@ -168,9 +168,8 @@ pub async fn cosmos_get_accounts_impl( ctx.publish_request(&topic, session_request).await?; }; - let mut session_handler = ctx.session_request_handler.lock().await; - if let Some((message_id, data)) = session_handler.next().await { - let accounts = serde_json::from_value::>(data)?; + if let Some((message_id, WcResponse::Other(response))) = ctx.session_request_handler.lock().await.next().await { + let accounts = serde_json::from_value::>(response)?; let response = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(&topic, response, &message_id).await?; @@ -184,7 +183,7 @@ pub async fn cosmos_get_accounts_impl( }; return Ok(accounts[account_index].clone()); - }; + } MmError::err(WalletConnectError::NoAccountFound(chain_id.to_owned())) } diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index 872675ad05..4bee54d960 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -64,7 +64,9 @@ impl From for EnablePlatformCoinWithTokensError { EthActivationV2Error::FailedSpawningBalanceEvents(e) => { EnablePlatformCoinWithTokensError::FailedSpawningBalanceEvents(e) }, - EthActivationV2Error::HDWalletStorageError(e) => EnablePlatformCoinWithTokensError::Internal(e), + EthActivationV2Error::HDWalletStorageError(e) | EthActivationV2Error::WalletConnectError(e) => { + EnablePlatformCoinWithTokensError::Internal(e) + }, #[cfg(target_arch = "wasm32")] EthActivationV2Error::MetamaskError(metamask) => { EnablePlatformCoinWithTokensError::Transport(metamask.to_string()) @@ -477,9 +479,15 @@ async fn eth_priv_key_build_policy( EthPrivKeyActivationPolicy::WalletConnect => { let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + + if !wc.is_chain_supported(&format!("eip155:{chain_id}")) { + return MmError::err(EthActivationV2Error::WalletConnectError(format!( + "Unsupported chain_id: {chain_id}" + ))); + }; let (pubkey, address) = eth_request_wc_personal_sign(&wc, chain_id) .await - .mm_err(|err| EthActivationV2Error::InternalError(err.to_string()))?; + .mm_err(|err| EthActivationV2Error::WalletConnectError(err.to_string()))?; Ok(EthPrivKeyBuildPolicy::WalletConnect { address, pubkey }) }, diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index b54aad9370..c9074ee3a5 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -237,7 +237,7 @@ impl From for EnablePlatformCoinWithTokensError { } } -async fn get_walletconnect_pubkey( +async fn activate_with_walletconnect( ctx: &MmArc, param: &WalletConnectParams, chain_id: &str, @@ -245,7 +245,6 @@ async fn get_walletconnect_pubkey( wallet_type: &mut TendermintWalletConnectionType, ) -> MmResult { let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); - let account = cosmos_get_accounts_impl(&wc, chain_id, Some(param.account_index)) .await .mm_err(|err| TendermintInitError { @@ -320,7 +319,7 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { }); }; - get_walletconnect_pubkey( + activate_with_walletconnect( &ctx, ¶ms, protocol_conf.chain_id.as_ref(), diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index 6f40aa4434..07c107ccf5 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -4,17 +4,29 @@ use std::collections::{BTreeMap, BTreeSet}; pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4", "eip155:1"]; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; -pub const COSMOS_CHAIN_ID: &str = "cosmos"; pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; -pub const ETH_CHAIN_ID: &str = "eip155"; pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "personal_sign"]; pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1"]; pub(crate) const ETH_SUPPORTED_EVENTS: &[&str] = &["accountsChanged", "chainChanged"]; pub(crate) const DEFAULT_CHAIN_ID: &str = "1"; +pub enum WcChain { + Eip155, + Cosmos, +} + +impl AsRef for WcChain { + fn as_ref(&self) -> &str { + match self { + Self::Eip155 => "eip155", + Self::Cosmos => "cosmos", + } + } +} + #[derive(Debug, Clone)] pub enum WcRequestMethods { CosmosSignDirect, @@ -36,19 +48,19 @@ impl AsRef for WcRequestMethods { } } -pub(crate) fn build_required_namespaces() -> ProposeNamespaces { - let mut required = BTreeMap::new(); - required.insert(COSMOS_CHAIN_ID.to_string(), ProposeNamespace { - events: BTreeSet::new(), - chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - }); - - required.insert(ETH_CHAIN_ID.to_string(), ProposeNamespace { - events: ETH_SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), - chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - }); +pub(crate) fn build_default_required_namespaces() -> ProposeNamespaces { + let required = BTreeMap::from([ + (WcChain::Eip155.as_ref().to_string(), ProposeNamespace { + events: ETH_SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), + chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + }), + (WcChain::Cosmos.as_ref().to_string(), ProposeNamespace { + events: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: BTreeSet::default(), + }), + ]); ProposeNamespaces(required) } diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 68c3673b19..c390eb194f 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,11 +1,8 @@ use crate::{error::WalletConnectError, pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, - session::rpc::{delete::reply_session_delete_request, - event::reply_session_event_request, - extend::reply_session_extend_request, - ping::reply_session_ping_request, - propose::{process_session_propose_response, reply_session_proposal_request}, - settle::reply_session_settle_request, + session::rpc::{delete::reply_session_delete_request, event::reply_session_event_request, + extend::reply_session_extend_request, ping::reply_session_ping_request, + propose::reply_session_proposal_request, settle::reply_session_settle_request, update::reply_session_update_request}, WalletConnectCtx}; @@ -19,7 +16,7 @@ use serde_json::Value; #[derive(Debug, Serialize, Deserialize)] #[serde(untagged)] -pub enum SuccessResponses { +pub enum WcResponse { ResponseParamsSuccess(ResponseParamsSuccess), Other(Value), } @@ -58,48 +55,21 @@ pub(crate) async fn process_inbound_request( pub(crate) async fn process_inbound_response( ctx: &WalletConnectCtx, response: Response, - topic: &Topic, + _topic: &Topic, ) -> MmResult<(), WalletConnectError> { let message_id = response.id(); match response { Response::Success(value) => { - let success_response = serde_json::from_value::(value.result)?; - match success_response { - SuccessResponses::ResponseParamsSuccess(params) => match params { - ResponseParamsSuccess::SessionPropose(param) => { - process_session_propose_response(ctx, topic, param).await - }, - ResponseParamsSuccess::SessionSettle(success) - | ResponseParamsSuccess::SessionUpdate(success) - | ResponseParamsSuccess::SessionExtend(success) - | ResponseParamsSuccess::SessionRequest(success) - | ResponseParamsSuccess::SessionEvent(success) - | ResponseParamsSuccess::SessionDelete(success) - | ResponseParamsSuccess::SessionPing(success) - | ResponseParamsSuccess::PairingExtend(success) - | ResponseParamsSuccess::PairingDelete(success) - | ResponseParamsSuccess::PairingPing(success) => { - if !success { - return MmError::err(WalletConnectError::UnSuccessfulResponse(format!( - "Unsuccessful response={params:?}" - ))); - }; + let success_response = serde_json::from_value::(value.result)?; + ctx.session_request_sender + .lock() + .await + .send((message_id, success_response)) + .await + .ok(); - Ok(()) - }, - }, - SuccessResponses::Other(value) => { - println!("Received: {value:?}"); - ctx.session_request_sender - .lock() - .await - .send((message_id, value)) - .await - .ok(); - Ok(()) - }, - } + Ok(()) }, Response::Error(err) => { // TODO: handle error properly diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 41c1350fe7..36c0e94a5e 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -1,7 +1,7 @@ pub mod chain; mod connection_handler; #[allow(unused)] pub mod error; -mod inbound_message; +pub mod inbound_message; mod metadata; #[allow(unused)] mod pairing; pub mod session; @@ -9,7 +9,7 @@ mod storage; use crate::session::rpc::propose::send_proposal_request; -use chain::{build_required_namespaces, DEFAULT_CHAIN_ID, SUPPORTED_CHAINS, SUPPORTED_PROTOCOL}; +use chain::{DEFAULT_CHAIN_ID, SUPPORTED_CHAINS, SUPPORTED_PROTOCOL}; use common::log::info; use common::{executor::SpawnFuture, log::error}; use connection_handler::Handler; @@ -17,7 +17,7 @@ use error::WalletConnectError; use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; use futures::lock::Mutex; use futures::StreamExt; -use inbound_message::{process_inbound_request, process_inbound_response}; +use inbound_message::{process_inbound_request, process_inbound_response, WcResponse}; use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_core::mm_ctx::{from_ctx, MmArc}; use mm2_err_handle::prelude::*; @@ -26,7 +26,7 @@ use relay_client::websocket::{Client, PublishedMessage}; use relay_client::{ConnectionOptions, MessageIdGenerator}; use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; use relay_rpc::domain::{MessageId, Topic}; -use relay_rpc::rpc::params::session::{Namespace, ProposeNamespaces}; +use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::{IrnMetadata, Metadata, Relay, RelayProtocolMetadata, RequestParams, ResponseParamsError, ResponseParamsSuccess}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; @@ -37,7 +37,7 @@ use storage::SessionStorageDb; use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; -type SessionEventMessage = (MessageId, Value); +type SessionEventMessage = (MessageId, WcResponse); pub struct WalletConnectCtx { pub client: Client, @@ -50,10 +50,10 @@ pub struct WalletConnectCtx { relay: Relay, metadata: Metadata, - required_namespaces: ProposeNamespaces, subscriptions: Arc>>, inbound_message_handler: Arc>>, connection_live_handler: Arc>>, + session_request_sender: Arc>>, pub session_request_handler: Arc>>, } @@ -67,8 +67,6 @@ impl WalletConnectCtx { let pairing = PairingClient::new(); let client = Client::new(Handler::new("Komodefi", msg_sender, conn_live_sender)); - let required = build_required_namespaces(); - let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), data: None, @@ -82,15 +80,16 @@ impl WalletConnectCtx { session: SessionManager::new(), active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), relay, - required_namespaces: required, metadata: generate_metadata(), key_pair: SymKeyPair::new(), storage, + subscriptions: Default::default(), + inbound_message_handler: Arc::new(Mutex::new(msg_receiver)), connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), + session_request_handler: Arc::new(Mutex::new(session_request_receiver)), session_request_sender: Arc::new(Mutex::new(session_request_sender)), - subscriptions: Default::default(), }) } @@ -118,10 +117,7 @@ impl WalletConnectCtx { } /// Create a WalletConnect pairing connection url. - pub async fn new_connection( - &self, - required_namespaces: Option, - ) -> MmResult { + pub async fn new_connection(&self) -> MmResult { let (topic, url) = self.pairing.create(self.metadata.clone(), None).await?; info!("Subscribing to topic: {topic:?}"); @@ -130,7 +126,7 @@ impl WalletConnectCtx { info!("Subscribed to topic: {topic:?}"); - send_proposal_request(self, topic.clone(), required_namespaces).await?; + send_proposal_request(self, topic.clone()).await?; { let mut subs = self.subscriptions.lock().await; diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index b32d7ac602..f927eb25ac 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,6 +1,7 @@ pub(crate) mod key; pub mod rpc; +use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; @@ -9,7 +10,7 @@ use dashmap::mapref::one::{Ref, RefMut}; use dashmap::DashMap; use futures::lock::Mutex; use key::SessionKey; -use mm2_err_handle::prelude::{MmError, MmResult}; +use mm2_err_handle::prelude::{MapMmError, MmError, MmResult}; use relay_rpc::domain::Topic; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; @@ -160,7 +161,7 @@ impl Session { controller, namespaces: BTreeMap::new(), proposer, - propose_namespaces: ctx.required_namespaces.clone(), + propose_namespaces: ProposeNamespaces::default(), relay: ctx.relay.clone(), expiry: Utc::now().timestamp() as u64 + FIVE_MINUTES, pairing_topic, @@ -257,6 +258,17 @@ impl SessionManager { MmError::err(WalletConnectError::SessionError("Session not found".to_owned())) } + pub(crate) async fn get_active_topic_or_err(&self) -> MmResult { + self.0 + .active_topic + .lock() + .await + .clone() + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active session".to_owned(), + ))) + } + /// Retrieves a cloned session associated with a given topic. pub fn get_session(&self, topic: &Topic) -> Option> { self.0.sessions.get(topic) } @@ -337,9 +349,13 @@ impl SessionManager { } } -pub async fn disconnect_session_rpc_rpc(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { +pub async fn disconnect_session_rpc(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { ctx.client.unsubscribe(topic.clone()).await?; ctx.session.delete_session(topic).await; + ctx.storage + .delete_session(topic) + .await + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 4d31d530c1..42f18f6dab 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,4 +1,6 @@ use super::settle::send_session_settle_request; +use crate::chain::build_default_required_namespaces; +use crate::inbound_message::WcResponse; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, metadata::generate_metadata, @@ -6,19 +8,15 @@ use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; +use futures::StreamExt; use mm2_err_handle::map_to_mm::MapToMmResult; use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session::ProposeNamespaces, - session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, + rpc::params::{session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, RequestParams, ResponseParamsSuccess}}; /// Creates a new session proposal form topic and metadata. -pub(crate) async fn send_proposal_request( - ctx: &WalletConnectCtx, - topic: Topic, - required_namespaces: Option, -) -> MmResult<(), WalletConnectError> { +pub(crate) async fn send_proposal_request(ctx: &WalletConnectCtx, topic: Topic) -> MmResult<(), WalletConnectError> { let proposer = Proposer { metadata: ctx.metadata.clone(), public_key: hex::encode(ctx.key_pair.public_key.as_bytes()), @@ -26,12 +24,20 @@ pub(crate) async fn send_proposal_request( let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], proposer, - required_namespaces: required_namespaces.unwrap_or(ctx.required_namespaces.clone()), + required_namespaces: build_default_required_namespaces(), }); - ctx.publish_request(&topic, session_proposal).await?; - Ok(()) + if let Some((_message_id, WcResponse::ResponseParamsSuccess(ResponseParamsSuccess::SessionPropose(response)))) = + ctx.session_request_handler.lock().await.next().await + { + return process_session_propose_response(ctx, &topic, response).await; + } + + // If the update is rejected, return an error + MmError::err(WalletConnectError::SessionError( + "Error while processing request".to_owned(), + )) } /// Process session proposal request @@ -99,7 +105,7 @@ pub async fn reply_session_proposal_request( } /// Process session propose reponse. -pub(crate) async fn process_session_propose_response( +async fn process_session_propose_response( ctx: &WalletConnectCtx, pairing_topic: &Topic, response: SessionProposeResponse, diff --git a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs index 3dfbd218ab..a44349aec9 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs @@ -18,7 +18,7 @@ pub async fn new_connection( let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; let url = ctx - .new_connection(None) + .new_connection() .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 645d8dee9e..98d0281f66 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -1,5 +1,5 @@ use kdf_walletconnect::session::SessionRpcInfo; -use kdf_walletconnect::session::{disconnect_session_rpc_rpc, rpc::send_session_ping_request}; +use kdf_walletconnect::session::{disconnect_session_rpc, rpc::send_session_ping_request}; use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -80,7 +80,7 @@ pub async fn disconnect_session( ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - disconnect_session_rpc_rpc(&ctx, &req.topic.into()) + disconnect_session_rpc(&ctx, &req.topic.into()) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; From b35882504d01f187cf57a3c58b796c93c37f2abd Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 24 Oct 2024 18:09:54 +0100 Subject: [PATCH 078/125] improve session message handling process --- mm2src/coins/eth/wallet_connect.rs | 23 ++++---- mm2src/coins/tendermint/wallet_connect.rs | 52 +++++++++++-------- mm2src/crypto/Cargo.toml | 2 +- mm2src/kdf_walletconnect/src/error.rs | 2 + .../kdf_walletconnect/src/inbound_message.rs | 50 +++++++----------- mm2src/kdf_walletconnect/src/lib.rs | 17 +++--- mm2src/kdf_walletconnect/src/session.rs | 2 +- .../src/session/rpc/propose.rs | 17 +++--- 8 files changed, 79 insertions(+), 86 deletions(-) diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 1c082409f0..6d5f92c7ce 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -7,7 +7,6 @@ use ethereum_types::{Address, Public, H160}; use ethkey::{public_to_address, Message, Signature}; use kdf_walletconnect::{chain::{WcChain, WcRequestMethods}, error::WalletConnectError, - inbound_message::WcResponse, WalletConnectCtx}; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session_request::SessionRequestRequest; @@ -51,18 +50,20 @@ pub async fn eth_request_wc_personal_sign( ctx.publish_request(&topic, session_request).await?; } - if let Some((message_id, WcResponse::Other(response))) = ctx.session_request_handler.lock().await.next().await { - let result = serde_json::from_value::(response)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&topic, response, &message_id).await?; + if let Some(resp) = ctx.message_rx.lock().await.next().await { + let result = resp.mm_err(WalletConnectError::InternalError)?; + if let ResponseParamsSuccess::Arbitrary(data) = result.data { + let signature = serde_json::from_value::(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&result.topic, response, &result.message_id) + .await?; - let res = extract_pubkey_from_signature(&result, message, &account_str) - .mm_err(|err| WalletConnectError::PayloadError(err.to_string()))?; - - return Ok(res); - } + return extract_pubkey_from_signature(&signature, message, &account_str) + .mm_err(|err| WalletConnectError::PayloadError(err.to_string())); + }; + }; - MmError::err(WalletConnectError::InternalError("No response from wallet".to_string())) + MmError::err(WalletConnectError::NoWalletFeedback) } fn extract_pubkey_from_signature( diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index ad2782e246..052a407cca 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -5,7 +5,6 @@ use base64::Engine; use chrono::Utc; use futures::StreamExt; use kdf_walletconnect::error::WalletConnectError; -use kdf_walletconnect::inbound_message::WcResponse; use kdf_walletconnect::{chain::WcRequestMethods, WalletConnectCtx}; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session_request::Request as SessionRequest; @@ -75,15 +74,19 @@ pub async fn cosmos_request_wc_signed_tx( ctx.publish_request(&topic, session_request).await?; } - if let Some((message_id, WcResponse::Other(response))) = ctx.session_request_handler.lock().await.next().await { - let result = serde_json::from_value::(response)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&topic, response, &message_id).await?; + if let Some(resp) = ctx.message_rx.lock().await.next().await { + let result = resp.mm_err(WalletConnectError::InternalError)?; + if let ResponseParamsSuccess::Arbitrary(data) = result.data { + let tx_data = serde_json::from_value::(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&result.topic, response, &result.message_id) + .await?; - return Ok(result); - } + return Ok(tx_data); + } + }; - MmError::err(WalletConnectError::InternalError("No response from wallet".to_string())) + MmError::err(WalletConnectError::NoWalletFeedback) } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -128,6 +131,7 @@ pub async fn cosmos_get_accounts_impl( .get_session_active() .await .ok_or(WalletConnectError::NotInitialized)?; + // Check if existing session has session_properties and return wallet account; if let Some(props) = &session.session_properties { if let Some(keys) = &props.keys { @@ -168,24 +172,28 @@ pub async fn cosmos_get_accounts_impl( ctx.publish_request(&topic, session_request).await?; }; - if let Some((message_id, WcResponse::Other(response))) = ctx.session_request_handler.lock().await.next().await { - let accounts = serde_json::from_value::>(response)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&topic, response, &message_id).await?; + if let Some(resp) = ctx.message_rx.lock().await.next().await { + let result = resp.mm_err(WalletConnectError::InternalError)?; + if let ResponseParamsSuccess::Arbitrary(data) = result.data { + let accounts = serde_json::from_value::>(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(&result.topic, response, &result.message_id) + .await?; - if accounts.is_empty() { - return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); - }; + if accounts.is_empty() { + return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); + }; - let account_index = account_index.unwrap_or(0); - if accounts.len() < account_index + 1 { - return MmError::err(WalletConnectError::NoAccountFoundForIndex(account_index)); - }; + let account_index = account_index.unwrap_or(0); + if accounts.len() < account_index + 1 { + return MmError::err(WalletConnectError::NoAccountFoundForIndex(account_index)); + }; - return Ok(accounts[account_index].clone()); - } + return Ok(accounts[account_index].clone()); + } + }; - MmError::err(WalletConnectError::NoAccountFound(chain_id.to_owned())) + MmError::err(WalletConnectError::NoWalletFeedback) } fn deserialize_vec_field<'de, D>(deserializer: D) -> Result, D::Error> diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index 72e2c0e884..08494c7b46 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -34,7 +34,7 @@ mm2_err_handle = { path = "../mm2_err_handle" } num-traits = "0.2" parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } -rand = "0.8.5" +rand = "0.8" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } rustc-hex = "2" diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 1c1b260e97..14cccf522d 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -84,6 +84,8 @@ pub enum WalletConnectError { StorageError(String), #[error("ChainId mismatch")] ChainIdMismatch, + #[error("No feedback from wallet")] + NoWalletFeedback, } impl From> for WalletConnectError { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index c390eb194f..87a5565256 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -9,16 +9,14 @@ use crate::{error::WalletConnectError, use common::log::info; use futures::sink::SinkExt; use mm2_err_handle::prelude::{MmError, MmResult}; -use relay_rpc::domain::Topic; +use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::{params::ResponseParamsSuccess, Params, Request, Response}; -use serde::{Deserialize, Serialize}; -use serde_json::Value; -#[derive(Debug, Serialize, Deserialize)] -#[serde(untagged)] -pub enum WcResponse { - ResponseParamsSuccess(ResponseParamsSuccess), - Other(Value), +pub(crate) type SessionMessageType = MmResult; +pub struct SessionMessage { + pub message_id: MessageId, + pub topic: Topic, + pub data: ResponseParamsSuccess, } pub(crate) async fn process_inbound_request( @@ -52,29 +50,19 @@ pub(crate) async fn process_inbound_request( Ok(()) } -pub(crate) async fn process_inbound_response( - ctx: &WalletConnectCtx, - response: Response, - _topic: &Topic, -) -> MmResult<(), WalletConnectError> { +pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: Response, topic: &Topic) { let message_id = response.id(); - - match response { - Response::Success(value) => { - let success_response = serde_json::from_value::(value.result)?; - ctx.session_request_sender - .lock() - .await - .send((message_id, success_response)) - .await - .ok(); - - Ok(()) + let result = match response { + Response::Success(value) => match serde_json::from_value::(value.result) { + Ok(data) => Ok(SessionMessage { + message_id, + topic: topic.clone(), + data, + }), + Err(e) => MmError::err(e.to_string()), }, - Response::Error(err) => { - // TODO: handle error properly - println!("Error: {err:?}"); - Ok(()) - }, - } + Response::Error(err) => MmError::err(format!("{err:?}")), + }; + + ctx.message_tx.lock().await.send(result).await.ok(); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 36c0e94a5e..5c1d463209 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -17,7 +17,7 @@ use error::WalletConnectError; use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; use futures::lock::Mutex; use futures::StreamExt; -use inbound_message::{process_inbound_request, process_inbound_response, WcResponse}; +use inbound_message::{process_inbound_request, process_inbound_response, SessionMessageType}; use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_core::mm_ctx::{from_ctx, MmArc}; use mm2_err_handle::prelude::*; @@ -37,8 +37,6 @@ use storage::SessionStorageDb; use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; -type SessionEventMessage = (MessageId, WcResponse); - pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, @@ -54,15 +52,15 @@ pub struct WalletConnectCtx { inbound_message_handler: Arc>>, connection_live_handler: Arc>>, - session_request_sender: Arc>>, - pub session_request_handler: Arc>>, + message_tx: Arc>>, + pub message_rx: Arc>>, } impl WalletConnectCtx { pub fn try_init(ctx: &MmArc) -> MmResult { let (msg_sender, msg_receiver) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); - let (session_request_sender, session_request_receiver) = unbounded(); + let (message_tx, session_request_receiver) = unbounded(); let pairing = PairingClient::new(); let client = Client::new(Handler::new("Komodefi", msg_sender, conn_live_sender)); @@ -88,8 +86,8 @@ impl WalletConnectCtx { inbound_message_handler: Arc::new(Mutex::new(msg_receiver)), connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), - session_request_handler: Arc::new(Mutex::new(session_request_receiver)), - session_request_sender: Arc::new(Mutex::new(session_request_sender)), + message_rx: Arc::new(Mutex::new(session_request_receiver)), + message_tx: Arc::new(Mutex::new(message_tx)), }) } @@ -276,7 +274,7 @@ impl WalletConnectCtx { match payload { Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, - Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await?, + Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await, } info!("Inbound message was handled successfully"); @@ -357,7 +355,6 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect fn find_account_in_namespace(namespace: &Namespace, chain_id: &str) -> Option { let accounts = namespace.accounts.as_ref()?; - println!("ACCOUNTS: {accounts:?}"); accounts.iter().find_map(|account_name| { let parts: Vec<&str> = account_name.split(':').collect(); if parts.len() >= 3 && parts[1] == chain_id { diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index f927eb25ac..4bf0cd642f 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -258,7 +258,7 @@ impl SessionManager { MmError::err(WalletConnectError::SessionError("Session not found".to_owned())) } - pub(crate) async fn get_active_topic_or_err(&self) -> MmResult { + pub async fn get_active_topic_or_err(&self) -> MmResult { self.0 .active_topic .lock() diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 42f18f6dab..d7cb9d3422 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,6 +1,5 @@ use super::settle::send_session_settle_request; use crate::chain::build_default_required_namespaces; -use crate::inbound_message::WcResponse; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, metadata::generate_metadata, @@ -28,16 +27,14 @@ pub(crate) async fn send_proposal_request(ctx: &WalletConnectCtx, topic: Topic) }); ctx.publish_request(&topic, session_proposal).await?; - if let Some((_message_id, WcResponse::ResponseParamsSuccess(ResponseParamsSuccess::SessionPropose(response)))) = - ctx.session_request_handler.lock().await.next().await - { - return process_session_propose_response(ctx, &topic, response).await; - } + if let Some(resp) = ctx.message_rx.lock().await.next().await { + let resp = resp.mm_err(WalletConnectError::InternalError)?; + if let ResponseParamsSuccess::SessionPropose(data) = resp.data { + return process_session_propose_response(ctx, &resp.topic, data).await; + }; + }; - // If the update is rejected, return an error - MmError::err(WalletConnectError::SessionError( - "Error while processing request".to_owned(), - )) + MmError::err(WalletConnectError::NoWalletFeedback) } /// Process session proposal request From afc4058545783b7c40b4ed0b28f32a5b7411ea2b Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 24 Oct 2024 21:24:46 +0100 Subject: [PATCH 079/125] further wc improve message handling --- Cargo.lock | 13 +- mm2src/coins/eth/wallet_connect.rs | 26 +- mm2src/coins/siacoin.rs | 6 + mm2src/coins/tendermint/wallet_connect.rs | 56 +- mm2src/crypto/Cargo.toml | 4 +- mm2src/kdf_walletconnect/Cargo.toml | 4 +- mm2src/kdf_walletconnect/src/chain.rs | 8 +- .../kdf_walletconnect/src/inbound_message.rs | 27 +- mm2src/kdf_walletconnect/src/lib.rs | 225 +- .../src/session/rpc/event.rs | 1 + .../src/session/rpc/propose.rs | 18 +- mm2src/mm2_test_helpers/Cargo.lock | 5763 +++++++++++++++++ 12 files changed, 5964 insertions(+), 187 deletions(-) create mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index c3ac18236f..919ff1fb35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -450,7 +450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" dependencies = [ "bitcoin_hashes 0.13.0", - "rand_core 0.6.4", + "rand_core 0.5.1", "zeroize", ] @@ -1342,7 +1342,6 @@ dependencies = [ "num-traits", "parking_lot", "primitives", - "rand 0.8.5", "rpc", "rpc_task", "rustc-hex", @@ -4745,7 +4744,7 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" dependencies = [ "anyhow", "chrono", @@ -5172,7 +5171,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes 1.4.0", - "heck 0.5.0", + "heck 0.4.0", "itertools", "log", "multimap", @@ -5645,7 +5644,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" dependencies = [ "chrono", "data-encoding", @@ -5673,7 +5672,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" dependencies = [ "anyhow", "bs58 0.4.0", @@ -8036,7 +8035,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#3ea808b981a7db0cb4c805bd156be0d48546a4fc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" dependencies = [ "base64 0.21.7", "chacha20poly1305", diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 6d5f92c7ce..fb7fd60566 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -1,6 +1,3 @@ -use std::str::FromStr; - -use async_std::stream::StreamExt; use chrono::Utc; use derive_more::Display; use ethereum_types::{Address, Public, H160}; @@ -10,9 +7,10 @@ use kdf_walletconnect::{chain::{WcChain, WcRequestMethods}, WalletConnectCtx}; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session_request::SessionRequestRequest; -use relay_rpc::rpc::params::{session_request::Request as SessionRequest, RequestParams, ResponseParamsSuccess}; +use relay_rpc::rpc::params::{session_request::Request as SessionRequest, RequestParams}; use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, Secp256k1}; +use std::str::FromStr; use web3::signing::hash_message; #[derive(Display, Debug)] @@ -21,6 +19,10 @@ pub enum EthWalletConnectError { AccoountMisMatch(String), } +impl From for WalletConnectError { + fn from(value: EthWalletConnectError) -> Self { Self::SessionError(value.to_string()) } +} + pub async fn eth_request_wc_personal_sign( ctx: &WalletConnectCtx, chain_id: u64, @@ -50,20 +52,8 @@ pub async fn eth_request_wc_personal_sign( ctx.publish_request(&topic, session_request).await?; } - if let Some(resp) = ctx.message_rx.lock().await.next().await { - let result = resp.mm_err(WalletConnectError::InternalError)?; - if let ResponseParamsSuccess::Arbitrary(data) = result.data { - let signature = serde_json::from_value::(data)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&result.topic, response, &result.message_id) - .await?; - - return extract_pubkey_from_signature(&signature, message, &account_str) - .mm_err(|err| WalletConnectError::PayloadError(err.to_string())); - }; - }; - - MmError::err(WalletConnectError::NoWalletFeedback) + ctx.on_wc_session_response(|data: String| Ok(extract_pubkey_from_signature(&data, message, &account_str)?)) + .await } fn extract_pubkey_from_signature( diff --git a/mm2src/coins/siacoin.rs b/mm2src/coins/siacoin.rs index 4e77a74731..08c8baa0d3 100644 --- a/mm2src/coins/siacoin.rs +++ b/mm2src/coins/siacoin.rs @@ -312,6 +312,12 @@ impl MarketCoinOps for SiaCoin { ) .into()); }, + &PrivKeyPolicy::WalletConnect { .. } => { + return Err(MyAddressError::UnexpectedDerivationMethod( + "WalletConnect not yet supported. Must use iguana seed.".to_string(), + ) + .into()) + }, }; let address = SpendPolicy::PublicKey(key_pair.public).address(); Ok(address.to_string()) diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 052a407cca..4c5cdaa21a 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -1,17 +1,16 @@ -use std::str::FromStr; - use base64::engine::general_purpose; use base64::Engine; use chrono::Utc; -use futures::StreamExt; +use kdf_walletconnect::chain::WcChain; use kdf_walletconnect::error::WalletConnectError; use kdf_walletconnect::{chain::WcRequestMethods, WalletConnectCtx}; use mm2_err_handle::prelude::*; use relay_rpc::rpc::params::session_request::Request as SessionRequest; use relay_rpc::rpc::params::session_request::SessionRequestRequest; -use relay_rpc::rpc::params::{RequestParams, ResponseParamsSuccess}; +use relay_rpc::rpc::params::RequestParams; use serde::{Deserialize, Serialize}; use serde_json::Value; +use std::str::FromStr; #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct CosmosTxSignedData { @@ -67,26 +66,14 @@ pub async fn cosmos_request_wc_signed_tx( expiry: Some(Utc::now().timestamp() as u64 + 300), params: sign_doc, }, - chain_id: format!("cosmos:{chain_id}"), + chain_id: (WcChain::Cosmos).to_chain_id(chain_id), }; { let session_request = RequestParams::SessionRequest(request); ctx.publish_request(&topic, session_request).await?; } - if let Some(resp) = ctx.message_rx.lock().await.next().await { - let result = resp.mm_err(WalletConnectError::InternalError)?; - if let ResponseParamsSuccess::Arbitrary(data) = result.data { - let tx_data = serde_json::from_value::(data)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&result.topic, response, &result.message_id) - .await?; - - return Ok(tx_data); - } - }; - - MmError::err(WalletConnectError::NoWalletFeedback) + ctx.on_wc_session_response::(Ok).await } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -164,7 +151,7 @@ pub async fn cosmos_get_accounts_impl( expiry: Some(Utc::now().timestamp() as u64 + 300), params: serde_json::to_value(&account).unwrap(), }, - chain_id: format!("cosmos:{chain_id}"), + chain_id: WcChain::Cosmos.to_chain_id(chain_id), }; { @@ -172,28 +159,19 @@ pub async fn cosmos_get_accounts_impl( ctx.publish_request(&topic, session_request).await?; }; - if let Some(resp) = ctx.message_rx.lock().await.next().await { - let result = resp.mm_err(WalletConnectError::InternalError)?; - if let ResponseParamsSuccess::Arbitrary(data) = result.data { - let accounts = serde_json::from_value::>(data)?; - let response = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(&result.topic, response, &result.message_id) - .await?; - - if accounts.is_empty() { - return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); - }; - - let account_index = account_index.unwrap_or(0); - if accounts.len() < account_index + 1 { - return MmError::err(WalletConnectError::NoAccountFoundForIndex(account_index)); - }; + ctx.on_wc_session_response::, _, _>(|accounts| { + if accounts.is_empty() { + return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); + }; - return Ok(accounts[account_index].clone()); - } - }; + let account_index = account_index.unwrap_or(0); + if accounts.len() < account_index + 1 { + return MmError::err(WalletConnectError::NoAccountFoundForIndex(account_index)); + }; - MmError::err(WalletConnectError::NoWalletFeedback) + Ok(accounts[account_index].clone()) + }) + .await } fn deserialize_vec_field<'de, D>(deserializer: D) -> Result, D::Error> diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index 08494c7b46..0a5abe3919 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -34,7 +34,6 @@ mm2_err_handle = { path = "../mm2_err_handle" } num-traits = "0.2" parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } -rand = "0.8" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } rustc-hex = "2" @@ -61,3 +60,6 @@ tokio = { version = "1.20", default-features = false } [features] trezor-udp = ["trezor/trezor-udp"] + +[patch.crates-io] +rand = { version = "0.8.5", package = "rand" } diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 9850057fd9..b46301ca30 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -29,15 +29,13 @@ relay_client = { git = "https://github.com/komodoplatform/walletconnectrust", br relay_rpc = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } sha2 = "0.10.7" thiserror = "1.0.40" +tokio = { version = "1.20" } wc_common = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } secp256k1 = { version = "0.20" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } x25519-dalek = { version = "2.0", features = ["static_secrets"] } -[target.'cfg(not(target_arch = "wasm32"))'.dependencies] -tokio = { version = "1.20" } - [target.'cfg(target_arch = "wasm32")'.dependencies] js-sys = { version = "0.3.27" } mm2_db = { path = "../mm2_db" } diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index 07c107ccf5..0a2c9f81d4 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -27,6 +27,10 @@ impl AsRef for WcChain { } } +impl WcChain { + pub fn to_chain_id(&self, chain_id: &str) -> String { format!("{}:{chain_id}", self.as_ref()) } +} + #[derive(Debug, Clone)] pub enum WcRequestMethods { CosmosSignDirect, @@ -56,9 +60,9 @@ pub(crate) fn build_default_required_namespaces() -> ProposeNamespaces { methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), }), (WcChain::Cosmos.as_ref().to_string(), ProposeNamespace { - events: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: BTreeSet::default(), + events: BTreeSet::default(), }), ]); diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 87a5565256..eb1eddedeb 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,8 +1,11 @@ use crate::{error::WalletConnectError, pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, - session::rpc::{delete::reply_session_delete_request, event::reply_session_event_request, - extend::reply_session_extend_request, ping::reply_session_ping_request, - propose::reply_session_proposal_request, settle::reply_session_settle_request, + session::rpc::{delete::reply_session_delete_request, + event::reply_session_event_request, + extend::reply_session_extend_request, + ping::reply_session_ping_request, + propose::{process_session_propose_response, reply_session_proposal_request}, + settle::reply_session_settle_request, update::reply_session_update_request}, WalletConnectCtx}; @@ -13,6 +16,7 @@ use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::{params::ResponseParamsSuccess, Params, Request, Response}; pub(crate) type SessionMessageType = MmResult; +#[derive(Debug)] pub struct SessionMessage { pub message_id: MessageId, pub topic: Topic, @@ -54,11 +58,18 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: R let message_id = response.id(); let result = match response { Response::Success(value) => match serde_json::from_value::(value.result) { - Ok(data) => Ok(SessionMessage { - message_id, - topic: topic.clone(), - data, - }), + Ok(data) => { + // Probably the best place to handle session propose response. + if let ResponseParamsSuccess::SessionPropose(propose) = &data { + process_session_propose_response(ctx, topic, propose).await.ok(); + } + + Ok(SessionMessage { + message_id, + topic: topic.clone(), + data, + }) + }, Err(e) => MmError::err(e.to_string()), }, Response::Error(err) => MmError::err(format!("{err:?}")), diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 5c1d463209..bde97fe4bc 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -30,11 +30,13 @@ use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::{IrnMetadata, Metadata, Relay, RelayProtocolMetadata, RequestParams, ResponseParamsError, ResponseParamsSuccess}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; +use serde::de::DeserializeOwned; use serde_json::Value; use session::{key::SymKeyPair, SessionManager}; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; +use tokio::time::timeout; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; pub struct WalletConnectCtx { @@ -134,42 +136,7 @@ impl WalletConnectCtx { Ok(url) } - pub async fn is_ledger_connection(&self) -> bool { - self.session - .get_session_active() - .await - .and_then(|session| session.session_properties.clone()) - .and_then(|props| props.keys.as_ref().cloned()) - .and_then(|keys| keys.first().cloned()) - .map(|key| key.is_nano_ledger) - .unwrap_or(false) - } - - pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|&chain| chain == chain_id) } - - pub async fn set_active_chain(&self, chain_id: &str) { - let mut active_chain = self.active_chain_id.lock().await; - *active_chain = chain_id.to_owned(); - } - - pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } - - /// Retrieves the available account for a given chain ID. - pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { - let namespaces = &self - .session - .get_session_active() - .await - .ok_or(MmError::new(WalletConnectError::SessionError( - "No active WalletConnect session found".to_string(), - )))? - .namespaces; - namespaces - .iter() - .find_map(|(_key, namespace)| find_account_in_namespace(namespace, chain_id)) - .ok_or(MmError::new(WalletConnectError::NoAccountFound(chain_id.to_string()))) - } - + /// Retrieves the symmetric key associated with a given `topic`. async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectError> { { if let Some(key) = self.session.sym_key(topic) { @@ -185,7 +152,62 @@ impl WalletConnectCtx { } } - MmError::err(WalletConnectError::PairingError(format!("Topic not found:{topic}"))) + MmError::err(WalletConnectError::InternalError(format!("Topic not found:{topic}"))) + } + + /// Handles an inbound published message by decrypting, decoding, and processing it. + async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectError> { + let message = { + let key = self.sym_key(&msg.topic).await?; + decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() + }; + + info!("Inbound message payload={message}"); + + let payload: Payload = serde_json::from_str(&message)?; + + match payload { + Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, + Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await, + } + + info!("Inbound message was handled successfully"); + Ok(()) + } + + /// Loads sessions from storage, activates valid ones, and deletes expired ones. + async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectError> { + let now = chrono::Utc::now().timestamp() as u64; + let mut sessions = self + .storage + .get_all_sessions() + .await + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; + + sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); + + for session in sessions { + // delete expired session + if now > session.expiry { + info!("Session {} expired, trying to delete from storage", session.topic); + if let Err(err) = self.storage.delete_session(&session.topic).await { + error!("Unable to delete session: {:?} from storage", err); + } + continue; + }; + + let topic = session.topic.clone(); + let pairing_topic = session.pairing_topic.clone(); + + info!("Session found! activating :{}", topic); + self.session.add_session(session).await; + + // subcribe to session topics + self.client.subscribe(topic).await?; + self.client.subscribe(pairing_topic).await?; + } + + Ok(()) } /// function to publish a request. @@ -202,7 +224,7 @@ impl WalletConnectCtx { } /// Private function to publish a success request response. - pub async fn publish_response_ok( + pub(crate) async fn publish_response_ok( &self, topic: &Topic, result: ResponseParamsSuccess, @@ -218,7 +240,7 @@ impl WalletConnectCtx { } /// Private function to publish an error request response. - async fn publish_response_err( + pub(crate) async fn publish_response_err( &self, topic: &Topic, error_data: ResponseParamsError, @@ -234,7 +256,7 @@ impl WalletConnectCtx { } /// Private function to publish a payload. - async fn publish_payload( + pub(crate) async fn publish_payload( &self, topic: &Topic, irn_metadata: IrnMetadata, @@ -262,60 +284,84 @@ impl WalletConnectCtx { Ok(()) } - async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectError> { - let message = { - let key = self.sym_key(&msg.topic).await?; - decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() - }; - - info!("Inbound message payload={message}"); - - let payload: Payload = serde_json::from_str(&message)?; - - match payload { - Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, - Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await, - } - - info!("Inbound message was handled successfully"); - Ok(()) - } - - async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectError> { - let now = chrono::Utc::now().timestamp() as u64; - let mut sessions = self - .storage - .get_all_sessions() + /// Checks if the current session is connected to a Ledger device. + /// NOTE: for COSMOS chains only. + pub async fn is_ledger_connection(&self) -> bool { + self.session + .get_session_active() .await - .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; + .and_then(|session| session.session_properties.clone()) + .and_then(|props| props.keys.as_ref().cloned()) + .and_then(|keys| keys.first().cloned()) + .map(|key| key.is_nano_ledger) + .unwrap_or(false) + } - sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); + /// Checks if a given chain ID is supported. + pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|&c| c == chain_id) } - for session in sessions { - // delete expired session - if now > session.expiry { - info!("Session {} expired, trying to delete from storage", session.topic); - if let Err(err) = self.storage.delete_session(&session.topic).await { - error!("Unable to delete session: {:?} from storage", err); - } - continue; - }; + /// Sets the active chain ID for the current session. + pub async fn set_active_chain(&self, chain_id: &str) { + let mut active_chain = self.active_chain_id.lock().await; + *active_chain = chain_id.to_owned(); + } - let topic = session.topic.clone(); - let pairing_topic = session.pairing_topic.clone(); + /// Retrieves the current active chain ID. + pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } - info!("Session found! activating :{}", topic); - self.session.add_session(session).await; + /// Retrieves the available account for a given chain ID. + pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { + let namespaces = &self + .session + .get_session_active() + .await + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active WalletConnect session found".to_string(), + )))? + .namespaces; + namespaces + .iter() + .find_map(|(_key, namespace)| find_account_in_namespace(namespace, chain_id)) + .ok_or(MmError::new(WalletConnectError::NoAccountFound(chain_id.to_string()))) + } - // subcribe to session topics - self.client.subscribe(topic).await?; - self.client.subscribe(pairing_topic).await?; + /// Waits for and handles a WalletConnect session response with arbitrary data. + pub async fn on_wc_session_response(&self, func: F) -> MmResult + where + T: DeserializeOwned, + F: Fn(T) -> MmResult, + { + let wait_duration = Duration::from_secs(30); + + while let Ok(Some(resp)) = timeout(wait_duration, self.message_rx.lock().await.next()).await { + let result = resp.mm_err(WalletConnectError::InternalError)?; + if let ResponseParamsSuccess::Arbitrary(data) = result.data { + let data = serde_json::from_value::(data)?; + let response = ResponseParamsSuccess::SessionEvent(true); + self.publish_response_ok(&result.topic, response, &result.message_id) + .await?; + + return func(data); + } } - Ok(()) + MmError::err(WalletConnectError::NoWalletFeedback) } } +#[async_trait::async_trait] +pub trait WcRequestOps { + type Error; + type SignTxData; + + async fn wc_request_sign_tx( + &self, + ctx: &WalletConnectCtx, + chain_id: &str, + tx_json: Value, + ) -> Result; +} + /// This function spwans related WalletConnect related tasks and needed initialization before /// WalletConnect can be usable in KDF. pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectError> { @@ -364,16 +410,3 @@ fn find_account_in_namespace(namespace: &Namespace, chain_id: &str) -> Option Result; -} diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 869c3408a4..20092bc173 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -92,6 +92,7 @@ impl SessionEvent { message: "Chain_Id was changed to an unsupported chain".to_string(), data: None, }; + ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) .await?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index d7cb9d3422..1a4bc3a622 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -7,7 +7,6 @@ use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; -use futures::StreamExt; use mm2_err_handle::map_to_mm::MapToMmResult; use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, @@ -27,14 +26,7 @@ pub(crate) async fn send_proposal_request(ctx: &WalletConnectCtx, topic: Topic) }); ctx.publish_request(&topic, session_proposal).await?; - if let Some(resp) = ctx.message_rx.lock().await.next().await { - let resp = resp.mm_err(WalletConnectError::InternalError)?; - if let ResponseParamsSuccess::SessionPropose(data) = resp.data { - return process_session_propose_response(ctx, &resp.topic, data).await; - }; - }; - - MmError::err(WalletConnectError::NoWalletFeedback) + Ok(()) } /// Process session proposal request @@ -102,10 +94,10 @@ pub async fn reply_session_proposal_request( } /// Process session propose reponse. -async fn process_session_propose_response( +pub(crate) async fn process_session_propose_response( ctx: &WalletConnectCtx, pairing_topic: &Topic, - response: SessionProposeResponse, + response: &SessionProposeResponse, ) -> MmResult<(), WalletConnectError> { let other_public_key = hex::decode(&response.responder_public_key)? .as_slice() @@ -131,9 +123,9 @@ async fn process_session_propose_response( generate_metadata(), SessionType::Proposer, ); - session.relay = response.relay; + session.relay = response.relay.clone(); session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; - session.controller.public_key = response.responder_public_key; + session.controller.public_key = response.responder_public_key.clone(); { // save session to storage diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock new file mode 100644 index 0000000000..32fa8dda62 --- /dev/null +++ b/mm2src/mm2_test_helpers/Cargo.lock @@ -0,0 +1,5763 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[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.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "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 1.0.0", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" + +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", + "zeroize", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "asn1_der" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite 0.2.15", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if 1.0.0", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[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 0.2.15", +] + +[[package]] +name = "async-process" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" +dependencies = [ + "async-channel 2.3.1", + "async-io", + "async-lock", + "async-signal", + "async-task", + "blocking", + "cfg-if 1.0.0", + "event-listener 5.3.1", + "futures-lite", + "rustix", + "tracing", +] + +[[package]] +name = "async-signal" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" +dependencies = [ + "async-io", + "async-lock", + "atomic-waker", + "cfg-if 1.0.0", + "futures-core", + "futures-io", + "rustix", + "signal-hook-registry", + "slab", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "async-process", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers 0.3.0", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite 0.2.15", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + +[[package]] +name = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "asynchronous-codec" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" +dependencies = [ + "bytes 1.8.0", + "futures-sink", + "futures-util", + "memchr", + "pin-project-lite 0.2.15", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" +dependencies = [ + "autocfg 1.4.0", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if 1.0.0", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base-x" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" + +[[package]] +name = "base58" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" + +[[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 = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bech32" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" + +[[package]] +name = "bigdecimal" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "bip32" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" +dependencies = [ + "bs58 0.4.0", + "hkd32", + "hmac 0.11.0", + "ripemd160", + "secp256k1 0.20.3", + "sha2 0.9.9", + "subtle", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" +dependencies = [ + "bitcoin_hashes 0.13.0", + "rand_core 0.6.4", + "zeroize", +] + +[[package]] +name = "bitcoin" +version = "0.29.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" +dependencies = [ + "bech32", + "bitcoin_hashes 0.11.0", + "secp256k1 0.24.3", +] + +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + +[[package]] +name = "bitcrypto" +version = "0.1.0" +dependencies = [ + "groestl", + "primitives", + "ripemd160", + "serialization", + "sha-1", + "sha2 0.10.8", + "sha3 0.9.1", + "siphasher", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[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 = "blake2b_simd" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "block-padding 0.2.1", + "generic-array", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + +[[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 = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "byte-slice-cast" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" +dependencies = [ + "byteorder", + "iovec", +] + +[[package]] +name = "bytes" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" + +[[package]] +name = "cbc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "chain" +version = "0.1.0" +dependencies = [ + "bitcoin", + "bitcrypto", + "primitives", + "rustc-hex", + "serialization", + "serialization_derive", +] + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-targets 0.52.6", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[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 = "common" +version = "0.1.0" +dependencies = [ + "anyhow", + "arrayref", + "async-trait", + "backtrace", + "bytes 1.8.0", + "cc", + "cfg-if 1.0.0", + "chrono", + "crossbeam", + "derive_more", + "env_logger", + "findshlibs", + "fnv", + "futures 0.1.31", + "futures 0.3.31", + "futures-timer", + "gstuff", + "hex", + "http 0.2.12", + "http-body 0.1.0", + "hyper", + "hyper-rustls", + "instant", + "itertools 0.10.5", + "js-sys", + "lazy_static", + "libc", + "lightning", + "log", + "parking_lot", + "parking_lot_core 0.6.3", + "primitive-types", + "rand 0.7.3", + "regex", + "rustc-hash", + "ser_error", + "ser_error_derive", + "serde", + "serde-wasm-bindgen", + "serde_derive", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "tokio", + "uuid", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", + "winapi", +] + +[[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_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core2" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" +dependencies = [ + "memchr", +] + +[[package]] +name = "cpufeatures" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-epoch", + "crossbeam-queue", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto" +version = "1.0.0" +dependencies = [ + "aes", + "argon2", + "arrayref", + "async-trait", + "base64 0.21.7", + "bip32", + "bip39", + "bitcrypto", + "bs58 0.4.0", + "cbc", + "cfg-if 1.0.0", + "cipher", + "common", + "derive_more", + "enum-primitive-derive", + "enum_derives", + "futures 0.3.31", + "hex", + "hmac 0.12.1", + "http 0.2.12", + "hw_common", + "keys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_eth", + "mm2_metamask", + "num-traits", + "parking_lot", + "primitives", + "rpc", + "rpc_task", + "rustc-hex", + "secp256k1 0.20.3", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", + "serde_json", + "sha2 0.10.8", + "trezor", + "wasm-bindgen-test", + "web3", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "cuckoofilter" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" +dependencies = [ + "byteorder", + "fnv", + "rand 0.7.3", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto", + "rustc_version 0.4.1", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "data-encoding" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" + +[[package]] +name = "data-encoding-macro" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" +dependencies = [ + "data-encoding", + "data-encoding-macro-internal", +] + +[[package]] +name = "data-encoding-macro-internal" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" +dependencies = [ + "data-encoding", + "syn 1.0.109", +] + +[[package]] +name = "db_common" +version = "0.1.0" +dependencies = [ + "common", + "crossbeam-channel", + "futures 0.3.31", + "hex", + "log", + "rusqlite", + "sql-builder", + "tokio", + "uuid", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derive_more" +version = "0.99.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +dependencies = [ + "convert_case", + "proc-macro2", + "quote 1.0.37", + "rustc_version 0.4.1", + "syn 2.0.85", +] + +[[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", + "crypto-common", + "subtle", +] + +[[package]] +name = "dtoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek 4.1.3", + "ed25519", + "serde", + "sha2 0.10.8", + "subtle", + "zeroize", +] + +[[package]] +name = "edit-distance" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "enum-as-inner" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" +dependencies = [ + "heck", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "enum-primitive-derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" +dependencies = [ + "num-traits", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "enum_derives" +version = "0.1.0" +dependencies = [ + "itertools 0.10.5", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "env_logger" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" +dependencies = [ + "atty", + "humantime", + "log", + "regex", + "termcolor", +] + +[[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 = "ethabi" +version = "17.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" +dependencies = [ + "ethereum-types", + "hex", + "once_cell", + "regex", + "serde", + "serde_json", + "sha3 0.10.8", + "thiserror", + "uint", +] + +[[package]] +name = "ethbloom" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" +dependencies = [ + "crunchy", + "fixed-hash", + "impl-rlp", + "impl-serde", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "ethcore-transaction" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "ethereum-types", + "ethkey", + "keccak-hash", + "rlp", + "rustc-hex", + "unexpected", +] + +[[package]] +name = "ethereum-types" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" +dependencies = [ + "ethbloom", + "fixed-hash", + "impl-rlp", + "impl-serde", + "primitive-types", + "uint", +] + +[[package]] +name = "ethkey" +version = "0.3.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "byteorder", + "edit-distance", + "ethereum-types", + "log", + "mem", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "tiny-keccak 1.4.4", +] + +[[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 0.2.15", +] + +[[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 0.2.15", +] + +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "findshlibs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "fixed-hash" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite 0.2.15", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "futures-rustls" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" +dependencies = [ + "futures-io", + "rustls 0.20.9", + "webpki", +] + +[[package]] +name = "futures-rustls" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" +dependencies = [ + "futures-io", + "rustls 0.21.12", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-ticker" +version = "0.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9763058047f713632a52e916cc7f6a4b3fc6e9fc1ff8c5b1dc49e5a89041682e" +dependencies = [ + "futures 0.3.31", + "futures-timer", + "instant", +] + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +dependencies = [ + "gloo-timers 0.2.6", + "send_wrapper 0.4.0", +] + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures 0.1.31", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite 0.2.15", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[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.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "groestl" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "gstuff" +version = "0.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" +dependencies = [ + "lazy_static", + "libc", +] + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes 1.8.0", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 0.2.12", + "indexmap 2.6.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" +dependencies = [ + "ahash", +] + +[[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 = "hashbrown" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.5", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-conservative" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + +[[package]] +name = "hex_fmt" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" + +[[package]] +name = "hkd32" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" +dependencies = [ + "hmac 0.11.0", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" +dependencies = [ + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "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 = "hmac-drbg" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" +dependencies = [ + "digest 0.9.0", + "generic-array", + "hmac 0.8.1", +] + +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi", +] + +[[package]] +name = "http" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" +dependencies = [ + "bytes 0.4.12", + "fnv", + "itoa 0.4.8", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes 1.8.0", + "fnv", + "itoa 1.0.11", +] + +[[package]] +name = "http-body" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", + "http 0.1.21", + "tokio-buf", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes 1.8.0", + "http 0.2.12", + "pin-project-lite 0.2.15", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[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 = "hw_common" +version = "0.1.0" +dependencies = [ + "async-trait", + "bip32", + "common", + "derive_more", + "futures 0.3.31", + "js-sys", + "mm2_err_handle", + "rusb", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "hyper" +version = "0.14.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" +dependencies = [ + "bytes 1.8.0", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "httpdate", + "itoa 1.0.11", + "pin-project-lite 0.2.15", + "socket2 0.5.7", + "tokio", + "tower-service", + "tracing", + "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", + "rustls 0.21.12", + "tokio", + "tokio-rustls", + "webpki-roots 0.25.4", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "if-addrs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "if-watch" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" +dependencies = [ + "async-io", + "core-foundation", + "fnv", + "futures 0.3.31", + "if-addrs", + "ipnet", + "log", + "rtnetlink", + "system-configuration", + "tokio", + "windows", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-rlp" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" +dependencies = [ + "rlp", +] + +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg 1.4.0", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.0", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "block-padding 0.3.3", + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "iovec" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" +dependencies = [ + "libc", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.7", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" + +[[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.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "js-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc-core" +version = "18.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" +dependencies = [ + "futures 0.3.31", + "futures-executor", + "futures-util", + "log", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-hash" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" +dependencies = [ + "primitive-types", + "tiny-keccak 2.0.2", +] + +[[package]] +name = "keys" +version = "0.1.0" +dependencies = [ + "base58", + "bech32", + "bitcrypto", + "derive_more", + "lazy_static", + "primitives", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", +] + +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.161" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" + +[[package]] +name = "libp2p" +version = "0.52.1" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "bytes 1.8.0", + "futures 0.3.31", + "futures-timer", + "getrandom 0.2.15", + "instant", + "libp2p-allow-block-list", + "libp2p-connection-limits", + "libp2p-core", + "libp2p-dns", + "libp2p-floodsub", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-identity", + "libp2p-mdns", + "libp2p-metrics", + "libp2p-noise", + "libp2p-ping", + "libp2p-request-response", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-wasm-ext", + "libp2p-websocket", + "libp2p-yamux", + "multiaddr", + "pin-project", +] + +[[package]] +name = "libp2p-allow-block-list" +version = "0.2.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-connection-limits" +version = "0.2.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "void", +] + +[[package]] +name = "libp2p-core" +version = "0.40.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "either", + "fnv", + "futures 0.3.31", + "futures-timer", + "instant", + "libp2p-identity", + "log", + "multiaddr", + "multihash", + "multistream-select", + "once_cell", + "parking_lot", + "pin-project", + "quick-protobuf", + "rand 0.8.5", + "rw-stream-sink", + "smallvec 1.13.2", + "thiserror", + "unsigned-varint 0.7.2", + "void", +] + +[[package]] +name = "libp2p-dns" +version = "0.40.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "futures 0.3.31", + "libp2p-core", + "libp2p-identity", + "log", + "parking_lot", + "smallvec 1.13.2", + "trust-dns-resolver", +] + +[[package]] +name = "libp2p-floodsub" +version = "0.43.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "asynchronous-codec", + "cuckoofilter", + "fnv", + "futures 0.3.31", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "quick-protobuf", + "quick-protobuf-codec", + "rand 0.8.5", + "smallvec 1.13.2", + "thiserror", +] + +[[package]] +name = "libp2p-gossipsub" +version = "0.45.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "asynchronous-codec", + "base64 0.21.7", + "byteorder", + "bytes 1.8.0", + "either", + "fnv", + "futures 0.3.31", + "futures-ticker", + "getrandom 0.2.15", + "hex_fmt", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "prometheus-client", + "quick-protobuf", + "quick-protobuf-codec", + "rand 0.8.5", + "regex", + "sha2 0.10.8", + "smallvec 1.13.2", + "unsigned-varint 0.7.2", + "void", +] + +[[package]] +name = "libp2p-identify" +version = "0.43.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "asynchronous-codec", + "either", + "futures 0.3.31", + "futures-timer", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "lru", + "quick-protobuf", + "quick-protobuf-codec", + "smallvec 1.13.2", + "thiserror", + "void", +] + +[[package]] +name = "libp2p-identity" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" +dependencies = [ + "asn1_der", + "bs58 0.5.1", + "ed25519-dalek", + "hkdf", + "libsecp256k1", + "multihash", + "quick-protobuf", + "sha2 0.10.8", + "thiserror", + "tracing", + "zeroize", +] + +[[package]] +name = "libp2p-mdns" +version = "0.44.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "data-encoding", + "futures 0.3.31", + "if-watch", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "rand 0.8.5", + "smallvec 1.13.2", + "socket2 0.5.7", + "tokio", + "trust-dns-proto", + "void", +] + +[[package]] +name = "libp2p-metrics" +version = "0.13.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "instant", + "libp2p-core", + "libp2p-gossipsub", + "libp2p-identify", + "libp2p-identity", + "libp2p-ping", + "libp2p-swarm", + "once_cell", + "prometheus-client", +] + +[[package]] +name = "libp2p-noise" +version = "0.43.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "bytes 1.8.0", + "curve25519-dalek 3.2.0", + "futures 0.3.31", + "libp2p-core", + "libp2p-identity", + "log", + "multiaddr", + "multihash", + "once_cell", + "quick-protobuf", + "rand 0.8.5", + "sha2 0.10.8", + "snow", + "static_assertions", + "thiserror", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "libp2p-ping" +version = "0.43.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "either", + "futures 0.3.31", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "rand 0.8.5", + "void", +] + +[[package]] +name = "libp2p-request-response" +version = "0.25.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "async-trait", + "futures 0.3.31", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm", + "log", + "rand 0.8.5", + "smallvec 1.13.2", + "void", +] + +[[package]] +name = "libp2p-swarm" +version = "0.43.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "either", + "fnv", + "futures 0.3.31", + "futures-timer", + "instant", + "libp2p-core", + "libp2p-identity", + "libp2p-swarm-derive", + "log", + "multistream-select", + "once_cell", + "rand 0.8.5", + "smallvec 1.13.2", + "tokio", + "void", +] + +[[package]] +name = "libp2p-swarm-derive" +version = "0.33.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "heck", + "proc-macro-warning", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "libp2p-tcp" +version = "0.40.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "futures 0.3.31", + "futures-timer", + "if-watch", + "libc", + "libp2p-core", + "libp2p-identity", + "log", + "socket2 0.5.7", + "tokio", +] + +[[package]] +name = "libp2p-wasm-ext" +version = "0.40.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "futures 0.3.31", + "js-sys", + "libp2p-core", + "send_wrapper 0.6.0", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "libp2p-websocket" +version = "0.42.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "either", + "futures 0.3.31", + "futures-rustls 0.22.2", + "libp2p-core", + "libp2p-identity", + "log", + "parking_lot", + "quicksink", + "rw-stream-sink", + "soketto", + "url", + "webpki-roots 0.23.1", +] + +[[package]] +name = "libp2p-yamux" +version = "0.44.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "either", + "futures 0.3.31", + "libp2p-core", + "thiserror", + "tracing", + "yamux 0.12.1", + "yamux 0.13.3", +] + +[[package]] +name = "libsecp256k1" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" +dependencies = [ + "arrayref", + "base64 0.13.1", + "digest 0.9.0", + "hmac-drbg", + "libsecp256k1-core", + "libsecp256k1-gen-ecmult", + "libsecp256k1-gen-genmult", + "rand 0.8.5", + "serde", + "sha2 0.9.9", + "typenum", +] + +[[package]] +name = "libsecp256k1-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" +dependencies = [ + "crunchy", + "digest 0.9.0", + "subtle", +] + +[[package]] +name = "libsecp256k1-gen-ecmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsecp256k1-gen-genmult" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" +dependencies = [ + "libsecp256k1-core", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libusb1-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "lightning" +version = "0.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" +dependencies = [ + "bitcoin", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg 1.4.0", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] + +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.1", +] + +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "mach2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" +dependencies = [ + "libc", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "mem" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "metrics" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" +dependencies = [ + "ahash", + "metrics-macros", + "portable-atomic", +] + +[[package]] +name = "metrics-exporter-prometheus" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" +dependencies = [ + "base64 0.21.7", + "hyper", + "indexmap 1.9.3", + "ipnet", + "metrics", + "metrics-util", + "quanta", + "thiserror", + "tokio", + "tracing", +] + +[[package]] +name = "metrics-macros" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "metrics-util" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" +dependencies = [ + "aho-corasick", + "crossbeam-epoch", + "crossbeam-utils", + "hashbrown 0.13.1", + "indexmap 1.9.3", + "metrics", + "num_cpus", + "ordered-float", + "quanta", + "radix_trie", + "sketches-ddsketch", +] + +[[package]] +name = "minicov" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "def6d99771d7c499c26ad4d40eb6645eafd3a1553b35fc26ea5a489a45e82d9a" +dependencies = [ + "cc", + "walkdir", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" +dependencies = [ + "hermit-abi 0.3.9", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "mm2_core" +version = "0.1.0" +dependencies = [ + "arrayref", + "async-std", + "async-trait", + "cfg-if 1.0.0", + "common", + "db_common", + "derive_more", + "futures 0.3.31", + "gstuff", + "hex", + "instant", + "lazy_static", + "mm2_err_handle", + "mm2_event_stream", + "mm2_metrics", + "mm2_p2p", + "mm2_rpc", + "primitives", + "rand 0.7.3", + "rustls 0.21.12", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "shared_ref_counter", + "tokio", + "uuid", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_err_handle" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.1.31", + "http 0.2.12", + "itertools 0.10.5", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_eth" +version = "0.1.0" +dependencies = [ + "ethabi", + "ethkey", + "hex", + "indexmap 1.9.3", + "itertools 0.10.5", + "mm2_err_handle", + "secp256k1 0.20.3", + "serde", + "serde_json", + "web3", +] + +[[package]] +name = "mm2_event_stream" +version = "0.1.0" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "common", + "futures 0.3.31", + "parking_lot", + "serde", + "tokio", + "wasm-bindgen-test", +] + +[[package]] +name = "mm2_io" +version = "0.1.0" +dependencies = [ + "async-std", + "common", + "derive_more", + "futures 0.3.31", + "gstuff", + "mm2_err_handle", + "rand 0.7.3", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_metamask" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.31", + "itertools 0.10.5", + "js-sys", + "jsonrpc-core", + "lazy_static", + "mm2_err_handle", + "mm2_eth", + "parking_lot", + "serde", + "serde_derive", + "serde_json", + "wasm-bindgen", + "wasm-bindgen-futures", + "web3", +] + +[[package]] +name = "mm2_metrics" +version = "0.1.0" +dependencies = [ + "base64 0.21.7", + "common", + "derive_more", + "futures 0.3.31", + "hyper", + "hyper-rustls", + "itertools 0.10.5", + "metrics", + "metrics-exporter-prometheus", + "metrics-util", + "mm2_err_handle", + "serde", + "serde_derive", + "serde_json", +] + +[[package]] +name = "mm2_net" +version = "0.1.0" +dependencies = [ + "async-trait", + "base64 0.21.7", + "bytes 1.8.0", + "cfg-if 1.0.0", + "common", + "derive_more", + "ethkey", + "futures 0.3.31", + "futures-util", + "gstuff", + "http 0.2.12", + "http-body 0.4.6", + "httparse", + "hyper", + "js-sys", + "lazy_static", + "mm2_core", + "mm2_err_handle", + "mm2_state_machine", + "pin-project", + "prost", + "rand 0.7.3", + "rustls 0.21.12", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-rustls", + "tonic", + "tower-service", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "mm2_number" +version = "0.1.0" +dependencies = [ + "bigdecimal", + "num-bigint", + "num-rational", + "num-traits", + "paste", + "serde", + "serde_json", +] + +[[package]] +name = "mm2_p2p" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.31", + "futures-rustls 0.22.2", + "futures-rustls 0.24.0", + "futures-ticker", + "hex", + "instant", + "lazy_static", + "libp2p", + "log", + "rand 0.7.3", + "regex", + "rmp-serde", + "secp256k1 0.20.3", + "serde", + "serde_bytes", + "sha2 0.10.8", + "smallvec 1.13.2", + "syn 2.0.85", + "tokio", + "void", +] + +[[package]] +name = "mm2_rpc" +version = "0.1.0" +dependencies = [ + "common", + "derive_more", + "futures 0.3.31", + "gstuff", + "http 0.2.12", + "mm2_err_handle", + "mm2_number", + "rpc", + "ser_error", + "ser_error_derive", + "serde", + "serde_json", + "uuid", +] + +[[package]] +name = "mm2_state_machine" +version = "0.1.0" +dependencies = [ + "async-trait", +] + +[[package]] +name = "mm2_test_helpers" +version = "0.1.0" +dependencies = [ + "bytes 1.8.0", + "cfg-if 1.0.0", + "chrono", + "common", + "crypto", + "db_common", + "futures 0.3.31", + "gstuff", + "http 0.2.12", + "lazy_static", + "mm2_core", + "mm2_io", + "mm2_metrics", + "mm2_net", + "mm2_number", + "mm2_rpc", + "rand 0.7.3", + "regex", + "rpc", + "serde", + "serde_derive", + "serde_json", + "uuid", +] + +[[package]] +name = "multiaddr" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "libp2p-identity", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint 0.8.0", + "url", +] + +[[package]] +name = "multibase" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" +dependencies = [ + "base-x", + "data-encoding", + "data-encoding-macro", +] + +[[package]] +name = "multihash" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2" +dependencies = [ + "core2", + "unsigned-varint 0.8.0", +] + +[[package]] +name = "multistream-select" +version = "0.13.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "bytes 1.8.0", + "futures 0.3.31", + "log", + "pin-project", + "smallvec 1.13.2", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "netlink-packet-core" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" +dependencies = [ + "anyhow", + "byteorder", + "libc", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "byteorder", + "libc", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-utils" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror", +] + +[[package]] +name = "netlink-proto" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" +dependencies = [ + "bytes 1.8.0", + "futures 0.3.31", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror", + "tokio", +] + +[[package]] +name = "netlink-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" +dependencies = [ + "bytes 1.8.0", + "futures 0.3.31", + "libc", + "log", + "tokio", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec 1.13.2", +] + +[[package]] +name = "nix" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" +dependencies = [ + "bitflags 1.3.2", + "cfg-if 1.0.0", + "libc", +] + +[[package]] +name = "nohash-hasher" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "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", + "num-integer", + "num-traits", + "serde", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg 1.4.0", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.9", + "libc", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "ordered-float" +version = "3.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" +dependencies = [ + "num-traits", +] + +[[package]] +name = "parity-scale-codec" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" +dependencies = [ + "arrayvec 0.7.6", + "bitvec", + "byte-slice-cast", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote 1.0.37", + "syn 1.0.109", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.10", +] + +[[package]] +name = "parking_lot_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" +dependencies = [ + "cfg-if 0.1.10", + "cloudabi", + "libc", + "redox_syscall 0.1.57", + "rustc_version 0.2.3", + "smallvec 0.6.14", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "redox_syscall 0.5.7", + "smallvec 1.13.2", + "windows-targets 0.52.6", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "pin-project-lite" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if 1.0.0", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite 0.2.15", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "primitive-types" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" +dependencies = [ + "fixed-hash", + "impl-codec", + "impl-rlp", + "impl-serde", + "uint", +] + +[[package]] +name = "primitives" +version = "0.1.0" +dependencies = [ + "bitcoin_hashes 0.11.0", + "byteorder", + "rustc-hex", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-warning" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "proc-macro2" +version = "1.0.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus-client" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c99afa9a01501019ac3a14d71d9f94050346f55ca471ce90c799a15c58f61e2" +dependencies = [ + "dtoa", + "itoa 1.0.11", + "parking_lot", + "prometheus-client-derive-encode", +] + +[[package]] +name = "prometheus-client-derive-encode" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "prost" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" +dependencies = [ + "bytes 1.8.0", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" +dependencies = [ + "anyhow", + "itertools 0.12.1", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "quanta" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" +dependencies = [ + "crossbeam-utils", + "libc", + "mach2", + "once_cell", + "raw-cpuid", + "wasi 0.11.0+wasi-snapshot-preview1", + "web-sys", + "winapi", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quick-protobuf-codec" +version = "0.2.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "asynchronous-codec", + "bytes 1.8.0", + "quick-protobuf", + "thiserror", + "unsigned-varint 0.7.2", +] + +[[package]] +name = "quicksink" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project-lite 0.1.12", +] + +[[package]] +name = "quote" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", + "rand_pcg 0.2.1", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.15", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +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", + "wasm-bindgen", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +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-cpuid" +version = "10.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" +dependencies = [ + "bitflags 1.3.2", +] + +[[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.1.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" + +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + +[[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]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if 1.0.0", + "getrandom 0.2.15", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "ripemd160" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes 1.8.0", + "rustc-hex", +] + +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ce7d70c926fe472aed493b902010bccc17fa9f7284145cb8772fd22fdb052d8" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "rpc" +version = "0.1.0" +dependencies = [ + "chain", + "keys", + "log", + "primitives", + "rustc-hex", + "script", + "serde", + "serde_derive", + "serde_json", + "serialization", +] + +[[package]] +name = "rpc_task" +version = "0.1.0" +dependencies = [ + "async-trait", + "common", + "derive_more", + "futures 0.3.31", + "mm2_err_handle", + "ser_error", + "ser_error_derive", + "serde", + "serde_derive", +] + +[[package]] +name = "rtnetlink" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" +dependencies = [ + "futures 0.3.31", + "log", + "netlink-packet-route", + "netlink-proto", + "nix", + "thiserror", + "tokio", +] + +[[package]] +name = "rusb" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" +dependencies = [ + "libc", + "libusb1-sys", +] + +[[package]] +name = "rusqlite" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" +dependencies = [ + "bitflags 1.3.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec 1.13.2", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.23", +] + +[[package]] +name = "rustix" +version = "0.38.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" +dependencies = [ + "bitflags 2.6.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct", + "webpki", +] + +[[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-webpki" +version = "0.100.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[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 = "rw-stream-sink" +version = "0.4.0" +source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" +dependencies = [ + "futures 0.3.31", + "pin-project", + "static_assertions", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[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 = "script" +version = "0.1.0" +dependencies = [ + "bitcrypto", + "blake2b_simd", + "chain", + "keys", + "log", + "primitives", + "serde", + "serialization", +] + +[[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 = "secp256k1" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" +dependencies = [ + "rand 0.6.5", + "secp256k1-sys 0.4.2", +] + +[[package]] +name = "secp256k1" +version = "0.24.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" +dependencies = [ + "bitcoin_hashes 0.11.0", + "secp256k1-sys 0.6.1", +] + +[[package]] +name = "secp256k1-sys" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" +dependencies = [ + "cc", +] + +[[package]] +name = "secp256k1-sys" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" +dependencies = [ + "cc", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "ser_error" +version = "0.1.0" +dependencies = [ + "serde", +] + +[[package]] +name = "ser_error_derive" +version = "0.1.0" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "ser_error", + "syn 1.0.109", +] + +[[package]] +name = "serde" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_bytes" +version = "0.11.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.213" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "serde_json" +version = "1.0.132" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" +dependencies = [ + "indexmap 2.6.0", + "itoa 1.0.11", + "memchr", + "ryu", + "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 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "serialization" +version = "0.1.0" +dependencies = [ + "byteorder", + "derive_more", + "primitives", + "test_helpers", +] + +[[package]] +name = "serialization_derive" +version = "0.1.0" +dependencies = [ + "quote 0.3.15", + "syn 0.11.11", +] + +[[package]] +name = "sha-1" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "cpufeatures", + "digest 0.9.0", + "opaque-debug", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.0", + "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 1.0.0", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +dependencies = [ + "block-buffer 0.9.0", + "digest 0.9.0", + "keccak", + "opaque-debug", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shared_ref_counter" +version = "0.1.0" + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" + +[[package]] +name = "sketches-ddsketch" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg 1.4.0", +] + +[[package]] +name = "smallvec" +version = "0.6.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" +dependencies = [ + "maybe-uninit", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "snow" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" +dependencies = [ + "aes-gcm", + "blake2", + "chacha20poly1305", + "curve25519-dalek 4.1.3", + "rand_core 0.6.4", + "ring 0.17.8", + "rustc_version 0.4.1", + "sha2 0.10.8", + "subtle", +] + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soketto" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" +dependencies = [ + "base64 0.13.1", + "bytes 1.8.0", + "futures 0.3.31", + "httparse", + "log", + "rand 0.8.5", + "sha-1", +] + +[[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.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sql-builder" +version = "3.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" +dependencies = [ + "anyhow", + "thiserror", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "syn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" +dependencies = [ + "quote 0.3.15", + "synom", + "unicode-xid", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "unicode-ident", +] + +[[package]] +name = "synom" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +dependencies = [ + "unicode-xid", +] + +[[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 = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "test_helpers" +version = "0.1.0" +dependencies = [ + "hex", +] + +[[package]] +name = "thiserror" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "tiny-keccak" +version = "1.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.41.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +dependencies = [ + "backtrace", + "bytes 1.8.0", + "libc", + "mio", + "pin-project-lite 0.2.15", + "socket2 0.5.7", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-buf" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" +dependencies = [ + "bytes 0.4.12", + "futures 0.1.31", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[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-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite 0.2.15", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes 1.8.0", + "futures-core", + "futures-sink", + "pin-project-lite 0.2.15", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap 2.6.0", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-trait", + "base64 0.21.7", + "bytes 1.8.0", + "http 0.2.12", + "http-body 0.4.6", + "percent-encoding", + "pin-project", + "prost", + "tokio", + "tokio-stream", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite 0.2.15", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trezor" +version = "0.1.1" +dependencies = [ + "async-std", + "async-trait", + "bip32", + "byteorder", + "common", + "derive_more", + "ethcore-transaction", + "ethereum-types", + "ethkey", + "futures 0.3.31", + "hw_common", + "js-sys", + "lazy_static", + "mm2_err_handle", + "prost", + "rand 0.7.3", + "rpc_task", + "serde", + "serde_derive", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test", + "web-sys", +] + +[[package]] +name = "trust-dns-proto" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" +dependencies = [ + "async-trait", + "cfg-if 1.0.0", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna 0.2.3", + "ipnet", + "lazy_static", + "rand 0.8.5", + "smallvec 1.13.2", + "socket2 0.4.10", + "thiserror", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" +dependencies = [ + "cfg-if 1.0.0", + "futures-util", + "ipconfig", + "lazy_static", + "lru-cache", + "parking_lot", + "resolv-conf", + "smallvec 1.13.2", + "thiserror", + "tokio", + "tracing", + "trust-dns-proto", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unexpected" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + +[[package]] +name = "unicode-bidi" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" + +[[package]] +name = "unicode-ident" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-xid" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" + +[[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 = "unsigned-varint" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" +dependencies = [ + "asynchronous-codec", + "bytes 1.8.0", +] + +[[package]] +name = "unsigned-varint" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" + +[[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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +dependencies = [ + "form_urlencoded", + "idna 0.5.0", + "percent-encoding", +] + +[[package]] +name = "uuid" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" +dependencies = [ + "getrandom 0.2.15", + "rand 0.8.5", + "serde", +] + +[[package]] +name = "value-bag" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "void" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" +dependencies = [ + "cfg-if 1.0.0", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" +dependencies = [ + "quote 1.0.37", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" + +[[package]] +name = "wasm-bindgen-test" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d381749acb0943d357dcbd8f0b100640679883fcdeeef04def49daf8d33a5426" +dependencies = [ + "console_error_panic_hook", + "js-sys", + "minicov", + "scoped-tls", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-bindgen-test-macro", +] + +[[package]] +name = "wasm-bindgen-test-macro" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "web-sys" +version = "0.3.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web3" +version = "0.19.0" +source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" +dependencies = [ + "arrayvec 0.7.6", + "derive_more", + "ethabi", + "ethereum-types", + "futures 0.3.31", + "futures-timer", + "getrandom 0.2.15", + "hex", + "idna 0.2.3", + "js-sys", + "jsonrpc-core", + "log", + "parking_lot", + "pin-project", + "rand 0.8.5", + "rlp", + "serde", + "serde-wasm-bindgen", + "serde_json", + "tiny-keccak 2.0.2", + "wasm-bindgen", + "wasm-bindgen-futures", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.8", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" +dependencies = [ + "rustls-webpki 0.100.3", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" +dependencies = [ + "windows-core 0.51.1", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.51.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if 1.0.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "yamux" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed0164ae619f2dc144909a9f082187ebb5893693d8c0196e8085283ccd4b776" +dependencies = [ + "futures 0.3.31", + "log", + "nohash-hasher", + "parking_lot", + "pin-project", + "rand 0.8.5", + "static_assertions", +] + +[[package]] +name = "yamux" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31b5e376a8b012bee9c423acdbb835fc34d45001cfa3106236a624e4b738028" +dependencies = [ + "futures 0.3.31", + "log", + "nohash-hasher", + "parking_lot", + "pin-project", + "rand 0.8.5", + "static_assertions", + "web-time", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote 1.0.37", + "syn 2.0.85", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +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 1.0.37", + "syn 2.0.85", +] From 18eb62f4d85a274255b5d5ddb86fbea80c040bc0 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 24 Oct 2024 21:25:47 +0100 Subject: [PATCH 080/125] uncommit mm2_test_helpers lock file --- mm2src/mm2_test_helpers/Cargo.lock | 5763 ---------------------------- 1 file changed, 5763 deletions(-) delete mode 100644 mm2src/mm2_test_helpers/Cargo.lock diff --git a/mm2src/mm2_test_helpers/Cargo.lock b/mm2src/mm2_test_helpers/Cargo.lock deleted file mode 100644 index 32fa8dda62..0000000000 --- a/mm2src/mm2_test_helpers/Cargo.lock +++ /dev/null @@ -1,5763 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - -[[package]] -name = "adler2" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" - -[[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.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures", -] - -[[package]] -name = "aes-gcm" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" -dependencies = [ - "aead", - "aes", - "cipher", - "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 1.0.0", - "once_cell", - "version_check", - "zerocopy", -] - -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - -[[package]] -name = "allocator-api2" -version = "0.2.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" - -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - -[[package]] -name = "anyhow" -version = "1.0.91" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" - -[[package]] -name = "argon2" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" -dependencies = [ - "base64ct", - "blake2", - "cpufeatures", - "password-hash", - "zeroize", -] - -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - -[[package]] -name = "arrayvec" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" - -[[package]] -name = "arrayvec" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" - -[[package]] -name = "asn1_der" -version = "0.7.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" - -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite 0.2.15", -] - -[[package]] -name = "async-executor" -version = "1.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" -dependencies = [ - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-global-executor" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" -dependencies = [ - "async-channel 2.3.1", - "async-executor", - "async-io", - "async-lock", - "blocking", - "futures-lite", - "once_cell", -] - -[[package]] -name = "async-io" -version = "2.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" -dependencies = [ - "async-lock", - "cfg-if 1.0.0", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[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 0.2.15", -] - -[[package]] -name = "async-process" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" -dependencies = [ - "async-channel 2.3.1", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if 1.0.0", - "event-listener 5.3.1", - "futures-lite", - "rustix", - "tracing", -] - -[[package]] -name = "async-signal" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if 1.0.0", - "futures-core", - "futures-io", - "rustix", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-std" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" -dependencies = [ - "async-channel 1.9.0", - "async-global-executor", - "async-io", - "async-lock", - "async-process", - "crossbeam-utils", - "futures-channel", - "futures-core", - "futures-io", - "futures-lite", - "gloo-timers 0.3.0", - "kv-log-macro", - "log", - "memchr", - "once_cell", - "pin-project-lite 0.2.15", - "pin-utils", - "slab", - "wasm-bindgen-futures", -] - -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - -[[package]] -name = "async-trait" -version = "0.1.83" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "asynchronous-codec" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" -dependencies = [ - "bytes 1.8.0", - "futures-sink", - "futures-util", - "memchr", - "pin-project-lite 0.2.15", -] - -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi 0.1.19", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dde43e75fd43e8a1bf86103336bc699aa8d17ad1be60c76c0bdfd4828e19b78" -dependencies = [ - "autocfg 1.4.0", -] - -[[package]] -name = "autocfg" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" - -[[package]] -name = "backtrace" -version = "0.3.74" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" -dependencies = [ - "addr2line", - "cfg-if 1.0.0", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - -[[package]] -name = "base-x" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270" - -[[package]] -name = "base58" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6107fe1be6682a68940da878d9e9f5e90ca5745b3dec9fd1bb393c8777d4f581" - -[[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 = "base64ct" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" - -[[package]] -name = "bech32" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d86b93f97252c47b41663388e6d155714a9d0c398b99f1005cbc5f978b29f445" - -[[package]] -name = "bigdecimal" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6773ddc0eafc0e509fb60e48dff7f450f8e674a0686ae8605e8d9901bd5eefa" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "bip32" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2d0f0fc59c7ba0333eed9dcc1b6980baa7b7a4dc7c6c5885994d0674f7adf34" -dependencies = [ - "bs58 0.4.0", - "hkd32", - "hmac 0.11.0", - "ripemd160", - "secp256k1 0.20.3", - "sha2 0.9.9", - "subtle", - "zeroize", -] - -[[package]] -name = "bip39" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" -dependencies = [ - "bitcoin_hashes 0.13.0", - "rand_core 0.6.4", - "zeroize", -] - -[[package]] -name = "bitcoin" -version = "0.29.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" -dependencies = [ - "bech32", - "bitcoin_hashes 0.11.0", - "secp256k1 0.24.3", -] - -[[package]] -name = "bitcoin-internals" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" - -[[package]] -name = "bitcoin_hashes" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" - -[[package]] -name = "bitcoin_hashes" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" -dependencies = [ - "bitcoin-internals", - "hex-conservative", -] - -[[package]] -name = "bitcrypto" -version = "0.1.0" -dependencies = [ - "groestl", - "primitives", - "ripemd160", - "serialization", - "sha-1", - "sha2 0.10.8", - "sha3 0.9.1", - "siphasher", -] - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" - -[[package]] -name = "bitvec" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" -dependencies = [ - "funty", - "radium", - "tap", - "wyz", -] - -[[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 = "blake2b_simd" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afa748e348ad3be8263be728124b24a24f268266f6f5d58af9d75f6a40b5c587" -dependencies = [ - "arrayref", - "arrayvec 0.5.2", - "constant_time_eq", -] - -[[package]] -name = "block-buffer" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" -dependencies = [ - "block-padding 0.2.1", - "generic-array", -] - -[[package]] -name = "block-buffer" -version = "0.10.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" -dependencies = [ - "generic-array", -] - -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - -[[package]] -name = "block-padding" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" -dependencies = [ - "generic-array", -] - -[[package]] -name = "blocking" -version = "1.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" -dependencies = [ - "async-channel 2.3.1", - "async-task", - "futures-io", - "futures-lite", - "piper", -] - -[[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 = "bs58" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "bumpalo" -version = "3.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" - -[[package]] -name = "byte-slice-cast" -version = "1.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c" - -[[package]] -name = "byteorder" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" - -[[package]] -name = "bytes" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206fdffcfa2df7cbe15601ef46c813fce0965eb3286db6b56c583b814b51c81c" -dependencies = [ - "byteorder", - "iovec", -] - -[[package]] -name = "bytes" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" - -[[package]] -name = "cbc" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26b52a9543ae338f279b96b0b9fed9c8093744685043739079ce85cd58f289a6" -dependencies = [ - "cipher", -] - -[[package]] -name = "cc" -version = "1.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" -dependencies = [ - "shlex", -] - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - -[[package]] -name = "chacha20" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" -dependencies = [ - "cfg-if 1.0.0", - "cipher", - "cpufeatures", -] - -[[package]] -name = "chacha20poly1305" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" -dependencies = [ - "aead", - "chacha20", - "cipher", - "poly1305", - "zeroize", -] - -[[package]] -name = "chain" -version = "0.1.0" -dependencies = [ - "bitcoin", - "bitcrypto", - "primitives", - "rustc-hex", - "serialization", - "serialization_derive", -] - -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "wasm-bindgen", - "windows-targets 0.52.6", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", - "zeroize", -] - -[[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 = "common" -version = "0.1.0" -dependencies = [ - "anyhow", - "arrayref", - "async-trait", - "backtrace", - "bytes 1.8.0", - "cc", - "cfg-if 1.0.0", - "chrono", - "crossbeam", - "derive_more", - "env_logger", - "findshlibs", - "fnv", - "futures 0.1.31", - "futures 0.3.31", - "futures-timer", - "gstuff", - "hex", - "http 0.2.12", - "http-body 0.1.0", - "hyper", - "hyper-rustls", - "instant", - "itertools 0.10.5", - "js-sys", - "lazy_static", - "libc", - "lightning", - "log", - "parking_lot", - "parking_lot_core 0.6.3", - "primitive-types", - "rand 0.7.3", - "regex", - "rustc-hash", - "ser_error", - "ser_error_derive", - "serde", - "serde-wasm-bindgen", - "serde_derive", - "serde_json", - "serde_repr", - "sha2 0.10.8", - "tokio", - "uuid", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", - "winapi", -] - -[[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_error_panic_hook" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" -dependencies = [ - "cfg-if 1.0.0", - "wasm-bindgen", -] - -[[package]] -name = "const-oid" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - -[[package]] -name = "core-foundation-sys" -version = "0.8.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" - -[[package]] -name = "core2" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49ba7ef1ad6107f8824dbe97de947cbaac53c44e7f9756a1fba0d37c1eec505" -dependencies = [ - "memchr", -] - -[[package]] -name = "cpufeatures" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" -dependencies = [ - "libc", -] - -[[package]] -name = "crossbeam" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8" -dependencies = [ - "crossbeam-channel", - "crossbeam-deque", - "crossbeam-epoch", - "crossbeam-queue", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-channel" -version = "0.5.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-queue" -version = "0.3.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" -dependencies = [ - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-utils" -version = "0.8.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" - -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - -[[package]] -name = "crypto" -version = "1.0.0" -dependencies = [ - "aes", - "argon2", - "arrayref", - "async-trait", - "base64 0.21.7", - "bip32", - "bip39", - "bitcrypto", - "bs58 0.4.0", - "cbc", - "cfg-if 1.0.0", - "cipher", - "common", - "derive_more", - "enum-primitive-derive", - "enum_derives", - "futures 0.3.31", - "hex", - "hmac 0.12.1", - "http 0.2.12", - "hw_common", - "keys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_eth", - "mm2_metamask", - "num-traits", - "parking_lot", - "primitives", - "rpc", - "rpc_task", - "rustc-hex", - "secp256k1 0.20.3", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", - "serde_json", - "sha2 0.10.8", - "trezor", - "wasm-bindgen-test", - "web3", - "zeroize", -] - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "typenum", -] - -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "crypto-mac" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" -dependencies = [ - "generic-array", - "subtle", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - -[[package]] -name = "cuckoofilter" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b810a8449931679f64cd7eef1bbd0fa315801b6d5d9cdc1ace2804d6529eee18" -dependencies = [ - "byteorder", - "fnv", - "rand 0.7.3", -] - -[[package]] -name = "curve25519-dalek" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" -dependencies = [ - "byteorder", - "digest 0.9.0", - "rand_core 0.5.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "curve25519-dalek-derive", - "digest 0.10.7", - "fiat-crypto", - "rustc_version 0.4.1", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "data-encoding" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8566979429cf69b49a5c740c60791108e86440e8be149bbea4fe54d2c32d6e2" - -[[package]] -name = "data-encoding-macro" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1559b6cba622276d6d63706db152618eeb15b89b3e4041446b05876e352e639" -dependencies = [ - "data-encoding", - "data-encoding-macro-internal", -] - -[[package]] -name = "data-encoding-macro-internal" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "332d754c0af53bc87c108fed664d121ecf59207ec4196041f04d6ab9002ad33f" -dependencies = [ - "data-encoding", - "syn 1.0.109", -] - -[[package]] -name = "db_common" -version = "0.1.0" -dependencies = [ - "common", - "crossbeam-channel", - "futures 0.3.31", - "hex", - "log", - "rusqlite", - "sql-builder", - "tokio", - "uuid", -] - -[[package]] -name = "der" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" -dependencies = [ - "const-oid", - "zeroize", -] - -[[package]] -name = "derive_more" -version = "0.99.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" -dependencies = [ - "convert_case", - "proc-macro2", - "quote 1.0.37", - "rustc_version 0.4.1", - "syn 2.0.85", -] - -[[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", - "crypto-common", - "subtle", -] - -[[package]] -name = "dtoa" -version = "1.0.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" -dependencies = [ - "curve25519-dalek 4.1.3", - "ed25519", - "serde", - "sha2 0.10.8", - "subtle", - "zeroize", -] - -[[package]] -name = "edit-distance" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3f497e87b038c09a155dfd169faa5ec940d0644635555ef6bd464ac20e97397" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "endian-type" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" - -[[package]] -name = "enum-as-inner" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" -dependencies = [ - "heck", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "enum-primitive-derive" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c375b9c5eadb68d0a6efee2999fef292f45854c3444c86f09d8ab086ba942b0e" -dependencies = [ - "num-traits", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "enum_derives" -version = "0.1.0" -dependencies = [ - "itertools 0.10.5", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "env_logger" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7" -dependencies = [ - "atty", - "humantime", - "log", - "regex", - "termcolor", -] - -[[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 = "ethabi" -version = "17.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4966fba78396ff92db3b817ee71143eccd98acf0f876b8d600e585a670c5d1b" -dependencies = [ - "ethereum-types", - "hex", - "once_cell", - "regex", - "serde", - "serde_json", - "sha3 0.10.8", - "thiserror", - "uint", -] - -[[package]] -name = "ethbloom" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11da94e443c60508eb62cf256243a64da87304c2802ac2528847f79d750007ef" -dependencies = [ - "crunchy", - "fixed-hash", - "impl-rlp", - "impl-serde", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "ethcore-transaction" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "ethereum-types", - "ethkey", - "keccak-hash", - "rlp", - "rustc-hex", - "unexpected", -] - -[[package]] -name = "ethereum-types" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2827b94c556145446fcce834ca86b7abf0c39a805883fe20e72c5bfdb5a0dc6" -dependencies = [ - "ethbloom", - "fixed-hash", - "impl-rlp", - "impl-serde", - "primitive-types", - "uint", -] - -[[package]] -name = "ethkey" -version = "0.3.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" -dependencies = [ - "byteorder", - "edit-distance", - "ethereum-types", - "log", - "mem", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "tiny-keccak 1.4.4", -] - -[[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 0.2.15", -] - -[[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 0.2.15", -] - -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - -[[package]] -name = "fastrand" -version = "2.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - -[[package]] -name = "findshlibs" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1260d61e4fe2a6ab845ffdc426a0bd68ffb240b91cf0ec5a8d1170cec535bd8" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "fixed-hash" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c" -dependencies = [ - "byteorder", - "rand 0.8.5", - "rustc-hex", - "static_assertions", -] - -[[package]] -name = "fnv" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" - -[[package]] -name = "form_urlencoded" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" -dependencies = [ - "percent-encoding", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" - -[[package]] -name = "futures" -version = "0.1.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a471a38ef8ed83cd6e40aa59c1ffe17db6855c18e3604d9c4ed8c08ebc28678" - -[[package]] -name = "futures" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" -dependencies = [ - "futures-channel", - "futures-core", - "futures-executor", - "futures-io", - "futures-sink", - "futures-task", - "futures-util", -] - -[[package]] -name = "futures-channel" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" -dependencies = [ - "futures-core", - "futures-sink", -] - -[[package]] -name = "futures-core" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" - -[[package]] -name = "futures-executor" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", - "num_cpus", -] - -[[package]] -name = "futures-io" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" - -[[package]] -name = "futures-lite" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "parking", - "pin-project-lite 0.2.15", -] - -[[package]] -name = "futures-macro" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "futures-rustls" -version = "0.22.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2411eed028cdf8c8034eaf21f9915f956b6c3abec4d4c7949ee67f0721127bd" -dependencies = [ - "futures-io", - "rustls 0.20.9", - "webpki", -] - -[[package]] -name = "futures-rustls" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd3cf68c183738046838e300353e4716c674dc5e56890de4826801a6622a28" -dependencies = [ - "futures-io", - "rustls 0.21.12", -] - -[[package]] -name = "futures-sink" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" - -[[package]] -name = "futures-task" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" - -[[package]] -name = "futures-ticker" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9763058047f713632a52e916cc7f6a4b3fc6e9fc1ff8c5b1dc49e5a89041682e" -dependencies = [ - "futures 0.3.31", - "futures-timer", - "instant", -] - -[[package]] -name = "futures-timer" -version = "3.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" -dependencies = [ - "gloo-timers 0.2.6", - "send_wrapper 0.4.0", -] - -[[package]] -name = "futures-util" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" -dependencies = [ - "futures 0.1.31", - "futures-channel", - "futures-core", - "futures-io", - "futures-macro", - "futures-sink", - "futures-task", - "memchr", - "pin-project-lite 0.2.15", - "pin-utils", - "slab", -] - -[[package]] -name = "generic-array" -version = "0.14.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "getrandom" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.9.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[package]] -name = "getrandom" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "wasm-bindgen", -] - -[[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.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - -[[package]] -name = "gloo-timers" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "gloo-timers" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" -dependencies = [ - "futures-channel", - "futures-core", - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "groestl" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2432787a9b8f0d58dca43fe2240399479b7582dc8afa2126dc7652b864029e47" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "gstuff" -version = "0.7.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c495d42791143a3be6d33e5f442c35118ffc0819bd867bfe355b4cb6bfc20ee" -dependencies = [ - "lazy_static", - "libc", -] - -[[package]] -name = "h2" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" -dependencies = [ - "bytes 1.8.0", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 0.2.12", - "indexmap 2.6.0", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "hashbrown" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ff8ae62cd3a9102e5637afc8452c55acf3844001bd5374e0b0bd7b6616c038" -dependencies = [ - "ahash", -] - -[[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 = "hashbrown" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" - -[[package]] -name = "hashlink" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" -dependencies = [ - "hashbrown 0.14.5", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - -[[package]] -name = "hex" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" - -[[package]] -name = "hex-conservative" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" - -[[package]] -name = "hex_fmt" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b07f60793ff0a4d9cef0f18e63b5357e06209987153a64648c972c1e5aff336f" - -[[package]] -name = "hkd32" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84f2a5541afe0725f0b95619d6af614f48c1b176385b8aa30918cfb8c4bfafc8" -dependencies = [ - "hmac 0.11.0", - "rand_core 0.6.4", - "sha2 0.9.9", - "zeroize", -] - -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac 0.12.1", -] - -[[package]] -name = "hmac" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840" -dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", -] - -[[package]] -name = "hmac" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" -dependencies = [ - "crypto-mac 0.11.1", - "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 = "hmac-drbg" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ea0a1394df5b6574da6e0c1ade9e78868c9fb0a4e5ef4428e32da4676b85b1" -dependencies = [ - "digest 0.9.0", - "generic-array", - "hmac 0.8.1", -] - -[[package]] -name = "hostname" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" -dependencies = [ - "libc", - "match_cfg", - "winapi", -] - -[[package]] -name = "http" -version = "0.1.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6ccf5ede3a895d8856620237b2f02972c1bbc78d2965ad7fe8838d4a0ed41f0" -dependencies = [ - "bytes 0.4.12", - "fnv", - "itoa 0.4.8", -] - -[[package]] -name = "http" -version = "0.2.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" -dependencies = [ - "bytes 1.8.0", - "fnv", - "itoa 1.0.11", -] - -[[package]] -name = "http-body" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6741c859c1b2463a423a1dbce98d418e6c3c3fc720fb0d45528657320920292d" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", - "http 0.1.21", - "tokio-buf", -] - -[[package]] -name = "http-body" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" -dependencies = [ - "bytes 1.8.0", - "http 0.2.12", - "pin-project-lite 0.2.15", -] - -[[package]] -name = "httparse" -version = "1.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" - -[[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 = "hw_common" -version = "0.1.0" -dependencies = [ - "async-trait", - "bip32", - "common", - "derive_more", - "futures 0.3.31", - "js-sys", - "mm2_err_handle", - "rusb", - "secp256k1 0.20.3", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "hyper" -version = "0.14.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c08302e8fa335b151b788c775ff56e7a03ae64ff85c548ee820fecb70356e85" -dependencies = [ - "bytes 1.8.0", - "futures-channel", - "futures-core", - "futures-util", - "h2", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "httpdate", - "itoa 1.0.11", - "pin-project-lite 0.2.15", - "socket2 0.5.7", - "tokio", - "tower-service", - "tracing", - "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", - "rustls 0.21.12", - "tokio", - "tokio-rustls", - "webpki-roots 0.25.4", -] - -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core 0.52.0", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - -[[package]] -name = "idna" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" -dependencies = [ - "matches", - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "idna" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" -dependencies = [ - "unicode-bidi", - "unicode-normalization", -] - -[[package]] -name = "if-addrs" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cabb0019d51a643781ff15c9c8a3e5dedc365c47211270f4e8f82812fedd8f0a" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "if-watch" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b0422c86d7ce0e97169cc42e04ae643caf278874a7a3c87b8150a220dc7e1e" -dependencies = [ - "async-io", - "core-foundation", - "fnv", - "futures 0.3.31", - "if-addrs", - "ipnet", - "log", - "rtnetlink", - "system-configuration", - "tokio", - "windows", -] - -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - -[[package]] -name = "impl-rlp" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f28220f89297a075ddc7245cd538076ee98b01f2a9c23a53a4f1105d5a322808" -dependencies = [ - "rlp", -] - -[[package]] -name = "impl-serde" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" -dependencies = [ - "serde", -] - -[[package]] -name = "impl-trait-for-tuples" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg 1.4.0", - "hashbrown 0.12.3", -] - -[[package]] -name = "indexmap" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" -dependencies = [ - "equivalent", - "hashbrown 0.15.0", -] - -[[package]] -name = "inout" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" -dependencies = [ - "block-padding 0.3.3", - "generic-array", -] - -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "iovec" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" -dependencies = [ - "libc", -] - -[[package]] -name = "ipconfig" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" -dependencies = [ - "socket2 0.5.7", - "widestring", - "windows-sys 0.48.0", - "winreg", -] - -[[package]] -name = "ipnet" -version = "2.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" - -[[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.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - -[[package]] -name = "js-sys" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9" -dependencies = [ - "wasm-bindgen", -] - -[[package]] -name = "jsonrpc-core" -version = "18.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14f7f76aef2d054868398427f6c54943cf3d1caa9a7ec7d0c38d69df97a965eb" -dependencies = [ - "futures 0.3.31", - "futures-executor", - "futures-util", - "log", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "keccak" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" -dependencies = [ - "cpufeatures", -] - -[[package]] -name = "keccak-hash" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82bc5d5ca345b067619615f62ac6f93e7daa67eb82d080bc380ed480708ec9e3" -dependencies = [ - "primitive-types", - "tiny-keccak 2.0.2", -] - -[[package]] -name = "keys" -version = "0.1.0" -dependencies = [ - "base58", - "bech32", - "bitcrypto", - "derive_more", - "lazy_static", - "primitives", - "rand 0.6.5", - "rustc-hex", - "secp256k1 0.20.3", - "serde", - "serde_derive", -] - -[[package]] -name = "kv-log-macro" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" -dependencies = [ - "log", -] - -[[package]] -name = "lazy_static" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" - -[[package]] -name = "libc" -version = "0.2.161" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" - -[[package]] -name = "libp2p" -version = "0.52.1" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "bytes 1.8.0", - "futures 0.3.31", - "futures-timer", - "getrandom 0.2.15", - "instant", - "libp2p-allow-block-list", - "libp2p-connection-limits", - "libp2p-core", - "libp2p-dns", - "libp2p-floodsub", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-identity", - "libp2p-mdns", - "libp2p-metrics", - "libp2p-noise", - "libp2p-ping", - "libp2p-request-response", - "libp2p-swarm", - "libp2p-tcp", - "libp2p-wasm-ext", - "libp2p-websocket", - "libp2p-yamux", - "multiaddr", - "pin-project", -] - -[[package]] -name = "libp2p-allow-block-list" -version = "0.2.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "void", -] - -[[package]] -name = "libp2p-connection-limits" -version = "0.2.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "void", -] - -[[package]] -name = "libp2p-core" -version = "0.40.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "either", - "fnv", - "futures 0.3.31", - "futures-timer", - "instant", - "libp2p-identity", - "log", - "multiaddr", - "multihash", - "multistream-select", - "once_cell", - "parking_lot", - "pin-project", - "quick-protobuf", - "rand 0.8.5", - "rw-stream-sink", - "smallvec 1.13.2", - "thiserror", - "unsigned-varint 0.7.2", - "void", -] - -[[package]] -name = "libp2p-dns" -version = "0.40.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "futures 0.3.31", - "libp2p-core", - "libp2p-identity", - "log", - "parking_lot", - "smallvec 1.13.2", - "trust-dns-resolver", -] - -[[package]] -name = "libp2p-floodsub" -version = "0.43.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "asynchronous-codec", - "cuckoofilter", - "fnv", - "futures 0.3.31", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "log", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "smallvec 1.13.2", - "thiserror", -] - -[[package]] -name = "libp2p-gossipsub" -version = "0.45.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "asynchronous-codec", - "base64 0.21.7", - "byteorder", - "bytes 1.8.0", - "either", - "fnv", - "futures 0.3.31", - "futures-ticker", - "getrandom 0.2.15", - "hex_fmt", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "log", - "prometheus-client", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "regex", - "sha2 0.10.8", - "smallvec 1.13.2", - "unsigned-varint 0.7.2", - "void", -] - -[[package]] -name = "libp2p-identify" -version = "0.43.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "asynchronous-codec", - "either", - "futures 0.3.31", - "futures-timer", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "log", - "lru", - "quick-protobuf", - "quick-protobuf-codec", - "smallvec 1.13.2", - "thiserror", - "void", -] - -[[package]] -name = "libp2p-identity" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55cca1eb2bc1fd29f099f3daaab7effd01e1a54b7c577d0ed082521034d912e8" -dependencies = [ - "asn1_der", - "bs58 0.5.1", - "ed25519-dalek", - "hkdf", - "libsecp256k1", - "multihash", - "quick-protobuf", - "sha2 0.10.8", - "thiserror", - "tracing", - "zeroize", -] - -[[package]] -name = "libp2p-mdns" -version = "0.44.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "data-encoding", - "futures 0.3.31", - "if-watch", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "log", - "rand 0.8.5", - "smallvec 1.13.2", - "socket2 0.5.7", - "tokio", - "trust-dns-proto", - "void", -] - -[[package]] -name = "libp2p-metrics" -version = "0.13.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "instant", - "libp2p-core", - "libp2p-gossipsub", - "libp2p-identify", - "libp2p-identity", - "libp2p-ping", - "libp2p-swarm", - "once_cell", - "prometheus-client", -] - -[[package]] -name = "libp2p-noise" -version = "0.43.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "bytes 1.8.0", - "curve25519-dalek 3.2.0", - "futures 0.3.31", - "libp2p-core", - "libp2p-identity", - "log", - "multiaddr", - "multihash", - "once_cell", - "quick-protobuf", - "rand 0.8.5", - "sha2 0.10.8", - "snow", - "static_assertions", - "thiserror", - "x25519-dalek", - "zeroize", -] - -[[package]] -name = "libp2p-ping" -version = "0.43.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "either", - "futures 0.3.31", - "futures-timer", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "log", - "rand 0.8.5", - "void", -] - -[[package]] -name = "libp2p-request-response" -version = "0.25.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "async-trait", - "futures 0.3.31", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm", - "log", - "rand 0.8.5", - "smallvec 1.13.2", - "void", -] - -[[package]] -name = "libp2p-swarm" -version = "0.43.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "either", - "fnv", - "futures 0.3.31", - "futures-timer", - "instant", - "libp2p-core", - "libp2p-identity", - "libp2p-swarm-derive", - "log", - "multistream-select", - "once_cell", - "rand 0.8.5", - "smallvec 1.13.2", - "tokio", - "void", -] - -[[package]] -name = "libp2p-swarm-derive" -version = "0.33.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "heck", - "proc-macro-warning", - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "libp2p-tcp" -version = "0.40.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "futures 0.3.31", - "futures-timer", - "if-watch", - "libc", - "libp2p-core", - "libp2p-identity", - "log", - "socket2 0.5.7", - "tokio", -] - -[[package]] -name = "libp2p-wasm-ext" -version = "0.40.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "futures 0.3.31", - "js-sys", - "libp2p-core", - "send_wrapper 0.6.0", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "libp2p-websocket" -version = "0.42.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "either", - "futures 0.3.31", - "futures-rustls 0.22.2", - "libp2p-core", - "libp2p-identity", - "log", - "parking_lot", - "quicksink", - "rw-stream-sink", - "soketto", - "url", - "webpki-roots 0.23.1", -] - -[[package]] -name = "libp2p-yamux" -version = "0.44.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "either", - "futures 0.3.31", - "libp2p-core", - "thiserror", - "tracing", - "yamux 0.12.1", - "yamux 0.13.3", -] - -[[package]] -name = "libsecp256k1" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b09eff1b35ed3b33b877ced3a691fc7a481919c7e29c53c906226fcf55e2a1" -dependencies = [ - "arrayref", - "base64 0.13.1", - "digest 0.9.0", - "hmac-drbg", - "libsecp256k1-core", - "libsecp256k1-gen-ecmult", - "libsecp256k1-gen-genmult", - "rand 0.8.5", - "serde", - "sha2 0.9.9", - "typenum", -] - -[[package]] -name = "libsecp256k1-core" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5be9b9bb642d8522a44d533eab56c16c738301965504753b03ad1de3425d5451" -dependencies = [ - "crunchy", - "digest 0.9.0", - "subtle", -] - -[[package]] -name = "libsecp256k1-gen-ecmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3038c808c55c87e8a172643a7d87187fc6c4174468159cb3090659d55bcb4809" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsecp256k1-gen-genmult" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3db8d6ba2cec9eacc40e6e8ccc98931840301f1006e95647ceb2dd5c3aa06f7c" -dependencies = [ - "libsecp256k1-core", -] - -[[package]] -name = "libsqlite3-sys" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29f835d03d717946d28b1d1ed632eb6f0e24a299388ee623d0c23118d3e8a7fa" -dependencies = [ - "cc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "libusb1-sys" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e22e89d08bbe6816c6c5d446203b859eba35b8fa94bf1b7edb2f6d25d43f023f" -dependencies = [ - "cc", - "libc", - "pkg-config", - "vcpkg", -] - -[[package]] -name = "lightning" -version = "0.0.113" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "087add70f81d2fdc6d4409bc0cef69e11ad366ef1d0068550159bd22b3ac8664" -dependencies = [ - "bitcoin", -] - -[[package]] -name = "linked-hash-map" -version = "0.5.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg 1.4.0", - "scopeguard", -] - -[[package]] -name = "log" -version = "0.4.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -dependencies = [ - "value-bag", -] - -[[package]] -name = "lru" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" -dependencies = [ - "hashbrown 0.13.1", -] - -[[package]] -name = "lru-cache" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" -dependencies = [ - "linked-hash-map", -] - -[[package]] -name = "mach2" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709" -dependencies = [ - "libc", -] - -[[package]] -name = "match_cfg" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" - -[[package]] -name = "matches" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" - -[[package]] -name = "maybe-uninit" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" - -[[package]] -name = "mem" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "memchr" -version = "2.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" - -[[package]] -name = "metrics" -version = "0.21.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fde3af1a009ed76a778cb84fdef9e7dbbdf5775ae3e4cc1f434a6a307f6f76c5" -dependencies = [ - "ahash", - "metrics-macros", - "portable-atomic", -] - -[[package]] -name = "metrics-exporter-prometheus" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d4fa7ce7c4862db464a37b0b31d89bca874562f034bd7993895572783d02950" -dependencies = [ - "base64 0.21.7", - "hyper", - "indexmap 1.9.3", - "ipnet", - "metrics", - "metrics-util", - "quanta", - "thiserror", - "tokio", - "tracing", -] - -[[package]] -name = "metrics-macros" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38b4faf00617defe497754acde3024865bc143d44a86799b24e191ecff91354f" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "metrics-util" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4de2ed6e491ed114b40b732e4d1659a9d53992ebd87490c44a6ffe23739d973e" -dependencies = [ - "aho-corasick", - "crossbeam-epoch", - "crossbeam-utils", - "hashbrown 0.13.1", - "indexmap 1.9.3", - "metrics", - "num_cpus", - "ordered-float", - "quanta", - "radix_trie", - "sketches-ddsketch", -] - -[[package]] -name = "minicov" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "def6d99771d7c499c26ad4d40eb6645eafd3a1553b35fc26ea5a489a45e82d9a" -dependencies = [ - "cc", - "walkdir", -] - -[[package]] -name = "miniz_oxide" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" -dependencies = [ - "adler2", -] - -[[package]] -name = "mio" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" -dependencies = [ - "hermit-abi 0.3.9", - "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", -] - -[[package]] -name = "mm2_core" -version = "0.1.0" -dependencies = [ - "arrayref", - "async-std", - "async-trait", - "cfg-if 1.0.0", - "common", - "db_common", - "derive_more", - "futures 0.3.31", - "gstuff", - "hex", - "instant", - "lazy_static", - "mm2_err_handle", - "mm2_event_stream", - "mm2_metrics", - "mm2_p2p", - "mm2_rpc", - "primitives", - "rand 0.7.3", - "rustls 0.21.12", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "shared_ref_counter", - "tokio", - "uuid", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_err_handle" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.1.31", - "http 0.2.12", - "itertools 0.10.5", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_eth" -version = "0.1.0" -dependencies = [ - "ethabi", - "ethkey", - "hex", - "indexmap 1.9.3", - "itertools 0.10.5", - "mm2_err_handle", - "secp256k1 0.20.3", - "serde", - "serde_json", - "web3", -] - -[[package]] -name = "mm2_event_stream" -version = "0.1.0" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "common", - "futures 0.3.31", - "parking_lot", - "serde", - "tokio", - "wasm-bindgen-test", -] - -[[package]] -name = "mm2_io" -version = "0.1.0" -dependencies = [ - "async-std", - "common", - "derive_more", - "futures 0.3.31", - "gstuff", - "mm2_err_handle", - "rand 0.7.3", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_metamask" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.31", - "itertools 0.10.5", - "js-sys", - "jsonrpc-core", - "lazy_static", - "mm2_err_handle", - "mm2_eth", - "parking_lot", - "serde", - "serde_derive", - "serde_json", - "wasm-bindgen", - "wasm-bindgen-futures", - "web3", -] - -[[package]] -name = "mm2_metrics" -version = "0.1.0" -dependencies = [ - "base64 0.21.7", - "common", - "derive_more", - "futures 0.3.31", - "hyper", - "hyper-rustls", - "itertools 0.10.5", - "metrics", - "metrics-exporter-prometheus", - "metrics-util", - "mm2_err_handle", - "serde", - "serde_derive", - "serde_json", -] - -[[package]] -name = "mm2_net" -version = "0.1.0" -dependencies = [ - "async-trait", - "base64 0.21.7", - "bytes 1.8.0", - "cfg-if 1.0.0", - "common", - "derive_more", - "ethkey", - "futures 0.3.31", - "futures-util", - "gstuff", - "http 0.2.12", - "http-body 0.4.6", - "httparse", - "hyper", - "js-sys", - "lazy_static", - "mm2_core", - "mm2_err_handle", - "mm2_state_machine", - "pin-project", - "prost", - "rand 0.7.3", - "rustls 0.21.12", - "serde", - "serde_json", - "thiserror", - "tokio", - "tokio-rustls", - "tonic", - "tower-service", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "mm2_number" -version = "0.1.0" -dependencies = [ - "bigdecimal", - "num-bigint", - "num-rational", - "num-traits", - "paste", - "serde", - "serde_json", -] - -[[package]] -name = "mm2_p2p" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.31", - "futures-rustls 0.22.2", - "futures-rustls 0.24.0", - "futures-ticker", - "hex", - "instant", - "lazy_static", - "libp2p", - "log", - "rand 0.7.3", - "regex", - "rmp-serde", - "secp256k1 0.20.3", - "serde", - "serde_bytes", - "sha2 0.10.8", - "smallvec 1.13.2", - "syn 2.0.85", - "tokio", - "void", -] - -[[package]] -name = "mm2_rpc" -version = "0.1.0" -dependencies = [ - "common", - "derive_more", - "futures 0.3.31", - "gstuff", - "http 0.2.12", - "mm2_err_handle", - "mm2_number", - "rpc", - "ser_error", - "ser_error_derive", - "serde", - "serde_json", - "uuid", -] - -[[package]] -name = "mm2_state_machine" -version = "0.1.0" -dependencies = [ - "async-trait", -] - -[[package]] -name = "mm2_test_helpers" -version = "0.1.0" -dependencies = [ - "bytes 1.8.0", - "cfg-if 1.0.0", - "chrono", - "common", - "crypto", - "db_common", - "futures 0.3.31", - "gstuff", - "http 0.2.12", - "lazy_static", - "mm2_core", - "mm2_io", - "mm2_metrics", - "mm2_net", - "mm2_number", - "mm2_rpc", - "rand 0.7.3", - "regex", - "rpc", - "serde", - "serde_derive", - "serde_json", - "uuid", -] - -[[package]] -name = "multiaddr" -version = "0.18.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" -dependencies = [ - "arrayref", - "byteorder", - "data-encoding", - "libp2p-identity", - "multibase", - "multihash", - "percent-encoding", - "serde", - "static_assertions", - "unsigned-varint 0.8.0", - "url", -] - -[[package]] -name = "multibase" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b3539ec3c1f04ac9748a260728e855f261b4977f5c3406612c884564f329404" -dependencies = [ - "base-x", - "data-encoding", - "data-encoding-macro", -] - -[[package]] -name = "multihash" -version = "0.19.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc41f430805af9d1cf4adae4ed2149c759b877b01d909a1f40256188d09345d2" -dependencies = [ - "core2", - "unsigned-varint 0.8.0", -] - -[[package]] -name = "multistream-select" -version = "0.13.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "bytes 1.8.0", - "futures 0.3.31", - "log", - "pin-project", - "smallvec 1.13.2", - "unsigned-varint 0.7.2", -] - -[[package]] -name = "netlink-packet-core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "345b8ab5bd4e71a2986663e88c56856699d060e78e152e6e9d7966fcd5491297" -dependencies = [ - "anyhow", - "byteorder", - "libc", - "netlink-packet-utils", -] - -[[package]] -name = "netlink-packet-route" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9ea4302b9759a7a88242299225ea3688e63c85ea136371bb6cf94fd674efaab" -dependencies = [ - "anyhow", - "bitflags 1.3.2", - "byteorder", - "libc", - "netlink-packet-core", - "netlink-packet-utils", -] - -[[package]] -name = "netlink-packet-utils" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" -dependencies = [ - "anyhow", - "byteorder", - "paste", - "thiserror", -] - -[[package]] -name = "netlink-proto" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" -dependencies = [ - "bytes 1.8.0", - "futures 0.3.31", - "log", - "netlink-packet-core", - "netlink-sys", - "thiserror", - "tokio", -] - -[[package]] -name = "netlink-sys" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" -dependencies = [ - "bytes 1.8.0", - "futures 0.3.31", - "libc", - "log", - "tokio", -] - -[[package]] -name = "nibble_vec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" -dependencies = [ - "smallvec 1.13.2", -] - -[[package]] -name = "nix" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069" -dependencies = [ - "bitflags 1.3.2", - "cfg-if 1.0.0", - "libc", -] - -[[package]] -name = "nohash-hasher" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bf50223579dc7cdcfb3bfcacf7069ff68243f8c363f62ffa99cf000a6b9c451" - -[[package]] -name = "num-bigint" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" -dependencies = [ - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "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", - "num-integer", - "num-traits", - "serde", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg 1.4.0", -] - -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.9", - "libc", -] - -[[package]] -name = "object" -version = "0.36.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" -dependencies = [ - "memchr", -] - -[[package]] -name = "once_cell" -version = "1.20.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" - -[[package]] -name = "opaque-debug" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" - -[[package]] -name = "ordered-float" -version = "3.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1e1c390732d15f1d48471625cd92d154e66db2c56645e29a9cd26f4699f72dc" -dependencies = [ - "num-traits", -] - -[[package]] -name = "parity-scale-codec" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee" -dependencies = [ - "arrayvec 0.7.6", - "bitvec", - "byte-slice-cast", - "impl-trait-for-tuples", - "parity-scale-codec-derive", - "serde", -] - -[[package]] -name = "parity-scale-codec-derive" -version = "3.6.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c" -dependencies = [ - "proc-macro-crate", - "proc-macro2", - "quote 1.0.37", - "syn 1.0.109", -] - -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core 0.9.10", -] - -[[package]] -name = "parking_lot_core" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66b810a62be75176a80873726630147a5ca780cd33921e0b5709033e66b0a" -dependencies = [ - "cfg-if 0.1.10", - "cloudabi", - "libc", - "redox_syscall 0.1.57", - "rustc_version 0.2.3", - "smallvec 0.6.14", - "winapi", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if 1.0.0", - "libc", - "redox_syscall 0.5.7", - "smallvec 1.13.2", - "windows-targets 0.52.6", -] - -[[package]] -name = "password-hash" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" -dependencies = [ - "base64ct", - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "paste" -version = "1.0.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" - -[[package]] -name = "percent-encoding" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" - -[[package]] -name = "pin-project" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" -dependencies = [ - "pin-project-internal", -] - -[[package]] -name = "pin-project-internal" -version = "1.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "pin-project-lite" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "257b64915a082f7811703966789728173279bdebb956b143dbcd23f6f970a777" - -[[package]] -name = "pin-project-lite" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" - -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - -[[package]] -name = "pkg-config" -version = "0.3.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" - -[[package]] -name = "polling" -version = "3.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" -dependencies = [ - "cfg-if 1.0.0", - "concurrent-queue", - "hermit-abi 0.4.0", - "pin-project-lite 0.2.15", - "rustix", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "poly1305" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" -dependencies = [ - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "polyval" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" -dependencies = [ - "cfg-if 1.0.0", - "cpufeatures", - "opaque-debug", - "universal-hash", -] - -[[package]] -name = "portable-atomic" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" - -[[package]] -name = "ppv-lite86" -version = "0.2.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] - -[[package]] -name = "primitive-types" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" -dependencies = [ - "fixed-hash", - "impl-codec", - "impl-rlp", - "impl-serde", - "uint", -] - -[[package]] -name = "primitives" -version = "0.1.0" -dependencies = [ - "bitcoin_hashes 0.11.0", - "byteorder", - "rustc-hex", - "uint", -] - -[[package]] -name = "proc-macro-crate" -version = "3.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" -dependencies = [ - "toml_edit", -] - -[[package]] -name = "proc-macro-warning" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1eaa7fa0aa1929ffdf7eeb6eac234dde6268914a14ad44d23521ab6a9b258e" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "proc-macro2" -version = "1.0.89" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" -dependencies = [ - "unicode-ident", -] - -[[package]] -name = "prometheus-client" -version = "0.21.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c99afa9a01501019ac3a14d71d9f94050346f55ca471ce90c799a15c58f61e2" -dependencies = [ - "dtoa", - "itoa 1.0.11", - "parking_lot", - "prometheus-client-derive-encode", -] - -[[package]] -name = "prometheus-client-derive-encode" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "prost" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deb1435c188b76130da55f17a466d252ff7b1418b2ad3e037d127b94e3411f29" -dependencies = [ - "bytes 1.8.0", - "prost-derive", -] - -[[package]] -name = "prost-derive" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1" -dependencies = [ - "anyhow", - "itertools 0.12.1", - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "quanta" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a17e662a7a8291a865152364c20c7abc5e60486ab2001e8ec10b24862de0b9ab" -dependencies = [ - "crossbeam-utils", - "libc", - "mach2", - "once_cell", - "raw-cpuid", - "wasi 0.11.0+wasi-snapshot-preview1", - "web-sys", - "winapi", -] - -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - -[[package]] -name = "quick-protobuf" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" -dependencies = [ - "byteorder", -] - -[[package]] -name = "quick-protobuf-codec" -version = "0.2.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "asynchronous-codec", - "bytes 1.8.0", - "quick-protobuf", - "thiserror", - "unsigned-varint 0.7.2", -] - -[[package]] -name = "quicksink" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77de3c815e5a160b1539c6592796801df2043ae35e123b46d73380cfa57af858" -dependencies = [ - "futures-core", - "futures-sink", - "pin-project-lite 0.1.12", -] - -[[package]] -name = "quote" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" - -[[package]] -name = "quote" -version = "1.0.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "radium" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" - -[[package]] -name = "radix_trie" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" -dependencies = [ - "endian-type", - "nibble_vec", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" -dependencies = [ - "getrandom 0.1.16", - "libc", - "rand_chacha 0.2.2", - "rand_core 0.5.1", - "rand_hc 0.2.0", - "rand_pcg 0.2.1", -] - -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" -dependencies = [ - "ppv-lite86", - "rand_core 0.5.1", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - -[[package]] -name = "rand_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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" -dependencies = [ - "getrandom 0.1.16", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.15", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" -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", - "wasm-bindgen", - "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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" -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-cpuid" -version = "10.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332" -dependencies = [ - "bitflags 1.3.2", -] - -[[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.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_syscall" -version = "0.5.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" -dependencies = [ - "bitflags 2.6.0", -] - -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - -[[package]] -name = "resolv-conf" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" -dependencies = [ - "hostname", - "quick-error", -] - -[[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]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if 1.0.0", - "getrandom 0.2.15", - "libc", - "spin 0.9.8", - "untrusted 0.9.0", - "windows-sys 0.52.0", -] - -[[package]] -name = "ripemd160" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eca4ecc81b7f313189bf73ce724400a07da2a6dac19588b03c8bd76a2dcc251" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes 1.8.0", - "rustc-hex", -] - -[[package]] -name = "rmp" -version = "0.8.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" -dependencies = [ - "byteorder", - "num-traits", - "paste", -] - -[[package]] -name = "rmp-serde" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ce7d70c926fe472aed493b902010bccc17fa9f7284145cb8772fd22fdb052d8" -dependencies = [ - "byteorder", - "rmp", - "serde", -] - -[[package]] -name = "rpc" -version = "0.1.0" -dependencies = [ - "chain", - "keys", - "log", - "primitives", - "rustc-hex", - "script", - "serde", - "serde_derive", - "serde_json", - "serialization", -] - -[[package]] -name = "rpc_task" -version = "0.1.0" -dependencies = [ - "async-trait", - "common", - "derive_more", - "futures 0.3.31", - "mm2_err_handle", - "ser_error", - "ser_error_derive", - "serde", - "serde_derive", -] - -[[package]] -name = "rtnetlink" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322c53fd76a18698f1c27381d58091de3a043d356aa5bd0d510608b565f469a0" -dependencies = [ - "futures 0.3.31", - "log", - "netlink-packet-route", - "netlink-proto", - "nix", - "thiserror", - "tokio", -] - -[[package]] -name = "rusb" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c470dc7dc6e4710b6f85e9c4aa4650bc742260b39a36328180578db76fa258c1" -dependencies = [ - "libc", - "libusb1-sys", -] - -[[package]] -name = "rusqlite" -version = "0.28.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01e213bc3ecb39ac32e81e51ebe31fd888a940515173e3a18a35f8c6e896422a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink", - "libsqlite3-sys", - "smallvec 1.13.2", -] - -[[package]] -name = "rustc-demangle" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - -[[package]] -name = "rustc-hex" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" - -[[package]] -name = "rustc_version" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" -dependencies = [ - "semver 0.9.0", -] - -[[package]] -name = "rustc_version" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" -dependencies = [ - "semver 1.0.23", -] - -[[package]] -name = "rustix" -version = "0.38.37" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" -dependencies = [ - "bitflags 2.6.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] - -[[package]] -name = "rustls" -version = "0.20.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" -dependencies = [ - "log", - "ring 0.16.20", - "sct", - "webpki", -] - -[[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-webpki" -version = "0.100.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6a5fc258f1c1276dfe3016516945546e2d5383911efc0fc4f1cdc5df3a4ae3" -dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", -] - -[[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 = "rw-stream-sink" -version = "0.4.0" -source = "git+https://github.com/KomodoPlatform/rust-libp2p.git?tag=k-0.52.4#6fc061b58853c1b0dafaa19a4a29343c0ac6eab3" -dependencies = [ - "futures 0.3.31", - "pin-project", - "static_assertions", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "same-file" -version = "1.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" -dependencies = [ - "winapi-util", -] - -[[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 = "script" -version = "0.1.0" -dependencies = [ - "bitcrypto", - "blake2b_simd", - "chain", - "keys", - "log", - "primitives", - "serde", - "serialization", -] - -[[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 = "secp256k1" -version = "0.20.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97d03ceae636d0fed5bae6a7f4f664354c5f4fcedf6eef053fef17e49f837d0a" -dependencies = [ - "rand 0.6.5", - "secp256k1-sys 0.4.2", -] - -[[package]] -name = "secp256k1" -version = "0.24.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" -dependencies = [ - "bitcoin_hashes 0.11.0", - "secp256k1-sys 0.6.1", -] - -[[package]] -name = "secp256k1-sys" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "957da2573cde917463ece3570eab4a0b3f19de6f1646cde62e6fd3868f566036" -dependencies = [ - "cc", -] - -[[package]] -name = "secp256k1-sys" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83080e2c2fc1006e625be82e5d1eb6a43b7fd9578b617fcc55814daf286bba4b" -dependencies = [ - "cc", -] - -[[package]] -name = "semver" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" -dependencies = [ - "semver-parser", -] - -[[package]] -name = "semver" -version = "1.0.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" - -[[package]] -name = "semver-parser" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" - -[[package]] -name = "send_wrapper" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" - -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - -[[package]] -name = "ser_error" -version = "0.1.0" -dependencies = [ - "serde", -] - -[[package]] -name = "ser_error_derive" -version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "ser_error", - "syn 1.0.109", -] - -[[package]] -name = "serde" -version = "1.0.213" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde-wasm-bindgen" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf" -dependencies = [ - "js-sys", - "serde", - "wasm-bindgen", -] - -[[package]] -name = "serde_bytes" -version = "0.11.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a" -dependencies = [ - "serde", -] - -[[package]] -name = "serde_derive" -version = "1.0.213" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "serde_json" -version = "1.0.132" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" -dependencies = [ - "indexmap 2.6.0", - "itoa 1.0.11", - "memchr", - "ryu", - "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 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "serialization" -version = "0.1.0" -dependencies = [ - "byteorder", - "derive_more", - "primitives", - "test_helpers", -] - -[[package]] -name = "serialization_derive" -version = "0.1.0" -dependencies = [ - "quote 0.3.15", - "syn 0.11.11", -] - -[[package]] -name = "sha-1" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "cpufeatures", - "digest 0.9.0", - "opaque-debug", -] - -[[package]] -name = "sha2" -version = "0.9.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" -dependencies = [ - "block-buffer 0.9.0", - "cfg-if 1.0.0", - "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 1.0.0", - "cpufeatures", - "digest 0.10.7", -] - -[[package]] -name = "sha3" -version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" -dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", - "keccak", - "opaque-debug", -] - -[[package]] -name = "sha3" -version = "0.10.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" -dependencies = [ - "digest 0.10.7", - "keccak", -] - -[[package]] -name = "shared_ref_counter" -version = "0.1.0" - -[[package]] -name = "shlex" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" - -[[package]] -name = "signal-hook-registry" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" -dependencies = [ - "libc", -] - -[[package]] -name = "signature" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" -dependencies = [ - "rand_core 0.6.4", -] - -[[package]] -name = "siphasher" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "833011ca526bd88f16778d32c699d325a9ad302fa06381cd66f7be63351d3f6d" - -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" - -[[package]] -name = "slab" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" -dependencies = [ - "autocfg 1.4.0", -] - -[[package]] -name = "smallvec" -version = "0.6.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97fcaeba89edba30f044a10c6a3cc39df9c3f17d7cd829dd1446cab35f890e0" -dependencies = [ - "maybe-uninit", -] - -[[package]] -name = "smallvec" -version = "1.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" - -[[package]] -name = "snow" -version = "0.9.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "850948bee068e713b8ab860fe1adc4d109676ab4c3b621fd8147f06b261f2f85" -dependencies = [ - "aes-gcm", - "blake2", - "chacha20poly1305", - "curve25519-dalek 4.1.3", - "rand_core 0.6.4", - "ring 0.17.8", - "rustc_version 0.4.1", - "sha2 0.10.8", - "subtle", -] - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - -[[package]] -name = "soketto" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1c5305e39e09653383c2c7244f2f78b3bcae37cf50c64cb4789c9f5096ec2" -dependencies = [ - "base64 0.13.1", - "bytes 1.8.0", - "futures 0.3.31", - "httparse", - "log", - "rand 0.8.5", - "sha-1", -] - -[[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.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - -[[package]] -name = "sql-builder" -version = "3.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1008d95d2ec2d062959352527be30e10fec42a1aa5e5a48d990a5ff0fb9bdc0" -dependencies = [ - "anyhow", - "thiserror", -] - -[[package]] -name = "static_assertions" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" - -[[package]] -name = "subtle" -version = "2.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" - -[[package]] -name = "syn" -version = "0.11.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" -dependencies = [ - "quote 0.3.15", - "synom", - "unicode-xid", -] - -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "syn" -version = "2.0.85" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "unicode-ident", -] - -[[package]] -name = "synom" -version = "0.11.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" -dependencies = [ - "unicode-xid", -] - -[[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 = "tap" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "test_helpers" -version = "0.1.0" -dependencies = [ - "hex", -] - -[[package]] -name = "thiserror" -version = "1.0.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" -dependencies = [ - "thiserror-impl", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "tiny-keccak" -version = "1.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f11c56c1b46016bb1129db9399f905385490f3e17907e4a8430e57f9a5b979c" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tiny-keccak" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" -dependencies = [ - "crunchy", -] - -[[package]] -name = "tinyvec" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" -dependencies = [ - "tinyvec_macros", -] - -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - -[[package]] -name = "tokio" -version = "1.41.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" -dependencies = [ - "backtrace", - "bytes 1.8.0", - "libc", - "mio", - "pin-project-lite 0.2.15", - "socket2 0.5.7", - "tokio-macros", - "windows-sys 0.52.0", -] - -[[package]] -name = "tokio-buf" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fb220f46c53859a4b7ec083e41dec9778ff0b1851c0942b211edb89e0ccdc46" -dependencies = [ - "bytes 0.4.12", - "futures 0.1.31", -] - -[[package]] -name = "tokio-macros" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[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-stream" -version = "0.1.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" -dependencies = [ - "futures-core", - "pin-project-lite 0.2.15", - "tokio", -] - -[[package]] -name = "tokio-util" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" -dependencies = [ - "bytes 1.8.0", - "futures-core", - "futures-sink", - "pin-project-lite 0.2.15", - "tokio", -] - -[[package]] -name = "toml_datetime" -version = "0.6.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" - -[[package]] -name = "toml_edit" -version = "0.22.22" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" -dependencies = [ - "indexmap 2.6.0", - "toml_datetime", - "winnow", -] - -[[package]] -name = "tonic" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" -dependencies = [ - "async-trait", - "base64 0.21.7", - "bytes 1.8.0", - "http 0.2.12", - "http-body 0.4.6", - "percent-encoding", - "pin-project", - "prost", - "tokio", - "tokio-stream", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - -[[package]] -name = "tower-service" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" - -[[package]] -name = "tracing" -version = "0.1.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" -dependencies = [ - "pin-project-lite 0.2.15", - "tracing-attributes", - "tracing-core", -] - -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "tracing-core" -version = "0.1.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" -dependencies = [ - "once_cell", -] - -[[package]] -name = "trezor" -version = "0.1.1" -dependencies = [ - "async-std", - "async-trait", - "bip32", - "byteorder", - "common", - "derive_more", - "ethcore-transaction", - "ethereum-types", - "ethkey", - "futures 0.3.31", - "hw_common", - "js-sys", - "lazy_static", - "mm2_err_handle", - "prost", - "rand 0.7.3", - "rpc_task", - "serde", - "serde_derive", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test", - "web-sys", -] - -[[package]] -name = "trust-dns-proto" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26" -dependencies = [ - "async-trait", - "cfg-if 1.0.0", - "data-encoding", - "enum-as-inner", - "futures-channel", - "futures-io", - "futures-util", - "idna 0.2.3", - "ipnet", - "lazy_static", - "rand 0.8.5", - "smallvec 1.13.2", - "socket2 0.4.10", - "thiserror", - "tinyvec", - "tokio", - "tracing", - "url", -] - -[[package]] -name = "trust-dns-resolver" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe" -dependencies = [ - "cfg-if 1.0.0", - "futures-util", - "ipconfig", - "lazy_static", - "lru-cache", - "parking_lot", - "resolv-conf", - "smallvec 1.13.2", - "thiserror", - "tokio", - "tracing", - "trust-dns-proto", -] - -[[package]] -name = "try-lock" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" - -[[package]] -name = "typenum" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - -[[package]] -name = "unexpected" -version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" - -[[package]] -name = "unicode-bidi" -version = "0.3.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ab17db44d7388991a428b2ee655ce0c212e862eff1768a455c58f9aad6e7893" - -[[package]] -name = "unicode-ident" -version = "1.0.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" - -[[package]] -name = "unicode-normalization" -version = "0.1.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" -dependencies = [ - "tinyvec", -] - -[[package]] -name = "unicode-xid" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc" - -[[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 = "unsigned-varint" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6889a77d49f1f013504cec6bf97a2c730394adedaeb1deb5ea08949a50541105" -dependencies = [ - "asynchronous-codec", - "bytes 1.8.0", -] - -[[package]] -name = "unsigned-varint" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb066959b24b5196ae73cb057f45598450d2c5f71460e98c49b738086eff9c06" - -[[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" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - -[[package]] -name = "url" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" -dependencies = [ - "form_urlencoded", - "idna 0.5.0", - "percent-encoding", -] - -[[package]] -name = "uuid" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" -dependencies = [ - "getrandom 0.2.15", - "rand 0.8.5", - "serde", -] - -[[package]] -name = "value-bag" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" - -[[package]] -name = "vcpkg" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" - -[[package]] -name = "version_check" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" - -[[package]] -name = "void" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d" - -[[package]] -name = "walkdir" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" -dependencies = [ - "same-file", - "winapi-util", -] - -[[package]] -name = "want" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" -dependencies = [ - "try-lock", -] - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" - -[[package]] -name = "wasm-bindgen" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e" -dependencies = [ - "cfg-if 1.0.0", - "once_cell", - "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358" -dependencies = [ - "bumpalo", - "log", - "once_cell", - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-futures" -version = "0.4.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7ec4f8827a71586374db3e87abdb5a2bb3a15afed140221307c3ec06b1f63b" -dependencies = [ - "cfg-if 1.0.0", - "js-sys", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "wasm-bindgen-macro" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56" -dependencies = [ - "quote 1.0.37", - "wasm-bindgen-macro-support", -] - -[[package]] -name = "wasm-bindgen-macro-support" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", - "wasm-bindgen-backend", - "wasm-bindgen-shared", -] - -[[package]] -name = "wasm-bindgen-shared" -version = "0.2.95" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d" - -[[package]] -name = "wasm-bindgen-test" -version = "0.3.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d381749acb0943d357dcbd8f0b100640679883fcdeeef04def49daf8d33a5426" -dependencies = [ - "console_error_panic_hook", - "js-sys", - "minicov", - "scoped-tls", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasm-bindgen-test-macro", -] - -[[package]] -name = "wasm-bindgen-test-macro" -version = "0.3.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c97b2ef2c8d627381e51c071c2ab328eac606d3f69dd82bcbca20a9e389d95f0" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "web-sys" -version = "0.3.72" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6488b90108c040df0fe62fa815cbdee25124641df01814dd7282749234c6112" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web-time" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" -dependencies = [ - "js-sys", - "wasm-bindgen", -] - -[[package]] -name = "web3" -version = "0.19.0" -source = "git+https://github.com/KomodoPlatform/rust-web3?tag=v0.20.0#01de1d732e61c920cfb2fb1533db7d7110c8a457" -dependencies = [ - "arrayvec 0.7.6", - "derive_more", - "ethabi", - "ethereum-types", - "futures 0.3.31", - "futures-timer", - "getrandom 0.2.15", - "hex", - "idna 0.2.3", - "js-sys", - "jsonrpc-core", - "log", - "parking_lot", - "pin-project", - "rand 0.8.5", - "rlp", - "serde", - "serde-wasm-bindgen", - "serde_json", - "tiny-keccak 2.0.2", - "wasm-bindgen", - "wasm-bindgen-futures", -] - -[[package]] -name = "webpki" -version = "0.22.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" -dependencies = [ - "ring 0.17.8", - "untrusted 0.9.0", -] - -[[package]] -name = "webpki-roots" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338" -dependencies = [ - "rustls-webpki 0.100.3", -] - -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - -[[package]] -name = "widestring" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" -dependencies = [ - "windows-sys 0.59.0", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" -dependencies = [ - "windows-core 0.51.1", - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-core" -version = "0.51.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-core" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" - -[[package]] -name = "winnow" -version = "0.6.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" -dependencies = [ - "memchr", -] - -[[package]] -name = "winreg" -version = "0.50.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - -[[package]] -name = "wyz" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" -dependencies = [ - "tap", -] - -[[package]] -name = "x25519-dalek" -version = "1.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" -dependencies = [ - "curve25519-dalek 3.2.0", - "rand_core 0.5.1", - "zeroize", -] - -[[package]] -name = "yamux" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ed0164ae619f2dc144909a9f082187ebb5893693d8c0196e8085283ccd4b776" -dependencies = [ - "futures 0.3.31", - "log", - "nohash-hasher", - "parking_lot", - "pin-project", - "rand 0.8.5", - "static_assertions", -] - -[[package]] -name = "yamux" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31b5e376a8b012bee9c423acdbb835fc34d45001cfa3106236a624e4b738028" -dependencies = [ - "futures 0.3.31", - "log", - "nohash-hasher", - "parking_lot", - "pin-project", - "rand 0.8.5", - "static_assertions", - "web-time", -] - -[[package]] -name = "zerocopy" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" -dependencies = [ - "byteorder", - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" -dependencies = [ - "proc-macro2", - "quote 1.0.37", - "syn 2.0.85", -] - -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" -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 1.0.37", - "syn 2.0.85", -] From 9c083acbcac37bcb9b836fc284af2be6b0f9c648 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 25 Oct 2024 15:18:10 +0100 Subject: [PATCH 081/125] eth wc transaction - save dev state --- mm2src/coins/eth.rs | 2 +- mm2src/coins/eth/eth_withdraw.rs | 48 +++++++++++++++++-- mm2src/coins/eth/v2_activation.rs | 2 +- mm2src/coins/eth/wallet_connect.rs | 36 ++++++++++++-- .../src/eth_with_token_activation.rs | 6 ++- .../kdf_walletconnect/src/inbound_message.rs | 3 +- 6 files changed, 86 insertions(+), 11 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 5a5d5394ba..d708463cd9 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2483,7 +2483,7 @@ impl MarketCoinOps for EthCoin { EthPrivKeyPolicy::Trezor => ERR!("'display_priv_key' is not supported for Hardware Wallets"), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => ERR!("'display_priv_key' is not supported for MetaMask"), - EthPrivKeyPolicy::WalletConnect { .. } => ERR!("'display_priv_key' is not supported for MetaMask"), + EthPrivKeyPolicy::WalletConnect { .. } => ERR!("'display_priv_key' is not supported for WalletConnect"), } } diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index 1baa2431d3..df99ec6602 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -1,5 +1,6 @@ use super::{checksum_address, u256_to_big_decimal, wei_from_big_decimal, EthCoinType, EthDerivationMethod, EthPrivKeyPolicy, Public, WithdrawError, WithdrawRequest, WithdrawResult, ERC20_CONTRACT, H160, H256}; +use crate::eth::wallet_connect::wc_sign_eth_transaction; use crate::eth::{calc_total_fee, get_eth_gas_details_from_withdraw_fee, tx_builder_with_pay_for_gas_option, tx_type_from_pay_for_gas_option, Action, Address, EthTxFeeDetails, KeyPair, PayForGasOption, SignedEthTx, TransactionWrapper, UnSignedEthTxBuilder}; @@ -16,10 +17,12 @@ use crypto::trezor::trezor_rpc_task::{TrezorRequestStatuses, TrezorRpcTaskProces use crypto::{CryptoCtx, HwRpcError}; use ethabi::Token; use futures::compat::Future01CompatExt; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::map_mm_error::MapMmError; use mm2_err_handle::mm_error::MmResult; use mm2_err_handle::prelude::{MapToMmResult, MmError, OrMmError}; +use std::collections::HashMap; use std::ops::Deref; use std::sync::Arc; #[cfg(target_arch = "wasm32")] @@ -139,7 +142,10 @@ where let bytes = rlp::encode(&signed); Ok((signed.tx_hash(), BytesJson::from(bytes.to_vec()))) }, - EthPrivKeyPolicy::WalletConnect { .. } => todo!(), + EthPrivKeyPolicy::WalletConnect { .. } => { + // let data = unsigned_tx + todo!() + }, #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => MmError::err(WithdrawError::InternalError("invalid policy".to_owned())), } @@ -147,7 +153,7 @@ where /// Sends the transaction and returns the transaction hash and the signed transaction. /// This method should only be used when withdrawing using an external wallet like MetaMask. - #[cfg(target_arch = "wasm32")] + #[cfg(not(target_arch = "wasm32"))] async fn send_withdraw_tx( &self, req: &WithdrawRequest, @@ -296,7 +302,43 @@ where }; self.send_withdraw_tx(&req, tx_to_send).await? }, - EthPrivKeyPolicy::WalletConnect { address: _, pubkey: _ } => todo!(), + EthPrivKeyPolicy::WalletConnect { address: _, pubkey: _ } => { + let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); + let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + let chain_id = coin.chain_id.to_string(); + + let gas_price = pay_for_gas_option.get_gas_price(); + let (nonce, _) = coin + .clone() + .get_addr_nonce(my_address) + .compat() + .timeout_secs(30.) + .await? + .map_to_mm(WithdrawError::Transport)?; + let mut mapped_data = HashMap::new(); + mapped_data.insert("nonce", hex::encode(nonce.to_string())); + mapped_data.insert("to", hex::encode(to_addr.as_bytes())); + mapped_data.insert("from", hex::encode(my_address.as_bytes())); + mapped_data.insert("gas", hex::encode(gas.to_string())); + + if let Some(gas_price) = gas_price { + mapped_data.insert("gasPrice", hex::encode(gas_price.to_string())); + }; + + mapped_data.insert("value", hex::encode(eth_value.to_string())); + mapped_data.insert("data", hex::encode(data)); + + let signed= wc_sign_eth_transaction( + &wc, + &chain_id.to_string(), + serde_json::to_value(mapped_data).expect("invalid tx_json data"), + ) + .await + .mm_err(|err| WithdrawError::SigningError(err.to_string()))?; + + let tx_hex = BytesJson::from(rlp::encode(&signed).to_vec()) + todo!() + }, }; self.on_finishing()?; diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 686b57c6a2..55aa9187e4 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -806,7 +806,7 @@ async fn build_web3_instances( eth_nodes.as_mut_slice().shuffle(&mut rng); drop_mutability!(eth_nodes); - let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker.clone()); + let event_handlers = rpc_event_handlers_for_eth_transport(ctx, coin_ticker); let mut web3_instances = Vec::with_capacity(eth_nodes.len()); for eth_node in eth_nodes { diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index fb7fd60566..4ae9d1f9b3 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -23,6 +23,35 @@ impl From for WalletConnectError { fn from(value: EthWalletConnectError) -> Self { Self::SessionError(value.to_string()) } } +pub async fn wc_sign_eth_transaction( + ctx: &WalletConnectCtx, + chain_id: u64, + tx_json: serde_json::Value, +) -> MmResult { + let chain_id = chain_id.to_string(); + let topic = ctx + .session + .get_session_active() + .await + .map(|session| session.topic.clone()) + .ok_or(WalletConnectError::NotInitialized)?; + let request = SessionRequestRequest { + chain_id: WcChain::Eip155.to_chain_id(&chain_id), + request: SessionRequest { + method: WcRequestMethods::EthSignTransaction.as_ref().to_string(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: tx_json.clone(), + }, + }; + + { + let req_params = RequestParams::SessionRequest(request); + ctx.publish_request(&topic, req_params).await?; + }; + + ctx.on_wc_session_response(Ok).await +} + pub async fn eth_request_wc_personal_sign( ctx: &WalletConnectCtx, chain_id: u64, @@ -35,7 +64,7 @@ pub async fn eth_request_wc_personal_sign( .ok_or(WalletConnectError::NotInitialized)?; let account_str = ctx.get_account_for_chain_id(&chain_id.to_string()).await?; - let message = "Hello World"; + let message = "Authenticate with Komodefi"; let message_hex = format!("0x{}", hex::encode(message)); let params = json!(&[&message_hex, &account_str]); @@ -58,10 +87,10 @@ pub async fn eth_request_wc_personal_sign( fn extract_pubkey_from_signature( signature_str: &str, - message: &str, + message: impl ToString, account: &str, ) -> MmResult<(Public, Address), EthWalletConnectError> { - let message_hash = hash_message(message); + let message_hash = hash_message(message.to_string()); let account = H160::from_str(&account[2..]).expect("valid eth account"); let signature = Signature::from_str(&signature_str[2..]) .map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; @@ -76,6 +105,7 @@ fn extract_pubkey_from_signature( let error = format!("Recovered address '{recovered_address:?}' should be the same as '{account:?}'"); return MmError::err(EthWalletConnectError::AccoountMisMatch(error)); } + Ok((pubkey, recovered_address)) } diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index 4bee54d960..e689f606f9 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -19,6 +19,7 @@ use coins::my_tx_history_v2::TxHistoryStorage; use coins::nft::nft_structs::NftInfo; use coins::{CoinBalance, CoinBalanceMap, CoinProtocol, CoinWithDerivationMethod, DerivationMethod, MarketCoinOps, MmCoin, MmCoinEnum}; +use kdf_walletconnect::chain::WcChain; use kdf_walletconnect::WalletConnectCtx; use crate::platform_coin_with_tokens::InitPlatformCoinWithTokensTask; @@ -477,14 +478,15 @@ async fn eth_priv_key_build_policy( }, EthPrivKeyActivationPolicy::Trezor => Ok(EthPrivKeyBuildPolicy::Trezor), EthPrivKeyActivationPolicy::WalletConnect => { - let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; - if !wc.is_chain_supported(&format!("eip155:{chain_id}")) { + if !wc.is_chain_supported(&WcChain::Eip155.to_chain_id(&chain_id.to_string())) { return MmError::err(EthActivationV2Error::WalletConnectError(format!( "Unsupported chain_id: {chain_id}" ))); }; + let (pubkey, address) = eth_request_wc_personal_sign(&wc, chain_id) .await .mm_err(|err| EthActivationV2Error::WalletConnectError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index eb1eddedeb..73ce5a7904 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -59,7 +59,8 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: R let result = match response { Response::Success(value) => match serde_json::from_value::(value.result) { Ok(data) => { - // Probably the best place to handle session propose response. + // Probably the best place to handle session propose response + // as we might not get a feedback for a long time or even at all if let ResponseParamsSuccess::SessionPropose(propose) = &data { process_session_propose_response(ctx, topic, propose).await.ok(); } From 7f37fd3d7fe2684ebcef2b0c7483b4e904e96e57 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 26 Oct 2024 04:11:37 +0100 Subject: [PATCH 082/125] impl eth withdraw for walletconnect policy --- mm2src/coins/eth/eth_withdraw.rs | 56 +++++++------------ mm2src/coins/eth/wallet_connect.rs | 86 +++++++++++++++++++++++++----- 2 files changed, 92 insertions(+), 50 deletions(-) diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index df99ec6602..c063c207b0 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -1,6 +1,6 @@ use super::{checksum_address, u256_to_big_decimal, wei_from_big_decimal, EthCoinType, EthDerivationMethod, EthPrivKeyPolicy, Public, WithdrawError, WithdrawRequest, WithdrawResult, ERC20_CONTRACT, H160, H256}; -use crate::eth::wallet_connect::wc_sign_eth_transaction; +use crate::eth::wallet_connect::{wc_prepare_eth_tx_data, wc_sign_eth_transaction}; use crate::eth::{calc_total_fee, get_eth_gas_details_from_withdraw_fee, tx_builder_with_pay_for_gas_option, tx_type_from_pay_for_gas_option, Action, Address, EthTxFeeDetails, KeyPair, PayForGasOption, SignedEthTx, TransactionWrapper, UnSignedEthTxBuilder}; @@ -22,7 +22,6 @@ use mm2_core::mm_ctx::MmArc; use mm2_err_handle::map_mm_error::MapMmError; use mm2_err_handle::mm_error::MmResult; use mm2_err_handle::prelude::{MapToMmResult, MmError, OrMmError}; -use std::collections::HashMap; use std::ops::Deref; use std::sync::Arc; #[cfg(target_arch = "wasm32")] @@ -143,8 +142,7 @@ where Ok((signed.tx_hash(), BytesJson::from(bytes.to_vec()))) }, EthPrivKeyPolicy::WalletConnect { .. } => { - // let data = unsigned_tx - todo!() + MmError::err(WithdrawError::InternalError("invalid policy".to_owned())) }, #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => MmError::err(WithdrawError::InternalError("invalid policy".to_owned())), @@ -153,7 +151,7 @@ where /// Sends the transaction and returns the transaction hash and the signed transaction. /// This method should only be used when withdrawing using an external wallet like MetaMask. - #[cfg(not(target_arch = "wasm32"))] + #[cfg(target_arch = "wasm32")] async fn send_withdraw_tx( &self, req: &WithdrawRequest, @@ -305,39 +303,25 @@ where EthPrivKeyPolicy::WalletConnect { address: _, pubkey: _ } => { let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); - let chain_id = coin.chain_id.to_string(); - - let gas_price = pay_for_gas_option.get_gas_price(); - let (nonce, _) = coin - .clone() - .get_addr_nonce(my_address) - .compat() - .timeout_secs(30.) - .await? - .map_to_mm(WithdrawError::Transport)?; - let mut mapped_data = HashMap::new(); - mapped_data.insert("nonce", hex::encode(nonce.to_string())); - mapped_data.insert("to", hex::encode(to_addr.as_bytes())); - mapped_data.insert("from", hex::encode(my_address.as_bytes())); - mapped_data.insert("gas", hex::encode(gas.to_string())); - - if let Some(gas_price) = gas_price { - mapped_data.insert("gasPrice", hex::encode(gas_price.to_string())); + let chain_id = coin.chain_id; + + let tx_json = { + let gas_price = pay_for_gas_option.get_gas_price(); + let (nonce, _) = coin + .clone() + .get_addr_nonce(my_address) + .compat() + .timeout_secs(30.) + .await? + .map_to_mm(WithdrawError::Transport)?; + + wc_prepare_eth_tx_data(gas, nonce, &data, my_address, to_addr, eth_value, gas_price) + .mm_err(WithdrawError::InternalError)? }; - mapped_data.insert("value", hex::encode(eth_value.to_string())); - mapped_data.insert("data", hex::encode(data)); - - let signed= wc_sign_eth_transaction( - &wc, - &chain_id.to_string(), - serde_json::to_value(mapped_data).expect("invalid tx_json data"), - ) - .await - .mm_err(|err| WithdrawError::SigningError(err.to_string()))?; - - let tx_hex = BytesJson::from(rlp::encode(&signed).to_vec()) - todo!() + wc_sign_eth_transaction(&wc, chain_id, tx_json) + .await + .mm_err(|err| WithdrawError::SigningError(err.to_string()))? }, }; diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 4ae9d1f9b3..354672eb78 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -1,6 +1,9 @@ +use crate::{BytesJson, H256}; + use chrono::Utc; use derive_more::Display; -use ethereum_types::{Address, Public, H160}; +use ethcore_transaction::SignedTransaction; +use ethereum_types::{Address, Public, H160, U256}; use ethkey::{public_to_address, Message, Signature}; use kdf_walletconnect::{chain::{WcChain, WcRequestMethods}, error::WalletConnectError, @@ -10,24 +13,43 @@ use relay_rpc::rpc::params::session_request::SessionRequestRequest; use relay_rpc::rpc::params::{session_request::Request as SessionRequest, RequestParams}; use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, Secp256k1}; -use std::str::FromStr; +use std::{collections::HashMap, str::FromStr}; use web3::signing::hash_message; #[derive(Display, Debug)] pub enum EthWalletConnectError { InvalidSignature(String), AccoountMisMatch(String), + TxDecodingFailed(String), + InternalError(String), + WalletConnectError(WalletConnectError), +} + +impl From for EthWalletConnectError { + fn from(value: WalletConnectError) -> Self { Self::WalletConnectError(value) } } impl From for WalletConnectError { fn from(value: EthWalletConnectError) -> Self { Self::SessionError(value.to_string()) } } +impl From for EthWalletConnectError { + fn from(value: rlp::DecoderError) -> Self { Self::TxDecodingFailed(value.to_string()) } +} + +impl From for EthWalletConnectError { + fn from(value: ethkey::Error) -> Self { Self::InternalError(value.to_string()) } +} + +impl From for EthWalletConnectError { + fn from(value: hex::FromHexError) -> Self { Self::TxDecodingFailed(value.to_string()) } +} + pub async fn wc_sign_eth_transaction( ctx: &WalletConnectCtx, chain_id: u64, tx_json: serde_json::Value, -) -> MmResult { +) -> MmResult<(H256, BytesJson), EthWalletConnectError> { let chain_id = chain_id.to_string(); let topic = ctx .session @@ -35,21 +57,30 @@ pub async fn wc_sign_eth_transaction( .await .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; - let request = SessionRequestRequest { - chain_id: WcChain::Eip155.to_chain_id(&chain_id), - request: SessionRequest { - method: WcRequestMethods::EthSignTransaction.as_ref().to_string(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: tx_json.clone(), - }, - }; { - let req_params = RequestParams::SessionRequest(request); - ctx.publish_request(&topic, req_params).await?; + let request = SessionRequestRequest { + chain_id: WcChain::Eip155.to_chain_id(&chain_id), + request: SessionRequest { + method: WcRequestMethods::EthSignTransaction.as_ref().to_string(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: tx_json.clone(), + }, + }; + ctx.publish_request(&topic, RequestParams::SessionRequest(request)) + .await?; }; - ctx.on_wc_session_response(Ok).await + let bytes = { + let tx_hex: String = ctx.on_wc_session_response(Ok).await?; + // First 4 bytes from WalletConnect represents Protoc info + hex::decode(&tx_hex[4..])? + }; + let unverified = rlp::decode(&bytes)?; + let signed = SignedTransaction::new(unverified)?; + let bytes = rlp::encode(&signed); + + Ok((signed.tx_hash(), BytesJson::from(bytes.to_vec()))) } pub async fn eth_request_wc_personal_sign( @@ -120,3 +151,30 @@ pub fn recover(signature: &Signature, message: &Message) -> Result, +) -> MmResult { + fn u256_to_hex(value: U256) -> String { format!("0x{:x}", value) } + + let mut mapped_data = HashMap::from([ + ("nonce", u256_to_hex(nonce)), + ("to", format!("0x{}", hex::encode(to_addr.as_bytes()))), + ("from", format!("0x{}", hex::encode(my_address.as_bytes()))), + ("gas", u256_to_hex(gas)), + ("value", u256_to_hex(value)), + ("data", format!("0x{}", hex::encode(data))), + ]); + + if let Some(gas_price) = gas_price { + mapped_data.insert("gasPrice", u256_to_hex(gas_price)); + } + + serde_json::to_value(vec![mapped_data]).map_to_mm(|err| err.to_string()) +} From 6e57330a99ddeab54f089fe4e2f1e25d1c3db96d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 26 Oct 2024 18:23:51 +0100 Subject: [PATCH 083/125] don't support sign_raw_tx rpc in walletconnect mode --- mm2src/coins/eth.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index d708463cd9..531de8f98c 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2687,14 +2687,16 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw }) .map_to_mm(|err| RawTransactionError::TransactionError(err.get_plain_text_format())) }, - #[cfg(target_arch = "wasm32")] - EthPrivKeyPolicy::Metamask(_) => MmError::err(RawTransactionError::InvalidParam( - "sign raw eth tx not implemented for Metamask".into(), + EthPrivKeyPolicy::WalletConnect { .. } => MmError::err(RawTransactionError::InvalidParam( + "sign raw eth tx not implemented for WalletConnect".into(), )), EthPrivKeyPolicy::Trezor => MmError::err(RawTransactionError::InvalidParam( "sign raw eth tx not implemented for Trezor".into(), )), - EthPrivKeyPolicy::WalletConnect { .. } => todo!(), + #[cfg(target_arch = "wasm32")] + EthPrivKeyPolicy::Metamask(_) => MmError::err(RawTransactionError::InvalidParam( + "sign raw eth tx not implemented for Metamask".into(), + )), } } From e45243b9af2f378121b50d6049ae5ffb84fde57b Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 27 Oct 2024 06:10:57 +0100 Subject: [PATCH 084/125] cleanups --- mm2src/coins/eth.rs | 1 + mm2src/coins/eth/eth_withdraw.rs | 34 ++--- mm2src/coins/eth/wallet_connect.rs | 122 +++++++++++------- .../src/eth_with_token_activation.rs | 8 -- mm2src/kdf_walletconnect/src/chain.rs | 1 - .../src/connection_handler.rs | 2 +- .../kdf_walletconnect/src/inbound_message.rs | 3 +- mm2src/kdf_walletconnect/src/lib.rs | 37 +++--- mm2src/kdf_walletconnect/src/session.rs | 14 +- .../src/session/rpc/event.rs | 26 ++-- 10 files changed, 137 insertions(+), 111 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 531de8f98c..febad4a7ec 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2534,6 +2534,7 @@ async fn sign_transaction_with_keypair<'a>( ) -> Result<(SignedEthTx, Vec), TransactionErr> { info!(target: "sign", "get_addr_nonce…"); let (nonce, web3_instances_with_latest_nonce) = try_tx_s!(coin.clone().get_addr_nonce(from_address).compat().await); + if let EthPrivKeyPolicy::WalletConnect { .. } = coin.priv_key_policy() {} let tx_type = tx_type_from_pay_for_gas_option!(pay_for_gas_option); if !coin.is_tx_type_supported(&tx_type) { return Err(TransactionErr::Plain("Eth transaction type not supported".into())); diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index c063c207b0..76c2ce1fae 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -1,6 +1,6 @@ use super::{checksum_address, u256_to_big_decimal, wei_from_big_decimal, EthCoinType, EthDerivationMethod, EthPrivKeyPolicy, Public, WithdrawError, WithdrawRequest, WithdrawResult, ERC20_CONTRACT, H160, H256}; -use crate::eth::wallet_connect::{wc_prepare_eth_tx_data, wc_sign_eth_transaction}; +use crate::eth::wallet_connect::{wc_sign_eth_transaction, WcEthTxParams}; use crate::eth::{calc_total_fee, get_eth_gas_details_from_withdraw_fee, tx_builder_with_pay_for_gas_option, tx_type_from_pay_for_gas_option, Action, Address, EthTxFeeDetails, KeyPair, PayForGasOption, SignedEthTx, TransactionWrapper, UnSignedEthTxBuilder}; @@ -304,22 +304,26 @@ where let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); let chain_id = coin.chain_id; - - let tx_json = { - let gas_price = pay_for_gas_option.get_gas_price(); - let (nonce, _) = coin - .clone() - .get_addr_nonce(my_address) - .compat() - .timeout_secs(30.) - .await? - .map_to_mm(WithdrawError::Transport)?; - - wc_prepare_eth_tx_data(gas, nonce, &data, my_address, to_addr, eth_value, gas_price) - .mm_err(WithdrawError::InternalError)? + let gas_price = pay_for_gas_option.get_gas_price(); + let (nonce, _) = coin + .clone() + .get_addr_nonce(my_address) + .compat() + .timeout_secs(30.) + .await? + .map_to_mm(WithdrawError::Transport)?; + let params = WcEthTxParams { + chain_id, + gas, + nonce, + data: &data, + my_address, + to_addr, + value: eth_value, + gas_price, }; - wc_sign_eth_transaction(&wc, chain_id, tx_json) + wc_sign_eth_transaction(&wc, params) .await .mm_err(|err| WithdrawError::SigningError(err.to_string()))? }, diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 354672eb78..4127fe4d40 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -13,15 +13,17 @@ use relay_rpc::rpc::params::session_request::SessionRequestRequest; use relay_rpc::rpc::params::{session_request::Request as SessionRequest, RequestParams}; use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, Secp256k1}; -use std::{collections::HashMap, str::FromStr}; +use std::str::FromStr; use web3::signing::hash_message; #[derive(Display, Debug)] pub enum EthWalletConnectError { + UnsupportedChainId(String), InvalidSignature(String), AccoountMisMatch(String), TxDecodingFailed(String), InternalError(String), + InvalidTxData(String), WalletConnectError(WalletConnectError), } @@ -45,12 +47,52 @@ impl From for EthWalletConnectError { fn from(value: hex::FromHexError) -> Self { Self::TxDecodingFailed(value.to_string()) } } -pub async fn wc_sign_eth_transaction( +pub(crate) struct WcEthTxParams<'a> { + pub(crate) chain_id: u64, + pub(crate) gas: U256, + pub(crate) nonce: U256, + pub(crate) data: &'a [u8], + pub(crate) my_address: H160, + pub(crate) to_addr: H160, + pub(crate) value: U256, + pub(crate) gas_price: Option, +} + +impl<'a> WcEthTxParams<'a> { + fn prepare_wc_tx_format(&self) -> MmResult { + fn u256_to_hex(value: U256) -> String { format!("0x{:x}", value) } + + let mut tx_json = json!({ + "nonce": u256_to_hex(self.nonce), + "to": format!("0x{}", hex::encode(self.to_addr.as_bytes())), + "from": format!("0x{}", hex::encode(self.my_address.as_bytes())), + "gas": u256_to_hex(self.gas), + "value": u256_to_hex(self.value), + "data": format!("0x{}", hex::encode(self.data)) + }); + + if let Some(gas_price) = self.gas_price { + tx_json + .as_object_mut() + .unwrap() + .insert("gasPrice".to_string(), json!(u256_to_hex(gas_price))); + } + + Ok(tx_json) + } +} + +pub(crate) async fn wc_sign_eth_transaction<'a>( ctx: &WalletConnectCtx, - chain_id: u64, - tx_json: serde_json::Value, + tx_params: WcEthTxParams<'a>, ) -> MmResult<(H256, BytesJson), EthWalletConnectError> { - let chain_id = chain_id.to_string(); + let chain_id = tx_params.chain_id.to_string(); + + if !ctx.is_chain_supported(WcChain::Eip155, &chain_id).await { + return MmError::err(EthWalletConnectError::UnsupportedChainId(chain_id)); + } + + let tx_json = tx_params.prepare_wc_tx_format()?; let topic = ctx .session .get_session_active() @@ -86,7 +128,13 @@ pub async fn wc_sign_eth_transaction( pub async fn eth_request_wc_personal_sign( ctx: &WalletConnectCtx, chain_id: u64, -) -> MmResult<(Public, Address), WalletConnectError> { +) -> MmResult<(Public, Address), EthWalletConnectError> { + let chain_id = chain_id.to_string(); + // validate chain_id + if !ctx.is_chain_supported(WcChain::Eip155, &chain_id).await { + return MmError::err(EthWalletConnectError::UnsupportedChainId(chain_id)); + } + let topic = ctx .session .get_session_active() @@ -94,26 +142,29 @@ pub async fn eth_request_wc_personal_sign( .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; - let account_str = ctx.get_account_for_chain_id(&chain_id.to_string()).await?; + let account_str = ctx.get_account_for_chain_id(&chain_id).await?; let message = "Authenticate with Komodefi"; - let message_hex = format!("0x{}", hex::encode(message)); - let params = json!(&[&message_hex, &account_str]); - - let request = SessionRequestRequest { - request: SessionRequest { - method: WcRequestMethods::PersonalSign.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params, - }, - chain_id: format!("{}:{chain_id}", WcChain::Eip155.as_ref()), - }; + { + let message_hex = format!("0x{}", hex::encode(message)); + let params = json!(&[&message_hex, &account_str]); + let request = SessionRequestRequest { + request: SessionRequest { + method: WcRequestMethods::PersonalSign.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params, + }, + chain_id: WcChain::Eip155.to_chain_id(&chain_id), + }; let session_request = RequestParams::SessionRequest(request); ctx.publish_request(&topic, session_request).await?; } - ctx.on_wc_session_response(|data: String| Ok(extract_pubkey_from_signature(&data, message, &account_str)?)) - .await + let result = ctx + .on_wc_session_response(|data: String| Ok(extract_pubkey_from_signature(&data, message, &account_str)?)) + .await?; + + Ok(result) } fn extract_pubkey_from_signature( @@ -122,7 +173,8 @@ fn extract_pubkey_from_signature( account: &str, ) -> MmResult<(Public, Address), EthWalletConnectError> { let message_hash = hash_message(message.to_string()); - let account = H160::from_str(&account[2..]).expect("valid eth account"); + let account = + H160::from_str(&account[2..]).map_to_mm(|err| EthWalletConnectError::InternalError(err.to_string()))?; let signature = Signature::from_str(&signature_str[2..]) .map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; let pubkey = recover(&signature, &message_hash).map_to_mm(|err| { @@ -131,7 +183,6 @@ fn extract_pubkey_from_signature( })?; let recovered_address = public_to_address(&pubkey); - if account != recovered_address { let error = format!("Recovered address '{recovered_address:?}' should be the same as '{account:?}'"); return MmError::err(EthWalletConnectError::AccoountMisMatch(error)); @@ -151,30 +202,3 @@ pub fn recover(signature: &Signature, message: &Message) -> Result, -) -> MmResult { - fn u256_to_hex(value: U256) -> String { format!("0x{:x}", value) } - - let mut mapped_data = HashMap::from([ - ("nonce", u256_to_hex(nonce)), - ("to", format!("0x{}", hex::encode(to_addr.as_bytes()))), - ("from", format!("0x{}", hex::encode(my_address.as_bytes()))), - ("gas", u256_to_hex(gas)), - ("value", u256_to_hex(value)), - ("data", format!("0x{}", hex::encode(data))), - ]); - - if let Some(gas_price) = gas_price { - mapped_data.insert("gasPrice", u256_to_hex(gas_price)); - } - - serde_json::to_value(vec![mapped_data]).map_to_mm(|err| err.to_string()) -} diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index e689f606f9..8e38ed18f4 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -19,7 +19,6 @@ use coins::my_tx_history_v2::TxHistoryStorage; use coins::nft::nft_structs::NftInfo; use coins::{CoinBalance, CoinBalanceMap, CoinProtocol, CoinWithDerivationMethod, DerivationMethod, MarketCoinOps, MmCoin, MmCoinEnum}; -use kdf_walletconnect::chain::WcChain; use kdf_walletconnect::WalletConnectCtx; use crate::platform_coin_with_tokens::InitPlatformCoinWithTokensTask; @@ -480,13 +479,6 @@ async fn eth_priv_key_build_policy( EthPrivKeyActivationPolicy::WalletConnect => { let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; - - if !wc.is_chain_supported(&WcChain::Eip155.to_chain_id(&chain_id.to_string())) { - return MmError::err(EthActivationV2Error::WalletConnectError(format!( - "Unsupported chain_id: {chain_id}" - ))); - }; - let (pubkey, address) = eth_request_wc_personal_sign(&wc, chain_id) .await .mm_err(|err| EthActivationV2Error::WalletConnectError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index 0a2c9f81d4..6812fe4fb9 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -1,7 +1,6 @@ use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; use std::collections::{BTreeMap, BTreeSet}; -pub(crate) const SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4", "eip155:1"]; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 67cf5a6608..8573b9fb4a 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -87,7 +87,7 @@ pub(crate) async fn initial_connection(this: &WalletConnectCtx) { } pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { - let mut recv = this.connection_live_handler.lock().await; + let mut recv = this.connection_live_rx.lock().await; while let Some(_msg) = recv.next().await { info!("Connection disconnected. Attempting to reconnect..."); diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 73ce5a7904..d8c271f681 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -76,5 +76,6 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: R Response::Error(err) => MmError::err(format!("{err:?}")), }; - ctx.message_tx.lock().await.send(result).await.ok(); + let mut sender = ctx.message_tx.clone(); + sender.send(result).await.ok(); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index bde97fe4bc..38a9a484d5 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -9,7 +9,7 @@ mod storage; use crate::session::rpc::propose::send_proposal_request; -use chain::{DEFAULT_CHAIN_ID, SUPPORTED_CHAINS, SUPPORTED_PROTOCOL}; +use chain::{WcChain, DEFAULT_CHAIN_ID, SUPPORTED_PROTOCOL}; use common::log::info; use common::{executor::SpawnFuture, log::error}; use connection_handler::Handler; @@ -51,11 +51,10 @@ pub struct WalletConnectCtx { relay: Relay, metadata: Metadata, subscriptions: Arc>>, - inbound_message_handler: Arc>>, - connection_live_handler: Arc>>, - - message_tx: Arc>>, - pub message_rx: Arc>>, + inbound_message_rx: Arc>>, + connection_live_rx: Arc>>, + message_tx: UnboundedSender, + message_rx: Arc>>, } impl WalletConnectCtx { @@ -78,18 +77,17 @@ impl WalletConnectCtx { client, pairing, session: SessionManager::new(), - active_chain_id: Arc::new(Mutex::new(DEFAULT_CHAIN_ID.to_string())), + active_chain_id: Arc::new(DEFAULT_CHAIN_ID.to_owned().into()), relay, metadata: generate_metadata(), key_pair: SymKeyPair::new(), storage, subscriptions: Default::default(), - inbound_message_handler: Arc::new(Mutex::new(msg_receiver)), - connection_live_handler: Arc::new(Mutex::new(conn_live_receiver)), - - message_rx: Arc::new(Mutex::new(session_request_receiver)), - message_tx: Arc::new(Mutex::new(message_tx)), + inbound_message_rx: Arc::new(msg_receiver.into()), + connection_live_rx: Arc::new(conn_live_receiver.into()), + message_rx: Arc::new(session_request_receiver.into()), + message_tx, }) } @@ -218,7 +216,7 @@ impl WalletConnectCtx { self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; - info!("Outbound request sent!\n"); + info!("Outbound request sent!"); Ok(()) } @@ -298,7 +296,16 @@ impl WalletConnectCtx { } /// Checks if a given chain ID is supported. - pub fn is_chain_supported(&self, chain_id: &str) -> bool { SUPPORTED_CHAINS.iter().any(|&c| c == chain_id) } + pub async fn is_chain_supported(&self, chain: WcChain, chain_id: &str) -> bool { + if let Some(session) = self.session.get_session_active().await { + if let Some(ns) = session.namespaces.get(chain.as_ref()) { + if let Some(chains) = &ns.chains { + return chains.contains(&chain.to_chain_id(chain_id)); + } + } + } + false + } /// Sets the active chain ID for the current session. pub async fn set_active_chain(&self, chain_id: &str) { @@ -386,7 +393,7 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect // spawn message handler event loop ctx.spawner().spawn(async move { let this = wallet_connect.clone(); - let mut recv = wallet_connect.inbound_message_handler.lock().await; + let mut recv = wallet_connect.inbound_message_rx.lock().await; while let Some(msg) = recv.next().await { if let Err(e) = this.handle_published_message(msg).await { info!("Error processing message: {:?}", e); diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 4bf0cd642f..4fdea9e4d7 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -8,7 +8,6 @@ use chrono::Utc; use common::log::debug; use dashmap::mapref::one::{Ref, RefMut}; use dashmap::DashMap; -use futures::lock::Mutex; use key::SessionKey; use mm2_err_handle::prelude::{MapMmError, MmError, MmResult}; use relay_rpc::domain::Topic; @@ -22,6 +21,7 @@ use serde_json::Value; use std::collections::BTreeMap; use std::fmt::Debug; use std::sync::Arc; +use tokio::sync::RwLock; pub(crate) const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; @@ -178,7 +178,7 @@ impl Session { #[derive(Default, Debug)] struct SessionManagerImpl { /// The currently active session topic. - active_topic: Mutex>, + active_topic: RwLock>, /// A thread-safe map of sessions indexed by topic. sessions: DashMap, } @@ -211,7 +211,7 @@ impl SessionManager { /// If a session with the same topic already exists, it will be overwritten. pub(crate) async fn add_session(&self, session: Session) { // set active session topic. - *self.0.active_topic.lock().await = Some(session.topic.clone()); + *self.0.active_topic.write().await = Some(session.topic.clone()); // insert session self.0.sessions.insert(session.topic.clone(), session); @@ -221,7 +221,7 @@ impl SessionManager { /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { debug!("Deleting session with topic: {topic}"); - let mut active_topic = self.0.active_topic.lock().await; + let mut active_topic = self.0.active_topic.write().await; // Remove the session and get the removed session (if any) let removed_session = self.0.sessions.remove(topic).map(|(_, session)| session); @@ -243,7 +243,7 @@ impl SessionManager { /// Retrieves a cloned session associated with a given topic. pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { - let mut active_topic = self.0.active_topic.lock().await; + let mut active_topic = self.0.active_topic.write().await; if let Some(this) = active_topic.as_mut() { if topic == this { return Ok(()); @@ -261,7 +261,7 @@ impl SessionManager { pub async fn get_active_topic_or_err(&self) -> MmResult { self.0 .active_topic - .lock() + .read() .await .clone() .ok_or(MmError::new(WalletConnectError::SessionError( @@ -279,7 +279,7 @@ impl SessionManager { /// Returns an `Option` containing the active session if it exists; otherwise, returns `None`. pub async fn get_session_active(&self) -> Option> { - let active_topic = self.0.active_topic.lock().await; + let active_topic = self.0.active_topic.read().await; if let Some(ref topic) = *active_topic { self.get_session(topic) } else { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 20092bc173..211b98e514 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -68,20 +68,18 @@ impl SessionEvent { topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectError> { - if ctx.is_chain_supported(chain_id) { - if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { - if let Some(session) = ctx.session.get_session_active().await { - if let Some(namespace) = session.namespaces.get(&key) { - let chains = namespace.chains.clone().unwrap_or_default(); - if chains.contains(&chain) { - // TODO: Notify GUI about chain changed. - ctx.set_active_chain(chain_id.clone()).await; - - let params = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, params, message_id).await?; - - return Ok(()); - } + if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { + if let Some(session) = ctx.session.get_session_active().await { + if let Some(namespace) = session.namespaces.get(&key) { + let chains = namespace.chains.clone().unwrap_or_default(); + if chains.contains(&chain) { + // TODO: Notify GUI about chain changed. + ctx.set_active_chain(chain_id.clone()).await; + + let params = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, params, message_id).await?; + + return Ok(()); } } } From a8d937ecd4fcdabd0a1e3da473a13385495fc4d6 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 28 Oct 2024 16:54:35 +0100 Subject: [PATCH 085/125] improvements to session, wc ops, and more --- Cargo.lock | 13 +- mm2src/coins/eth.rs | 25 ++- mm2src/coins/eth/eth_withdraw.rs | 9 +- mm2src/coins/eth/v2_activation.rs | 5 +- mm2src/coins/eth/wallet_connect.rs | 44 +++-- mm2src/coins/tendermint/tendermint_coin.rs | 21 +-- mm2src/coins/tendermint/wallet_connect.rs | 42 ++--- .../src/eth_with_token_activation.rs | 4 +- .../src/tendermint_with_assets_activation.rs | 2 +- mm2src/crypto/Cargo.toml | 3 +- mm2src/kdf_walletconnect/src/chain.rs | 95 ++++++++--- mm2src/kdf_walletconnect/src/error.rs | 2 + .../kdf_walletconnect/src/inbound_message.rs | 4 +- mm2src/kdf_walletconnect/src/lib.rs | 97 ++++++++--- mm2src/kdf_walletconnect/src/session.rs | 45 ++--- .../src/session/rpc/event.rs | 161 +++++++----------- .../src/session/rpc/propose.rs | 3 +- .../src/session/rpc/settle.rs | 2 +- .../src/session/rpc/update.rs | 7 +- .../src/rpc/wc_commands/get_chain_id.rs | 7 +- .../mm2_main/src/rpc/wc_commands/sessions.rs | 7 +- 21 files changed, 336 insertions(+), 262 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 919ff1fb35..12274afb14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -450,7 +450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" dependencies = [ "bitcoin_hashes 0.13.0", - "rand_core 0.5.1", + "rand_core 0.6.4", "zeroize", ] @@ -1342,6 +1342,7 @@ dependencies = [ "num-traits", "parking_lot", "primitives", + "rand 0.8.5", "rpc", "rpc_task", "rustc-hex", @@ -4744,7 +4745,7 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" dependencies = [ "anyhow", "chrono", @@ -5171,7 +5172,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes 1.4.0", - "heck 0.4.0", + "heck 0.5.0", "itertools", "log", "multimap", @@ -5644,7 +5645,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" dependencies = [ "chrono", "data-encoding", @@ -5672,7 +5673,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" dependencies = [ "anyhow", "bs58 0.4.0", @@ -8035,7 +8036,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#994db68a1001a47523847b070f01a3ae5fb974f6" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" dependencies = [ "base64 0.21.7", "chacha20poly1305", diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index febad4a7ec..27d0c7ba5d 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -1,3 +1,5 @@ +use self::wallet_connect::{EthWalletConnectError, WcEthTxParams}; + /****************************************************************************** * Copyright © 2023 Pampex LTD and TillyHK LTD * * * @@ -26,6 +28,7 @@ use super::*; use crate::coin_balance::{EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, HDWalletBalance, HDWalletBalanceOps}; use crate::eth::eth_rpc::ETH_RPC_REQUEST_TIMEOUT; +use crate::eth::wallet_connect::wc_sign_eth_transaction; use crate::eth::web3_transport::websocket_transport::{WebsocketTransport, WebsocketTransportNode}; use crate::hd_wallet::{HDAccountOps, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, HDPathAccountToAddressId, HDWalletCoinOps, HDXPubExtractor}; @@ -76,8 +79,9 @@ use futures::future::{join, join_all, select_ok, try_join_all, Either, FutureExt use futures01::Future; use http::Uri; use instant::Instant; +use kdf_walletconnect::chain::WcChainId; use kdf_walletconnect::error::WalletConnectError; -use kdf_walletconnect::{WalletConnectCtx, WcRequestOps}; +use kdf_walletconnect::{WalletConnectCtx, WalletConnectOps}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; use mm2_number::bigdecimal_custom::CheckedDivision; @@ -7236,15 +7240,18 @@ impl EthCoin { } #[async_trait::async_trait] -impl WcRequestOps for EthCoin { - type Error = WalletConnectError; - type SignTxData = String; - async fn wc_request_sign_tx( +impl WalletConnectOps for EthCoin { + type Error = MmError; + type SignTxData = (H256, BytesJson); + type Params<'a> = WcEthTxParams<'a>; + + fn wc_chain_id(&self) -> WcChainId { WcChainId::new_eip155(self.chain_id.to_string()) } + + async fn wc_request_sign_tx<'a>( &self, - _ctx: &WalletConnectCtx, - _chain_id: &str, - _tx_json: serde_json::Value, + ctx: &WalletConnectCtx, + params: Self::Params<'a>, ) -> Result { - todo!() + wc_sign_eth_transaction(ctx, &self.wc_chain_id(), params).await } } diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index 76c2ce1fae..a27a4651fb 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -1,6 +1,6 @@ use super::{checksum_address, u256_to_big_decimal, wei_from_big_decimal, EthCoinType, EthDerivationMethod, EthPrivKeyPolicy, Public, WithdrawError, WithdrawRequest, WithdrawResult, ERC20_CONTRACT, H160, H256}; -use crate::eth::wallet_connect::{wc_sign_eth_transaction, WcEthTxParams}; +use crate::eth::wallet_connect::WcEthTxParams; use crate::eth::{calc_total_fee, get_eth_gas_details_from_withdraw_fee, tx_builder_with_pay_for_gas_option, tx_type_from_pay_for_gas_option, Action, Address, EthTxFeeDetails, KeyPair, PayForGasOption, SignedEthTx, TransactionWrapper, UnSignedEthTxBuilder}; @@ -17,7 +17,7 @@ use crypto::trezor::trezor_rpc_task::{TrezorRequestStatuses, TrezorRpcTaskProces use crypto::{CryptoCtx, HwRpcError}; use ethabi::Token; use futures::compat::Future01CompatExt; -use kdf_walletconnect::WalletConnectCtx; +use kdf_walletconnect::{WalletConnectCtx, WalletConnectOps}; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::map_mm_error::MapMmError; use mm2_err_handle::mm_error::MmResult; @@ -303,7 +303,6 @@ where EthPrivKeyPolicy::WalletConnect { address: _, pubkey: _ } => { let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); - let chain_id = coin.chain_id; let gas_price = pay_for_gas_option.get_gas_price(); let (nonce, _) = coin .clone() @@ -313,7 +312,6 @@ where .await? .map_to_mm(WithdrawError::Transport)?; let params = WcEthTxParams { - chain_id, gas, nonce, data: &data, @@ -323,7 +321,8 @@ where gas_price, }; - wc_sign_eth_transaction(&wc, params) + self.coin() + .wc_request_sign_tx(&wc, params) .await .mm_err(|err| WithdrawError::SigningError(err.to_string()))? }, diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 55aa9187e4..be891b1b8b 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -161,7 +161,10 @@ pub enum EthPrivKeyActivationPolicy { Trezor, #[cfg(target_arch = "wasm32")] Metamask, - WalletConnect, + WalletConnect { + #[serde(default)] + account_index: usize, + }, } impl EthPrivKeyActivationPolicy { diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 4127fe4d40..e5e002a552 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -5,7 +5,7 @@ use derive_more::Display; use ethcore_transaction::SignedTransaction; use ethereum_types::{Address, Public, H160, U256}; use ethkey::{public_to_address, Message, Signature}; -use kdf_walletconnect::{chain::{WcChain, WcRequestMethods}, +use kdf_walletconnect::{chain::{WcChainId, WcRequestMethods}, error::WalletConnectError, WalletConnectCtx}; use mm2_err_handle::prelude::*; @@ -18,7 +18,7 @@ use web3::signing::hash_message; #[derive(Display, Debug)] pub enum EthWalletConnectError { - UnsupportedChainId(String), + UnsupportedChainId(WcChainId), InvalidSignature(String), AccoountMisMatch(String), TxDecodingFailed(String), @@ -47,15 +47,14 @@ impl From for EthWalletConnectError { fn from(value: hex::FromHexError) -> Self { Self::TxDecodingFailed(value.to_string()) } } -pub(crate) struct WcEthTxParams<'a> { - pub(crate) chain_id: u64, - pub(crate) gas: U256, - pub(crate) nonce: U256, - pub(crate) data: &'a [u8], - pub(crate) my_address: H160, - pub(crate) to_addr: H160, - pub(crate) value: U256, - pub(crate) gas_price: Option, +pub struct WcEthTxParams<'a> { + pub gas: U256, + pub nonce: U256, + pub data: &'a [u8], + pub my_address: H160, + pub to_addr: H160, + pub value: U256, + pub gas_price: Option, } impl<'a> WcEthTxParams<'a> { @@ -84,15 +83,11 @@ impl<'a> WcEthTxParams<'a> { pub(crate) async fn wc_sign_eth_transaction<'a>( ctx: &WalletConnectCtx, + chain_id: &WcChainId, tx_params: WcEthTxParams<'a>, ) -> MmResult<(H256, BytesJson), EthWalletConnectError> { - let chain_id = tx_params.chain_id.to_string(); + ctx.validate_or_update_active_chain_id(chain_id).await?; - if !ctx.is_chain_supported(WcChain::Eip155, &chain_id).await { - return MmError::err(EthWalletConnectError::UnsupportedChainId(chain_id)); - } - - let tx_json = tx_params.prepare_wc_tx_format()?; let topic = ctx .session .get_session_active() @@ -101,8 +96,9 @@ pub(crate) async fn wc_sign_eth_transaction<'a>( .ok_or(WalletConnectError::NotInitialized)?; { + let tx_json = tx_params.prepare_wc_tx_format()?; let request = SessionRequestRequest { - chain_id: WcChain::Eip155.to_chain_id(&chain_id), + chain_id: chain_id.to_string(), request: SessionRequest { method: WcRequestMethods::EthSignTransaction.as_ref().to_string(), expiry: Some(Utc::now().timestamp() as u64 + 300), @@ -128,12 +124,12 @@ pub(crate) async fn wc_sign_eth_transaction<'a>( pub async fn eth_request_wc_personal_sign( ctx: &WalletConnectCtx, chain_id: u64, + account_index: usize, ) -> MmResult<(Public, Address), EthWalletConnectError> { let chain_id = chain_id.to_string(); - // validate chain_id - if !ctx.is_chain_supported(WcChain::Eip155, &chain_id).await { - return MmError::err(EthWalletConnectError::UnsupportedChainId(chain_id)); - } + let chain_id = WcChainId::new_eip155(chain_id); + + ctx.validate_or_update_active_chain_id(&chain_id).await?; let topic = ctx .session @@ -142,7 +138,7 @@ pub async fn eth_request_wc_personal_sign( .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; - let account_str = ctx.get_account_for_chain_id(&chain_id).await?; + let account_str = ctx.get_account_for_chain_id(&chain_id, account_index).await?; let message = "Authenticate with Komodefi"; { @@ -154,7 +150,7 @@ pub async fn eth_request_wc_personal_sign( expiry: Some(Utc::now().timestamp() as u64 + 300), params, }, - chain_id: WcChain::Eip155.to_chain_id(&chain_id), + chain_id: chain_id.to_string(), }; let session_request = RequestParams::SessionRequest(request); ctx.publish_request(&topic, session_request).await?; diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 60f9e6c123..ea09b77ab9 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -64,8 +64,9 @@ use futures01::Future; use hex::FromHexError; use instant::Duration; use itertools::Itertools; +use kdf_walletconnect::chain::WcChainId; use kdf_walletconnect::error::WalletConnectError; -use kdf_walletconnect::{WalletConnectCtx, WcRequestOps}; +use kdf_walletconnect::{WalletConnectCtx, WalletConnectOps}; use keys::{KeyPair, Public}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_err_handle::prelude::*; @@ -887,7 +888,7 @@ impl TendermintCoin { let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); let wc = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); - let response = try_tx_s!(self.wc_request_sign_tx(&wc, self.chain_id.as_ref(), tx_json).await); + let response = try_tx_s!(self.wc_request_sign_tx(&wc, tx_json).await); let signature = try_tx_s!(general_purpose::STANDARD .decode(response.signature.signature) .map_err(|e| ERRL!("{}", e))); @@ -1296,9 +1297,7 @@ impl TendermintCoin { let SerializedUnsignedTx { tx_json, body_bytes: _ } = self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo)?; - let response = self - .wc_request_sign_tx(&wallet_connect, self.chain_id.as_ref(), tx_json) - .await?; + let response = self.wc_request_sign_tx(&wallet_connect, tx_json).await?; let signature = general_purpose::STANDARD.decode(response.signature.signature)?; let body_bytes = response.signed.body_bytes; let auth_info_bytes = response.signed.auth_info_bytes; @@ -3477,17 +3476,19 @@ fn parse_expected_sequence_number(e: &str) -> MmResult; + type Params<'a> = serde_json::Value; type SignTxData = CosmosTxSignedData; - async fn wc_request_sign_tx( + fn wc_chain_id(&self) -> WcChainId { WcChainId::new_cosmos(self.chain_id.to_string()) } + + async fn wc_request_sign_tx<'a>( &self, ctx: &WalletConnectCtx, - chain_id: &str, - tx_json: serde_json::Value, + params: Self::Params<'a>, ) -> Result { - cosmos_request_wc_signed_tx(ctx, tx_json, chain_id, self.is_ledger_connection()).await + cosmos_request_wc_signed_tx(ctx, params, &self.wc_chain_id(), self.is_ledger_connection()).await } } diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 4c5cdaa21a..589684b7d3 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -1,7 +1,7 @@ use base64::engine::general_purpose; use base64::Engine; use chrono::Utc; -use kdf_walletconnect::chain::WcChain; +use kdf_walletconnect::chain::WcChainId; use kdf_walletconnect::error::WalletConnectError; use kdf_walletconnect::{chain::WcRequestMethods, WalletConnectCtx}; use mm2_err_handle::prelude::*; @@ -45,7 +45,7 @@ pub struct CosmosSignData { pub async fn cosmos_request_wc_signed_tx( ctx: &WalletConnectCtx, sign_doc: Value, - chain_id: &str, + chain_id: &WcChainId, is_ledger_conn: bool, ) -> MmResult { let topic = ctx @@ -55,20 +55,20 @@ pub async fn cosmos_request_wc_signed_tx( .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; - let method = if is_ledger_conn { - WcRequestMethods::CosmosSignAmino - } else { - WcRequestMethods::CosmosSignDirect - }; - let request = SessionRequestRequest { - request: SessionRequest { - method: method.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: sign_doc, - }, - chain_id: (WcChain::Cosmos).to_chain_id(chain_id), - }; { + let method = if is_ledger_conn { + WcRequestMethods::CosmosSignAmino + } else { + WcRequestMethods::CosmosSignDirect + }; + let request = SessionRequestRequest { + request: SessionRequest { + method: method.as_ref().to_owned(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: sign_doc, + }, + chain_id: chain_id.to_string(), + }; let session_request = RequestParams::SessionRequest(request); ctx.publish_request(&topic, session_request).await?; } @@ -109,10 +109,12 @@ pub struct CosmosAccount { pub async fn cosmos_get_accounts_impl( ctx: &WalletConnectCtx, chain_id: &str, - account_index: Option, + account_index: usize, ) -> MmResult { - let account = ctx.get_account_for_chain_id(chain_id).await?; + let chain_id = WcChainId::new_cosmos(chain_id.to_string()); + ctx.validate_or_update_active_chain_id(&chain_id).await?; + let account = ctx.get_account_for_chain_id(&chain_id, account_index).await?; let session = ctx .session .get_session_active() @@ -144,19 +146,18 @@ pub async fn cosmos_get_accounts_impl( } } - let topic = session.topic.clone(); let request = SessionRequestRequest { request: SessionRequest { method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), expiry: Some(Utc::now().timestamp() as u64 + 300), params: serde_json::to_value(&account).unwrap(), }, - chain_id: WcChain::Cosmos.to_chain_id(chain_id), + chain_id: chain_id.to_string(), }; { let session_request = RequestParams::SessionRequest(request); - ctx.publish_request(&topic, session_request).await?; + ctx.publish_request(&session.topic, session_request).await?; }; ctx.on_wc_session_response::, _, _>(|accounts| { @@ -164,7 +165,6 @@ pub async fn cosmos_get_accounts_impl( return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); }; - let account_index = account_index.unwrap_or(0); if accounts.len() < account_index + 1 { return MmError::err(WalletConnectError::NoAccountFoundForIndex(account_index)); }; diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index 8e38ed18f4..d4dbcb59da 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -476,10 +476,10 @@ async fn eth_priv_key_build_policy( Ok(EthPrivKeyBuildPolicy::Metamask(metamask_ctx)) }, EthPrivKeyActivationPolicy::Trezor => Ok(EthPrivKeyBuildPolicy::Trezor), - EthPrivKeyActivationPolicy::WalletConnect => { + EthPrivKeyActivationPolicy::WalletConnect { account_index } => { let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; - let (pubkey, address) = eth_request_wc_personal_sign(&wc, chain_id) + let (pubkey, address) = eth_request_wc_personal_sign(&wc, chain_id, *account_index) .await .mm_err(|err| EthActivationV2Error::WalletConnectError(err.to_string()))?; diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index c9074ee3a5..d948e76b72 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -245,7 +245,7 @@ async fn activate_with_walletconnect( wallet_type: &mut TendermintWalletConnectionType, ) -> MmResult { let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); - let account = cosmos_get_accounts_impl(&wc, chain_id, Some(param.account_index)) + let account = cosmos_get_accounts_impl(&wc, chain_id, param.account_index) .await .mm_err(|err| TendermintInitError { ticker: ticker.to_string(), diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index 0a5abe3919..af3c3b2012 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -13,7 +13,7 @@ arrayref = "0.3" async-trait = "0.1" base64 = "0.21.2" bip32 = { version = "0.2.2", default-features = false, features = ["alloc", "secp256k1-ffi"] } -bip39 = { version = "2.1.0", features = ["rand_core", "zeroize"], default-features = false } +bip39 = { version = "2.0.0", features = ["rand_core", "zeroize"], default-features = false } bitcrypto = { path = "../mm2_bitcoin/crypto" } bs58 = "0.4.0" cbc = "0.1.2" @@ -34,6 +34,7 @@ mm2_err_handle = { path = "../mm2_err_handle" } num-traits = "0.2" parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } +rand = "0.8.5" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } rustc-hex = "2" diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index 6812fe4fb9..f626a66a50 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -1,5 +1,9 @@ +use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; -use std::collections::{BTreeMap, BTreeSet}; +use std::{collections::{BTreeMap, BTreeSet}, + str::FromStr}; + +use crate::error::WalletConnectError; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; @@ -7,16 +11,70 @@ pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "co pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "personal_sign"]; -pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1"]; +pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:137"]; pub(crate) const ETH_SUPPORTED_EVENTS: &[&str] = &["accountsChanged", "chainChanged"]; -pub(crate) const DEFAULT_CHAIN_ID: &str = "1"; +#[derive(Debug)] +pub struct WcChainId { + pub chain: WcChain, + pub id: String, +} + +impl std::fmt::Display for WcChainId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}:{}", self.chain.as_ref(), self.id) + } +} + +impl WcChainId { + pub fn new_eip155(id: String) -> Self { + Self { + chain: WcChain::Eip155, + id, + } + } + + pub fn new_cosmos(id: String) -> Self { + Self { + chain: WcChain::Cosmos, + id, + } + } + + pub fn try_from_str(chain_id: &str) -> MmResult { + let sp = chain_id.split(':').collect::>(); + if sp.len() != 2 { + return MmError::err(WalletConnectError::InvalidChainId(chain_id.to_string())); + }; + + Ok(Self { + chain: WcChain::from_str(sp[0])?, + id: sp[1].to_owned(), + }) + } + + pub(crate) fn chain_id_from_id(&self, id: &str) -> String { format!("{}:{}", self.chain.as_ref(), id) } +} +#[derive(Debug)] pub enum WcChain { Eip155, Cosmos, } +impl FromStr for WcChain { + type Err = MmError; + fn from_str(s: &str) -> Result { + match s { + "eip155" => Ok(WcChain::Eip155), + "cosmos" => Ok(WcChain::Cosmos), + _ => MmError::err(WalletConnectError::InvalidChainId(format!( + "chain_id not supported: {s}" + ))), + } + } +} + impl AsRef for WcChain { fn as_ref(&self) -> &str { match self { @@ -26,10 +84,6 @@ impl AsRef for WcChain { } } -impl WcChain { - pub fn to_chain_id(&self, chain_id: &str) -> String { format!("{}:{chain_id}", self.as_ref()) } -} - #[derive(Debug, Clone)] pub enum WcRequestMethods { CosmosSignDirect, @@ -52,18 +106,21 @@ impl AsRef for WcRequestMethods { } pub(crate) fn build_default_required_namespaces() -> ProposeNamespaces { - let required = BTreeMap::from([ - (WcChain::Eip155.as_ref().to_string(), ProposeNamespace { - events: ETH_SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), - chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - }), - (WcChain::Cosmos.as_ref().to_string(), ProposeNamespace { - methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - events: BTreeSet::default(), - }), - ]); + let required = BTreeMap::from([(WcChain::Eip155.as_ref().to_string(), ProposeNamespace { + events: ETH_SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), + chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + })]); + + ProposeNamespaces(required) +} + +pub(crate) fn build_optional_namespaces() -> ProposeNamespaces { + let required = BTreeMap::from([(WcChain::Cosmos.as_ref().to_string(), ProposeNamespace { + methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), + chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), + events: BTreeSet::default(), + })]); ProposeNamespaces(required) } diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 14cccf522d..cc0a75ac85 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -86,6 +86,8 @@ pub enum WalletConnectError { ChainIdMismatch, #[error("No feedback from wallet")] NoWalletFeedback, + #[error("Invalid ChainId Error: {0}")] + InvalidChainId(String), } impl From> for WalletConnectError { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index d8c271f681..0e0f2ca0c7 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -1,7 +1,7 @@ use crate::{error::WalletConnectError, pairing::{reply_pairing_delete_response, reply_pairing_extend_response, reply_pairing_ping_response}, session::rpc::{delete::reply_session_delete_request, - event::reply_session_event_request, + event::handle_session_event, extend::reply_session_extend_request, ping::reply_session_ping_request, propose::{process_session_propose_response, reply_session_proposal_request}, @@ -36,7 +36,7 @@ pub(crate) async fn process_inbound_request( Params::SessionPing(()) => reply_session_ping_request(ctx, topic, &message_id).await?, Params::SessionSettle(param) => reply_session_settle_request(ctx, topic, &message_id, param).await?, Params::SessionUpdate(param) => reply_session_update_request(ctx, topic, &message_id, param).await?, - Params::SessionEvent(param) => reply_session_event_request(ctx, topic, &message_id, param).await?, + Params::SessionEvent(param) => handle_session_event(ctx, topic, &message_id, param).await?, Params::SessionRequest(_param) => { // TODO: Implement when integrating KDF as a Dapp. return MmError::err(WalletConnectError::NotImplemented); diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 38a9a484d5..ce5e3fac6e 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -9,7 +9,7 @@ mod storage; use crate::session::rpc::propose::send_proposal_request; -use chain::{WcChain, DEFAULT_CHAIN_ID, SUPPORTED_PROTOCOL}; +use chain::{WcChainId, SUPPORTED_PROTOCOL}; use common::log::info; use common::{executor::SpawnFuture, log::error}; use connection_handler::Handler; @@ -27,12 +27,13 @@ use relay_client::{ConnectionOptions, MessageIdGenerator}; use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::params::session::Namespace; +use relay_rpc::rpc::params::session_event::{Event, SessionEventRequest}; use relay_rpc::rpc::params::{IrnMetadata, Metadata, Relay, RelayProtocolMetadata, RequestParams, ResponseParamsError, ResponseParamsSuccess}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; use serde::de::DeserializeOwned; -use serde_json::Value; use session::{key::SymKeyPair, SessionManager}; +use std::collections::BTreeSet; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; @@ -43,7 +44,6 @@ pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, pub session: SessionManager, - pub active_chain_id: Arc>, pub(crate) key_pair: SymKeyPair, pub(crate) storage: SessionStorageDb, @@ -77,7 +77,6 @@ impl WalletConnectCtx { client, pairing, session: SessionManager::new(), - active_chain_id: Arc::new(DEFAULT_CHAIN_ID.to_owned().into()), relay, metadata: generate_metadata(), key_pair: SymKeyPair::new(), @@ -296,28 +295,61 @@ impl WalletConnectCtx { } /// Checks if a given chain ID is supported. - pub async fn is_chain_supported(&self, chain: WcChain, chain_id: &str) -> bool { + pub async fn is_chain_supported(&self, chain_id: &WcChainId) -> bool { if let Some(session) = self.session.get_session_active().await { - if let Some(ns) = session.namespaces.get(chain.as_ref()) { + if let Some(ns) = session.namespaces.get(chain_id.chain.as_ref()) { if let Some(chains) = &ns.chains { - return chains.contains(&chain.to_chain_id(chain_id)); + return chains.contains(&chain_id.to_string()); } } + + // https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces + // #13-chains-might-be-omitted-if-the-caip-2-is-defined-in-the-index + if session.namespaces.contains_key(&chain_id.to_string()) { + return true; + } } + false } - /// Sets the active chain ID for the current session. - pub async fn set_active_chain(&self, chain_id: &str) { - let mut active_chain = self.active_chain_id.lock().await; - *active_chain = chain_id.to_owned(); - } + pub async fn validate_or_update_active_chain_id(&self, chain_id: &WcChainId) -> MmResult<(), WalletConnectError> { + if !self.is_chain_supported(chain_id).await { + return MmError::err(WalletConnectError::InvalidChainId(chain_id.to_string())); + }; + + { + if let Some(active_chain_id) = self.session.get_active_chain_id().await { + if chain_id.to_string() == active_chain_id { + return Ok(()); + } + }; + + let event = SessionEventRequest { + event: Event { + name: "chainChanged".to_string(), + data: serde_json::to_value(&chain_id.id)?, + }, + chain_id: chain_id.to_string(), + }; + let param = RequestParams::SessionEvent(event); + + let active_topic = self.session.get_active_topic_or_err().await?; + self.publish_request(&active_topic, param).await?; + } + + self.session.set_active_chain_id(chain_id.id.clone()).await; - /// Retrieves the current active chain ID. - pub async fn get_active_chain_id(&self) -> String { self.active_chain_id.lock().await.clone() } + Ok(()) + } + /// TODO: accept WcChainId /// Retrieves the available account for a given chain ID. - pub async fn get_account_for_chain_id(&self, chain_id: &str) -> MmResult { + pub async fn get_account_for_chain_id( + &self, + chain_id: &WcChainId, + account_index: usize, + ) -> MmResult { let namespaces = &self .session .get_session_active() @@ -326,10 +358,18 @@ impl WalletConnectCtx { "No active WalletConnect session found".to_string(), )))? .namespaces; - namespaces - .iter() - .find_map(|(_key, namespace)| find_account_in_namespace(namespace, chain_id)) - .ok_or(MmError::new(WalletConnectError::NoAccountFound(chain_id.to_string()))) + + if let Some(Namespace { + accounts: Some(accounts), + .. + }) = namespaces.get(chain_id.chain.as_ref()) + { + if let Some(account) = find_accounts_in_namespace(accounts, &chain_id.id).nth(account_index) { + return Ok(account); + } + }; + + MmError::err(WalletConnectError::NoAccountFound(chain_id.to_string())) } /// Waits for and handles a WalletConnect session response with arbitrary data. @@ -357,15 +397,17 @@ impl WalletConnectCtx { } #[async_trait::async_trait] -pub trait WcRequestOps { +pub trait WalletConnectOps { type Error; + type Params<'a>; type SignTxData; - async fn wc_request_sign_tx( + fn wc_chain_id(&self) -> WcChainId; + + async fn wc_request_sign_tx<'a>( &self, ctx: &WalletConnectCtx, - chain_id: &str, - tx_json: Value, + params: Self::Params<'a>, ) -> Result; } @@ -405,10 +447,11 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect Ok(()) } -fn find_account_in_namespace(namespace: &Namespace, chain_id: &str) -> Option { - let accounts = namespace.accounts.as_ref()?; - - accounts.iter().find_map(|account_name| { +fn find_accounts_in_namespace<'a>( + accounts: &'a BTreeSet, + chain_id: &'a str, +) -> impl Iterator + 'a { + accounts.iter().filter_map(move |account_name| { let parts: Vec<&str> = account_name.split(':').collect(); if parts.len() >= 3 && parts[1] == chain_id { Some(parts[2].to_string()) diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 4fdea9e4d7..82dcda023d 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -21,7 +21,7 @@ use serde_json::Value; use std::collections::BTreeMap; use std::fmt::Debug; use std::sync::Arc; -use tokio::sync::RwLock; +use tokio::sync::Mutex; pub(crate) const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; @@ -178,7 +178,9 @@ impl Session { #[derive(Default, Debug)] struct SessionManagerImpl { /// The currently active session topic. - active_topic: RwLock>, + active_topic: Mutex>, + /// Session active chain_id + active_chain_id: Mutex>, /// A thread-safe map of sessions indexed by topic. sessions: DashMap, } @@ -207,11 +209,28 @@ impl From for SessionRpcInfo { impl SessionManager { pub fn new() -> Self { Self(Default::default()) } + pub async fn get_active_topic_or_err(&self) -> MmResult { + self.0 + .active_topic + .lock() + .await + .clone() + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active session".to_owned(), + ))) + } + + /// Get the active chain ID for the current session. + pub async fn get_active_chain_id(&self) -> Option { self.0.active_chain_id.lock().await.clone() } + + /// Sets the active chain ID for the current session. + pub async fn set_active_chain_id(&self, chain_id: String) { *self.0.active_chain_id.lock().await = Some(chain_id); } + /// Inserts the provided `Session` into the session store, associated with the specified topic. /// If a session with the same topic already exists, it will be overwritten. pub(crate) async fn add_session(&self, session: Session) { // set active session topic. - *self.0.active_topic.write().await = Some(session.topic.clone()); + *self.0.active_topic.lock().await = Some(session.topic.clone()); // insert session self.0.sessions.insert(session.topic.clone(), session); @@ -221,7 +240,7 @@ impl SessionManager { /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { debug!("Deleting session with topic: {topic}"); - let mut active_topic = self.0.active_topic.write().await; + let mut active_topic = self.0.active_topic.lock().await; // Remove the session and get the removed session (if any) let removed_session = self.0.sessions.remove(topic).map(|(_, session)| session); @@ -243,7 +262,7 @@ impl SessionManager { /// Retrieves a cloned session associated with a given topic. pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { - let mut active_topic = self.0.active_topic.write().await; + let mut active_topic = self.0.active_topic.lock().await; if let Some(this) = active_topic.as_mut() { if topic == this { return Ok(()); @@ -258,17 +277,6 @@ impl SessionManager { MmError::err(WalletConnectError::SessionError("Session not found".to_owned())) } - pub async fn get_active_topic_or_err(&self) -> MmResult { - self.0 - .active_topic - .read() - .await - .clone() - .ok_or(MmError::new(WalletConnectError::SessionError( - "No active session".to_owned(), - ))) - } - /// Retrieves a cloned session associated with a given topic. pub fn get_session(&self, topic: &Topic) -> Option> { self.0.sessions.get(topic) } @@ -279,7 +287,7 @@ impl SessionManager { /// Returns an `Option` containing the active session if it exists; otherwise, returns `None`. pub async fn get_session_active(&self) -> Option> { - let active_topic = self.0.active_topic.read().await; + let active_topic = self.0.active_topic.lock().await; if let Some(ref topic) = *active_topic { self.get_session(topic) } else { @@ -288,7 +296,7 @@ impl SessionManager { } /// Retrieves all sessions(active and inactive) - pub fn get_sessions(&self) -> Vec { + pub fn get_sessions(&self) -> impl Iterator { self.0 .sessions .clone() @@ -302,7 +310,6 @@ impl SessionManager { subscription_id: session.subscription_id, properties: session.session_properties, }) - .collect() } /// Updates the expiry time of the session associated with the given topic to the specified timestamp. diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 211b98e514..069459cab7 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -1,124 +1,79 @@ -use crate::{error::{WalletConnectError, INVALID_EVENT, UNSUPPORTED_CHAINS}, +use crate::{chain::WcChainId, + error::{WalletConnectError, INVALID_EVENT, UNSUPPORTED_CHAINS}, WalletConnectCtx}; -use mm2_err_handle::prelude::MmResult; +use common::log::info; +use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, - rpc::{params::{session_event::SessionEventRequest, ResponseParamsError, ResponseParamsSuccess}, + rpc::{params::{session::Namespace, session_event::SessionEventRequest, ResponseParamsError, + ResponseParamsSuccess}, ErrorData}}; -pub enum SessionEvent { - ChainChanged(String), - AccountsChanged(String, Vec), - Unknown(String), -} - -pub(crate) async fn reply_session_event_request( +pub async fn handle_session_event( ctx: &WalletConnectCtx, topic: &Topic, message_id: &MessageId, event: SessionEventRequest, ) -> MmResult<(), WalletConnectError> { - SessionEvent::from_event(event)? - .handle_session_event(ctx, topic, message_id) - .await -} - -impl SessionEvent { - pub fn from_event(event: SessionEventRequest) -> MmResult { - match event.event.name.as_str() { - "chainChanged" => Ok(SessionEvent::ChainChanged(event.chain_id)), - "accountsChanged" => { - let data = serde_json::from_value::>(event.event.data)?; - Ok(SessionEvent::AccountsChanged(event.chain_id, data)) - }, - _ => Ok(SessionEvent::Unknown(event.event.name)), - } - } + let chain_id = WcChainId::try_from_str(&event.chain_id)?; + let event_name = event.event.name.as_str(); + + match event_name { + "chainChanged" => { + // check if chain_id is supported. + let chain_id_new = serde_json::from_value::(event.event.data)?; + if !ctx.is_chain_supported(&chain_id).await { + return MmError::err(WalletConnectError::InternalError(format!( + "chain_id not supported: {}", + event.chain_id + ))); + }; - pub async fn handle_session_event( - &self, - ctx: &WalletConnectCtx, - topic: &Topic, - message_id: &MessageId, - ) -> MmResult<(), WalletConnectError> { - match &self { - SessionEvent::ChainChanged(chain_id) => { - Self::handle_chain_changed_event(ctx, chain_id, topic, message_id).await - }, - SessionEvent::AccountsChanged(chain_id, data) => { - Self::handle_accounts_changed_event(ctx, chain_id, data, topic, message_id).await - }, - SessionEvent::Unknown(name) => { - let error_data = ErrorData { - code: INVALID_EVENT, - message: format!("Received an invalid/unsupported session event: {name}"), - data: None, - }; - ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) - .await?; - - Ok(()) - }, - } - } - - async fn handle_chain_changed_event( - ctx: &WalletConnectCtx, - chain_id: &str, - topic: &Topic, - message_id: &MessageId, - ) -> MmResult<(), WalletConnectError> { - if let Some((key, chain)) = parse_chain_and_chain_id(chain_id) { if let Some(session) = ctx.session.get_session_active().await { - if let Some(namespace) = session.namespaces.get(&key) { - let chains = namespace.chains.clone().unwrap_or_default(); - if chains.contains(&chain) { - // TODO: Notify GUI about chain changed. - ctx.set_active_chain(chain_id.clone()).await; + if let Some(Namespace { + chains: Some(chains), .. + }) = session.namespaces.get(chain_id.chain.as_ref()) + { + if chains.contains(&chain_id.to_string()) { + let chain_id = chain_id.chain_id_from_id(chain_id_new.to_string().as_str()); + ctx.session.set_active_chain_id(chain_id).await; let params = ResponseParamsSuccess::SessionEvent(true); ctx.publish_response_ok(topic, params, message_id).await?; return Ok(()); - } + }; } - } - }; - - let error_data = ErrorData { - code: UNSUPPORTED_CHAINS, - message: "Chain_Id was changed to an unsupported chain".to_string(), - data: None, - }; - - ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) - .await?; - - Ok(()) - } - - async fn handle_accounts_changed_event( - ctx: &WalletConnectCtx, - _chain_id: &str, - _data: &[String], - topic: &Topic, - message_id: &MessageId, - ) -> MmResult<(), WalletConnectError> { - // TODO: Handle account change logic. - //TODO: Notify about account changed. - - let param = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, param, message_id).await?; - - Ok(()) - } -} - -fn parse_chain_and_chain_id(chain: &str) -> Option<(String, String)> { - let sp = chain.split(':').collect::>(); - if sp.len() != 2 { - return None; + }; + + println!("Chain ID not supported"); + let error_data = ErrorData { + code: UNSUPPORTED_CHAINS, + message: "Chain_Id was changed to an unsupported chain".to_string(), + data: None, + }; + + ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) + .await?; + }, + "accountsChanged" => { + // TODO: Handle account change logic. + + info!("accountsChanged session event received: {event:?}"); + // let data = serde_json::from_value::>(event.event.data)?; + let param = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, param, message_id).await?; + }, + _ => { + let error_data = ErrorData { + code: INVALID_EVENT, + message: format!("Received an invalid/unsupported session event: {}", event.event.name), + data: None, + }; + ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) + .await?; + }, }; - Some((sp[0].to_owned(), sp[1].to_owned())) + Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 1a4bc3a622..271f5ca70c 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,5 +1,5 @@ use super::settle::send_session_settle_request; -use crate::chain::build_default_required_namespaces; +use crate::chain::{build_default_required_namespaces, build_optional_namespaces}; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, metadata::generate_metadata, @@ -23,6 +23,7 @@ pub(crate) async fn send_proposal_request(ctx: &WalletConnectCtx, topic: Topic) relays: vec![ctx.relay.clone()], proposer, required_namespaces: build_default_required_namespaces(), + optional_namespaces: Some(build_optional_namespaces()), }); ctx.publish_request(&topic, session_proposal).await?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 9507222d86..98ca7cd39b 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -45,7 +45,7 @@ pub(crate) async fn reply_session_settle_request( if let Some(mut session) = session { session.namespaces = settle.namespaces.0.clone(); session.controller = settle.controller.clone(); - session.relay = settle.relay.clone(); + session.relay = settle.relay; session.expiry = settle.expiry; if let Some(value) = settle.session_properties { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index bc77a63f43..214a9419b8 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -16,6 +16,11 @@ pub(crate) async fn reply_session_update_request( ) -> MmResult<(), WalletConnectError> { { if let Some(mut session) = ctx.session.get_session_mut(topic).await { + update + .namespaces + .caip2_validate() + .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))?; + //TODO: session.namespaces.supported(update.namespaces.0) session.namespaces = update.namespaces.0; // Update storage session. ctx.storage @@ -23,7 +28,7 @@ pub(crate) async fn reply_session_update_request( .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; - info!("Updated extended, info: {:?}", session); + info!("Updated extended, info: {:?}", session.topic); }; } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs index 0ec7dff5c0..67e1400df0 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs @@ -7,14 +7,15 @@ use super::{EmptyRpcRequst, WalletConnectRpcError}; #[derive(Debug, PartialEq, Serialize)] pub struct GetChainIdResponse { - pub chain_id: String, + pub chain_id: Option, } /// `delete connection` RPC command implementation. pub async fn get_chain_id(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let chain_id = ctx.get_active_chain_id().await; - Ok(GetChainIdResponse { chain_id }) + Ok(GetChainIdResponse { + chain_id: ctx.session.get_active_chain_id().await, + }) } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 98d0281f66..38b19d4a8a 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -24,12 +24,7 @@ pub async fn get_all_sessions( ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let sessions = ctx - .session - .get_sessions() - .into_iter() - .map(SessionRpcInfo::from) - .collect::>(); + let sessions = ctx.session.get_sessions().map(SessionRpcInfo::from).collect::>(); Ok(GetSessionsResponse { sessions }) } From 1569edee4de65ed403427083aaa4a85fa21674d6 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 28 Oct 2024 18:16:17 +0100 Subject: [PATCH 086/125] create connection with custom namespaces --- .../src/platform_coin_with_tokens.rs | 10 ++--- mm2src/kdf_walletconnect/src/lib.rs | 38 ++++++++++--------- .../src/session/rpc/propose.rs | 11 ++++-- .../src/rpc/wc_commands/new_connection.rs | 13 +++++-- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/mm2src/coins_activation/src/platform_coin_with_tokens.rs b/mm2src/coins_activation/src/platform_coin_with_tokens.rs index 051dd22fc3..037997ec99 100644 --- a/mm2src/coins_activation/src/platform_coin_with_tokens.rs +++ b/mm2src/coins_activation/src/platform_coin_with_tokens.rs @@ -81,7 +81,7 @@ pub trait TokenAsMmCoinInitializer: Send + Sync { async fn enable_tokens_as_mm_coins( &self, - ctx: MmArc, + ctx: &MmArc, request: &Self::ActivationRequest, ) -> Result, MmError>; } @@ -131,14 +131,14 @@ where async fn enable_tokens_as_mm_coins( &self, - ctx: MmArc, + ctx: &MmArc, request: &Self::ActivationRequest, ) -> Result, MmError> { let tokens_requests = T::tokens_requests_from_platform_request(request); let token_params = tokens_requests .into_iter() .map(|req| -> Result<_, MmError> { - let (_, protocol): (_, T::TokenProtocol) = coin_conf_with_protocol(&ctx, &req.ticker)?; + let (_, protocol): (_, T::TokenProtocol) = coin_conf_with_protocol(ctx, &req.ticker)?; Ok(TokenActivationParams { ticker: req.ticker, activation_request: req.request, @@ -392,7 +392,7 @@ where { let mut mm_tokens = Vec::new(); for initializer in platform_coin.token_initializers() { - let tokens = initializer.enable_tokens_as_mm_coins(ctx.clone(), &req.request).await?; + let tokens = initializer.enable_tokens_as_mm_coins(&ctx, &req.request).await?; mm_tokens.extend(tokens); } @@ -462,7 +462,7 @@ where let mut mm_tokens = Vec::new(); for initializer in platform_coin.token_initializers() { - let tokens = initializer.enable_tokens_as_mm_coins(ctx.clone(), &req.request).await?; + let tokens = initializer.enable_tokens_as_mm_coins(&ctx, &req.request).await?; mm_tokens.extend(tokens); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index ce5e3fac6e..eb52f102d0 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -40,6 +40,21 @@ use storage::WalletConnectStorageOps; use tokio::time::timeout; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; +#[async_trait::async_trait] +pub trait WalletConnectOps { + type Error; + type Params<'a>; + type SignTxData; + + fn wc_chain_id(&self) -> WcChainId; + + async fn wc_request_sign_tx<'a>( + &self, + ctx: &WalletConnectCtx, + params: Self::Params<'a>, + ) -> Result; +} + pub struct WalletConnectCtx { pub client: Client, pub pairing: PairingClient, @@ -114,7 +129,11 @@ impl WalletConnectCtx { } /// Create a WalletConnect pairing connection url. - pub async fn new_connection(&self) -> MmResult { + pub async fn new_connection(&self, namespaces: Option) -> MmResult { + let namespaces = match namespaces { + Some(value) => Some(serde_json::from_value(value)?), + None => None, + }; let (topic, url) = self.pairing.create(self.metadata.clone(), None).await?; info!("Subscribing to topic: {topic:?}"); @@ -123,7 +142,7 @@ impl WalletConnectCtx { info!("Subscribed to topic: {topic:?}"); - send_proposal_request(self, topic.clone()).await?; + send_proposal_request(self, &topic, namespaces).await?; { let mut subs = self.subscriptions.lock().await; @@ -396,21 +415,6 @@ impl WalletConnectCtx { } } -#[async_trait::async_trait] -pub trait WalletConnectOps { - type Error; - type Params<'a>; - type SignTxData; - - fn wc_chain_id(&self) -> WcChainId; - - async fn wc_request_sign_tx<'a>( - &self, - ctx: &WalletConnectCtx, - params: Self::Params<'a>, - ) -> Result; -} - /// This function spwans related WalletConnect related tasks and needed initialization before /// WalletConnect can be usable in KDF. pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectError> { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 271f5ca70c..fcccb6685d 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -9,12 +9,17 @@ use crate::{error::WalletConnectError, use chrono::Utc; use mm2_err_handle::map_to_mm::MapToMmResult; use mm2_err_handle::prelude::*; +use relay_rpc::rpc::params::session::ProposeNamespaces; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, RequestParams, ResponseParamsSuccess}}; /// Creates a new session proposal form topic and metadata. -pub(crate) async fn send_proposal_request(ctx: &WalletConnectCtx, topic: Topic) -> MmResult<(), WalletConnectError> { +pub(crate) async fn send_proposal_request( + ctx: &WalletConnectCtx, + topic: &Topic, + namespaces: Option, +) -> MmResult<(), WalletConnectError> { let proposer = Proposer { metadata: ctx.metadata.clone(), public_key: hex::encode(ctx.key_pair.public_key.as_bytes()), @@ -22,10 +27,10 @@ pub(crate) async fn send_proposal_request(ctx: &WalletConnectCtx, topic: Topic) let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], proposer, - required_namespaces: build_default_required_namespaces(), + required_namespaces: namespaces.unwrap_or_else(build_default_required_namespaces), optional_namespaces: Some(build_optional_namespaces()), }); - ctx.publish_request(&topic, session_proposal).await?; + ctx.publish_request(topic, session_proposal).await?; Ok(()) } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs index a44349aec9..2ba1d60469 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs @@ -1,24 +1,29 @@ use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; -use serde::Serialize; +use serde::{Deserialize, Serialize}; -use super::{EmptyRpcRequst, WalletConnectRpcError}; +use super::WalletConnectRpcError; #[derive(Debug, PartialEq, Serialize)] pub struct CreateConnectionResponse { pub url: String, } +#[derive(Deserialize)] +pub struct NewConnectionRequest { + namespaces: Option, +} + /// `new_connection` RPC command implementation. pub async fn new_connection( ctx: MmArc, - _req: EmptyRpcRequst, + req: NewConnectionRequest, ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; let url = ctx - .new_connection() + .new_connection(req.namespaces) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; From 4fc5a430ad6ea759aa26ebc4afd6f6a6c8305a7b Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 31 Oct 2024 23:48:37 +0100 Subject: [PATCH 087/125] impl eth sign and send tx for WalletConnect --- Cargo.lock | 16 +- mm2src/coins/Cargo.toml | 4 +- mm2src/coins/eth.rs | 112 ++++++--- mm2src/coins/eth/eth_withdraw.rs | 13 +- mm2src/coins/eth/v2_activation.rs | 27 +- mm2src/coins/eth/wallet_connect.rs | 234 +++++++++++++----- mm2src/coins/lp_coins.rs | 9 +- mm2src/coins/tendermint/tendermint_coin.rs | 15 +- mm2src/coins/tendermint/wallet_connect.rs | 9 +- .../src/eth_with_token_activation.rs | 9 +- .../src/tendermint_with_assets_activation.rs | 8 +- mm2src/kdf_walletconnect/src/chain.rs | 4 +- mm2src/kdf_walletconnect/src/lib.rs | 44 ++-- mm2src/mm2_eth/Cargo.toml | 2 +- mm2src/mm2_main/Cargo.toml | 2 +- mm2src/mm2_main/src/lp_swap/taker_swap.rs | 1 + mm2src/mm2_net/Cargo.toml | 2 +- mm2src/trezor/Cargo.toml | 4 +- 18 files changed, 343 insertions(+), 172 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 12274afb14..91ca7af8a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1953,7 +1953,7 @@ dependencies = [ [[package]] name = "ethcore-transaction" version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig#676351596f590a08751eca8ddea5120f513b57a6" dependencies = [ "ethereum-types", "ethkey", @@ -1980,7 +1980,7 @@ dependencies = [ [[package]] name = "ethkey" version = "0.3.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig#676351596f590a08751eca8ddea5120f513b57a6" dependencies = [ "byteorder", "edit-distance", @@ -3847,7 +3847,7 @@ checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" [[package]] name = "mem" version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig#676351596f590a08751eca8ddea5120f513b57a6" [[package]] name = "memchr" @@ -4745,7 +4745,7 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" dependencies = [ "anyhow", "chrono", @@ -5645,7 +5645,7 @@ checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" dependencies = [ "chrono", "data-encoding", @@ -5673,7 +5673,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" dependencies = [ "anyhow", "bs58 0.4.0", @@ -7704,7 +7704,7 @@ dependencies = [ [[package]] name = "unexpected" version = "0.1.0" -source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig#676351596f590a08751eca8ddea5120f513b57a6" [[package]] name = "unicode-bidi" @@ -8036,7 +8036,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#174d3865f3f6b312aca259b3003084997a7c58dc" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" dependencies = [ "base64 0.21.7", "chacha20poly1305", diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index 563e41a71b..5be8c74ae3 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -41,9 +41,9 @@ derive_more = "0.99" ed25519-dalek = { version = "1.0.1", features = ["serde"] } enum_derives = { path = "../derives/enum_derives" } ethabi = { version = "17.0.0" } -ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } +ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } ethereum-types = { version = "0.13", default-features = false, features = ["std", "serialize"] } -ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } +ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } # Waiting for https://github.com/rust-lang/rust/issues/54725 to use on Stable. #enum_dispatch = "0.1" futures01 = { version = "0.1", package = "futures" } diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 27d0c7ba5d..96908fcde3 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -1,5 +1,3 @@ -use self::wallet_connect::{EthWalletConnectError, WcEthTxParams}; - /****************************************************************************** * Copyright © 2023 Pampex LTD and TillyHK LTD * * * @@ -22,13 +20,13 @@ use self::wallet_connect::{EthWalletConnectError, WcEthTxParams}; // // Copyright © 2023 Pampex LTD and TillyHK LTD. All rights reserved. // +use self::wallet_connect::{send_transaction_with_walletconnect, WcEthTxParams}; use super::eth::Action::{Call, Create}; use super::watcher_common::{validate_watcher_reward, REWARD_GAS_AMOUNT}; use super::*; use crate::coin_balance::{EnableCoinBalanceError, EnabledCoinBalanceParams, HDAccountBalance, HDAddressBalance, HDWalletBalance, HDWalletBalanceOps}; use crate::eth::eth_rpc::ETH_RPC_REQUEST_TIMEOUT; -use crate::eth::wallet_connect::wc_sign_eth_transaction; use crate::eth::web3_transport::websocket_transport::{WebsocketTransport, WebsocketTransportNode}; use crate::hd_wallet::{HDAccountOps, HDCoinAddress, HDCoinWithdrawOps, HDConfirmAddress, HDPathAccountToAddressId, HDWalletCoinOps, HDXPubExtractor}; @@ -61,6 +59,7 @@ use common::executor::{abortable_queue::AbortableQueue, AbortOnDropHandle, Abort AbortedError, SpawnAbortable, Timer}; use common::log::{debug, error, info, warn}; use common::number_type_casting::SafeTypeCastingNumbers; +use common::{now_ms, wait_until_ms}; use common::{now_sec, small_rng, DEX_FEE_ADDR_RAW_PUBKEY}; use crypto::privkey::key_pair_from_secret; use crypto::{Bip44Chain, CryptoCtx, CryptoCtxError, GlobalHDAccountArc, KeyPairPolicy}; @@ -79,8 +78,6 @@ use futures::future::{join, join_all, select_ok, try_join_all, Either, FutureExt use futures01::Future; use http::Uri; use instant::Instant; -use kdf_walletconnect::chain::WcChainId; -use kdf_walletconnect::error::WalletConnectError; use kdf_walletconnect::{WalletConnectCtx, WalletConnectOps}; use mm2_core::mm_ctx::{MmArc, MmWeak}; use mm2_event_stream::behaviour::{EventBehaviour, EventInitStatus}; @@ -107,9 +104,8 @@ use web3::types::{Action as TraceAction, BlockId, BlockNumber, Bytes, CallReques use web3::{self, Web3}; cfg_wasm32! { - use common::{now_ms, wait_until_ms}; use crypto::MetamaskArc; - use ethereum_types::{H264, H520}; + use ethereum_types::H520; use mm2_metamask::MetamaskError; use web3::types::TransactionRequest; } @@ -595,7 +591,7 @@ pub enum EthPrivKeyBuildPolicy { Trezor, WalletConnect { address: Address, - pubkey: Public, + public_key_uncompressed: H520, }, } @@ -1392,10 +1388,10 @@ impl SwapOps for EthCoin { .expect("valid key") .public_slice() .to_vec(), + EthPrivKeyPolicy::WalletConnect { public_key, .. } => public_key.as_bytes().to_vec(), EthPrivKeyPolicy::Trezor => todo!(), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(ref metamask_policy) => metamask_policy.public_key.as_bytes().to_vec(), - EthPrivKeyPolicy::WalletConnect { pubkey, .. } => pubkey.to_bytes().to_vec(), } } @@ -2167,7 +2163,10 @@ impl MarketCoinOps for EthCoin { EthPrivKeyPolicy::Metamask(ref metamask_policy) => { Ok(format!("{:02x}", metamask_policy.public_key_uncompressed)) }, - EthPrivKeyPolicy::WalletConnect { address: _, pubkey } => Ok(format!("04{}", hex::encode(pubkey))), + EthPrivKeyPolicy::WalletConnect { + public_key_uncompressed, + .. + } => Ok(format!("{public_key_uncompressed:02x}")), } } @@ -2538,25 +2537,23 @@ async fn sign_transaction_with_keypair<'a>( ) -> Result<(SignedEthTx, Vec), TransactionErr> { info!(target: "sign", "get_addr_nonce…"); let (nonce, web3_instances_with_latest_nonce) = try_tx_s!(coin.clone().get_addr_nonce(from_address).compat().await); - if let EthPrivKeyPolicy::WalletConnect { .. } = coin.priv_key_policy() {} let tx_type = tx_type_from_pay_for_gas_option!(pay_for_gas_option); if !coin.is_tx_type_supported(&tx_type) { return Err(TransactionErr::Plain("Eth transaction type not supported".into())); } + let tx_builder = UnSignedEthTxBuilder::new(tx_type, nonce, gas, action, value, data); let tx_builder = tx_builder_with_pay_for_gas_option(coin, tx_builder, pay_for_gas_option) .map_err(|e| TransactionErr::Plain(e.get_inner().to_string()))?; let tx = tx_builder.build()?; + let signed_tx = tx.sign(key_pair.secret(), Some(coin.chain_id))?; - Ok(( - tx.sign(key_pair.secret(), Some(coin.chain_id))?, - web3_instances_with_latest_nonce, - )) + Ok((signed_tx, web3_instances_with_latest_nonce)) } /// Sign and send eth transaction with provided keypair, /// This fn is primarily for swap transactions so it uses swap tx fee policy -async fn sign_and_send_transaction_with_keypair( +async fn sign_and_send_transaction_with_keypair<'a>( coin: &EthCoin, key_pair: &KeyPair, address: Address, @@ -2692,11 +2689,51 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw }) .map_to_mm(|err| RawTransactionError::TransactionError(err.get_plain_text_format())) }, - EthPrivKeyPolicy::WalletConnect { .. } => MmError::err(RawTransactionError::InvalidParam( - "sign raw eth tx not implemented for WalletConnect".into(), - )), + EthPrivKeyPolicy::WalletConnect { .. } => { + let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); + let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + let my_address = coin + .derivation_method + .single_addr_or_err() + .await + .mm_err(|e| RawTransactionError::InternalError(e.to_string()))?; + let address_lock = coin.get_address_lock(my_address.to_string()).await; + let _nonce_lock = address_lock.lock().await; + let pay_for_gas_option = if let Some(ref pay_for_gas) = args.pay_for_gas { + pay_for_gas.clone().try_into()? + } else { + // use legacy gas_price() if not set + info!(target: "sign-and-send", "get_gas_price…"); + let gas_price = coin.get_gas_price().await?; + PayForGasOption::Legacy(LegacyGasPrice { gas_price }) + }; + let (nonce, _) = coin + .clone() + .get_addr_nonce(my_address) + .compat() + .await + .map_to_mm(RawTransactionError::InvalidParam)?; + let tx_params = WcEthTxParams { + my_address, + gas_price: pay_for_gas_option.get_gas_price(), + action, + value, + gas: args.gas_limit, + data: &data, + nonce, + }; + + let (signed_tx, _) = coin + .wc_sign_tx(&wc, tx_params) + .await + .mm_err(|err| RawTransactionError::TransactionError(err.to_string()))?; + + Ok(RawTransactionRes { + tx_hex: signed_tx.tx_hex().into(), + }) + }, EthPrivKeyPolicy::Trezor => MmError::err(RawTransactionError::InvalidParam( - "sign raw eth tx not implemented for Trezor".into(), + "sign raw eth tx not implemented for Metamask".into(), )), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => MmError::err(RawTransactionError::InvalidParam( @@ -3646,12 +3683,16 @@ impl EthCoin { .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; sign_and_send_transaction_with_keypair(&coin, key_pair, address, value, action, data, gas).await }, + EthPrivKeyPolicy::WalletConnect { .. } => { + let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); + let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + send_transaction_with_walletconnect(coin, &wc, value, action, &data, gas).await + }, EthPrivKeyPolicy::Trezor => Err(TransactionErr::Plain(ERRL!("Trezor is not supported for swaps yet!"))), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => { sign_and_send_transaction_with_metamask(coin, value, action, data, gas).await }, - EthPrivKeyPolicy::WalletConnect { .. } => todo!(), } }; Box::new(fut.boxed().compat()) @@ -5254,7 +5295,6 @@ impl EthCoin { } /// Returns `None` if the transaction hasn't appeared on the RPC nodes at the specified time. - #[cfg(target_arch = "wasm32")] async fn wait_for_tx_appears_on_rpc( &self, tx_hash: H256, @@ -5276,6 +5316,7 @@ impl EthCoin { warn!( "Couldn't fetch the '{tx_hash:02x}' transaction hex as it hasn't appeared on the RPC node in {timeout_s}s" ); + Ok(None) } @@ -7193,7 +7234,15 @@ impl CommonSwapOpsV2 for EthCoin { .expect("slice with incorrect length"); Public::from_slice(&pubkey_bytes) }, - EthPrivKeyPolicy::WalletConnect { pubkey, .. } => pubkey, + EthPrivKeyPolicy::WalletConnect { + public_key_uncompressed, + .. + } => { + let pubkey_bytes: [u8; 64] = public_key_uncompressed[1..65] + .try_into() + .expect("slice with incorrect length"); + Public::from_slice(&pubkey_bytes) + }, } } @@ -7238,20 +7287,3 @@ impl EthCoin { EthCoin(Arc::new(coin)) } } - -#[async_trait::async_trait] -impl WalletConnectOps for EthCoin { - type Error = MmError; - type SignTxData = (H256, BytesJson); - type Params<'a> = WcEthTxParams<'a>; - - fn wc_chain_id(&self) -> WcChainId { WcChainId::new_eip155(self.chain_id.to_string()) } - - async fn wc_request_sign_tx<'a>( - &self, - ctx: &WalletConnectCtx, - params: Self::Params<'a>, - ) -> Result { - wc_sign_eth_transaction(ctx, &self.wc_chain_id(), params).await - } -} diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index a27a4651fb..c725bac29b 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -300,7 +300,7 @@ where }; self.send_withdraw_tx(&req, tx_to_send).await? }, - EthPrivKeyPolicy::WalletConnect { address: _, pubkey: _ } => { + EthPrivKeyPolicy::WalletConnect { .. } => { let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); let gas_price = pay_for_gas_option.get_gas_price(); @@ -316,15 +316,18 @@ where nonce, data: &data, my_address, - to_addr, + action: Action::Call(to_addr), value: eth_value, gas_price, }; - self.coin() - .wc_request_sign_tx(&wc, params) + let (tx, bytes) = self + .coin() + .wc_sign_tx(&wc, params) .await - .mm_err(|err| WithdrawError::SigningError(err.to_string()))? + .mm_err(|err| WithdrawError::SigningError(err.to_string()))?; + + (tx.tx_hash(), bytes) }, }; diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index be891b1b8b..9a19fad362 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -6,10 +6,13 @@ use crate::nft::get_nfts_for_activation; use crate::nft::nft_errors::{GetNftInfoError, ParseChainTypeError}; use crate::nft::nft_structs::Chain; #[cfg(target_arch = "wasm32")] use crate::EthMetamaskPolicy; + use common::executor::AbortedError; use crypto::{trezor::TrezorError, Bip32Error, CryptoCtxError, HwError}; use enum_derives::EnumFromTrait; +use ethereum_types::H264; use instant::Instant; +use kdf_walletconnect::error::WalletConnectError; use mm2_err_handle::common_errors::WithInternal; #[cfg(target_arch = "wasm32")] use mm2_metamask::{from_metamask_error, MetamaskError, MetamaskRpcError, WithMetamaskRpcError}; @@ -161,10 +164,7 @@ pub enum EthPrivKeyActivationPolicy { Trezor, #[cfg(target_arch = "wasm32")] Metamask, - WalletConnect { - #[serde(default)] - account_index: usize, - }, + WalletConnect, } impl EthPrivKeyActivationPolicy { @@ -789,10 +789,20 @@ pub(crate) async fn build_address_and_priv_key_policy( DerivationMethod::SingleAddress(address), )) }, - EthPrivKeyBuildPolicy::WalletConnect { address, pubkey } => Ok(( - EthPrivKeyPolicy::WalletConnect { address, pubkey }, - DerivationMethod::SingleAddress(address), - )), + EthPrivKeyBuildPolicy::WalletConnect { + address, + public_key_uncompressed, + } => { + let public_key = compress_public_key(public_key_uncompressed)?; + Ok(( + EthPrivKeyPolicy::WalletConnect { + address, + public_key, + public_key_uncompressed, + }, + DerivationMethod::SingleAddress(address), + )) + }, } } @@ -964,7 +974,6 @@ async fn check_metamask_supports_chain_id( } } -#[cfg(target_arch = "wasm32")] fn compress_public_key(uncompressed: H520) -> MmResult { let public_key = PublicKey::from_slice(uncompressed.as_bytes()) .map_to_mm(|e| EthActivationV2Error::InternalError(e.to_string()))?; diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index e5e002a552..2f52447de7 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -1,10 +1,15 @@ -use crate::{BytesJson, H256}; +use crate::common::Future01CompatExt; +use crate::Eip1559Ops; +use crate::{BytesJson, TransactionErr}; use chrono::Utc; +use common::log::info; use derive_more::Display; -use ethcore_transaction::SignedTransaction; -use ethereum_types::{Address, Public, H160, U256}; +use ethcore_transaction::{Action, SignedTransaction}; +use ethereum_types::H256; +use ethereum_types::{Address, Public, H160, H520, U256}; use ethkey::{public_to_address, Message, Signature}; +use kdf_walletconnect::WalletConnectOps; use kdf_walletconnect::{chain::{WcChainId, WcRequestMethods}, error::WalletConnectError, WalletConnectCtx}; @@ -16,6 +21,8 @@ use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, use std::str::FromStr; use web3::signing::hash_message; +use super::EthCoin; + #[derive(Display, Debug)] pub enum EthWalletConnectError { UnsupportedChainId(WcChainId), @@ -48,13 +55,13 @@ impl From for EthWalletConnectError { } pub struct WcEthTxParams<'a> { - pub gas: U256, - pub nonce: U256, - pub data: &'a [u8], - pub my_address: H160, - pub to_addr: H160, - pub value: U256, - pub gas_price: Option, + pub(crate) gas: U256, + pub(crate) nonce: U256, + pub(crate) data: &'a [u8], + pub(crate) my_address: H160, + pub(crate) action: Action, + pub(crate) value: U256, + pub(crate) gas_price: Option, } impl<'a> WcEthTxParams<'a> { @@ -63,7 +70,6 @@ impl<'a> WcEthTxParams<'a> { let mut tx_json = json!({ "nonce": u256_to_hex(self.nonce), - "to": format!("0x{}", hex::encode(self.to_addr.as_bytes())), "from": format!("0x{}", hex::encode(self.my_address.as_bytes())), "gas": u256_to_hex(self.gas), "value": u256_to_hex(self.value), @@ -77,60 +83,132 @@ impl<'a> WcEthTxParams<'a> { .insert("gasPrice".to_string(), json!(u256_to_hex(gas_price))); } - Ok(tx_json) + let to_addr = match self.action { + Action::Create => None, + Action::Call(addr) => Some(addr), + }; + if let Some(to) = to_addr { + tx_json + .as_object_mut() + .unwrap() + .insert("to".to_string(), json!(format!("0x{}", hex::encode(to.as_bytes())))); + } + + Ok(json!(vec![tx_json])) } } -pub(crate) async fn wc_sign_eth_transaction<'a>( - ctx: &WalletConnectCtx, - chain_id: &WcChainId, - tx_params: WcEthTxParams<'a>, -) -> MmResult<(H256, BytesJson), EthWalletConnectError> { - ctx.validate_or_update_active_chain_id(chain_id).await?; +#[async_trait::async_trait] +impl WalletConnectOps for EthCoin { + type Error = MmError; + type SignTxData = (SignedTransaction, BytesJson); + type SendTxData = (SignedTransaction, BytesJson); + type Params<'a> = WcEthTxParams<'a>; - let topic = ctx - .session - .get_session_active() - .await - .map(|session| session.topic.clone()) - .ok_or(WalletConnectError::NotInitialized)?; + fn wc_chain_id(&self) -> WcChainId { WcChainId::new_eip155(self.chain_id.to_string()) } - { - let tx_json = tx_params.prepare_wc_tx_format()?; - let request = SessionRequestRequest { - chain_id: chain_id.to_string(), - request: SessionRequest { - method: WcRequestMethods::EthSignTransaction.as_ref().to_string(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: tx_json.clone(), - }, + async fn wc_sign_tx<'a>( + &self, + ctx: &WalletConnectCtx, + params: Self::Params<'a>, + ) -> Result { + let topic = ctx + .session + .get_session_active() + .await + .map(|session| session.topic.clone()) + .ok_or(WalletConnectError::NotInitialized)?; + + { + let tx_json = params.prepare_wc_tx_format()?; + let request = SessionRequestRequest { + chain_id: self.wc_chain_id().to_string(), + request: SessionRequest { + method: WcRequestMethods::EthSignTransaction.as_ref().to_string(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: tx_json.clone(), + }, + }; + ctx.publish_request(&topic, RequestParams::SessionRequest(request)) + .await?; }; - ctx.publish_request(&topic, RequestParams::SessionRequest(request)) - .await?; - }; - let bytes = { - let tx_hex: String = ctx.on_wc_session_response(Ok).await?; - // First 4 bytes from WalletConnect represents Protoc info - hex::decode(&tx_hex[4..])? - }; - let unverified = rlp::decode(&bytes)?; - let signed = SignedTransaction::new(unverified)?; - let bytes = rlp::encode(&signed); + let bytes = { + let tx_hex: String = ctx.on_wc_session_response(Ok).await?; + // First 4 bytes from WalletConnect represents Protoc info + hex::decode(&tx_hex[4..])? + }; + let unverified = rlp::decode(&bytes)?; + let signed = SignedTransaction::new(unverified)?; + let bytes = rlp::encode(&signed); + + Ok((signed, BytesJson::from(bytes.to_vec()))) + } + + async fn wc_send_tx<'a>( + &self, + ctx: &WalletConnectCtx, + params: Self::Params<'a>, + ) -> Result { + let topic = ctx + .session + .get_session_active() + .await + .map(|session| session.topic.clone()) + .ok_or(WalletConnectError::NotInitialized)?; + + { + let tx_json = params.prepare_wc_tx_format()?; + let request = SessionRequestRequest { + chain_id: self.wc_chain_id().to_string(), + request: SessionRequest { + method: WcRequestMethods::EthSendTransaction.as_ref().to_string(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params: tx_json.clone(), + }, + }; + ctx.publish_request(&topic, RequestParams::SessionRequest(request)) + .await?; + }; - Ok((signed.tx_hash(), BytesJson::from(bytes.to_vec()))) + let tx_hash: String = ctx.on_wc_session_response(Ok).await?; + let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); + + // Wait for 10 seconds for the transaction to appear on the RPC node. + let wait_rpc_timeout = 10_000; + let check_every = 1.; + let maybe_signed_tx = self + .wait_for_tx_appears_on_rpc( + H256::from_slice( + &hex::decode(tx_hash).map_to_mm(|err| EthWalletConnectError::InvalidTxData(err.to_string()))?, + ), + wait_rpc_timeout, + check_every, + ) + .await + .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))?; + let signed_tx = match maybe_signed_tx { + Some(signed_tx) => signed_tx, + None => { + return MmError::err(EthWalletConnectError::InternalError(format!( + "Waited too long until the transaction {:?} appear on the RPC node", + tx_hash + ))) + }, + }; + let tx_hex = BytesJson::from(rlp::encode(&signed_tx).to_vec()); + + Ok((signed_tx, tx_hex)) + } } pub async fn eth_request_wc_personal_sign( ctx: &WalletConnectCtx, chain_id: u64, - account_index: usize, -) -> MmResult<(Public, Address), EthWalletConnectError> { +) -> MmResult<(H520, Address), EthWalletConnectError> { let chain_id = chain_id.to_string(); let chain_id = WcChainId::new_eip155(chain_id); - ctx.validate_or_update_active_chain_id(&chain_id).await?; - let topic = ctx .session .get_session_active() @@ -138,7 +216,7 @@ pub async fn eth_request_wc_personal_sign( .map(|session| session.topic.clone()) .ok_or(WalletConnectError::NotInitialized)?; - let account_str = ctx.get_account_for_chain_id(&chain_id, account_index).await?; + let account_str = ctx.get_account_for_chain_id(&chain_id).await?; let message = "Authenticate with Komodefi"; { @@ -167,34 +245,74 @@ fn extract_pubkey_from_signature( signature_str: &str, message: impl ToString, account: &str, -) -> MmResult<(Public, Address), EthWalletConnectError> { +) -> MmResult<(H520, Address), EthWalletConnectError> { let message_hash = hash_message(message.to_string()); let account = H160::from_str(&account[2..]).map_to_mm(|err| EthWalletConnectError::InternalError(err.to_string()))?; let signature = Signature::from_str(&signature_str[2..]) .map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; - let pubkey = recover(&signature, &message_hash).map_to_mm(|err| { + let uncompressed = recover(&signature, &message_hash).map_to_mm(|err| { let error = format!("Couldn't recover a public key from the signature: '{signature:?}, error: {err:?}'"); EthWalletConnectError::InvalidSignature(error) })?; - let recovered_address = public_to_address(&pubkey); + let mut public = Public::default(); + public.as_mut().copy_from_slice(&uncompressed[1..65]); + + let recovered_address = public_to_address(&public); if account != recovered_address { let error = format!("Recovered address '{recovered_address:?}' should be the same as '{account:?}'"); return MmError::err(EthWalletConnectError::AccoountMisMatch(error)); } - Ok((pubkey, recovered_address)) + Ok((uncompressed, recovered_address)) } -pub fn recover(signature: &Signature, message: &Message) -> Result { +pub fn recover(signature: &Signature, message: &Message) -> Result { let recovery_id = signature[64] as i32 - 27; let recovery_id = RecoveryId::from_i32(recovery_id)?; let sig = RecoverableSignature::from_compact(&signature[0..64], recovery_id)?; let pubkey = Secp256k1::new().recover(&secp256k1::Message::from_slice(&message[..])?, &sig)?; let serialized = pubkey.serialize_uncompressed(); - let mut public = Public::default(); - public.as_mut().copy_from_slice(&serialized[1..65]); - Ok(public) + Ok(serialized.into()) +} + +/// Sign and send eth transaction with WalletConnect, +/// This fn is primarily for swap transactions so it uses swap tx fee policy +pub(crate) async fn send_transaction_with_walletconnect( + coin: EthCoin, + wc: &WalletConnectCtx, + value: U256, + action: Action, + data: &[u8], + gas: U256, +) -> Result { + let address = try_tx_s!(coin + .derivation_method + .single_addr_or_err() + .await + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))); + + info!(target: "sign-and-send", "get_gas_price…"); + let pay_for_gas_option = try_tx_s!( + coin.get_swap_pay_for_gas_option(coin.get_swap_transaction_fee_policy()) + .await + ); + + let (nonce, _) = try_tx_s!(coin.clone().get_addr_nonce(address).compat().await); + let params = WcEthTxParams { + gas, + nonce, + data, + my_address: address, + action, + value, + gas_price: pay_for_gas_option.get_gas_price(), + }; + // Please note that this method may take a long time + // due to `eth_sendTransaction` requests. + let (signed_tx, _) = try_tx_s!(coin.wc_send_tx(wc, params).await); + + Ok(signed_tx) } diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index 919c0728a0..028a39a8a8 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -54,8 +54,8 @@ use crypto::{derive_secp256k1_secret, Bip32Error, Bip44Chain, CryptoCtx, CryptoC Secp256k1ExtendedPublicKey, Secp256k1Secret, WithHwRpcError}; use derive_more::Display; use enum_derives::{EnumFromStringify, EnumFromTrait}; -use ethereum_types::Public as EthPublic; use ethereum_types::{H160, H256}; +use ethereum_types::{H264, H520}; use futures::compat::Future01CompatExt; use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use futures::{FutureExt, TryFutureExt}; @@ -99,7 +99,7 @@ cfg_native! { } cfg_wasm32! { - use ethereum_types::{H264 as EthH264, H520 as EthH520}; + use ethereum_types::{H264 as EthH264}; use hd_wallet::HDWalletDb; use mm2_db::indexed_db::{ConstructibleDb, DbLocked, SharedDb}; use tx_history_storage::wasm::{clear_tx_history, load_tx_history, save_tx_history, TxHistoryDb}; @@ -3906,7 +3906,8 @@ pub enum PrivKeyPolicy { WalletConnect { address: H160, - pubkey: EthPublic, + public_key: H264, + public_key_uncompressed: H520, }, } @@ -3914,7 +3915,7 @@ pub enum PrivKeyPolicy { #[derive(Clone, Debug)] pub struct EthMetamaskPolicy { pub(crate) public_key: EthH264, - pub(crate) public_key_uncompressed: EthH520, + pub(crate) public_key_uncompressed: H520, } impl From for PrivKeyPolicy { diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index ea09b77ab9..ef8d6407a8 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -888,7 +888,7 @@ impl TendermintCoin { let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); let wc = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); - let response = try_tx_s!(self.wc_request_sign_tx(&wc, tx_json).await); + let response = try_tx_s!(self.wc_sign_tx(&wc, tx_json).await); let signature = try_tx_s!(general_purpose::STANDARD .decode(response.signature.signature) .map_err(|e| ERRL!("{}", e))); @@ -1297,7 +1297,7 @@ impl TendermintCoin { let SerializedUnsignedTx { tx_json, body_bytes: _ } = self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo)?; - let response = self.wc_request_sign_tx(&wallet_connect, tx_json).await?; + let response = self.wc_sign_tx(&wallet_connect, tx_json).await?; let signature = general_purpose::STANDARD.decode(response.signature.signature)?; let body_bytes = response.signed.body_bytes; let auth_info_bytes = response.signed.auth_info_bytes; @@ -3480,16 +3480,25 @@ impl WalletConnectOps for TendermintCoin { type Error = MmError; type Params<'a> = serde_json::Value; type SignTxData = CosmosTxSignedData; + type SendTxData = CosmosTransaction; fn wc_chain_id(&self) -> WcChainId { WcChainId::new_cosmos(self.chain_id.to_string()) } - async fn wc_request_sign_tx<'a>( + async fn wc_sign_tx<'a>( &self, ctx: &WalletConnectCtx, params: Self::Params<'a>, ) -> Result { cosmos_request_wc_signed_tx(ctx, params, &self.wc_chain_id(), self.is_ledger_connection()).await } + + async fn wc_send_tx<'a>( + &self, + _ctx: &WalletConnectCtx, + _params: Self::Params<'a>, + ) -> Result { + todo!() + } } #[cfg(test)] diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 589684b7d3..0e236a9df9 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -109,12 +109,11 @@ pub struct CosmosAccount { pub async fn cosmos_get_accounts_impl( ctx: &WalletConnectCtx, chain_id: &str, - account_index: usize, ) -> MmResult { let chain_id = WcChainId::new_cosmos(chain_id.to_string()); ctx.validate_or_update_active_chain_id(&chain_id).await?; - let account = ctx.get_account_for_chain_id(&chain_id, account_index).await?; + let account = ctx.get_account_for_chain_id(&chain_id).await?; let session = ctx .session .get_session_active() @@ -165,11 +164,7 @@ pub async fn cosmos_get_accounts_impl( return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); }; - if accounts.len() < account_index + 1 { - return MmError::err(WalletConnectError::NoAccountFoundForIndex(account_index)); - }; - - Ok(accounts[account_index].clone()) + Ok(accounts[0].clone()) }) .await } diff --git a/mm2src/coins_activation/src/eth_with_token_activation.rs b/mm2src/coins_activation/src/eth_with_token_activation.rs index d4dbcb59da..fa17c3ce72 100644 --- a/mm2src/coins_activation/src/eth_with_token_activation.rs +++ b/mm2src/coins_activation/src/eth_with_token_activation.rs @@ -476,14 +476,17 @@ async fn eth_priv_key_build_policy( Ok(EthPrivKeyBuildPolicy::Metamask(metamask_ctx)) }, EthPrivKeyActivationPolicy::Trezor => Ok(EthPrivKeyBuildPolicy::Trezor), - EthPrivKeyActivationPolicy::WalletConnect { account_index } => { + EthPrivKeyActivationPolicy::WalletConnect => { let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); let chain_id = conf["chain_id"].as_u64().ok_or(EthActivationV2Error::ChainIdNotSet)?; - let (pubkey, address) = eth_request_wc_personal_sign(&wc, chain_id, *account_index) + let (public_key_uncompressed, address) = eth_request_wc_personal_sign(&wc, chain_id) .await .mm_err(|err| EthActivationV2Error::WalletConnectError(err.to_string()))?; - Ok(EthPrivKeyBuildPolicy::WalletConnect { address, pubkey }) + Ok(EthPrivKeyBuildPolicy::WalletConnect { + address, + public_key_uncompressed, + }) }, } } diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index d948e76b72..ce32ec8750 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -42,8 +42,6 @@ impl RegisterTokenInfo for TendermintCoin { #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct WalletConnectParams { - #[serde(default)] - pub account_index: usize, #[serde(default)] pub enabled: bool, } @@ -239,13 +237,12 @@ impl From for EnablePlatformCoinWithTokensError { async fn activate_with_walletconnect( ctx: &MmArc, - param: &WalletConnectParams, chain_id: &str, ticker: &str, wallet_type: &mut TendermintWalletConnectionType, ) -> MmResult { let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); - let account = cosmos_get_accounts_impl(&wc, chain_id, param.account_index) + let account = cosmos_get_accounts_impl(&wc, chain_id) .await .mm_err(|err| TendermintInitError { ticker: ticker.to_string(), @@ -311,7 +308,7 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { TendermintActivationPolicy::with_public_key(pubkey) }, - TendermintPubkeyActivationParams::WalletConnect(params) => { + TendermintPubkeyActivationParams::WalletConnect(_params) => { if ctx.is_watcher() || ctx.use_watchers() { return MmError::err(TendermintInitError { ticker: ticker.to_string(), @@ -321,7 +318,6 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { activate_with_walletconnect( &ctx, - ¶ms, protocol_conf.chain_id.as_ref(), &ticker, &mut wallet_connectin_type, diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index f626a66a50..f6125d9dcc 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -10,7 +10,7 @@ pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; -pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "personal_sign"]; +pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "personal_sign", "eth_sendTransaction"]; pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:137"]; pub(crate) const ETH_SUPPORTED_EVENTS: &[&str] = &["accountsChanged", "chainChanged"]; @@ -90,6 +90,7 @@ pub enum WcRequestMethods { CosmosSignAmino, CosmosGetAccounts, EthSignTransaction, + EthSendTransaction, PersonalSign, } @@ -100,6 +101,7 @@ impl AsRef for WcRequestMethods { Self::CosmosSignAmino => "cosmos_signAmino", Self::CosmosGetAccounts => "cosmos_getAccounts", Self::EthSignTransaction => "eth_signTransaction", + Self::EthSendTransaction => "eth_sendTransaction", Self::PersonalSign => "personal_sign", } } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index eb52f102d0..0e2afd9e25 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -22,7 +22,7 @@ use metadata::{generate_metadata, AUTH_TOKEN_SUB, PROJECT_ID, RELAY_ADDRESS}; use mm2_core::mm_ctx::{from_ctx, MmArc}; use mm2_err_handle::prelude::*; use pairing_api::PairingClient; -use relay_client::websocket::{Client, PublishedMessage}; +use relay_client::websocket::{connection_event_loop as client_event_loop, Client, PublishedMessage}; use relay_client::{ConnectionOptions, MessageIdGenerator}; use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; use relay_rpc::domain::{MessageId, Topic}; @@ -45,14 +45,21 @@ pub trait WalletConnectOps { type Error; type Params<'a>; type SignTxData; + type SendTxData; fn wc_chain_id(&self) -> WcChainId; - async fn wc_request_sign_tx<'a>( + async fn wc_sign_tx<'a>( &self, ctx: &WalletConnectCtx, params: Self::Params<'a>, ) -> Result; + + async fn wc_send_tx<'a>( + &self, + ctx: &WalletConnectCtx, + params: Self::Params<'a>, + ) -> Result; } pub struct WalletConnectCtx { @@ -79,8 +86,6 @@ impl WalletConnectCtx { let (message_tx, session_request_receiver) = unbounded(); let pairing = PairingClient::new(); - let client = Client::new(Handler::new("Komodefi", msg_sender, conn_live_sender)); - let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), data: None, @@ -88,6 +93,12 @@ impl WalletConnectCtx { let storage = SessionStorageDb::init(ctx)?; + let client = Client::new_unmanaged(); + ctx.spawner().spawn(client_event_loop( + client.control_rx().expect("client controller should never fail!"), + Handler::new("Komodefi", msg_sender, conn_live_sender), + )); + Ok(Self { client, pairing, @@ -364,11 +375,7 @@ impl WalletConnectCtx { /// TODO: accept WcChainId /// Retrieves the available account for a given chain ID. - pub async fn get_account_for_chain_id( - &self, - chain_id: &WcChainId, - account_index: usize, - ) -> MmResult { + pub async fn get_account_for_chain_id(&self, chain_id: &WcChainId) -> MmResult { let namespaces = &self .session .get_session_active() @@ -383,7 +390,7 @@ impl WalletConnectCtx { .. }) = namespaces.get(chain_id.chain.as_ref()) { - if let Some(account) = find_accounts_in_namespace(accounts, &chain_id.id).nth(account_index) { + if let Some(account) = find_account_in_namespace(accounts, &chain_id.id) { return Ok(account); } }; @@ -397,7 +404,8 @@ impl WalletConnectCtx { T: DeserializeOwned, F: Fn(T) -> MmResult, { - let wait_duration = Duration::from_secs(30); + println!("HERE INNER"); + let wait_duration = Duration::from_secs(300); while let Ok(Some(resp)) = timeout(wait_duration, self.message_rx.lock().await.next()).await { let result = resp.mm_err(WalletConnectError::InternalError)?; @@ -419,13 +427,10 @@ impl WalletConnectCtx { /// WalletConnect can be usable in KDF. pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectError> { info!("Initializing WalletConnect"); - // Initialized WalletConnectCtx let wallet_connect = WalletConnectCtx::from_ctx(ctx)?; - // Intialize storage. wallet_connect.storage.init().await.unwrap(); - // WalletConnectCtx is initialized, now we can connect to relayer client and spawn a watcher // loop for disconnection. ctx.spawner().spawn({ @@ -435,11 +440,10 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect connection_handler::handle_disconnections(&this).await; } }); - // spawn message handler event loop ctx.spawner().spawn(async move { let this = wallet_connect.clone(); - let mut recv = wallet_connect.inbound_message_rx.lock().await; + let mut recv = this.inbound_message_rx.lock().await; while let Some(msg) = recv.next().await { if let Err(e) = this.handle_published_message(msg).await { info!("Error processing message: {:?}", e); @@ -448,14 +452,12 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect }); info!("WalletConnect initialization completed successfully"); + Ok(()) } -fn find_accounts_in_namespace<'a>( - accounts: &'a BTreeSet, - chain_id: &'a str, -) -> impl Iterator + 'a { - accounts.iter().filter_map(move |account_name| { +fn find_account_in_namespace<'a>(accounts: &'a BTreeSet, chain_id: &'a str) -> Option { + accounts.iter().find_map(move |account_name| { let parts: Vec<&str> = account_name.split(':').collect(); if parts.len() >= 3 && parts[1] == chain_id { Some(parts[2].to_string()) diff --git a/mm2src/mm2_eth/Cargo.toml b/mm2src/mm2_eth/Cargo.toml index 5992896424..8f84e2cf76 100644 --- a/mm2src/mm2_eth/Cargo.toml +++ b/mm2src/mm2_eth/Cargo.toml @@ -8,7 +8,7 @@ doctest = false [dependencies] ethabi = { version = "17.0.0" } -ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } +ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } hex = "0.4.2" indexmap = "1.7.0" itertools = "0.10" diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index bd597af45f..ab5a552ac0 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -140,7 +140,7 @@ web3 = { git = "https://github.com/KomodoPlatform/rust-web3", tag = "v0.20.0", d ] } ethabi = { version = "17.0.0" } rlp = { version = "0.5" } -ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } +ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } rustc-hex = "2" sia-rust = { git = "https://github.com/KomodoPlatform/sia-rust", rev = "9f188b80b3213bcb604e7619275251ce08fae808" } url = { version = "2.2.2", features = ["serde"] } diff --git a/mm2src/mm2_main/src/lp_swap/taker_swap.rs b/mm2src/mm2_main/src/lp_swap/taker_swap.rs index 3bedf837e4..9c4bea76e9 100644 --- a/mm2src/mm2_main/src/lp_swap/taker_swap.rs +++ b/mm2src/mm2_main/src/lp_swap/taker_swap.rs @@ -1256,6 +1256,7 @@ impl TakerSwap { NEGOTIATE_TIMEOUT_SEC as f64 / 6., self.p2p_privkey, ); + let recv_fut = recv_swap_msg( self.ctx.clone(), |store| store.negotiated.take(), diff --git a/mm2src/mm2_net/Cargo.toml b/mm2src/mm2_net/Cargo.toml index 27a6751e7d..3d192f95cb 100644 --- a/mm2src/mm2_net/Cargo.toml +++ b/mm2src/mm2_net/Cargo.toml @@ -17,7 +17,7 @@ bytes = "1.1" cfg-if = "1.0" common = { path = "../common" } derive_more = "0.99" -ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } +ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } futures = { version = "0.3", package = "futures", features = ["compat", "async-await", "thread-pool"] } gstuff = "0.7" http = "0.2" diff --git a/mm2src/trezor/Cargo.toml b/mm2src/trezor/Cargo.toml index 36e5abb0ec..2a19252be6 100644 --- a/mm2src/trezor/Cargo.toml +++ b/mm2src/trezor/Cargo.toml @@ -19,9 +19,9 @@ rand = { version = "0.7", features = ["std", "wasm-bindgen"] } rpc_task = { path = "../rpc_task" } serde = "1.0" serde_derive = "1.0" -ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } +ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } ethereum-types = { version = "0.13", default-features = false, features = ["std", "serialize"] } -ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } +ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } bip32 = { version = "0.2.2", default-features = false, features = ["alloc", "secp256k1-ffi"] } lazy_static = "1.4" From 3792027d67f2ae10cf56cfd2d6479849df5fc1f4 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 1 Nov 2024 04:57:57 +0100 Subject: [PATCH 088/125] swaps working, impl connection health manager --- Cargo.lock | 1 - mm2src/coins/Cargo.toml | 1 - mm2src/coins/eth/wallet_connect.rs | 85 ++-------- mm2src/coins/tendermint/wallet_connect.rs | 67 ++------ .../src/connection_handler.rs | 160 ++++++++++++++---- mm2src/kdf_walletconnect/src/lib.rs | 62 +++++-- 6 files changed, 210 insertions(+), 166 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 91ca7af8a2..be8097c249 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -910,7 +910,6 @@ dependencies = [ "proxy_signature", "rand 0.7.3", "regex", - "relay_rpc", "reqwest", "rlp", "rmp-serde", diff --git a/mm2src/coins/Cargo.toml b/mm2src/coins/Cargo.toml index 5be8c74ae3..24b3170c90 100644 --- a/mm2src/coins/Cargo.toml +++ b/mm2src/coins/Cargo.toml @@ -81,7 +81,6 @@ protobuf = "2.20" proxy_signature = { path = "../proxy_signature" } rand = { version = "0.7", features = ["std", "small_rng"] } regex = "1" -relay_rpc = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } reqwest = { version = "0.11.9", default-features = false, features = ["json"], optional = true } rlp = { version = "0.5" } rmp-serde = "0.14.3" diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 2f52447de7..72b5d66830 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -2,7 +2,6 @@ use crate::common::Future01CompatExt; use crate::Eip1559Ops; use crate::{BytesJson, TransactionErr}; -use chrono::Utc; use common::log::info; use derive_more::Display; use ethcore_transaction::{Action, SignedTransaction}; @@ -14,8 +13,6 @@ use kdf_walletconnect::{chain::{WcChainId, WcRequestMethods}, error::WalletConnectError, WalletConnectCtx}; use mm2_err_handle::prelude::*; -use relay_rpc::rpc::params::session_request::SessionRequestRequest; -use relay_rpc::rpc::params::{session_request::Request as SessionRequest, RequestParams}; use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, Secp256k1}; use std::str::FromStr; @@ -112,32 +109,15 @@ impl WalletConnectOps for EthCoin { ctx: &WalletConnectCtx, params: Self::Params<'a>, ) -> Result { - let topic = ctx - .session - .get_session_active() - .await - .map(|session| session.topic.clone()) - .ok_or(WalletConnectError::NotInitialized)?; - - { + let bytes = { let tx_json = params.prepare_wc_tx_format()?; - let request = SessionRequestRequest { - chain_id: self.wc_chain_id().to_string(), - request: SessionRequest { - method: WcRequestMethods::EthSignTransaction.as_ref().to_string(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: tx_json.clone(), - }, - }; - ctx.publish_request(&topic, RequestParams::SessionRequest(request)) + let tx_hex: String = ctx + .send_session_request_and_wait(&self.wc_chain_id(), WcRequestMethods::EthSignTransaction, tx_json, Ok) .await?; - }; - - let bytes = { - let tx_hex: String = ctx.on_wc_session_response(Ok).await?; // First 4 bytes from WalletConnect represents Protoc info hex::decode(&tx_hex[4..])? }; + let unverified = rlp::decode(&bytes)?; let signed = SignedTransaction::new(unverified)?; let bytes = rlp::encode(&signed); @@ -150,28 +130,11 @@ impl WalletConnectOps for EthCoin { ctx: &WalletConnectCtx, params: Self::Params<'a>, ) -> Result { - let topic = ctx - .session - .get_session_active() - .await - .map(|session| session.topic.clone()) - .ok_or(WalletConnectError::NotInitialized)?; - - { + let tx_hash: String = { let tx_json = params.prepare_wc_tx_format()?; - let request = SessionRequestRequest { - chain_id: self.wc_chain_id().to_string(), - request: SessionRequest { - method: WcRequestMethods::EthSendTransaction.as_ref().to_string(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: tx_json.clone(), - }, - }; - ctx.publish_request(&topic, RequestParams::SessionRequest(request)) - .await?; + ctx.send_session_request_and_wait(&self.wc_chain_id(), WcRequestMethods::EthSendTransaction, tx_json, Ok) + .await? }; - - let tx_hash: String = ctx.on_wc_session_response(Ok).await?; let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); // Wait for 10 seconds for the transaction to appear on the RPC node. @@ -209,34 +172,16 @@ pub async fn eth_request_wc_personal_sign( let chain_id = chain_id.to_string(); let chain_id = WcChainId::new_eip155(chain_id); - let topic = ctx - .session - .get_session_active() - .await - .map(|session| session.topic.clone()) - .ok_or(WalletConnectError::NotInitialized)?; - - let account_str = ctx.get_account_for_chain_id(&chain_id).await?; - let message = "Authenticate with Komodefi"; - - { + let result = { + let account_str = ctx.get_account_for_chain_id(&chain_id).await?; + let message = "Authenticate with Komodefi"; let message_hex = format!("0x{}", hex::encode(message)); let params = json!(&[&message_hex, &account_str]); - let request = SessionRequestRequest { - request: SessionRequest { - method: WcRequestMethods::PersonalSign.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params, - }, - chain_id: chain_id.to_string(), - }; - let session_request = RequestParams::SessionRequest(request); - ctx.publish_request(&topic, session_request).await?; - } - - let result = ctx - .on_wc_session_response(|data: String| Ok(extract_pubkey_from_signature(&data, message, &account_str)?)) - .await?; + ctx.send_session_request_and_wait(&chain_id, WcRequestMethods::PersonalSign, params, |data: String| { + Ok(extract_pubkey_from_signature(&data, message, &account_str)?) + }) + .await? + }; Ok(result) } diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 0e236a9df9..1570524128 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -1,13 +1,9 @@ use base64::engine::general_purpose; use base64::Engine; -use chrono::Utc; use kdf_walletconnect::chain::WcChainId; use kdf_walletconnect::error::WalletConnectError; use kdf_walletconnect::{chain::WcRequestMethods, WalletConnectCtx}; use mm2_err_handle::prelude::*; -use relay_rpc::rpc::params::session_request::Request as SessionRequest; -use relay_rpc::rpc::params::session_request::SessionRequestRequest; -use relay_rpc::rpc::params::RequestParams; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::str::FromStr; @@ -48,32 +44,13 @@ pub async fn cosmos_request_wc_signed_tx( chain_id: &WcChainId, is_ledger_conn: bool, ) -> MmResult { - let topic = ctx - .session - .get_session_active() - .await - .map(|session| session.topic.clone()) - .ok_or(WalletConnectError::NotInitialized)?; - - { - let method = if is_ledger_conn { - WcRequestMethods::CosmosSignAmino - } else { - WcRequestMethods::CosmosSignDirect - }; - let request = SessionRequestRequest { - request: SessionRequest { - method: method.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: sign_doc, - }, - chain_id: chain_id.to_string(), - }; - let session_request = RequestParams::SessionRequest(request); - ctx.publish_request(&topic, session_request).await?; - } + let method = if is_ledger_conn { + WcRequestMethods::CosmosSignAmino + } else { + WcRequestMethods::CosmosSignDirect + }; - ctx.on_wc_session_response::(Ok).await + ctx.send_session_request_and_wait(chain_id, method, sign_doc, Ok).await } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] @@ -145,27 +122,19 @@ pub async fn cosmos_get_accounts_impl( } } - let request = SessionRequestRequest { - request: SessionRequest { - method: WcRequestMethods::CosmosGetAccounts.as_ref().to_owned(), - expiry: Some(Utc::now().timestamp() as u64 + 300), - params: serde_json::to_value(&account).unwrap(), - }, - chain_id: chain_id.to_string(), - }; + let params = serde_json::to_value(&account).unwrap(); + ctx.send_session_request_and_wait( + &chain_id, + WcRequestMethods::CosmosGetAccounts, + params, + |accounts: Vec| { + if accounts.is_empty() { + return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); + }; - { - let session_request = RequestParams::SessionRequest(request); - ctx.publish_request(&session.topic, session_request).await?; - }; - - ctx.on_wc_session_response::, _, _>(|accounts| { - if accounts.is_empty() { - return MmError::err(WalletConnectError::EmptyAccount(chain_id.to_string())); - }; - - Ok(accounts[0].clone()) - }) + Ok(accounts[0].clone()) + }, + ) .await } diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 8573b9fb4a..77c470eba0 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -1,15 +1,22 @@ -use crate::WalletConnectCtx; +use crate::{WalletConnectCtx, WalletConnectError}; use common::executor::Timer; -use common::log::{error, info}; +use common::log::{debug, error, info}; use futures::channel::mpsc::UnboundedSender; use futures::StreamExt; +use mm2_err_handle::prelude::*; use relay_client::error::ClientError; use relay_client::websocket::{CloseFrame, ConnectionHandler, PublishedMessage}; +use relay_rpc::rpc::params::RequestParams; +use std::sync::Arc; +use tokio::time::interval; +use tokio::time::Duration; const INITIAL_RETRY_SECS: f64 = 5.0; const RETRY_INCREMENT: f64 = 5.0; -const RECONNECT_DELAY: f64 = 5.0; +const MAX_BACKOFF: u64 = 60; +const PING_INTERVAL: u64 = 140; +const PING_TIMEOUT: f64 = 60.; pub struct Handler { name: &'static str, @@ -33,7 +40,7 @@ impl Handler { impl ConnectionHandler for Handler { fn connected(&mut self) { - info!("\n[{}] connection open", self.name); + info!("\n[{}] connection to WalletConnect relay server successful", self.name); } fn disconnected(&mut self, frame: Option>) { @@ -64,6 +71,9 @@ impl ConnectionHandler for Handler { } } +/// Establishes initial connection to WalletConnect relay server with linear retry mechanism. +/// Uses increasing delay between retry attempts starting from INITIAL_RETRY_SECS. +/// After successful connection, attempts to restore previous session state from storage. pub(crate) async fn initial_connection(this: &WalletConnectCtx) { let mut retry_count = 0; let mut retry_secs = INITIAL_RETRY_SECS; @@ -78,7 +88,7 @@ pub(crate) async fn initial_connection(this: &WalletConnectCtx) { retry_secs += RETRY_INCREMENT; } - info!("Successfully connected to client after {} attempt(s).", retry_count + 1); + debug!("Successfully connected to client after {} attempt(s).", retry_count + 1); // load session from storage if let Err(err) = this.load_session_from_storage().await { @@ -86,41 +96,133 @@ pub(crate) async fn initial_connection(this: &WalletConnectCtx) { }; } +/// Handles unexpected disconnections from WalletConnect relay server. +/// Implements exponential backoff retry mechanism for reconnection attempts. +/// After successful reconnection, resubscribes to previous topics to restore full functionality. pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { let mut recv = this.connection_live_rx.lock().await; + let mut backoff = 1; while let Some(_msg) = recv.next().await { - info!("Connection disconnected. Attempting to reconnect..."); - reconnect(this).await; - resubscribe_to_topics(this).await; - info!("Reconnection process complete."); + debug!("Connection disconnected. Attempting to reconnect..."); + + loop { + match this.connect_client().await { + Ok(_) => { + if let Err(e) = resubscribe_to_topics(this).await { + error!("Failed to resubscribe after reconnection: {:?}", e); + } + debug!("Reconnection process complete."); + backoff = 1; + break; + }, + Err(e) => { + error!("Reconnection attempt failed: {:?}. Retrying in {:?}...", e, backoff); + Timer::sleep(backoff as f64).await; + backoff = std::cmp::min(backoff * 2, MAX_BACKOFF); + }, + } + } } } -async fn reconnect(this: &WalletConnectCtx) { - let mut retry_count = 0; +/// Maintains connection health with WalletConnect relay server through periodic pings. +/// Sends a ping every 4 minutes to proactively detect disconnections and automatically reconnects if needed. +/// This helps prevent connection drops as the relay server tends to disconnect inactive connections after 5 minutes. +/// The ping interval is designed to catch potential disconnections before the server timeout while minimizing +/// unnecessary network traffic. +pub(crate) async fn keep_alive_ping(ctx: Arc) { + let mut interval = interval(Duration::from_secs(PING_INTERVAL)); + let mut backoff = 1.; + + // Skip the first tick which happens immediately + interval.tick().await; + + loop { + tokio::select! { + _ = interval.tick() => { + match try_ping(&ctx).await { + Ok(_) => { + backoff = 1.; + continue; + } + Err(e) => { + error!("WalletConnect ping failed: {:?}. Attempting reconnect...", e); + // Attempt reconnection with backoff + if let Err(reconnect_err) = handle_ping_failure(&ctx).await { + error!("Reconnection failed: {:?}", reconnect_err); + // Increase backoff for next attempt + backoff = std::cmp::min(backoff as u64 * 2, MAX_BACKOFF ) as f64; + Timer::sleep(backoff).await; + continue; + } + // Reset backoff after successful reconnection + backoff = 1.; + debug!("Successfully reconnected after ping failure"); + } + } + } + } + } +} - while let Err(err) = this.connect_client().await { - retry_count += 1; - error!( - "Error while reconnecting to client (attempt {}): {:?}. Retrying in {} seconds...", - retry_count, err, RECONNECT_DELAY - ); - Timer::sleep(RECONNECT_DELAY).await; +/// Attempts to verify connection health with WalletConnect relay server by sending a ping message. +/// Waits for a pong response with a specified timeout period. +async fn try_ping(ctx: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { + let active_topic = ctx.session.get_active_topic_or_err().await?; + let param = RequestParams::SessionPing(()); + ctx.publish_request(&active_topic, param).await?; + + let timeout = Timer::sleep(PING_TIMEOUT); + tokio::pin!(timeout); + + let mut recv = ctx.message_rx.lock().await; + tokio::select! { + msg = recv.next() => { + match msg { + Some(Ok(_)) => { + debug!("WalletConnect Session Is Alive"); + Ok(()) + }, + Some(Err(err)) => { + MmError::err(WalletConnectError::InternalError( + format!("WalletConnect Ping Error: {err:?}") + )) + }, + None => { + error!("WalletConnect Ping timeout"); + MmError::err(WalletConnectError::InternalError( + "WalletConnect Ping timeout".into() + )) + } + } + }, + _ = timeout => { + error!("WalletConnect Ping timeout"); + MmError::err(WalletConnectError::InternalError( + "WalletConnect Ping timeout".into() + )) + } } +} - info!( - "Successfully reconnected to client after {} attempt(s).", - retry_count + 1 - ); +// Handle reconnection after ping failure +async fn handle_ping_failure(ctx: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { + // Attempt to disconnect client + ctx.client.disconnect().await?; + // Attempt to reconnect + ctx.connect_client().await?; + // Resubscribe to topics if needed + resubscribe_to_topics(ctx).await?; + // Verify connection with a new ping + try_ping(ctx).await } -async fn resubscribe_to_topics(this: &WalletConnectCtx) { +/// Resubscribes to previously active topics after reconnection. +/// Called by handle_disconnections to restore subscription state. +async fn resubscribe_to_topics(this: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { let subs = this.subscriptions.lock().await; - for topic in &*subs { - match this.client.subscribe(topic.clone()).await { - Ok(_) => info!("Successfully reconnected to topic: {:?}", topic), - Err(err) => error!("Failed to subscribe to topic: {:?}. Error: {:?}", topic, err), - } - } + this.client.batch_subscribe(&**subs).await?; + + Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 0e2afd9e25..92cc4cfa86 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -7,9 +7,12 @@ mod metadata; pub mod session; mod storage; +use crate::connection_handler::keep_alive_ping; use crate::session::rpc::propose::send_proposal_request; -use chain::{WcChainId, SUPPORTED_PROTOCOL}; +use chain::{WcChainId, WcRequestMethods, SUPPORTED_PROTOCOL}; +use chrono::Utc; +use common::custom_futures::timeout::FutureTimerExt; use common::log::info; use common::{executor::SpawnFuture, log::error}; use connection_handler::Handler; @@ -28,8 +31,9 @@ use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_event::{Event, SessionEventRequest}; -use relay_rpc::rpc::params::{IrnMetadata, Metadata, Relay, RelayProtocolMetadata, RequestParams, ResponseParamsError, - ResponseParamsSuccess}; +use relay_rpc::rpc::params::session_request::SessionRequestRequest; +use relay_rpc::rpc::params::{session_request::Request as SessionRequest, IrnMetadata, Metadata, Relay, + RelayProtocolMetadata, RequestParams, ResponseParamsError, ResponseParamsSuccess}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; use serde::de::DeserializeOwned; use session::{key::SymKeyPair, SessionManager}; @@ -37,7 +41,6 @@ use std::collections::BTreeSet; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; -use tokio::time::timeout; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; #[async_trait::async_trait] @@ -118,6 +121,7 @@ impl WalletConnectCtx { pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectError> { from_ctx(&ctx.wallet_connect, move || { + println!("HERE AGAIN"); Self::try_init(ctx).map_err(|err| err.to_string()) }) .map_to_mm(WalletConnectError::InternalError) @@ -230,15 +234,18 @@ impl WalletConnectCtx { self.session.add_session(session).await; // subcribe to session topics - self.client.subscribe(topic).await?; - self.client.subscribe(pairing_topic).await?; + self.client.batch_subscribe(vec![topic, pairing_topic]).await?; } Ok(()) } /// function to publish a request. - pub async fn publish_request(&self, topic: &Topic, param: RequestParams) -> MmResult<(), WalletConnectError> { + pub(crate) async fn publish_request( + &self, + topic: &Topic, + param: RequestParams, + ) -> MmResult<(), WalletConnectError> { let irn_metadata = param.irn_metadata(); let message_id = MessageIdGenerator::new().next(); let request = Request::new(message_id, param.into()); @@ -399,26 +406,45 @@ impl WalletConnectCtx { } /// Waits for and handles a WalletConnect session response with arbitrary data. - pub async fn on_wc_session_response(&self, func: F) -> MmResult + pub async fn send_session_request_and_wait( + &self, + chain_id: &WcChainId, + method: WcRequestMethods, + params: serde_json::Value, + response_handler: F, + ) -> MmResult where T: DeserializeOwned, F: Fn(T) -> MmResult, { - println!("HERE INNER"); - let wait_duration = Duration::from_secs(300); + // Send request + let active_topic = self.session.get_active_topic_or_err().await?; + let request = SessionRequestRequest { + chain_id: chain_id.to_string(), + request: SessionRequest { + method: method.as_ref().to_string(), + expiry: Some(Utc::now().timestamp() as u64 + 300), + params, + }, + }; + self.publish_request(&active_topic, RequestParams::SessionRequest(request)) + .await?; - while let Ok(Some(resp)) = timeout(wait_duration, self.message_rx.lock().await.next()).await { + // Wait for response + let wait_duration = Duration::from_secs(300); + if let Ok(Some(resp)) = self.message_rx.lock().await.next().timeout(wait_duration).await { let result = resp.mm_err(WalletConnectError::InternalError)?; if let ResponseParamsSuccess::Arbitrary(data) = result.data { let data = serde_json::from_value::(data)?; let response = ResponseParamsSuccess::SessionEvent(true); self.publish_response_ok(&result.topic, response, &result.message_id) .await?; - - return func(data); + return response_handler(data); } } + // Handle timeout/error + self.client.disconnect().await?; MmError::err(WalletConnectError::NoWalletFeedback) } } @@ -426,7 +452,6 @@ impl WalletConnectCtx { /// This function spwans related WalletConnect related tasks and needed initialization before /// WalletConnect can be usable in KDF. pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectError> { - info!("Initializing WalletConnect"); // Initialized WalletConnectCtx let wallet_connect = WalletConnectCtx::from_ctx(ctx)?; // Intialize storage. @@ -436,10 +461,17 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect ctx.spawner().spawn({ let this = wallet_connect.clone(); async move { + info!("Initializing WalletConnect connection"); connection_handler::initial_connection(&this).await; connection_handler::handle_disconnections(&this).await; } }); + + ctx.spawner().spawn({ + let this = wallet_connect.clone(); + keep_alive_ping(this) + }); + // spawn message handler event loop ctx.spawner().spawn(async move { let this = wallet_connect.clone(); @@ -451,8 +483,6 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect } }); - info!("WalletConnect initialization completed successfully"); - Ok(()) } From 0b1da0486271c688bc0f6adbbabfdb05a9d880e9 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 1 Nov 2024 05:01:38 +0100 Subject: [PATCH 089/125] remove debug log --- mm2src/kdf_walletconnect/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 92cc4cfa86..289c6a120d 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -121,7 +121,6 @@ impl WalletConnectCtx { pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectError> { from_ctx(&ctx.wallet_connect, move || { - println!("HERE AGAIN"); Self::try_init(ctx).map_err(|err| err.to_string()) }) .map_to_mm(WalletConnectError::InternalError) From f0659a4c5bb32914f5c55b53f0b443588eefcd73 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 1 Nov 2024 19:47:53 +0100 Subject: [PATCH 090/125] connection_handler improvements --- .../src/connection_handler.rs | 59 ++++++++++++------- mm2src/kdf_walletconnect/src/lib.rs | 29 +++++---- mm2src/kdf_walletconnect/src/session.rs | 23 +------- .../src/session/rpc/settle.rs | 24 +++++++- .../mm2_main/src/rpc/wc_commands/sessions.rs | 4 +- 5 files changed, 82 insertions(+), 57 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 77c470eba0..0fda20e6a7 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use crate::{WalletConnectCtx, WalletConnectError}; use common::executor::Timer; @@ -7,8 +9,8 @@ use futures::StreamExt; use mm2_err_handle::prelude::*; use relay_client::error::ClientError; use relay_client::websocket::{CloseFrame, ConnectionHandler, PublishedMessage}; +use relay_rpc::domain::Topic; use relay_rpc::rpc::params::RequestParams; -use std::sync::Arc; use tokio::time::interval; use tokio::time::Duration; @@ -109,7 +111,7 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { loop { match this.connect_client().await { Ok(_) => { - if let Err(e) = resubscribe_to_topics(this).await { + if let Err(e) = resubscribe_to_topics(this, None).await { error!("Failed to resubscribe after reconnection: {:?}", e); } debug!("Reconnection process complete."); @@ -131,7 +133,8 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { /// This helps prevent connection drops as the relay server tends to disconnect inactive connections after 5 minutes. /// The ping interval is designed to catch potential disconnections before the server timeout while minimizing /// unnecessary network traffic. -pub(crate) async fn keep_alive_ping(ctx: Arc) { +pub(crate) async fn keep_session_alive_ping(ctx: Arc) { + info!("keep_session_alive_ping running"); let mut interval = interval(Duration::from_secs(PING_INTERVAL)); let mut backoff = 1.; @@ -139,9 +142,14 @@ pub(crate) async fn keep_alive_ping(ctx: Arc) { interval.tick().await; loop { + let Ok(session_topic) = ctx.session.get_active_topic_or_err().await else { + info!("No active session to ping will check again shortly"); + Timer::sleep(PING_INTERVAL as f64).await; + continue; + }; tokio::select! { _ = interval.tick() => { - match try_ping(&ctx).await { + match try_ping(&ctx, &session_topic).await { Ok(_) => { backoff = 1.; continue; @@ -149,8 +157,8 @@ pub(crate) async fn keep_alive_ping(ctx: Arc) { Err(e) => { error!("WalletConnect ping failed: {:?}. Attempting reconnect...", e); // Attempt reconnection with backoff - if let Err(reconnect_err) = handle_ping_failure(&ctx).await { - error!("Reconnection failed: {:?}", reconnect_err); + if let Err(reconnect_err) = handle_ping_failure(&ctx, &session_topic).await { + error!("{} Session reconnection failed: {:?}", session_topic, reconnect_err); // Increase backoff for next attempt backoff = std::cmp::min(backoff as u64 * 2, MAX_BACKOFF ) as f64; Timer::sleep(backoff).await; @@ -158,7 +166,7 @@ pub(crate) async fn keep_alive_ping(ctx: Arc) { } // Reset backoff after successful reconnection backoff = 1.; - debug!("Successfully reconnected after ping failure"); + debug!("{}: Successfully reconnected after ping failure", session_topic); } } } @@ -168,10 +176,9 @@ pub(crate) async fn keep_alive_ping(ctx: Arc) { /// Attempts to verify connection health with WalletConnect relay server by sending a ping message. /// Waits for a pong response with a specified timeout period. -async fn try_ping(ctx: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { - let active_topic = ctx.session.get_active_topic_or_err().await?; +async fn try_ping(ctx: &WalletConnectCtx, session_topic: &Topic) -> MmResult<(), WalletConnectError> { let param = RequestParams::SessionPing(()); - ctx.publish_request(&active_topic, param).await?; + ctx.publish_request(session_topic, param).await?; let timeout = Timer::sleep(PING_TIMEOUT); tokio::pin!(timeout); @@ -181,12 +188,12 @@ async fn try_ping(ctx: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { msg = recv.next() => { match msg { Some(Ok(_)) => { - debug!("WalletConnect Session Is Alive"); + debug!("WalletConnect {}: Session is alive", session_topic); Ok(()) }, Some(Err(err)) => { MmError::err(WalletConnectError::InternalError( - format!("WalletConnect Ping Error: {err:?}") + format!("WalletConnect {}: Ping Error: {err:?}", session_topic) )) }, None => { @@ -198,7 +205,7 @@ async fn try_ping(ctx: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { } }, _ = timeout => { - error!("WalletConnect Ping timeout"); + error!("WalletConnect {}: Ping timeout", session_topic); MmError::err(WalletConnectError::InternalError( "WalletConnect Ping timeout".into() )) @@ -207,22 +214,32 @@ async fn try_ping(ctx: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { } // Handle reconnection after ping failure -async fn handle_ping_failure(ctx: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { - // Attempt to disconnect client - ctx.client.disconnect().await?; +async fn handle_ping_failure(ctx: &WalletConnectCtx, session_topic: &Topic) -> MmResult<(), WalletConnectError> { // Attempt to reconnect ctx.connect_client().await?; // Resubscribe to topics if needed - resubscribe_to_topics(ctx).await?; + resubscribe_to_topics(ctx, Some(session_topic)).await?; // Verify connection with a new ping - try_ping(ctx).await + try_ping(ctx, session_topic).await } /// Resubscribes to previously active topics after reconnection. /// Called by handle_disconnections to restore subscription state. -async fn resubscribe_to_topics(this: &WalletConnectCtx) -> MmResult<(), WalletConnectError> { - let subs = this.subscriptions.lock().await; - this.client.batch_subscribe(&**subs).await?; +async fn resubscribe_to_topics(this: &WalletConnectCtx, topic: Option<&Topic>) -> MmResult<(), WalletConnectError> { + if let Some(topic) = topic { + if let Some(session) = this.session.get_session(topic) { + this.client + .batch_subscribe(vec![session.topic.clone(), session.pairing_topic.clone()]) + .await?; + return Ok(()); + } + } + let sessions = this.session.get_sessions(); + for session in sessions { + this.client + .batch_subscribe(vec![session.topic.into(), session.pairing_topic.into()]) + .await?; + } Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 289c6a120d..86298d9df8 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -7,7 +7,7 @@ mod metadata; pub mod session; mod storage; -use crate::connection_handler::keep_alive_ping; +use crate::connection_handler::keep_session_alive_ping; use crate::session::rpc::propose::send_proposal_request; use chain::{WcChainId, WcRequestMethods, SUPPORTED_PROTOCOL}; @@ -105,11 +105,11 @@ impl WalletConnectCtx { Ok(Self { client, pairing, - session: SessionManager::new(), relay, + storage, metadata: generate_metadata(), key_pair: SymKeyPair::new(), - storage, + session: SessionManager::new(), subscriptions: Default::default(), inbound_message_rx: Arc::new(msg_receiver.into()), @@ -233,7 +233,7 @@ impl WalletConnectCtx { self.session.add_session(session).await; // subcribe to session topics - self.client.batch_subscribe(vec![topic, pairing_topic]).await?; + self.client.batch_subscribe(vec![topic.clone(), pairing_topic]).await?; } Ok(()) @@ -446,6 +446,17 @@ impl WalletConnectCtx { self.client.disconnect().await?; MmError::err(WalletConnectError::NoWalletFeedback) } + + pub async fn drop_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { + self.client.unsubscribe(topic.clone()).await?; + self.session.delete_session(topic).await; + self.storage + .delete_session(topic) + .await + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; + + Ok(()) + } } /// This function spwans related WalletConnect related tasks and needed initialization before @@ -466,17 +477,13 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect } }); - ctx.spawner().spawn({ - let this = wallet_connect.clone(); - keep_alive_ping(this) - }); + ctx.spawner().spawn(keep_session_alive_ping(wallet_connect.clone())); // spawn message handler event loop ctx.spawner().spawn(async move { - let this = wallet_connect.clone(); - let mut recv = this.inbound_message_rx.lock().await; + let mut recv = wallet_connect.inbound_message_rx.lock().await; while let Some(msg) = recv.next().await { - if let Err(e) = this.handle_published_message(msg).await { + if let Err(e) = wallet_connect.clone().handle_published_message(msg).await { info!("Error processing message: {:?}", e); } } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 82dcda023d..31bf9bce6f 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,15 +1,15 @@ pub(crate) mod key; pub mod rpc; -use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; use common::log::debug; +use dashmap::mapref::multiple::RefMulti; use dashmap::mapref::one::{Ref, RefMut}; use dashmap::DashMap; use key::SessionKey; -use mm2_err_handle::prelude::{MapMmError, MmError, MmResult}; +use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::domain::Topic; use relay_rpc::rpc::params::session::Namespace; use relay_rpc::rpc::params::session_propose::Proposer; @@ -260,15 +260,8 @@ impl SessionManager { removed_session } - /// Retrieves a cloned session associated with a given topic. pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { let mut active_topic = self.0.active_topic.lock().await; - if let Some(this) = active_topic.as_mut() { - if topic == this { - return Ok(()); - }; - } - if let Some(session) = self.get_session(topic) { *active_topic = Some(session.topic.clone()); return Ok(()); @@ -312,6 +305,7 @@ impl SessionManager { }) } + pub(crate) fn get_sessions_full(&self) -> impl Iterator> { self.0.sessions.iter() } /// Updates the expiry time of the session associated with the given topic to the specified timestamp. /// If the session does not exist, this method does nothing. pub(crate) fn extend_session(&self, topic: &Topic, till: u64) { @@ -356,17 +350,6 @@ impl SessionManager { } } -pub async fn disconnect_session_rpc(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { - ctx.client.unsubscribe(topic.clone()).await?; - ctx.session.delete_session(topic).await; - ctx.storage - .delete_session(topic) - .await - .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; - - Ok(()) -} - #[cfg(test)] mod tests { use super::*; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 98ca7cd39b..0356954672 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -2,7 +2,7 @@ use crate::session::{Session, SessionProperties}; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, WalletConnectCtx}; -use common::log::info; +use common::log::{debug, info}; use mm2_err_handle::prelude::{MapMmError, MmResult}; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_settle::SessionSettleRequest, ResponseParamsSuccess}}; @@ -52,18 +52,36 @@ pub(crate) async fn reply_session_settle_request( let session_properties = serde_json::from_str::(&value.to_string())?; session.session_properties = Some(session_properties); } + // Update storage session. ctx.storage .update_session(&session) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; - } + }; } - info!("Session successfully settled for topic: {:?}", topic); let param = ResponseParamsSuccess::SessionSettle(true); ctx.publish_response_ok(topic, param, message_id).await?; + // Delete other sessions with same controller + let all_sessions = ctx.session.get_sessions_full(); + for session in all_sessions { + if session.controller == settle.controller && session.topic.as_ref() != topic.as_ref() { + ctx.client.unsubscribe(session.topic.clone()).await?; + ctx.client.unsubscribe(session.pairing_topic.clone()).await?; + ctx.storage + .delete_session(&session.topic.clone()) + .await + .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; + + // Optionally: Remove from active sessions in memory too + ctx.session.delete_session(&session.topic).await; + ctx.drop_session(&session.topic).await?; + debug!("Deleted previous session with topic: {:?}", session.topic); + } + } + Ok(()) } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 38b19d4a8a..55be302eda 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -1,5 +1,5 @@ +use kdf_walletconnect::session::rpc::send_session_ping_request; use kdf_walletconnect::session::SessionRpcInfo; -use kdf_walletconnect::session::{disconnect_session_rpc, rpc::send_session_ping_request}; use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::MmArc; use mm2_err_handle::prelude::*; @@ -75,7 +75,7 @@ pub async fn disconnect_session( ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - disconnect_session_rpc(&ctx, &req.topic.into()) + ctx.drop_session(&req.topic.into()) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; From 187bf5edc66de7dd48a65c6ad551ad84d749c746 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 2 Nov 2024 07:26:42 +0100 Subject: [PATCH 091/125] improve tendermint wc code --- mm2src/coins/eth/wallet_connect.rs | 21 ++- mm2src/coins/tendermint/tendermint_coin.rs | 197 ++++++++------------- mm2src/coins/tendermint/wallet_connect.rs | 81 ++++++--- mm2src/kdf_walletconnect/src/error.rs | 2 + mm2src/kdf_walletconnect/src/lib.rs | 64 +++---- 5 files changed, 185 insertions(+), 180 deletions(-) diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 72b5d66830..7426a917d3 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -102,7 +102,14 @@ impl WalletConnectOps for EthCoin { type SendTxData = (SignedTransaction, BytesJson); type Params<'a> = WcEthTxParams<'a>; - fn wc_chain_id(&self) -> WcChainId { WcChainId::new_eip155(self.chain_id.to_string()) } + async fn wc_chain_id(&self, ctx: &WalletConnectCtx) -> Result { + let chain = WcChainId::new_eip155(self.chain_id.to_string()); + if ctx.is_chain_supported(&chain).await { + return MmError::err(WalletConnectError::ChainIdNotSupported(chain.to_string()).into()); + }; + + Ok(chain) + } async fn wc_sign_tx<'a>( &self, @@ -110,9 +117,10 @@ impl WalletConnectOps for EthCoin { params: Self::Params<'a>, ) -> Result { let bytes = { + let chain_id = self.wc_chain_id(ctx).await?; let tx_json = params.prepare_wc_tx_format()?; let tx_hex: String = ctx - .send_session_request_and_wait(&self.wc_chain_id(), WcRequestMethods::EthSignTransaction, tx_json, Ok) + .send_session_request_and_wait(&chain_id, WcRequestMethods::EthSignTransaction, tx_json, Ok) .await?; // First 4 bytes from WalletConnect represents Protoc info hex::decode(&tx_hex[4..])? @@ -131,8 +139,9 @@ impl WalletConnectOps for EthCoin { params: Self::Params<'a>, ) -> Result { let tx_hash: String = { + let chain_id = self.wc_chain_id(ctx).await?; let tx_json = params.prepare_wc_tx_format()?; - ctx.send_session_request_and_wait(&self.wc_chain_id(), WcRequestMethods::EthSendTransaction, tx_json, Ok) + ctx.send_session_request_and_wait(&chain_id, WcRequestMethods::EthSendTransaction, tx_json, Ok) .await? }; let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); @@ -169,8 +178,10 @@ pub async fn eth_request_wc_personal_sign( ctx: &WalletConnectCtx, chain_id: u64, ) -> MmResult<(H520, Address), EthWalletConnectError> { - let chain_id = chain_id.to_string(); - let chain_id = WcChainId::new_eip155(chain_id); + let chain_id = WcChainId::new_eip155(chain_id.to_string()); + if ctx.is_chain_supported(&chain_id).await { + return MmError::err(WalletConnectError::ChainIdNotSupported(chain_id.to_string()).into()); + }; let result = { let account_str = ctx.get_account_for_chain_id(&chain_id).await?; diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index ef8d6407a8..beeccefc38 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -3,7 +3,6 @@ use super::htlc::{ClaimHtlcMsg, ClaimHtlcProto, CreateHtlcMsg, CreateHtlcProto, QueryHtlcResponse, TendermintHtlc, HTLC_STATE_COMPLETED, HTLC_STATE_OPEN, HTLC_STATE_REFUNDED}; use super::ibc::transfer_v1::MsgTransfer; use super::ibc::IBC_GAS_LIMIT_DEFAULT; -use super::wallet_connect::{cosmos_request_wc_signed_tx, CosmosTxSignedData}; use super::{rpc::*, TENDERMINT_COIN_PROTOCOL_TYPE}; use crate::coin_errors::{MyAddressError, ValidatePaymentError, ValidatePaymentResult}; use crate::hd_wallet::{HDPathAccountToAddressId, WithdrawFrom}; @@ -64,8 +63,6 @@ use futures01::Future; use hex::FromHexError; use instant::Duration; use itertools::Itertools; -use kdf_walletconnect::chain::WcChainId; -use kdf_walletconnect::error::WalletConnectError; use kdf_walletconnect::{WalletConnectCtx, WalletConnectOps}; use keys::{KeyPair, Public}; use mm2_core::mm_ctx::{MmArc, MmWeak}; @@ -383,7 +380,7 @@ pub struct TendermintCoinImpl { pub(super) activation_policy: TendermintActivationPolicy, pub(crate) decimals: u8, pub(super) denom: Denom, - chain_id: ChainId, + pub(crate) chain_id: ChainId, gas_price: Option, pub tokens_info: PaMutex>, /// This spawner is used to spawn coin's related futures that should be aborted on coin deactivation @@ -868,39 +865,24 @@ impl TendermintCoin { .await ) }, - TendermintActivationPolicy::PublicKey(_) => match self.wallet_type { - // TODO implement ledger tx signing for WC. - TendermintWalletConnectionType::WcLedger | TendermintWalletConnectionType::Wc => try_tx_s!( - self.seq_safe_send_raw_tx_bytes(tx_payload, fee, timeout_height, memo) - .timeout(expiration) - .await - ), - _ => try_tx_s!( + TendermintActivationPolicy::PublicKey(_) => { + if self.is_wallet_connect() { + return try_tx_s!( + self.seq_safe_send_raw_tx_bytes(tx_payload, fee, timeout_height, memo) + .timeout(expiration) + .await + ); + }; + + try_tx_s!( self.send_unsigned_tx_externally(tx_payload, fee, timeout_height, memo, expiration) .timeout(expiration) .await - ), + ) }, } } - async fn wc_signed_tx(&self, tx_json: serde_json::Value) -> Result { - let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); - let wc = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| ERRL!("{}", e))); - - let response = try_tx_s!(self.wc_sign_tx(&wc, tx_json).await); - let signature = try_tx_s!(general_purpose::STANDARD - .decode(response.signature.signature) - .map_err(|e| ERRL!("{}", e))); - - Ok(TxRaw { - body_bytes: response.signed.body_bytes, - auth_info_bytes: response.signed.auth_info_bytes, - signatures: vec![signature], - } - .into()) - } - async fn get_tx_raw( &self, account_info: &BaseAccount, @@ -909,30 +891,28 @@ impl TendermintCoin { timeout_height: u64, memo: String, ) -> Result { - match self.wallet_type { - TendermintWalletConnectionType::Wc | TendermintWalletConnectionType::WcLedger => { - // Handle WalletConnect signing - let SerializedUnsignedTx { tx_json, .. } = if self.is_ledger_connection() { - try_tx_s!(self.any_to_legacy_amino_json(account_info, tx_payload, fee, timeout_height, memo)) - } else { - try_tx_s!(self.any_to_serialized_sign_doc(account_info, tx_payload, fee, timeout_height, memo)) - }; + if self.is_wallet_connect() { + let ctx = try_tx_s!(MmArc::from_weak(&self.ctx).ok_or(ERRL!("ctx must be initialized already"))); + let wc = try_tx_s!(WalletConnectCtx::from_ctx(&ctx).map_err(|e| e.to_string())); + let SerializedUnsignedTx { tx_json, .. } = if self.is_ledger_connection() { + try_tx_s!(self.any_to_legacy_amino_json(account_info, tx_payload, fee, timeout_height, memo)) + } else { + try_tx_s!(self.any_to_serialized_sign_doc(account_info, tx_payload, fee, timeout_height, memo)) + }; - self.wc_signed_tx(tx_json).await - }, - _ => { - // Handle local signing - let tx_raw = try_tx_s!(self.any_to_signed_raw_tx( - try_tx_s!(self.activation_policy.activated_key_or_err()), - account_info, - tx_payload, - fee, - timeout_height, - memo, - )); - Ok(tx_raw) - }, + return Ok(try_tx_s!(self.wc_sign_tx(&wc, tx_json).await.map_err(|err| err.to_string())).into()); } + + let tx_raw = try_tx_s!(self.any_to_signed_raw_tx( + try_tx_s!(self.activation_policy.activated_key_or_err()), + account_info, + tx_payload, + fee, + timeout_height, + memo, + )); + + Ok(tx_raw) } async fn seq_safe_send_raw_tx_bytes( @@ -1289,24 +1269,18 @@ impl TendermintCoin { )); }; - if let TendermintWalletConnectionType::Wc = self.wallet_type { + let SerializedUnsignedTx { tx_json, .. } = if self.is_ledger_connection() { + self.any_to_legacy_amino_json(account_info, message, fee, timeout_height, memo) + } else { + self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo) + }?; + + if self.is_wallet_connect() { let ctx = MmArc::from_weak(&self.ctx) .ok_or(MyAddressError::InternalError(ERRL!("ctx must be initialized already")))?; let wallet_connect = WalletConnectCtx::from_ctx(&ctx)?; - let SerializedUnsignedTx { tx_json, body_bytes: _ } = - self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo)?; - - let response = self.wc_sign_tx(&wallet_connect, tx_json).await?; - let signature = general_purpose::STANDARD.decode(response.signature.signature)?; - let body_bytes = response.signed.body_bytes; - let auth_info_bytes = response.signed.auth_info_bytes; - let tx_raw = TxRaw { - body_bytes, - auth_info_bytes, - signatures: vec![signature], - }; - let tx_raw: Raw = tx_raw.into(); + let tx_raw: Raw = self.wc_sign_tx(&wallet_connect, tx_json).await?.into(); let tx_bytes = tx_raw.to_bytes()?; let hash = sha256(&tx_bytes); @@ -1316,12 +1290,6 @@ impl TendermintCoin { )); }; - let SerializedUnsignedTx { tx_json, .. } = if self.is_ledger_connection() { - self.any_to_legacy_amino_json(account_info, message, fee, timeout_height, memo) - } else { - self.any_to_serialized_sign_doc(account_info, message, fee, timeout_height, memo) - }?; - Ok(TransactionData::Unsigned(tx_json)) } @@ -1410,30 +1378,27 @@ impl TendermintCoin { let auth_info = SignerInfo::single_direct(Some(pubkey), account_info.sequence).auth_info(fee); let sign_doc = SignDoc::new(&tx_body, &auth_info, &self.chain_id, account_info.account_number)?; - let tx_json = match self.wallet_type { - TendermintWalletConnectionType::Wc => { - // if wallet_type is WalletConnect, update tx_json to use WalletConnect type. - let my_address = self.my_address().unwrap(); - json!({ - "signerAddress": my_address, - "signDoc": { - "accountNumber": sign_doc.account_number.to_string(), - "chainId": sign_doc.chain_id, - "bodyBytes": general_purpose::STANDARD.encode(&sign_doc.body_bytes), - "authInfoBytes": general_purpose::STANDARD.encode(&sign_doc.auth_info_bytes) - } - }) - }, - _ => { - json!({ - "sign_doc": { - "body_bytes": &sign_doc.body_bytes, - "auth_info_bytes": sign_doc.auth_info_bytes, - "chain_id": sign_doc.chain_id, - "account_number": sign_doc.account_number, - } - }) - }, + let tx_json = if self.is_wallet_connect() { + // if wallet_type is WalletConnect, update tx_json to use WalletConnect type. + let my_address = self.my_address().unwrap(); + json!({ + "signerAddress": my_address, + "signDoc": { + "accountNumber": sign_doc.account_number.to_string(), + "chainId": sign_doc.chain_id, + "bodyBytes": general_purpose::STANDARD.encode(&sign_doc.body_bytes), + "authInfoBytes": general_purpose::STANDARD.encode(&sign_doc.auth_info_bytes) + } + }) + } else { + json!({ + "sign_doc": { + "body_bytes": &sign_doc.body_bytes, + "auth_info_bytes": sign_doc.auth_info_bytes, + "chain_id": sign_doc.chain_id, + "account_number": sign_doc.account_number, + } + }) }; Ok(SerializedUnsignedTx { @@ -1545,7 +1510,12 @@ impl TendermintCoin { }); (json, body_bytes) }, - _ => unreachable!(), + _ => { + return Err(ErrorReport::new(io::Error::new( + io::ErrorKind::InvalidInput, + "Only WalletConnect activated with Ledger can call this funciton", + ))) + }, }; Ok(SerializedUnsignedTx { tx_json, body_bytes }) @@ -2245,6 +2215,13 @@ impl TendermintCoin { TendermintWalletConnectionType::WcLedger | TendermintWalletConnectionType::KeplrLedger ) } + + pub fn is_wallet_connect(&self) -> bool { + matches!( + self.wallet_type, + TendermintWalletConnectionType::WcLedger | TendermintWalletConnectionType::Wc + ) + } } fn clients_from_urls(ctx: &MmArc, nodes: Vec) -> MmResult, TendermintInitErrorKind> { @@ -3475,32 +3452,6 @@ fn parse_expected_sequence_number(e: &str) -> MmResult; - type Params<'a> = serde_json::Value; - type SignTxData = CosmosTxSignedData; - type SendTxData = CosmosTransaction; - - fn wc_chain_id(&self) -> WcChainId { WcChainId::new_cosmos(self.chain_id.to_string()) } - - async fn wc_sign_tx<'a>( - &self, - ctx: &WalletConnectCtx, - params: Self::Params<'a>, - ) -> Result { - cosmos_request_wc_signed_tx(ctx, params, &self.wc_chain_id(), self.is_ledger_connection()).await - } - - async fn wc_send_tx<'a>( - &self, - _ctx: &WalletConnectCtx, - _params: Self::Params<'a>, - ) -> Result { - todo!() - } -} - #[cfg(test)] pub mod tendermint_falsecoin_tests { use super::*; diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 1570524128..1cc2ed564b 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -1,13 +1,17 @@ use base64::engine::general_purpose; use base64::Engine; +use cosmrs::proto::cosmos::tx::v1beta1::TxRaw; use kdf_walletconnect::chain::WcChainId; use kdf_walletconnect::error::WalletConnectError; +use kdf_walletconnect::WalletConnectOps; use kdf_walletconnect::{chain::WcRequestMethods, WalletConnectCtx}; use mm2_err_handle::prelude::*; use serde::{Deserialize, Serialize}; use serde_json::Value; use std::str::FromStr; +use super::{CosmosTransaction, TendermintCoin}; + #[derive(Debug, Serialize, Deserialize, PartialEq)] pub struct CosmosTxSignedData { pub signature: CosmosTxSignature, @@ -38,21 +42,6 @@ pub struct CosmosSignData { pub body_bytes: Vec, } -pub async fn cosmos_request_wc_signed_tx( - ctx: &WalletConnectCtx, - sign_doc: Value, - chain_id: &WcChainId, - is_ledger_conn: bool, -) -> MmResult { - let method = if is_ledger_conn { - WcRequestMethods::CosmosSignAmino - } else { - WcRequestMethods::CosmosSignDirect - }; - - ctx.send_session_request_and_wait(chain_id, method, sign_doc, Ok).await -} - #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] pub enum CosmosAccountAlgo { #[serde(rename = "secp256k1")] @@ -83,21 +72,71 @@ pub struct CosmosAccount { pub is_ledger: Option, } +#[async_trait::async_trait] +impl WalletConnectOps for TendermintCoin { + type Error = MmError; + type Params<'a> = serde_json::Value; + type SignTxData = TxRaw; + type SendTxData = CosmosTransaction; + + async fn wc_chain_id(&self, wc: &WalletConnectCtx) -> Result { + let chain = WcChainId::new_cosmos(self.chain_id.to_string()); + if !wc.is_chain_supported(&chain).await { + return MmError::err(WalletConnectError::ChainIdNotSupported(chain.to_string())); + }; + + Ok(chain) + } + + async fn wc_sign_tx<'a>( + &self, + wc: &WalletConnectCtx, + params: Self::Params<'a>, + ) -> Result { + let chain_id = self.wc_chain_id(wc).await?; + let method = if wc.is_ledger_connection().await { + WcRequestMethods::CosmosSignAmino + } else { + WcRequestMethods::CosmosSignDirect + }; + + wc.send_session_request_and_wait(&chain_id, method, params, |data: CosmosTxSignedData| { + let signature = general_purpose::STANDARD + .decode(data.signature.signature) + .map_to_mm(|err| WalletConnectError::PayloadError(err.to_string()))?; + Ok(TxRaw { + body_bytes: data.signed.body_bytes, + auth_info_bytes: data.signed.auth_info_bytes, + signatures: vec![signature], + }) + }) + .await + } + + async fn wc_send_tx<'a>( + &self, + _ctx: &WalletConnectCtx, + _params: Self::Params<'a>, + ) -> Result { + todo!() + } +} + pub async fn cosmos_get_accounts_impl( - ctx: &WalletConnectCtx, + wc: &WalletConnectCtx, chain_id: &str, ) -> MmResult { let chain_id = WcChainId::new_cosmos(chain_id.to_string()); - ctx.validate_or_update_active_chain_id(&chain_id).await?; + wc.validate_or_update_active_chain_id(&chain_id).await?; - let account = ctx.get_account_for_chain_id(&chain_id).await?; - let session = ctx + let account = wc.get_account_for_chain_id(&chain_id).await?; + let session = wc .session .get_session_active() .await .ok_or(WalletConnectError::NotInitialized)?; - // Check if existing session has session_properties and return wallet account; + // Check iexisting session has session_properties and return wallet account; if let Some(props) = &session.session_properties { if let Some(keys) = &props.keys { if let Some(key) = keys.iter().next() { @@ -123,7 +162,7 @@ pub async fn cosmos_get_accounts_impl( } let params = serde_json::to_value(&account).unwrap(); - ctx.send_session_request_and_wait( + wc.send_session_request_and_wait( &chain_id, WcRequestMethods::CosmosGetAccounts, params, diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index cc0a75ac85..7ba56ac29c 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -88,6 +88,8 @@ pub enum WalletConnectError { NoWalletFeedback, #[error("Invalid ChainId Error: {0}")] InvalidChainId(String), + #[error("ChainId not supported: {0}")] + ChainIdNotSupported(String), } impl From> for WalletConnectError { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 86298d9df8..2876c4ce84 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -13,7 +13,7 @@ use crate::session::rpc::propose::send_proposal_request; use chain::{WcChainId, WcRequestMethods, SUPPORTED_PROTOCOL}; use chrono::Utc; use common::custom_futures::timeout::FutureTimerExt; -use common::log::info; +use common::log::{debug, info}; use common::{executor::SpawnFuture, log::error}; use connection_handler::Handler; use error::WalletConnectError; @@ -50,7 +50,7 @@ pub trait WalletConnectOps { type SignTxData; type SendTxData; - fn wc_chain_id(&self) -> WcChainId; + async fn wc_chain_id(&self, ctx: &WalletConnectCtx) -> Result; async fn wc_sign_tx<'a>( &self, @@ -66,7 +66,7 @@ pub trait WalletConnectOps { } pub struct WalletConnectCtx { - pub client: Client, + pub client: Arc, pub pairing: PairingClient, pub session: SessionManager, @@ -96,7 +96,7 @@ impl WalletConnectCtx { let storage = SessionStorageDb::init(ctx)?; - let client = Client::new_unmanaged(); + let client = Arc::new(Client::new_unmanaged()); ctx.spawner().spawn(client_event_loop( client.control_rx().expect("client controller should never fail!"), Handler::new("Komodefi", msg_sender, conn_live_sender), @@ -189,19 +189,18 @@ impl WalletConnectCtx { async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectError> { let message = { let key = self.sym_key(&msg.topic).await?; - decode_and_decrypt_type0(msg.message.as_bytes(), &key).unwrap() + decode_and_decrypt_type0(msg.message.as_bytes(), &key)? }; - info!("Inbound message payload={message}"); + debug!("Inbound message payload={message}"); - let payload: Payload = serde_json::from_str(&message)?; - - match payload { + match serde_json::from_str(&message)? { Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await, } - info!("Inbound message was handled successfully"); + debug!("Inbound message was handled successfully"); + Ok(()) } @@ -214,12 +213,13 @@ impl WalletConnectCtx { .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; + // bring last session to the back. sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); for session in sessions { // delete expired session if now > session.expiry { - info!("Session {} expired, trying to delete from storage", session.topic); + debug!("Session {} expired, trying to delete from storage", session.topic); if let Err(err) = self.storage.delete_session(&session.topic).await { error!("Unable to delete session: {:?} from storage", err); } @@ -229,10 +229,9 @@ impl WalletConnectCtx { let topic = session.topic.clone(); let pairing_topic = session.pairing_topic.clone(); - info!("Session found! activating :{}", topic); + debug!("Session found! activating :{}", topic); self.session.add_session(session).await; - // subcribe to session topics self.client.batch_subscribe(vec![topic.clone(), pairing_topic]).await?; } @@ -245,13 +244,16 @@ impl WalletConnectCtx { topic: &Topic, param: RequestParams, ) -> MmResult<(), WalletConnectError> { + debug!("Outbound request message payload={param:?}"); + let irn_metadata = param.irn_metadata(); let message_id = MessageIdGenerator::new().next(); let request = Request::new(message_id, param.into()); + self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; - info!("Outbound request sent!"); + debug!("Outbound request sent!"); Ok(()) } @@ -266,6 +268,7 @@ impl WalletConnectCtx { let irn_metadata = result.irn_metadata(); let value = serde_json::to_value(result)?; let response = Response::Success(SuccessfulResponse::new(*message_id, value)); + self.publish_payload(topic, irn_metadata, Payload::Response(response)) .await?; @@ -282,6 +285,7 @@ impl WalletConnectCtx { let error = error_data.error(); let irn_metadata = error_data.irn_metadata(); let response = Response::Error(ErrorResponse::new(*message_id, error)); + self.publish_payload(topic, irn_metadata, Payload::Response(response)) .await?; @@ -295,25 +299,23 @@ impl WalletConnectCtx { irn_metadata: IrnMetadata, payload: Payload, ) -> MmResult<(), WalletConnectError> { - let sym_key = self.sym_key(topic).await?; - let payload = serde_json::to_string(&payload)?; - - info!("\n Sending Outbound request: {payload}!"); - - let message = encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key)?; - { - self.client - .publish( - topic.clone(), - message, - None, - irn_metadata.tag, - Duration::from_secs(irn_metadata.ttl), - irn_metadata.prompt, - ) - .await?; + let message = { + let sym_key = self.sym_key(topic).await?; + let payload = serde_json::to_string(&payload)?; + encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key)? }; + self.client + .publish( + topic.clone(), + message, + None, + irn_metadata.tag, + Duration::from_secs(irn_metadata.ttl), + irn_metadata.prompt, + ) + .await?; + Ok(()) } From 2a2f16764b3ba21eb7c10d4288e4ea56e33160e4 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 2 Nov 2024 08:40:53 +0100 Subject: [PATCH 092/125] use const_hex --- Cargo.lock | 57 ++++++++++++++++++- mm2src/kdf_walletconnect/Cargo.toml | 2 +- mm2src/kdf_walletconnect/src/error.rs | 2 +- mm2src/kdf_walletconnect/src/lib.rs | 2 +- mm2src/kdf_walletconnect/src/session.rs | 4 +- mm2src/kdf_walletconnect/src/session/key.rs | 2 +- .../src/session/rpc/propose.rs | 6 +- 7 files changed, 63 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index be8097c249..927e0f0635 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1077,6 +1077,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "const-hex" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0121754e84117e65f9d90648ee6aa4882a6e63110307ab73967a4c5e7e69e586" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "hex", + "proptest", + "serde", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -3132,12 +3145,12 @@ dependencies = [ "cfg-if 1.0.0", "chrono", "common", + "const-hex", "dashmap", "db_common", "derive_more", "enum_derives", "futures 0.3.28", - "hex", "hkdf", "js-sys", "mm2_core", @@ -4683,6 +4696,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg 1.1.0", + "libm", ] [[package]] @@ -5154,6 +5168,22 @@ dependencies = [ "syn 1.0.95", ] +[[package]] +name = "proptest" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c2511913b88df1637da85cc8d96ec8e43a3f8bb8ccb71ee1ac240d6f3df58d" +dependencies = [ + "bitflags 2.6.0", + "lazy_static", + "num-traits", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_xorshift 0.3.0", + "regex-syntax 0.8.5", + "unarray", +] + [[package]] name = "prost" version = "0.12.6" @@ -5356,7 +5386,7 @@ dependencies = [ "rand_jitter", "rand_os", "rand_pcg 0.1.2", - "rand_xorshift", + "rand_xorshift 0.1.1", "winapi", ] @@ -5529,6 +5559,15 @@ dependencies = [ "rand_core 0.3.1", ] +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core 0.6.4", +] + [[package]] name = "raw-cpuid" version = "10.4.0" @@ -5632,7 +5671,7 @@ checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" dependencies = [ "aho-corasick 1.0.2", "memchr", - "regex-syntax", + "regex-syntax 0.7.2", ] [[package]] @@ -5641,6 +5680,12 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "relay_client" version = "0.1.0" @@ -7700,6 +7745,12 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unexpected" version = "0.1.0" diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index b46301ca30..26e3ccc15a 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -9,6 +9,7 @@ async-trait = "0.1.52" base64 = "0.21.2" chrono = { version = "0.4.23", "features" = ["serde"] } common = { path = "../common" } +const-hex = "1.13.1" cfg-if = "1.0" db_common = { path = "../db_common" } derive_more = "0.99" @@ -17,7 +18,6 @@ futures = { version = "0.3", package = "futures", features = [ "compat", "async-await", ] } -hex = "0.4.2" hkdf = "0.12.4" dashmap = "6.1.0" mm2_core = { path = "../mm2_core" } diff --git a/mm2src/kdf_walletconnect/src/error.rs b/mm2src/kdf_walletconnect/src/error.rs index 7ba56ac29c..2a82b3ccf4 100644 --- a/mm2src/kdf_walletconnect/src/error.rs +++ b/mm2src/kdf_walletconnect/src/error.rs @@ -67,7 +67,7 @@ pub enum WalletConnectError { #[error("Request is not yet implemented")] NotImplemented, #[error("Hex Error: {0}")] - #[from_stringify("hex::FromHexError")] + #[from_stringify("const_hex::FromHexError")] HexError(String), #[error("Payload Error: {0}")] #[from_stringify("wc_common::PayloadError")] diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 2876c4ce84..b3927fd4b9 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -177,7 +177,7 @@ impl WalletConnectCtx { { let pairings = self.pairing.pairings.lock().await; if let Some(pairing) = pairings.get(topic.as_ref()) { - let key = hex::decode(pairing.sym_key.clone())?; + let key = const_hex::decode(pairing.sym_key.clone())?; return Ok(key); } } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 31bf9bce6f..e7b036e966 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -144,13 +144,13 @@ impl Session { let (proposer, controller) = match session_type { SessionType::Proposer => ( Proposer { - public_key: hex::encode(session_key.diffie_public_key()), + public_key: const_hex::encode(session_key.diffie_public_key()), metadata, }, Controller::default(), ), SessionType::Controller => (Proposer::default(), Controller { - public_key: hex::encode(session_key.diffie_public_key()), + public_key: const_hex::encode(session_key.diffie_public_key()), metadata, }), }; diff --git a/mm2src/kdf_walletconnect/src/session/key.rs b/mm2src/kdf_walletconnect/src/session/key.rs index 01f067d424..a2e87cd770 100644 --- a/mm2src/kdf_walletconnect/src/session/key.rs +++ b/mm2src/kdf_walletconnect/src/session/key.rs @@ -96,7 +96,7 @@ impl SessionKey { pub fn generate_topic(&self) -> String { let mut hasher = Sha256::new(); hasher.update(self.sym_key); - hex::encode(hasher.finalize()) + const_hex::encode(hasher.finalize()) } } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index fcccb6685d..0c949bda38 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -22,7 +22,7 @@ pub(crate) async fn send_proposal_request( ) -> MmResult<(), WalletConnectError> { let proposer = Proposer { metadata: ctx.metadata.clone(), - public_key: hex::encode(ctx.key_pair.public_key.as_bytes()), + public_key: const_hex::encode(ctx.key_pair.public_key.as_bytes()), }; let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], @@ -43,7 +43,7 @@ pub async fn reply_session_proposal_request( topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectError> { - let sender_public_key = hex::decode(&proposal.proposer.public_key)? + let sender_public_key = const_hex::decode(&proposal.proposer.public_key)? .as_slice() .try_into() .unwrap(); @@ -105,7 +105,7 @@ pub(crate) async fn process_session_propose_response( pairing_topic: &Topic, response: &SessionProposeResponse, ) -> MmResult<(), WalletConnectError> { - let other_public_key = hex::decode(&response.responder_public_key)? + let other_public_key = const_hex::decode(&response.responder_public_key)? .as_slice() .try_into() .unwrap(); From cd368bfb51dad9a10fc88c57c6d9b651008a8000 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 3 Nov 2024 04:54:10 +0100 Subject: [PATCH 093/125] major changes to connection handling and other minor fixes --- Cargo.lock | 1 + mm2src/coins/eth/wallet_connect.rs | 34 ++-- mm2src/coins/tendermint/wallet_connect.rs | 10 +- mm2src/kdf_walletconnect/Cargo.toml | 3 +- mm2src/kdf_walletconnect/src/chain.rs | 16 +- .../src/connection_handler.rs | 124 ++------------ mm2src/kdf_walletconnect/src/lib.rs | 157 ++++++++++-------- mm2src/kdf_walletconnect/src/session.rs | 52 +++--- .../src/session/rpc/event.rs | 91 +++++----- .../kdf_walletconnect/src/session/rpc/ping.rs | 14 +- .../src/session/rpc/propose.rs | 2 +- .../src/session/rpc/settle.rs | 2 +- .../src/session/rpc/update.rs | 2 +- .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 3 +- .../src/rpc/wc_commands/get_chain_id.rs | 21 --- .../mm2_main/src/rpc/wc_commands/sessions.rs | 5 +- .../src/rpc/wc_commands/wc_commands.rs | 2 - 17 files changed, 230 insertions(+), 309 deletions(-) delete mode 100644 mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs diff --git a/Cargo.lock b/Cargo.lock index 927e0f0635..9786e9034e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3158,6 +3158,7 @@ dependencies = [ "mm2_err_handle", "mm2_test_helpers", "pairing_api", + "parking_lot", "rand 0.8.5", "relay_client", "relay_rpc", diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 7426a917d3..d437dd7329 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -102,24 +102,22 @@ impl WalletConnectOps for EthCoin { type SendTxData = (SignedTransaction, BytesJson); type Params<'a> = WcEthTxParams<'a>; - async fn wc_chain_id(&self, ctx: &WalletConnectCtx) -> Result { - let chain = WcChainId::new_eip155(self.chain_id.to_string()); - if ctx.is_chain_supported(&chain).await { - return MmError::err(WalletConnectError::ChainIdNotSupported(chain.to_string()).into()); - }; + async fn wc_chain_id(&self, wc: &WalletConnectCtx) -> Result { + let chain_id = WcChainId::new_eip155(self.chain_id.to_string()); + wc.validate_update_active_chain_id(&chain_id).await?; - Ok(chain) + Ok(chain_id) } async fn wc_sign_tx<'a>( &self, - ctx: &WalletConnectCtx, + wc: &WalletConnectCtx, params: Self::Params<'a>, ) -> Result { let bytes = { - let chain_id = self.wc_chain_id(ctx).await?; + let chain_id = self.wc_chain_id(wc).await?; let tx_json = params.prepare_wc_tx_format()?; - let tx_hex: String = ctx + let tx_hex: String = wc .send_session_request_and_wait(&chain_id, WcRequestMethods::EthSignTransaction, tx_json, Ok) .await?; // First 4 bytes from WalletConnect represents Protoc info @@ -135,13 +133,13 @@ impl WalletConnectOps for EthCoin { async fn wc_send_tx<'a>( &self, - ctx: &WalletConnectCtx, + wc: &WalletConnectCtx, params: Self::Params<'a>, ) -> Result { let tx_hash: String = { - let chain_id = self.wc_chain_id(ctx).await?; + let chain_id = self.wc_chain_id(wc).await?; let tx_json = params.prepare_wc_tx_format()?; - ctx.send_session_request_and_wait(&chain_id, WcRequestMethods::EthSendTransaction, tx_json, Ok) + wc.send_session_request_and_wait(&chain_id, WcRequestMethods::EthSendTransaction, tx_json, Ok) .await? }; let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); @@ -175,20 +173,18 @@ impl WalletConnectOps for EthCoin { } pub async fn eth_request_wc_personal_sign( - ctx: &WalletConnectCtx, + wc: &WalletConnectCtx, chain_id: u64, ) -> MmResult<(H520, Address), EthWalletConnectError> { let chain_id = WcChainId::new_eip155(chain_id.to_string()); - if ctx.is_chain_supported(&chain_id).await { - return MmError::err(WalletConnectError::ChainIdNotSupported(chain_id.to_string()).into()); - }; + wc.validate_update_active_chain_id(&chain_id).await?; let result = { - let account_str = ctx.get_account_for_chain_id(&chain_id).await?; + let account_str = wc.get_account_for_chain_id(&chain_id).await?; let message = "Authenticate with Komodefi"; let message_hex = format!("0x{}", hex::encode(message)); let params = json!(&[&message_hex, &account_str]); - ctx.send_session_request_and_wait(&chain_id, WcRequestMethods::PersonalSign, params, |data: String| { + wc.send_session_request_and_wait(&chain_id, WcRequestMethods::PersonalSign, params, |data: String| { Ok(extract_pubkey_from_signature(&data, message, &account_str)?) }) .await? @@ -255,7 +251,6 @@ pub(crate) async fn send_transaction_with_walletconnect( coin.get_swap_pay_for_gas_option(coin.get_swap_transaction_fee_policy()) .await ); - let (nonce, _) = try_tx_s!(coin.clone().get_addr_nonce(address).compat().await); let params = WcEthTxParams { gas, @@ -268,6 +263,7 @@ pub(crate) async fn send_transaction_with_walletconnect( }; // Please note that this method may take a long time // due to `eth_sendTransaction` requests. + info!(target: "sign-and-send", "wallet signing and sending tx…"); let (signed_tx, _) = try_tx_s!(coin.wc_send_tx(wc, params).await); Ok(signed_tx) diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 1cc2ed564b..432881ee53 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -80,12 +80,10 @@ impl WalletConnectOps for TendermintCoin { type SendTxData = CosmosTransaction; async fn wc_chain_id(&self, wc: &WalletConnectCtx) -> Result { - let chain = WcChainId::new_cosmos(self.chain_id.to_string()); - if !wc.is_chain_supported(&chain).await { - return MmError::err(WalletConnectError::ChainIdNotSupported(chain.to_string())); - }; + let chain_id = WcChainId::new_cosmos(self.chain_id.to_string()); + wc.validate_update_active_chain_id(&chain_id).await?; - Ok(chain) + Ok(chain_id) } async fn wc_sign_tx<'a>( @@ -127,7 +125,7 @@ pub async fn cosmos_get_accounts_impl( chain_id: &str, ) -> MmResult { let chain_id = WcChainId::new_cosmos(chain_id.to_string()); - wc.validate_or_update_active_chain_id(&chain_id).await?; + wc.validate_update_active_chain_id(&chain_id).await?; let account = wc.get_account_for_chain_id(&chain_id).await?; let session = wc diff --git a/mm2src/kdf_walletconnect/Cargo.toml b/mm2src/kdf_walletconnect/Cargo.toml index 26e3ccc15a..e863d523f3 100644 --- a/mm2src/kdf_walletconnect/Cargo.toml +++ b/mm2src/kdf_walletconnect/Cargo.toml @@ -23,17 +23,18 @@ dashmap = "6.1.0" mm2_core = { path = "../mm2_core" } mm2_db = { path = "../mm2_db" } mm2_err_handle = { path = "../mm2_err_handle" } +parking_lot = { version = "0.12.0", features = ["nightly"] } pairing_api = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } rand = "0.8" relay_client = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } relay_rpc = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } -sha2 = "0.10.7" thiserror = "1.0.40" tokio = { version = "1.20" } wc_common = { git = "https://github.com/komodoplatform/walletconnectrust", branch = "pairing-api" } secp256k1 = { version = "0.20" } serde = { version = "1.0", features = ["derive"] } serde_json = { version = "1", features = ["preserve_order", "raw_value"] } +sha2 = "0.10.7" x25519-dalek = { version = "2.0", features = ["static_secrets"] } [target.'cfg(target_arch = "wasm32")'.dependencies] diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index f6125d9dcc..d1b2361d50 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -1,5 +1,6 @@ use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; +use serde::{Deserialize, Serialize}; use std::{collections::{BTreeMap, BTreeSet}, str::FromStr}; @@ -14,7 +15,7 @@ pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "pers pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:137"]; pub(crate) const ETH_SUPPORTED_EVENTS: &[&str] = &["accountsChanged", "chainChanged"]; -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct WcChainId { pub chain: WcChain, pub id: String, @@ -52,11 +53,9 @@ impl WcChainId { id: sp[1].to_owned(), }) } - - pub(crate) fn chain_id_from_id(&self, id: &str) -> String { format!("{}:{}", self.chain.as_ref(), id) } } -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum WcChain { Eip155, Cosmos, @@ -84,6 +83,15 @@ impl AsRef for WcChain { } } +impl WcChain { + pub(crate) fn derive_chain_id(&self, id: String) -> WcChainId { + WcChainId { + chain: self.clone(), + id, + } + } +} + #[derive(Debug, Clone)] pub enum WcRequestMethods { CosmosSignDirect, diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 0fda20e6a7..506a5349bb 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -1,24 +1,20 @@ use std::sync::Arc; +use crate::storage::WalletConnectStorageOps; use crate::{WalletConnectCtx, WalletConnectError}; use common::executor::Timer; -use common::log::{debug, error, info}; +use common::log::{error, info}; use futures::channel::mpsc::UnboundedSender; use futures::StreamExt; use mm2_err_handle::prelude::*; use relay_client::error::ClientError; use relay_client::websocket::{CloseFrame, ConnectionHandler, PublishedMessage}; use relay_rpc::domain::Topic; -use relay_rpc::rpc::params::RequestParams; -use tokio::time::interval; -use tokio::time::Duration; const INITIAL_RETRY_SECS: f64 = 5.0; -const RETRY_INCREMENT: f64 = 5.0; const MAX_BACKOFF: u64 = 60; -const PING_INTERVAL: u64 = 140; -const PING_TIMEOUT: f64 = 60.; +const RETRY_INCREMENT: f64 = 5.0; pub struct Handler { name: &'static str, @@ -76,7 +72,8 @@ impl ConnectionHandler for Handler { /// Establishes initial connection to WalletConnect relay server with linear retry mechanism. /// Uses increasing delay between retry attempts starting from INITIAL_RETRY_SECS. /// After successful connection, attempts to restore previous session state from storage. -pub(crate) async fn initial_connection(this: &WalletConnectCtx) { +pub(crate) async fn initialize_connection(this: Arc) { + info!("Initializing WalletConnect connection"); let mut retry_count = 0; let mut retry_secs = INITIAL_RETRY_SECS; @@ -90,12 +87,20 @@ pub(crate) async fn initial_connection(this: &WalletConnectCtx) { retry_secs += RETRY_INCREMENT; } - debug!("Successfully connected to client after {} attempt(s).", retry_count + 1); + info!("Successfully connected to client after {} attempt(s).", retry_count + 1); + + // Initialize storage + if let Err(err) = this.storage.init().await { + info!("Unable to initialize WalletConnect persistent storage: {err:?}. Only inmemory storage will be utilized for this Session."); + }; // load session from storage if let Err(err) = this.load_session_from_storage().await { - error!("Unable to load session from storage: {err:?}"); + info!("Unable to load session from storage: {err:?}"); }; + + // Spawn session disconnection watcher. + handle_disconnections(&this).await; } /// Handles unexpected disconnections from WalletConnect relay server. @@ -106,7 +111,7 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { let mut backoff = 1; while let Some(_msg) = recv.next().await { - debug!("Connection disconnected. Attempting to reconnect..."); + info!("Connection disconnected. Attempting to reconnect..."); loop { match this.connect_client().await { @@ -114,7 +119,7 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { if let Err(e) = resubscribe_to_topics(this, None).await { error!("Failed to resubscribe after reconnection: {:?}", e); } - debug!("Reconnection process complete."); + info!("Reconnection process complete."); backoff = 1; break; }, @@ -128,101 +133,6 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { } } -/// Maintains connection health with WalletConnect relay server through periodic pings. -/// Sends a ping every 4 minutes to proactively detect disconnections and automatically reconnects if needed. -/// This helps prevent connection drops as the relay server tends to disconnect inactive connections after 5 minutes. -/// The ping interval is designed to catch potential disconnections before the server timeout while minimizing -/// unnecessary network traffic. -pub(crate) async fn keep_session_alive_ping(ctx: Arc) { - info!("keep_session_alive_ping running"); - let mut interval = interval(Duration::from_secs(PING_INTERVAL)); - let mut backoff = 1.; - - // Skip the first tick which happens immediately - interval.tick().await; - - loop { - let Ok(session_topic) = ctx.session.get_active_topic_or_err().await else { - info!("No active session to ping will check again shortly"); - Timer::sleep(PING_INTERVAL as f64).await; - continue; - }; - tokio::select! { - _ = interval.tick() => { - match try_ping(&ctx, &session_topic).await { - Ok(_) => { - backoff = 1.; - continue; - } - Err(e) => { - error!("WalletConnect ping failed: {:?}. Attempting reconnect...", e); - // Attempt reconnection with backoff - if let Err(reconnect_err) = handle_ping_failure(&ctx, &session_topic).await { - error!("{} Session reconnection failed: {:?}", session_topic, reconnect_err); - // Increase backoff for next attempt - backoff = std::cmp::min(backoff as u64 * 2, MAX_BACKOFF ) as f64; - Timer::sleep(backoff).await; - continue; - } - // Reset backoff after successful reconnection - backoff = 1.; - debug!("{}: Successfully reconnected after ping failure", session_topic); - } - } - } - } - } -} - -/// Attempts to verify connection health with WalletConnect relay server by sending a ping message. -/// Waits for a pong response with a specified timeout period. -async fn try_ping(ctx: &WalletConnectCtx, session_topic: &Topic) -> MmResult<(), WalletConnectError> { - let param = RequestParams::SessionPing(()); - ctx.publish_request(session_topic, param).await?; - - let timeout = Timer::sleep(PING_TIMEOUT); - tokio::pin!(timeout); - - let mut recv = ctx.message_rx.lock().await; - tokio::select! { - msg = recv.next() => { - match msg { - Some(Ok(_)) => { - debug!("WalletConnect {}: Session is alive", session_topic); - Ok(()) - }, - Some(Err(err)) => { - MmError::err(WalletConnectError::InternalError( - format!("WalletConnect {}: Ping Error: {err:?}", session_topic) - )) - }, - None => { - error!("WalletConnect Ping timeout"); - MmError::err(WalletConnectError::InternalError( - "WalletConnect Ping timeout".into() - )) - } - } - }, - _ = timeout => { - error!("WalletConnect {}: Ping timeout", session_topic); - MmError::err(WalletConnectError::InternalError( - "WalletConnect Ping timeout".into() - )) - } - } -} - -// Handle reconnection after ping failure -async fn handle_ping_failure(ctx: &WalletConnectCtx, session_topic: &Topic) -> MmResult<(), WalletConnectError> { - // Attempt to reconnect - ctx.connect_client().await?; - // Resubscribe to topics if needed - resubscribe_to_topics(ctx, Some(session_topic)).await?; - // Verify connection with a new ping - try_ping(ctx, session_topic).await -} - /// Resubscribes to previously active topics after reconnection. /// Called by handle_disconnections to restore subscription state. async fn resubscribe_to_topics(this: &WalletConnectCtx, topic: Option<&Topic>) -> MmResult<(), WalletConnectError> { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index b3927fd4b9..d4a3023485 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -7,15 +7,14 @@ mod metadata; pub mod session; mod storage; -use crate::connection_handler::keep_session_alive_ping; use crate::session::rpc::propose::send_proposal_request; use chain::{WcChainId, WcRequestMethods, SUPPORTED_PROTOCOL}; use chrono::Utc; use common::custom_futures::timeout::FutureTimerExt; -use common::log::{debug, info}; +use common::log::info; use common::{executor::SpawnFuture, log::error}; -use connection_handler::Handler; +use connection_handler::{initialize_connection, Handler}; use error::WalletConnectError; use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; use futures::lock::Mutex; @@ -30,12 +29,12 @@ use relay_client::{ConnectionOptions, MessageIdGenerator}; use relay_rpc::auth::{ed25519_dalek::SigningKey, AuthToken}; use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::params::session::Namespace; -use relay_rpc::rpc::params::session_event::{Event, SessionEventRequest}; use relay_rpc::rpc::params::session_request::SessionRequestRequest; use relay_rpc::rpc::params::{session_request::Request as SessionRequest, IrnMetadata, Metadata, Relay, RelayProtocolMetadata, RequestParams, ResponseParamsError, ResponseParamsSuccess}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; use serde::de::DeserializeOwned; +use session::Session; use session::{key::SymKeyPair, SessionManager}; use std::collections::BTreeSet; use std::{sync::Arc, time::Duration}; @@ -66,7 +65,7 @@ pub trait WalletConnectOps { } pub struct WalletConnectCtx { - pub client: Arc, + pub client: Client, pub pairing: PairingClient, pub session: SessionManager, @@ -96,7 +95,7 @@ impl WalletConnectCtx { let storage = SessionStorageDb::init(ctx)?; - let client = Arc::new(Client::new_unmanaged()); + let client = Client::new_unmanaged(); ctx.spawner().spawn(client_event_loop( client.control_rx().expect("client controller should never fail!"), Handler::new("Komodefi", msg_sender, conn_live_sender), @@ -192,14 +191,14 @@ impl WalletConnectCtx { decode_and_decrypt_type0(msg.message.as_bytes(), &key)? }; - debug!("Inbound message payload={message}"); + info!("Inbound message payload={message}"); match serde_json::from_str(&message)? { Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await, } - debug!("Inbound message was handled successfully"); + info!("Inbound message was handled successfully"); Ok(()) } @@ -219,7 +218,7 @@ impl WalletConnectCtx { for session in sessions { // delete expired session if now > session.expiry { - debug!("Session {} expired, trying to delete from storage", session.topic); + info!("Session {} expired, trying to delete from storage", session.topic); if let Err(err) = self.storage.delete_session(&session.topic).await { error!("Unable to delete session: {:?} from storage", err); } @@ -229,7 +228,7 @@ impl WalletConnectCtx { let topic = session.topic.clone(); let pairing_topic = session.pairing_topic.clone(); - debug!("Session found! activating :{}", topic); + info!("Session found! activating :{}", topic); self.session.add_session(session).await; self.client.batch_subscribe(vec![topic.clone(), pairing_topic]).await?; @@ -244,8 +243,6 @@ impl WalletConnectCtx { topic: &Topic, param: RequestParams, ) -> MmResult<(), WalletConnectError> { - debug!("Outbound request message payload={param:?}"); - let irn_metadata = param.irn_metadata(); let message_id = MessageIdGenerator::new().next(); let request = Request::new(message_id, param.into()); @@ -253,7 +250,7 @@ impl WalletConnectCtx { self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; - debug!("Outbound request sent!"); + info!("Outbound request sent!"); Ok(()) } @@ -299,6 +296,7 @@ impl WalletConnectCtx { irn_metadata: IrnMetadata, payload: Payload, ) -> MmResult<(), WalletConnectError> { + info!("Publishing message={:?} to topic: {topic}", payload); let message = { let sym_key = self.sym_key(topic).await?; let payload = serde_json::to_string(&payload)?; @@ -316,6 +314,8 @@ impl WalletConnectCtx { ) .await?; + info!("Message published successfully"); + Ok(()) } @@ -325,7 +325,7 @@ impl WalletConnectCtx { self.session .get_session_active() .await - .and_then(|session| session.session_properties.clone()) + .and_then(|session| session.session_properties) .and_then(|props| props.keys.as_ref().cloned()) .and_then(|keys| keys.first().cloned()) .map(|key| key.is_nano_ledger) @@ -333,50 +333,80 @@ impl WalletConnectCtx { } /// Checks if a given chain ID is supported. - pub async fn is_chain_supported(&self, chain_id: &WcChainId) -> bool { - if let Some(session) = self.session.get_session_active().await { - if let Some(ns) = session.namespaces.get(chain_id.chain.as_ref()) { - if let Some(chains) = &ns.chains { - return chains.contains(&chain_id.to_string()); - } + pub(crate) async fn validate_chain_id( + &self, + session: &Session, + chain_id: &WcChainId, + ) -> MmResult<(), WalletConnectError> { + if let Some(ns) = session.namespaces.get(chain_id.chain.as_ref()) { + if let Some(chains) = &ns.chains { + if chains.contains(&chain_id.to_string()) { + return Ok(()); + }; } + } - // https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces - // #13-chains-might-be-omitted-if-the-caip-2-is-defined-in-the-index - if session.namespaces.contains_key(&chain_id.to_string()) { - return true; - } + // https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces + // #13-chains-might-be-omitted-if-the-caip-2-is-defined-in-the-index + if session.namespaces.contains_key(&chain_id.to_string()) { + return Ok(()); } - false + MmError::err(WalletConnectError::ChainIdNotSupported(chain_id.to_string())) } - pub async fn validate_or_update_active_chain_id(&self, chain_id: &WcChainId) -> MmResult<(), WalletConnectError> { - if !self.is_chain_supported(chain_id).await { - return MmError::err(WalletConnectError::InvalidChainId(chain_id.to_string())); - }; - - { - if let Some(active_chain_id) = self.session.get_active_chain_id().await { - if chain_id.to_string() == active_chain_id { - return Ok(()); - } - }; - - let event = SessionEventRequest { - event: Event { - name: "chainChanged".to_string(), - data: serde_json::to_value(&chain_id.id)?, - }, - chain_id: chain_id.to_string(), - }; - let param = RequestParams::SessionEvent(event); - - let active_topic = self.session.get_active_topic_or_err().await?; - self.publish_request(&active_topic, param).await?; - } - - self.session.set_active_chain_id(chain_id.id.clone()).await; + pub async fn validate_update_active_chain_id(&self, chain_id: &WcChainId) -> MmResult<(), WalletConnectError> { + let session = self + .session + .get_session_active() + .await + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active WalletConnect session found".to_string(), + )))?; + + self.validate_chain_id(&session, chain_id).await?; + + // TODO: uncomment when WalletConnect wallets start listening to chainChanged event + // if WcChain::Eip155 != chain_id.chain { + // return Ok(()); + // }; + // + // if let Some(active_chain_id) = session.get_active_chain_id().await { + // if chain_id == active_chain_id { + // return Ok(()); + // } + // }; + // + // let event = SessionEventRequest { + // event: Event { + // name: "chainChanged".to_string(), + // data: serde_json::to_value(&chain_id.id)?, + // }, + // chain_id: chain_id.to_string(), + // }; + // self.publish_request(&session.topic, RequestParams::SessionEvent(event)) + // .await?; + // + // let wait_duration = Duration::from_secs(60); + // if let Ok(Some(resp)) = self.message_rx.lock().await.next().timeout(wait_duration).await { + // println!("{resp:?}"); + // let result = resp.mm_err(WalletConnectError::InternalError)?; + // if let ResponseParamsSuccess::SessionEvent(data) = result.data { + // if !data { + // return MmError::err(WalletConnectError::PayloadError( + // "Please approve chain id change".to_owned(), + // )); + // } + // + // self.session + // .get_session_mut(&session.topic) + // .ok_or(MmError::new(WalletConnectError::SessionError( + // "No active WalletConnect session found".to_string(), + // )))? + // .set_active_chain_id(chain_id.clone()) + // .await; + // } + // } Ok(()) } @@ -451,7 +481,13 @@ impl WalletConnectCtx { pub async fn drop_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { self.client.unsubscribe(topic.clone()).await?; - self.session.delete_session(topic).await; + + if let Some(session) = self.session.delete_session(topic).await { + self.pairing + .disconnect(session.pairing_topic.as_ref(), &self.client) + .await?; + }; + self.storage .delete_session(topic) .await @@ -466,26 +502,15 @@ impl WalletConnectCtx { pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectError> { // Initialized WalletConnectCtx let wallet_connect = WalletConnectCtx::from_ctx(ctx)?; - // Intialize storage. - wallet_connect.storage.init().await.unwrap(); // WalletConnectCtx is initialized, now we can connect to relayer client and spawn a watcher // loop for disconnection. - ctx.spawner().spawn({ - let this = wallet_connect.clone(); - async move { - info!("Initializing WalletConnect connection"); - connection_handler::initial_connection(&this).await; - connection_handler::handle_disconnections(&this).await; - } - }); - - ctx.spawner().spawn(keep_session_alive_ping(wallet_connect.clone())); + ctx.spawner().spawn(initialize_connection(wallet_connect.clone())); // spawn message handler event loop ctx.spawner().spawn(async move { let mut recv = wallet_connect.inbound_message_rx.lock().await; while let Some(msg) = recv.next().await { - if let Err(e) = wallet_connect.clone().handle_published_message(msg).await { + if let Err(e) = wallet_connect.handle_published_message(msg).await { info!("Error processing message: {:?}", e); } } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index e7b036e966..53156e85b8 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -1,12 +1,13 @@ pub(crate) mod key; pub mod rpc; +use crate::chain::WcChainId; use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; -use common::log::debug; +use common::log::info; use dashmap::mapref::multiple::RefMulti; -use dashmap::mapref::one::{Ref, RefMut}; +use dashmap::mapref::one::RefMut; use dashmap::DashMap; use key::SessionKey; use mm2_err_handle::prelude::{MmError, MmResult}; @@ -128,6 +129,8 @@ pub struct Session { /// Indicates whether this session info represents a Controller or Proposer perspective. pub session_type: SessionType, pub session_properties: Option, + /// Session active chain_id + pub active_chain_id: Option, } impl Session { @@ -168,10 +171,17 @@ impl Session { session_type, topic: session_topic, session_properties: None, + active_chain_id: Default::default(), } } pub(crate) fn extend(&mut self, till: u64) { self.expiry = till; } + + /// Get the active chain ID for the current session. + pub async fn get_active_chain_id(&self) -> &Option { &self.active_chain_id } + + /// Sets the active chain ID for the current session. + pub async fn set_active_chain_id(&mut self, chain_id: WcChainId) { self.active_chain_id = Some(chain_id); } } /// Internal implementation of session management. @@ -179,8 +189,6 @@ impl Session { struct SessionManagerImpl { /// The currently active session topic. active_topic: Mutex>, - /// Session active chain_id - active_chain_id: Mutex>, /// A thread-safe map of sessions indexed by topic. sessions: DashMap, } @@ -220,12 +228,6 @@ impl SessionManager { ))) } - /// Get the active chain ID for the current session. - pub async fn get_active_chain_id(&self) -> Option { self.0.active_chain_id.lock().await.clone() } - - /// Sets the active chain ID for the current session. - pub async fn set_active_chain_id(&self, chain_id: String) { *self.0.active_chain_id.lock().await = Some(chain_id); } - /// Inserts the provided `Session` into the session store, associated with the specified topic. /// If a session with the same topic already exists, it will be overwritten. pub(crate) async fn add_session(&self, session: Session) { @@ -239,7 +241,7 @@ impl SessionManager { /// Removes the session corresponding to the specified topic from the session store. /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { - debug!("Deleting session with topic: {topic}"); + info!("Deleting session with topic: {topic}"); let mut active_topic = self.0.active_topic.lock().await; // Remove the session and get the removed session (if any) @@ -251,9 +253,9 @@ impl SessionManager { *active_topic = self.0.sessions.iter().next().map(|session| session.topic.clone()); if let Some(new_active_topic) = active_topic.as_ref() { - debug!("New session with topic: {} activated!", new_active_topic); + info!("New session with topic: {} activated!", new_active_topic); } else { - debug!("No active sessions remaining"); + info!("No active sessions remaining"); } } @@ -263,7 +265,7 @@ impl SessionManager { pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { let mut active_topic = self.0.active_topic.lock().await; if let Some(session) = self.get_session(topic) { - *active_topic = Some(session.topic.clone()); + *active_topic = Some(session.topic); return Ok(()); } @@ -271,15 +273,15 @@ impl SessionManager { } /// Retrieves a cloned session associated with a given topic. - pub fn get_session(&self, topic: &Topic) -> Option> { self.0.sessions.get(topic) } + pub fn get_session(&self, topic: &Topic) -> Option { self.0.sessions.get(topic).map(|s| s.clone()) } /// Retrieves a mutable reference to the session associated with a given topic. - pub(crate) async fn get_session_mut(&self, topic: &Topic) -> Option> { + pub(crate) fn get_session_mut(&self, topic: &Topic) -> Option> { self.0.sessions.get_mut(topic) } - /// Returns an `Option` containing the active session if it exists; otherwise, returns `None`. - pub async fn get_session_active(&self) -> Option> { + /// returns an `option` containing the active session if it exists; otherwise, returns `none`. + pub async fn get_session_active(&self) -> Option { let active_topic = self.0.active_topic.lock().await; if let Some(ref topic) = *active_topic { self.get_session(topic) @@ -296,10 +298,10 @@ impl SessionManager { .into_iter() .map(|(topic, session)| SessionRpcInfo { topic: topic.to_string(), - metadata: session.controller.metadata.clone(), - peer_pubkey: session.controller.public_key.clone(), + metadata: session.controller.metadata, + peer_pubkey: session.controller.public_key, pairing_topic: session.pairing_topic.to_string(), - namespaces: session.namespaces.clone(), + namespaces: session.namespaces, subscription_id: session.subscription_id, properties: session.session_properties, }) @@ -309,7 +311,7 @@ impl SessionManager { /// Updates the expiry time of the session associated with the given topic to the specified timestamp. /// If the session does not exist, this method does nothing. pub(crate) fn extend_session(&self, topic: &Topic, till: u64) { - debug!("Extending session with topic: {topic}"); + info!("Extending session with topic: {topic}"); if let Some(mut session) = self.0.sessions.get_mut(topic) { session.extend(till); } @@ -337,10 +339,8 @@ impl SessionManager { /// Retrieves the symmetric key associated with a given topic. pub(crate) fn sym_key(&self, topic: &Topic) -> Option> { - self.0 - .sessions - .get(topic) - .map(|k| k.session_key.symmetric_key().to_vec()) + self.get_session(topic) + .map(|sess| sess.session_key.symmetric_key().to_vec()) } async fn disconnect_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 069459cab7..55f8c7404c 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -1,12 +1,11 @@ -use crate::{chain::WcChainId, - error::{WalletConnectError, INVALID_EVENT, UNSUPPORTED_CHAINS}, +use crate::{chain::{WcChain, WcChainId}, + error::{WalletConnectError, UNSUPPORTED_CHAINS}, WalletConnectCtx}; -use common::log::info; +use common::log::{error, info}; use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, - rpc::{params::{session::Namespace, session_event::SessionEventRequest, ResponseParamsError, - ResponseParamsSuccess}, + rpc::{params::{session_event::SessionEventRequest, ResponseParamsError, ResponseParamsSuccess}, ErrorData}}; pub async fn handle_session_event( @@ -20,60 +19,60 @@ pub async fn handle_session_event( match event_name { "chainChanged" => { - // check if chain_id is supported. - let chain_id_new = serde_json::from_value::(event.event.data)?; - if !ctx.is_chain_supported(&chain_id).await { - return MmError::err(WalletConnectError::InternalError(format!( - "chain_id not supported: {}", - event.chain_id - ))); - }; + let session = ctx + .session + .get_session(topic) + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active WalletConnect session found".to_string(), + )))?; - if let Some(session) = ctx.session.get_session_active().await { - if let Some(Namespace { - chains: Some(chains), .. - }) = session.namespaces.get(chain_id.chain.as_ref()) - { - if chains.contains(&chain_id.to_string()) { - let chain_id = chain_id.chain_id_from_id(chain_id_new.to_string().as_str()); - ctx.session.set_active_chain_id(chain_id).await; + if WcChain::Eip155 != chain_id.chain { + return Ok(()); + }; - let params = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, params, message_id).await?; + ctx.validate_chain_id(&session, &chain_id).await?; - return Ok(()); - }; + if let Some(active_chain_id) = session.get_active_chain_id().await { + if &chain_id == active_chain_id { + return Ok(()); } }; - println!("Chain ID not supported"); - let error_data = ErrorData { - code: UNSUPPORTED_CHAINS, - message: "Chain_Id was changed to an unsupported chain".to_string(), - data: None, - }; + // check if chain_id is supported. + let id_string = serde_json::from_value::(event.event.data)?; + let new_chain = chain_id.chain.derive_chain_id(id_string.to_string()); + if let Err(err) = ctx.validate_chain_id(&session, &new_chain).await { + error!("{err:?}"); + let error_data = ErrorData { + code: UNSUPPORTED_CHAINS, + message: "Unsupported chain id".to_string(), + data: None, + }; + let params = ResponseParamsError::SessionEvent(error_data); + ctx.publish_response_err(topic, params, message_id).await?; + } else { + { + ctx.session + .get_session_mut(topic) + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active WalletConnect session found".to_string(), + )))? + .set_active_chain_id(chain_id.clone()) + .await; + } - ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) - .await?; + let params = ResponseParamsSuccess::SessionEvent(true); + ctx.publish_response_ok(topic, params, message_id).await?; + }; }, "accountsChanged" => { - // TODO: Handle account change logic. - - info!("accountsChanged session event received: {event:?}"); - // let data = serde_json::from_value::>(event.event.data)?; - let param = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, param, message_id).await?; + // TODO: Handle accountsChanged event logic. }, _ => { - let error_data = ErrorData { - code: INVALID_EVENT, - message: format!("Received an invalid/unsupported session event: {}", event.event.name), - data: None, - }; - ctx.publish_response_err(topic, ResponseParamsError::SessionEvent(error_data), message_id) - .await?; + // TODO: Handle other event logic.}, }, }; + info!("chainChanged event handled successfully"); Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs index 8009b309e9..640465bebf 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs @@ -1,6 +1,10 @@ +use std::time::Duration; + use crate::{error::WalletConnectError, WalletConnectCtx}; -use mm2_err_handle::prelude::MmResult; +use common::custom_futures::timeout::FutureTimerExt; +use futures::StreamExt; +use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{RequestParams, ResponseParamsSuccess}}; @@ -19,5 +23,11 @@ pub async fn send_session_ping_request(ctx: &WalletConnectCtx, topic: &Topic) -> let param = RequestParams::SessionPing(()); ctx.publish_request(topic, param).await?; - Ok(()) + let wait_duration = Duration::from_secs(30); + if let Ok(Some(resp)) = ctx.message_rx.lock().await.next().timeout(wait_duration).await { + resp.mm_err(WalletConnectError::InternalError)?; + return Ok(()); + } + + MmError::err(WalletConnectError::PayloadError("Session Ping Error".to_owned())) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 0c949bda38..917a2f9198 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -46,7 +46,7 @@ pub async fn reply_session_proposal_request( let sender_public_key = const_hex::decode(&proposal.proposer.public_key)? .as_slice() .try_into() - .unwrap(); + .map_to_mm(|_| WalletConnectError::InternalError("Invalid sender_public_key".to_owned()))?; let session_key = SessionKey::from_osrng(&sender_public_key)?; let session_topic: Topic = session_key.generate_topic().into(); diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 0356954672..4cdf9ef407 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -41,7 +41,7 @@ pub(crate) async fn reply_session_settle_request( settle: SessionSettleRequest, ) -> MmResult<(), WalletConnectError> { { - let session = ctx.session.get_session_mut(topic).await; + let session = ctx.session.get_session_mut(topic); if let Some(mut session) = session { session.namespaces = settle.namespaces.0.clone(); session.controller = settle.controller.clone(); diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index 214a9419b8..077d7d96e2 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -15,7 +15,7 @@ pub(crate) async fn reply_session_update_request( update: SessionUpdateRequest, ) -> MmResult<(), WalletConnectError> { { - if let Some(mut session) = ctx.session.get_session_mut(topic).await { + if let Some(mut session) = ctx.session.get_session_mut(topic) { update .namespaces .caip2_validate() diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index a84c2848ff..c5e6295523 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -9,7 +9,7 @@ use crate::lp_ordermatch::{best_orders_rpc_v2, orderbook_rpc_v2, start_simple_ma use crate::lp_swap::swap_v2_rpcs::{active_swaps_rpc, my_recent_swaps_rpc, my_swap_status_rpc}; use crate::lp_wallet::{get_mnemonic_rpc, get_wallet_names_rpc}; use crate::rpc::rate_limiter::{process_rate_limit, RateLimitContext}; -use crate::rpc::wc_commands::{delete_connection, get_chain_id, new_connection, ping_session}; +use crate::rpc::wc_commands::{delete_connection, new_connection, ping_session}; use crate::{lp_stats::{add_node_to_version_stat, remove_node_from_version_stat, start_version_stat_collection, stop_version_stat_collection, update_version_stat_collection}, lp_swap::{get_locked_amount_rpc, max_maker_vol, recreate_swap_data, trade_preimage_rpc}, @@ -221,7 +221,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, coins::my_tx_history_v2::z_coin_tx_history_rpc).await, "wc_new_connection" => handle_mmrpc(ctx, request, new_connection).await, "wc_delete_connection" => handle_mmrpc(ctx, request, delete_connection).await, - "wc_get_chain_id" => handle_mmrpc(ctx, request, get_chain_id).await, "wc_get_session" => handle_mmrpc(ctx, request, get_session).await, "wc_get_sessions" => handle_mmrpc(ctx, request, get_all_sessions).await, "wc_disconnect_session" => handle_mmrpc(ctx, request, disconnect_session).await, diff --git a/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs b/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs deleted file mode 100644 index 67e1400df0..0000000000 --- a/mm2src/mm2_main/src/rpc/wc_commands/get_chain_id.rs +++ /dev/null @@ -1,21 +0,0 @@ -use kdf_walletconnect::WalletConnectCtx; -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::*; -use serde::Serialize; - -use super::{EmptyRpcRequst, WalletConnectRpcError}; - -#[derive(Debug, PartialEq, Serialize)] -pub struct GetChainIdResponse { - pub chain_id: Option, -} - -/// `delete connection` RPC command implementation. -pub async fn get_chain_id(ctx: MmArc, _req: EmptyRpcRequst) -> MmResult { - let ctx = - WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - - Ok(GetChainIdResponse { - chain_id: ctx.session.get_active_chain_id().await, - }) -} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 55be302eda..104a14a8d5 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -43,10 +43,7 @@ pub struct GetSessionRequest { pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let session = ctx - .session - .get_session(&req.topic.into()) - .map(|s| SessionRpcInfo::from(s.clone())); + let session = ctx.session.get_session(&req.topic.into()).map(SessionRpcInfo::from); Ok(GetSessionResponse { session }) } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs index cd2ef9e7bd..5dfc605516 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs @@ -1,12 +1,10 @@ mod delete_connection; -mod get_chain_id; mod new_connection; mod sessions; use common::HttpStatusCode; pub use delete_connection::delete_connection; use derive_more::Display; -pub use get_chain_id::get_chain_id; use http::StatusCode; pub use new_connection::new_connection; use serde::Deserialize; From 0c6128719ef3ba01772c4ea89eea793f8ad71bff Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 3 Nov 2024 22:51:41 +0100 Subject: [PATCH 094/125] add logging to wc storage impl --- mm2src/kdf_walletconnect/src/connection_handler.rs | 14 ++++++++++---- mm2src/kdf_walletconnect/src/lib.rs | 1 + mm2src/kdf_walletconnect/src/storage/indexed_db.rs | 14 ++++++++++++-- mm2src/kdf_walletconnect/src/storage/sqlite.rs | 7 +++++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 506a5349bb..f22ba9477e 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -45,7 +45,7 @@ impl ConnectionHandler for Handler { info!("\n[{}] connection closed: frame={frame:?}", self.name); if let Err(e) = self.conn_live_sender.start_send(()) { - info!("\n[{}] failed to send to the receiver: {e}", self.name); + error!("\n[{}] failed to send to the receiver: {e}", self.name); } } @@ -56,16 +56,22 @@ impl ConnectionHandler for Handler { ); if let Err(e) = self.msg_sender.start_send(message) { - info!("\n[{}] failed to send to the receiver: {e}", self.name); + error!("\n[{}] failed to send to the receiver: {e}", self.name); } } fn inbound_error(&mut self, error: ClientError) { info!("\n[{}] inbound error: {error}", self.name); + if let Err(e) = self.conn_live_sender.start_send(()) { + error!("\n[{}] failed to send to the receiver: {e}", self.name); + } } fn outbound_error(&mut self, error: ClientError) { info!("\n[{}] outbound error: {error}", self.name); + if let Err(e) = self.conn_live_sender.start_send(()) { + error!("\n[{}] failed to send to the receiver: {e}", self.name); + } } } @@ -91,12 +97,12 @@ pub(crate) async fn initialize_connection(this: Arc) { // Initialize storage if let Err(err) = this.storage.init().await { - info!("Unable to initialize WalletConnect persistent storage: {err:?}. Only inmemory storage will be utilized for this Session."); + error!("Unable to initialize WalletConnect persistent storage: {err:?}. Only inmemory storage will be utilized for this Session."); }; // load session from storage if let Err(err) = this.load_session_from_storage().await { - info!("Unable to load session from storage: {err:?}"); + error!("Unable to load session from storage: {err:?}"); }; // Spawn session disconnection watcher. diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d4a3023485..84312c004d 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -205,6 +205,7 @@ impl WalletConnectCtx { /// Loads sessions from storage, activates valid ones, and deletes expired ones. async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectError> { + info!("Loading WalletConnect session from storage"); let now = chrono::Utc::now().timestamp() as u64; let mut sessions = self .storage diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index 64f1a8ac99..d14d9f678f 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -66,11 +66,15 @@ impl IDBSessionStorage { impl WalletConnectStorageOps for IDBSessionStorage { type Error = WcIndexedDbError; - async fn init(&self) -> MmResult<(), Self::Error> { Ok(()) } + async fn init(&self) -> MmResult<(), Self::Error> { + debug!("Initializing WalletConnect session storage"); + Ok(()) + } async fn is_initialized(&self) -> MmResult { Ok(true) } async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { + debug!("Saving WalletConnect session: {} to storage", session.topic); let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -82,6 +86,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { } async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { + debug!("Retrieving WalletConnect session: {topic} from storage"); let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -93,6 +98,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { } async fn get_all_sessions(&self) -> MmResult, Self::Error> { + debug!("Loading WalletConnect sessions from storage"); let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -106,6 +112,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { } async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { + debug!("Deleting WalletConnect session: {topic} from storage"); let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -114,5 +121,8 @@ impl WalletConnectStorageOps for IDBSessionStorage { Ok(()) } - async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { self.save_session(session).await } + async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { + debug!("Updating WalletConnect session: {topic} in storage"); + self.save_session(session).await + } } diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 96540ff845..a4dabfb6f2 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -1,4 +1,5 @@ use async_trait::async_trait; +use common::log::debug; use db_common::sqlite::rusqlite::Result as SqlResult; use db_common::sqlite::{query_single_row, string_from_row, CHECK_TABLE_EXISTS_SQL}; use db_common::{async_sql_conn::{AsyncConnError, AsyncConnection}, @@ -48,6 +49,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { type Error = AsyncConnError; async fn init(&self) -> MmResult<(), Self::Error> { + debug!("Initializing WalletConnect session storage"); let lock = self.lock_db().await; lock.call(move |conn| { conn.execute(&create_sessions_table()?, []).map(|_| ())?; @@ -70,6 +72,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { + debug!("Saving WalletConnect session: {} to storage", session.topic); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; @@ -95,6 +98,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { + debug!("Retrieving WalletConnect session: {topic} from storage"); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; let topic = topic.clone(); @@ -113,6 +117,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn get_all_sessions(&self) -> MmResult, Self::Error> { + debug!("Loading WalletConnect sessions from storage"); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; let sessions_str = lock @@ -136,6 +141,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { + debug!("Deleting WalletConnect session: {topic} from storage"); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let topic = topic.clone(); let lock = self.lock_db().await; @@ -151,6 +157,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { + debug!("Updating WalletConnect session: {} in storage", session.topic); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let session = session.clone(); let lock = self.lock_db().await; From a0220d74cdc5b4f6cfa35948ed7d5f8ccd240db1 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sun, 3 Nov 2024 23:10:33 +0100 Subject: [PATCH 095/125] fix conflict and minor changes + merge with dev branch --- Cargo.lock | 61 ++++++++++++++++--- .../src/storage/indexed_db.rs | 3 +- mm2src/trezor/Cargo.toml | 4 +- 3 files changed, 55 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3a40cffd84..a8a9d90f13 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -859,9 +859,9 @@ dependencies = [ "ed25519-dalek 1.0.1", "enum_derives", "ethabi", - "ethcore-transaction", + "ethcore-transaction 0.1.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", "ethereum-types", - "ethkey", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", "ff 0.8.0", "futures 0.1.29", "futures 0.3.28", @@ -1969,11 +1969,24 @@ version = "0.1.0" source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig#676351596f590a08751eca8ddea5120f513b57a6" dependencies = [ "ethereum-types", - "ethkey", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", "keccak-hash", "rlp", "rustc-hex", - "unexpected", + "unexpected 0.1.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", +] + +[[package]] +name = "ethcore-transaction" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "ethereum-types", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", + "keccak-hash", + "rlp", + "rustc-hex", + "unexpected 0.1.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", ] [[package]] @@ -1999,7 +2012,25 @@ dependencies = [ "edit-distance", "ethereum-types", "log", - "mem", + "mem 0.1.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", + "rand 0.6.5", + "rustc-hex", + "secp256k1 0.20.3", + "serde", + "serde_derive", + "tiny-keccak 1.4.4", +] + +[[package]] +name = "ethkey" +version = "0.3.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" +dependencies = [ + "byteorder", + "edit-distance", + "ethereum-types", + "log", + "mem 0.1.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", "rand 0.6.5", "rustc-hex", "secp256k1 0.20.3", @@ -3863,6 +3894,11 @@ name = "mem" version = "0.1.0" source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig#676351596f590a08751eca8ddea5120f513b57a6" +[[package]] +name = "mem" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + [[package]] name = "memchr" version = "2.5.0" @@ -4096,7 +4132,7 @@ name = "mm2_eth" version = "0.1.0" dependencies = [ "ethabi", - "ethkey", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", "hex", "indexmap 1.9.3", "itertools", @@ -4196,7 +4232,7 @@ dependencies = [ "enum-primitive-derive", "enum_derives", "ethabi", - "ethcore-transaction", + "ethcore-transaction 0.1.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", "ethereum-types", "futures 0.1.29", "futures 0.3.28", @@ -4327,7 +4363,7 @@ dependencies = [ "cfg-if 1.0.0", "common", "derive_more", - "ethkey", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", "futures 0.3.28", "futures-util", "gstuff", @@ -7610,9 +7646,9 @@ dependencies = [ "byteorder", "common", "derive_more", - "ethcore-transaction", + "ethcore-transaction 0.1.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", "ethereum-types", - "ethkey", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", "futures 0.3.28", "hw_common", "js-sys", @@ -7761,6 +7797,11 @@ name = "unexpected" version = "0.1.0" source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig#676351596f590a08751eca8ddea5120f513b57a6" +[[package]] +name = "unexpected" +version = "0.1.0" +source = "git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1#d5524212230c4773d01b2527e9b3c422a251e0dc" + [[package]] name = "unicode-bidi" version = "0.3.17" diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index d14d9f678f..6dd6baf765 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -2,6 +2,7 @@ use super::WalletConnectStorageOps; use crate::error::WcIndexedDbError; use crate::session::Session; use async_trait::async_trait; +use common::log::debug; use mm2_core::mm_ctx::MmArc; use mm2_db::indexed_db::{ConstructibleDb, DbIdentifier, DbInstance, DbLocked, DbUpgrader, IndexedDb, IndexedDbBuilder, InitDbResult, OnUpgradeResult, SharedDb, TableSignature}; @@ -122,7 +123,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { } async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { - debug!("Updating WalletConnect session: {topic} in storage"); + debug!("Updating WalletConnect session: {} in storage", session.topic); self.save_session(session).await } } diff --git a/mm2src/trezor/Cargo.toml b/mm2src/trezor/Cargo.toml index 2a19252be6..36e5abb0ec 100644 --- a/mm2src/trezor/Cargo.toml +++ b/mm2src/trezor/Cargo.toml @@ -19,9 +19,9 @@ rand = { version = "0.7", features = ["std", "wasm-bindgen"] } rpc_task = { path = "../rpc_task" } serde = "1.0" serde_derive = "1.0" -ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } +ethcore-transaction = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } ethereum-types = { version = "0.13", default-features = false, features = ["std", "serialize"] } -ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } +ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } bip32 = { version = "0.2.2", default-features = false, features = ["alloc", "secp256k1-ffi"] } lazy_static = "1.4" From 346850235f50623d43866db23e101a34b11130f7 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 4 Nov 2024 10:33:46 +0100 Subject: [PATCH 096/125] minor changes --- Cargo.lock | 51 +++++-------------- mm2src/coins/eth.rs | 33 ++++++------ mm2src/coins/eth/wallet_connect.rs | 38 ++++++++------ mm2src/crypto/Cargo.toml | 2 +- mm2src/kdf_walletconnect/src/lib.rs | 22 ++++---- mm2src/kdf_walletconnect/src/session.rs | 6 +-- mm2src/kdf_walletconnect/src/session/key.rs | 15 +++--- mm2src/mm2_main/Cargo.toml | 1 - .../tests/docker_tests/qrc20_tests.rs | 4 +- 9 files changed, 78 insertions(+), 94 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a8a9d90f13..5b2594389a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,12 +445,12 @@ dependencies = [ [[package]] name = "bip39" -version = "2.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" dependencies = [ - "bitcoin_hashes 0.13.0", - "rand_core 0.6.4", + "bitcoin_hashes", + "rand_core 0.5.1", "zeroize", ] @@ -461,32 +461,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" dependencies = [ "bech32", - "bitcoin_hashes 0.11.0", + "bitcoin_hashes", "secp256k1 0.24.3", ] -[[package]] -name = "bitcoin-internals" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" - [[package]] name = "bitcoin_hashes" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" -[[package]] -name = "bitcoin_hashes" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" -dependencies = [ - "bitcoin-internals", - "hex-conservative", -] - [[package]] name = "bitcrypto" version = "0.1.0" @@ -841,7 +825,7 @@ dependencies = [ "base64 0.21.7", "bip32", "bitcoin", - "bitcoin_hashes 0.11.0", + "bitcoin_hashes", "bitcrypto", "blake2b_simd", "byteorder", @@ -2615,12 +2599,6 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hex-conservative" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" - [[package]] name = "hex_fmt" version = "0.3.0" @@ -3755,7 +3733,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9680857590c3529cf8c7d32b04501f215f2bf1e029fdfa22f4112f66c1741e4" dependencies = [ "bech32", - "bitcoin_hashes 0.11.0", + "bitcoin_hashes", "lightning", "num-traits", "secp256k1 0.24.3", @@ -4271,7 +4249,6 @@ dependencies = [ "primitives", "prost", "prost-build", - "rand 0.6.5", "rand 0.7.3", "rcgen", "regex", @@ -4799,7 +4776,7 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" dependencies = [ "anyhow", "chrono", @@ -5126,7 +5103,7 @@ dependencies = [ name = "primitives" version = "0.1.0" dependencies = [ - "bitcoin_hashes 0.11.0", + "bitcoin_hashes", "byteorder", "rustc-hex", "uint", @@ -5242,7 +5219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4" dependencies = [ "bytes 1.4.0", - "heck 0.5.0", + "heck 0.4.0", "itertools", "log", "multimap", @@ -5730,7 +5707,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" dependencies = [ "chrono", "data-encoding", @@ -5758,7 +5735,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" dependencies = [ "anyhow", "bs58 0.4.0", @@ -6284,7 +6261,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ - "bitcoin_hashes 0.11.0", + "bitcoin_hashes", "secp256k1-sys 0.6.1", ] @@ -8132,7 +8109,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#a271959b4c6323a56963c36f9c4fb704f926d7c0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" dependencies = [ "base64 0.21.7", "chacha20poly1305", diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 023bf7a401..d43f4dc616 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2557,7 +2557,7 @@ async fn sign_transaction_with_keypair<'a>( /// Sign and send eth transaction with provided keypair, /// This fn is primarily for swap transactions so it uses swap tx fee policy -async fn sign_and_send_transaction_with_keypair<'a>( +async fn sign_and_send_transaction_with_keypair( coin: &EthCoin, key_pair: &KeyPair, address: Address, @@ -2694,8 +2694,10 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw .map_to_mm(|err| RawTransactionError::TransactionError(err.get_plain_text_format())) }, EthPrivKeyPolicy::WalletConnect { .. } => { - let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); - let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + let wc = { + let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); + WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!") + }; let my_address = coin .derivation_method .single_addr_or_err() @@ -2717,18 +2719,17 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw .compat() .await .map_to_mm(RawTransactionError::InvalidParam)?; - let tx_params = WcEthTxParams { - my_address, - gas_price: pay_for_gas_option.get_gas_price(), - action, - value, - gas: args.gas_limit, - data: &data, - nonce, - }; let (signed_tx, _) = coin - .wc_sign_tx(&wc, tx_params) + .wc_sign_tx(&wc, WcEthTxParams { + my_address, + gas_price: pay_for_gas_option.get_gas_price(), + action, + value, + gas: args.gas_limit, + data: &data, + nonce, + }) .await .mm_err(|err| RawTransactionError::TransactionError(err.to_string()))?; @@ -3688,8 +3689,10 @@ impl EthCoin { sign_and_send_transaction_with_keypair(&coin, key_pair, address, value, action, data, gas).await }, EthPrivKeyPolicy::WalletConnect { .. } => { - let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); - let wc = WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!"); + let wc = { + let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); + WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!") + }; send_transaction_with_walletconnect(coin, &wc, value, action, &data, gas).await }, EthPrivKeyPolicy::Trezor => Err(TransactionErr::Plain(ERRL!("Trezor is not supported for swaps yet!"))), diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index d437dd7329..65df66a452 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -144,11 +144,11 @@ impl WalletConnectOps for EthCoin { }; let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); - // Wait for 10 seconds for the transaction to appear on the RPC node. - let wait_rpc_timeout = 10_000; - let check_every = 1.; - let maybe_signed_tx = self - .wait_for_tx_appears_on_rpc( + let maybe_signed_tx = { + // Wait for 10 seconds for the transaction to appear on the RPC node. + let wait_rpc_timeout = 10_000; + let check_every = 1.; + self.wait_for_tx_appears_on_rpc( H256::from_slice( &hex::decode(tx_hash).map_to_mm(|err| EthWalletConnectError::InvalidTxData(err.to_string()))?, ), @@ -156,7 +156,9 @@ impl WalletConnectOps for EthCoin { check_every, ) .await - .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))?; + .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))? + }; + let signed_tx = match maybe_signed_tx { Some(signed_tx) => signed_tx, None => { @@ -198,15 +200,17 @@ fn extract_pubkey_from_signature( message: impl ToString, account: &str, ) -> MmResult<(H520, Address), EthWalletConnectError> { - let message_hash = hash_message(message.to_string()); let account = H160::from_str(&account[2..]).map_to_mm(|err| EthWalletConnectError::InternalError(err.to_string()))?; - let signature = Signature::from_str(&signature_str[2..]) - .map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; - let uncompressed = recover(&signature, &message_hash).map_to_mm(|err| { - let error = format!("Couldn't recover a public key from the signature: '{signature:?}, error: {err:?}'"); - EthWalletConnectError::InvalidSignature(error) - })?; + let uncompressed = { + let message_hash = hash_message(message.to_string()); + let signature = Signature::from_str(&signature_str[2..]) + .map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; + recover(&signature, &message_hash).map_to_mm(|err| { + let error = format!("Couldn't recover a public key from the signature: '{signature:?}, error: {err:?}'"); + EthWalletConnectError::InvalidSignature(error) + })? + }; let mut public = Public::default(); public.as_mut().copy_from_slice(&uncompressed[1..65]); @@ -221,8 +225,12 @@ fn extract_pubkey_from_signature( } pub fn recover(signature: &Signature, message: &Message) -> Result { - let recovery_id = signature[64] as i32 - 27; - let recovery_id = RecoveryId::from_i32(recovery_id)?; + let recovery_id = { + let recovery_id = (signature[64] as i32) + .checked_sub(27) + .ok_or_else(|| ethkey::Error::InvalidSignature)?; + RecoveryId::from_i32(recovery_id)? + }; let sig = RecoverableSignature::from_compact(&signature[0..64], recovery_id)?; let pubkey = Secp256k1::new().recover(&secp256k1::Message::from_slice(&message[..])?, &sig)?; let serialized = pubkey.serialize_uncompressed(); diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index af3c3b2012..6b7cf93d37 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -34,7 +34,7 @@ mm2_err_handle = { path = "../mm2_err_handle" } num-traits = "0.2" parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } -rand = "0.8.5" +rand = "0.8.4" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } rustc-hex = "2" diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 84312c004d..8dc8781764 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -40,7 +40,7 @@ use std::collections::BTreeSet; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; -use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType}; +use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType, SymKey}; #[async_trait::async_trait] pub trait WalletConnectOps { @@ -166,22 +166,18 @@ impl WalletConnectCtx { } /// Retrieves the symmetric key associated with a given `topic`. - async fn sym_key(&self, topic: &Topic) -> MmResult, WalletConnectError> { - { - if let Some(key) = self.session.sym_key(topic) { - return Ok(key); - } + async fn sym_key(&self, topic: &Topic) -> MmResult { + if let Some(key) = self.session.sym_key(topic) { + return Ok(key); } - { - let pairings = self.pairing.pairings.lock().await; - if let Some(pairing) = pairings.get(topic.as_ref()) { - let key = const_hex::decode(pairing.sym_key.clone())?; - return Ok(key); - } + if let Ok(key) = self.pairing.sym_key(topic.as_ref()).await { + return Ok(key); } - MmError::err(WalletConnectError::InternalError(format!("Topic not found:{topic}"))) + MmError::err(WalletConnectError::InternalError(format!( + "topic sym_key not found:{topic}" + ))) } /// Handles an inbound published message by decrypting, decoding, and processing it. diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 53156e85b8..6943cd5680 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -23,6 +23,7 @@ use std::collections::BTreeMap; use std::fmt::Debug; use std::sync::Arc; use tokio::sync::Mutex; +use wc_common::SymKey; pub(crate) const FIVE_MINUTES: u64 = 300; pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; @@ -338,9 +339,8 @@ impl SessionManager { } /// Retrieves the symmetric key associated with a given topic. - pub(crate) fn sym_key(&self, topic: &Topic) -> Option> { - self.get_session(topic) - .map(|sess| sess.session_key.symmetric_key().to_vec()) + pub(crate) fn sym_key(&self, topic: &Topic) -> Option { + self.get_session(topic).map(|sess| sess.session_key.symmetric_key()) } async fn disconnect_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { diff --git a/mm2src/kdf_walletconnect/src/session/key.rs b/mm2src/kdf_walletconnect/src/session/key.rs index a2e87cd770..e942024098 100644 --- a/mm2src/kdf_walletconnect/src/session/key.rs +++ b/mm2src/kdf_walletconnect/src/session/key.rs @@ -1,6 +1,7 @@ use crate::error::SessionError; use serde::{Deserialize, Serialize}; +use wc_common::SymKey; use x25519_dalek::{PublicKey, SharedSecret, StaticSecret}; use {hkdf::Hkdf, rand::{rngs::OsRng, CryptoRng, RngCore}, @@ -24,8 +25,8 @@ impl SymKeyPair { #[derive(Clone, Serialize, Deserialize, PartialEq, Eq)] pub struct SessionKey { - pub(crate) sym_key: [u8; 32], - pub(crate) public_key: [u8; 32], + pub(crate) sym_key: SymKey, + pub(crate) public_key: SymKey, } impl std::fmt::Debug for SessionKey { @@ -47,12 +48,12 @@ impl SessionKey { } /// Creates a new `SessionKey` using a random number generator and a peer's public key. - pub fn from_osrng(other_public_key: &[u8; 32]) -> Result { + pub fn from_osrng(other_public_key: &SymKey) -> Result { SessionKey::diffie_hellman(OsRng, other_public_key) } /// Performs Diffie-Hellman key exchange to derive a symmetric key. - pub fn diffie_hellman(csprng: T, other_public_key: &[u8; 32]) -> Result + pub fn diffie_hellman(csprng: T, other_public_key: &SymKey) -> Result where T: RngCore + CryptoRng, { @@ -73,7 +74,7 @@ impl SessionKey { pub fn generate_symmetric_key( &mut self, static_secret: &StaticSecret, - peer_public_key: &[u8; 32], + peer_public_key: &SymKey, ) -> Result<(), SessionError> { let shared_secret = static_secret.diffie_hellman(&PublicKey::from(*peer_public_key)); self.derive_symmetric_key(&shared_secret) @@ -87,10 +88,10 @@ impl SessionKey { } /// Gets symmetic key reference. - pub fn symmetric_key(&self) -> &[u8; 32] { &self.sym_key } + pub fn symmetric_key(&self) -> SymKey { self.sym_key } /// Gets "our" public key used in symmetric key derivation. - pub fn diffie_public_key(&self) -> &[u8; 32] { &self.public_key } + pub fn diffie_public_key(&self) -> SymKey { self.public_key } /// Generates new session topic. pub fn generate_topic(&self) -> String { diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index 5cfb8f0515..d4af0213bd 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -85,7 +85,6 @@ parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } prost = "0.12" rand = { version = "0.7", features = ["std", "small_rng"] } -rand6 = { version = "0.6", package = "rand" } rmp-serde = "0.14.3" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } diff --git a/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs b/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs index 352b383941..4ed3772f03 100644 --- a/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs @@ -20,7 +20,7 @@ use mm2_main::lp_swap::{dex_fee_amount, max_taker_vol_from_available}; use mm2_number::BigDecimal; use mm2_rpc::data::legacy::{CoinInitResponse, OrderbookResponse}; use mm2_test_helpers::structs::{trade_preimage_error, RpcErrorResponse, RpcSuccessResponse, TransactionDetails}; -use rand6::Rng; +use rand::Rng; use serde_json::{self as json, Value as Json}; use std::convert::TryFrom; use std::process::Command; @@ -1104,7 +1104,7 @@ fn test_max_taker_vol_dynamic_trade_fee() { // generate QTUM coin with the dynamic fee and fill the wallet by 2 Qtums let (_ctx, coin, priv_key) = generate_qtum_coin_with_random_privkey("QTUM", 2.into(), Some(0)); let my_address = coin.my_address().expect("!my_address"); - let mut rng = rand6::thread_rng(); + let mut rng = rand::thread_rng(); let mut qtum_balance = BigDecimal::from(2); let mut qtum_balance_steps = "2".to_owned(); for _ in 0..4 { From c4a07e42d44f4248baddf80575e89fb40e7773af Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 4 Nov 2024 10:44:53 +0100 Subject: [PATCH 097/125] monitor if relay client is connected --- mm2src/kdf_walletconnect/src/connection_handler.rs | 3 +++ mm2src/kdf_walletconnect/src/lib.rs | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index f22ba9477e..6818a679fa 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -113,6 +113,9 @@ pub(crate) async fn initialize_connection(this: Arc) { /// Implements exponential backoff retry mechanism for reconnection attempts. /// After successful reconnection, resubscribes to previous topics to restore full functionality. pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { + this.is_client_connected + .store(false, std::sync::atomic::Ordering::Relaxed); + let mut recv = this.connection_live_rx.lock().await; let mut backoff = 1; diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 8dc8781764..6fc191d04d 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -37,6 +37,7 @@ use serde::de::DeserializeOwned; use session::Session; use session::{key::SymKeyPair, SessionManager}; use std::collections::BTreeSet; +use std::sync::atomic::{AtomicBool, Ordering}; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; @@ -66,6 +67,7 @@ pub trait WalletConnectOps { pub struct WalletConnectCtx { pub client: Client, + is_client_connected: AtomicBool, pub pairing: PairingClient, pub session: SessionManager, @@ -103,6 +105,7 @@ impl WalletConnectCtx { Ok(Self { client, + is_client_connected: AtomicBool::default(), pairing, relay, storage, @@ -137,6 +140,7 @@ impl WalletConnectCtx { let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); self.client.connect(&opts).await?; + self.is_client_connected.store(true, Ordering::Relaxed); Ok(()) } @@ -240,6 +244,11 @@ impl WalletConnectCtx { topic: &Topic, param: RequestParams, ) -> MmResult<(), WalletConnectError> { + let is_client_connected = self.is_client_connected.load(Ordering::Relaxed); + if !is_client_connected { + self.connect_client().await?; + } + let irn_metadata = param.irn_metadata(); let message_id = MessageIdGenerator::new().next(); let request = Request::new(message_id, param.into()); From 1e78257a6e6b209fe289ddd3d788e726e2c89b80 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 6 Nov 2024 11:15:23 +0100 Subject: [PATCH 098/125] changes to client impls --- Cargo.lock | 51 ++++++--- mm2src/coins/eth/wallet_connect.rs | 15 ++- mm2src/crypto/Cargo.toml | 3 +- .../src/connection_handler.rs | 5 - .../kdf_walletconnect/src/inbound_message.rs | 6 +- mm2src/kdf_walletconnect/src/lib.rs | 104 ++++++++++-------- 6 files changed, 108 insertions(+), 76 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b2594389a..de1f0b3704 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -445,11 +445,11 @@ dependencies = [ [[package]] name = "bip39" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.13.0", "rand_core 0.5.1", "zeroize", ] @@ -461,16 +461,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0694ea59225b0c5f3cb405ff3f670e4828358ed26aec49dc352f730f0cb1a8a3" dependencies = [ "bech32", - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "secp256k1 0.24.3", ] +[[package]] +name = "bitcoin-internals" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb" + [[package]] name = "bitcoin_hashes" version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" +[[package]] +name = "bitcoin_hashes" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b" +dependencies = [ + "bitcoin-internals", + "hex-conservative", +] + [[package]] name = "bitcrypto" version = "0.1.0" @@ -825,7 +841,7 @@ dependencies = [ "base64 0.21.7", "bip32", "bitcoin", - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "bitcrypto", "blake2b_simd", "byteorder", @@ -1339,7 +1355,6 @@ dependencies = [ "num-traits", "parking_lot", "primitives", - "rand 0.8.5", "rpc", "rpc_task", "rustc-hex", @@ -2599,6 +2614,12 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +[[package]] +name = "hex-conservative" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20" + [[package]] name = "hex_fmt" version = "0.3.0" @@ -3733,7 +3754,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9680857590c3529cf8c7d32b04501f215f2bf1e029fdfa22f4112f66c1741e4" dependencies = [ "bech32", - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "lightning", "num-traits", "secp256k1 0.24.3", @@ -4776,10 +4797,11 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" dependencies = [ "anyhow", "chrono", + "getrandom 0.2.9", "hex", "lazy_static", "paste", @@ -5103,7 +5125,7 @@ dependencies = [ name = "primitives" version = "0.1.0" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "byteorder", "rustc-hex", "uint", @@ -5707,7 +5729,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" dependencies = [ "chrono", "data-encoding", @@ -5716,7 +5738,7 @@ dependencies = [ "http 1.1.0", "js-sys", "pin-project", - "rand 0.7.3", + "rand 0.8.5", "relay_rpc", "serde", "serde_json", @@ -5735,7 +5757,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" dependencies = [ "anyhow", "bs58 0.4.0", @@ -5743,6 +5765,7 @@ dependencies = [ "data-encoding", "derive_more", "ed25519-dalek 2.1.1", + "getrandom 0.2.9", "hex", "jsonwebtoken", "once_cell", @@ -6261,7 +6284,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b1629c9c557ef9b293568b338dddfc8208c98a18c59d722a9d53f859d9c9b62" dependencies = [ - "bitcoin_hashes", + "bitcoin_hashes 0.11.0", "secp256k1-sys 0.6.1", ] @@ -8109,7 +8132,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#b427ff077094254b224ce7b00c423f96878e938a" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" dependencies = [ "base64 0.21.7", "chacha20poly1305", diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 65df66a452..8fc18fd78a 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -181,16 +181,15 @@ pub async fn eth_request_wc_personal_sign( let chain_id = WcChainId::new_eip155(chain_id.to_string()); wc.validate_update_active_chain_id(&chain_id).await?; - let result = { - let account_str = wc.get_account_for_chain_id(&chain_id).await?; - let message = "Authenticate with Komodefi"; - let message_hex = format!("0x{}", hex::encode(message)); - let params = json!(&[&message_hex, &account_str]); - wc.send_session_request_and_wait(&chain_id, WcRequestMethods::PersonalSign, params, |data: String| { + let account_str = wc.get_account_for_chain_id(&chain_id).await?; + let message = "Authenticate with Komodefi"; + let message_hex = format!("0x{}", hex::encode(message)); + let params = json!(&[&message_hex, &account_str]); + let result = wc + .send_session_request_and_wait(&chain_id, WcRequestMethods::PersonalSign, params, |data: String| { Ok(extract_pubkey_from_signature(&data, message, &account_str)?) }) - .await? - }; + .await?; Ok(result) } diff --git a/mm2src/crypto/Cargo.toml b/mm2src/crypto/Cargo.toml index 6b7cf93d37..4a194c2951 100644 --- a/mm2src/crypto/Cargo.toml +++ b/mm2src/crypto/Cargo.toml @@ -34,7 +34,6 @@ mm2_err_handle = { path = "../mm2_err_handle" } num-traits = "0.2" parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } -rand = "0.8.4" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } rustc-hex = "2" @@ -63,4 +62,4 @@ tokio = { version = "1.20", default-features = false } trezor-udp = ["trezor/trezor-udp"] [patch.crates-io] -rand = { version = "0.8.5", package = "rand" } +rand_core = { version = "0.6.2", package = "bip39" } diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 6818a679fa..c07b01c066 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -93,8 +93,6 @@ pub(crate) async fn initialize_connection(this: Arc) { retry_secs += RETRY_INCREMENT; } - info!("Successfully connected to client after {} attempt(s).", retry_count + 1); - // Initialize storage if let Err(err) = this.storage.init().await { error!("Unable to initialize WalletConnect persistent storage: {err:?}. Only inmemory storage will be utilized for this Session."); @@ -113,9 +111,6 @@ pub(crate) async fn initialize_connection(this: Arc) { /// Implements exponential backoff retry mechanism for reconnection attempts. /// After successful reconnection, resubscribes to previous topics to restore full functionality. pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { - this.is_client_connected - .store(false, std::sync::atomic::Ordering::Relaxed); - let mut recv = this.connection_live_rx.lock().await; let mut backoff = 1; diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 0e0f2ca0c7..828adc9a61 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -9,7 +9,7 @@ use crate::{error::WalletConnectError, update::reply_session_update_request}, WalletConnectCtx}; -use common::log::info; +use common::log::{info, LogOnError}; use futures::sink::SinkExt; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::domain::{MessageId, Topic}; @@ -62,7 +62,7 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: R // Probably the best place to handle session propose response // as we might not get a feedback for a long time or even at all if let ResponseParamsSuccess::SessionPropose(propose) = &data { - process_session_propose_response(ctx, topic, propose).await.ok(); + process_session_propose_response(ctx, topic, propose).await.error_log(); } Ok(SessionMessage { @@ -77,5 +77,5 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: R }; let mut sender = ctx.message_tx.clone(); - sender.send(result).await.ok(); + sender.send(result).await.error_log(); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 6fc191d04d..7427a70eb7 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -12,7 +12,8 @@ use crate::session::rpc::propose::send_proposal_request; use chain::{WcChainId, WcRequestMethods, SUPPORTED_PROTOCOL}; use chrono::Utc; use common::custom_futures::timeout::FutureTimerExt; -use common::log::info; +use common::executor::{spawn_abortable, AbortOnDropHandle}; +use common::log::{debug, info}; use common::{executor::SpawnFuture, log::error}; use connection_handler::{initialize_connection, Handler}; use error::WalletConnectError; @@ -37,12 +38,13 @@ use serde::de::DeserializeOwned; use session::Session; use session::{key::SymKeyPair, SessionManager}; use std::collections::BTreeSet; -use std::sync::atomic::{AtomicBool, Ordering}; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType, SymKey}; +const WAIT_DURATION: Duration = Duration::from_secs(60); + #[async_trait::async_trait] pub trait WalletConnectOps { type Error; @@ -67,7 +69,6 @@ pub trait WalletConnectOps { pub struct WalletConnectCtx { pub client: Client, - is_client_connected: AtomicBool, pub pairing: PairingClient, pub session: SessionManager, @@ -81,11 +82,13 @@ pub struct WalletConnectCtx { connection_live_rx: Arc>>, message_tx: UnboundedSender, message_rx: Arc>>, + + _abort_handle: AbortOnDropHandle, } impl WalletConnectCtx { pub fn try_init(ctx: &MmArc) -> MmResult { - let (msg_sender, msg_receiver) = unbounded(); + let (inbound_message_tx, inbound_message_rx) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); let (message_tx, session_request_receiver) = unbounded(); @@ -97,15 +100,12 @@ impl WalletConnectCtx { let storage = SessionStorageDb::init(ctx)?; - let client = Client::new_unmanaged(); - ctx.spawner().spawn(client_event_loop( - client.control_rx().expect("client controller should never fail!"), - Handler::new("Komodefi", msg_sender, conn_live_sender), - )); + let handler = Handler::new("Komodefi", inbound_message_tx, conn_live_sender); + let (client, _abort_handle) = + Client::new_with_callback(handler, |r, h| spawn_abortable(client_event_loop(r, h))); Ok(Self { client, - is_client_connected: AtomicBool::default(), pairing, relay, storage, @@ -114,10 +114,12 @@ impl WalletConnectCtx { session: SessionManager::new(), subscriptions: Default::default(), - inbound_message_rx: Arc::new(msg_receiver.into()), + inbound_message_rx: Arc::new(inbound_message_rx.into()), connection_live_rx: Arc::new(conn_live_receiver.into()), message_rx: Arc::new(session_request_receiver.into()), message_tx, + + _abort_handle, }) } @@ -135,12 +137,11 @@ impl WalletConnectCtx { .aud(RELAY_ADDRESS) .ttl(Duration::from_secs(8 * 60 * 60)) .as_jwt(&key) - .unwrap() + .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))? }; let opts = ConnectionOptions::new(PROJECT_ID, auth).with_address(RELAY_ADDRESS); self.client.connect(&opts).await?; - self.is_client_connected.store(true, Ordering::Relaxed); Ok(()) } @@ -155,7 +156,11 @@ impl WalletConnectCtx { info!("Subscribing to topic: {topic:?}"); - self.client.subscribe(topic.clone()).await?; + self.client + .subscribe(topic.clone()) + .timeout(WAIT_DURATION) + .await + .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))??; info!("Subscribed to topic: {topic:?}"); @@ -213,13 +218,12 @@ impl WalletConnectCtx { .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; - // bring last session to the back. + // bring last active session to the back. sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); - for session in sessions { // delete expired session if now > session.expiry { - info!("Session {} expired, trying to delete from storage", session.topic); + debug!("Session {} expired, trying to delete from storage", session.topic); if let Err(err) = self.storage.delete_session(&session.topic).await { error!("Unable to delete session: {:?} from storage", err); } @@ -228,10 +232,8 @@ impl WalletConnectCtx { let topic = session.topic.clone(); let pairing_topic = session.pairing_topic.clone(); - - info!("Session found! activating :{}", topic); + debug!("Session found! activating :{}", topic); self.session.add_session(session).await; - self.client.batch_subscribe(vec![topic.clone(), pairing_topic]).await?; } @@ -244,11 +246,6 @@ impl WalletConnectCtx { topic: &Topic, param: RequestParams, ) -> MmResult<(), WalletConnectError> { - let is_client_connected = self.is_client_connected.load(Ordering::Relaxed); - if !is_client_connected { - self.connect_client().await?; - } - let irn_metadata = param.irn_metadata(); let message_id = MessageIdGenerator::new().next(); let request = Request::new(message_id, param.into()); @@ -256,8 +253,6 @@ impl WalletConnectCtx { self.publish_payload(topic, irn_metadata, Payload::Request(request)) .await?; - info!("Outbound request sent!"); - Ok(()) } @@ -302,27 +297,51 @@ impl WalletConnectCtx { irn_metadata: IrnMetadata, payload: Payload, ) -> MmResult<(), WalletConnectError> { - info!("Publishing message={:?} to topic: {topic}", payload); + debug!("Publishing message={:?} to topic: {topic}", payload); let message = { let sym_key = self.sym_key(topic).await?; let payload = serde_json::to_string(&payload)?; encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key)? }; - self.client + // Attempt to publish, retrying once on NotConnected error + match self + .client .publish( topic.clone(), - message, + message.clone(), None, irn_metadata.tag, Duration::from_secs(irn_metadata.ttl), irn_metadata.prompt, ) - .await?; - - info!("Message published successfully"); - - Ok(()) + .await + { + Ok(_) => { + info!("Message published successfully to topic: {topic}"); + Ok(()) + }, + Err(err) => { + if err.to_string().contains("WebsocketClient") { + debug!("Reconnecting client after NotConnected error..."); + self.connect_client().await?; + self.client + .publish( + topic.clone(), + message, + None, + irn_metadata.tag, + Duration::from_secs(irn_metadata.ttl), + irn_metadata.prompt, + ) + .await?; + info!("Message published successfully after reconnect"); + Ok(()) + } else { + MmError::err(err.into()) + } + }, + } } /// Checks if the current session is connected to a Ledger device. @@ -448,40 +467,37 @@ impl WalletConnectCtx { chain_id: &WcChainId, method: WcRequestMethods, params: serde_json::Value, - response_handler: F, + callback: F, ) -> MmResult where T: DeserializeOwned, F: Fn(T) -> MmResult, { - // Send request let active_topic = self.session.get_active_topic_or_err().await?; let request = SessionRequestRequest { chain_id: chain_id.to_string(), request: SessionRequest { method: method.as_ref().to_string(), - expiry: Some(Utc::now().timestamp() as u64 + 300), + expiry: Some(Utc::now().timestamp() as u64 + 60), params, }, }; self.publish_request(&active_topic, RequestParams::SessionRequest(request)) .await?; - // Wait for response - let wait_duration = Duration::from_secs(300); - if let Ok(Some(resp)) = self.message_rx.lock().await.next().timeout(wait_duration).await { + if let Ok(Some(resp)) = self.message_rx.lock().await.next().timeout(WAIT_DURATION).await { let result = resp.mm_err(WalletConnectError::InternalError)?; if let ResponseParamsSuccess::Arbitrary(data) = result.data { let data = serde_json::from_value::(data)?; let response = ResponseParamsSuccess::SessionEvent(true); self.publish_response_ok(&result.topic, response, &result.message_id) .await?; - return response_handler(data); + + return callback(data); } } - // Handle timeout/error - self.client.disconnect().await?; + // QUESTION: should we consider retrying request instead of returning error immediately. MmError::err(WalletConnectError::NoWalletFeedback) } From a43dc6066ec8761c9d38a9cca956b8e7321daece Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 6 Nov 2024 13:32:09 +0100 Subject: [PATCH 099/125] handle broadcast option for WalletConnect and some minor fixes --- Cargo.lock | 3 +- mm2src/coins/eth/eth_tests.rs | 2 ++ mm2src/coins/eth/eth_withdraw.rs | 16 ++++++---- mm2src/coins/eth/wallet_connect.rs | 3 +- mm2src/coins/lp_coins.rs | 5 ++-- mm2src/coins/qrc20/qrc20_tests.rs | 2 ++ mm2src/coins/tendermint/wallet_connect.rs | 29 ++++++++++--------- mm2src/coins/utxo/utxo_tests.rs | 13 +++++++++ mm2src/mm2_main/Cargo.toml | 1 + .../tests/docker_tests/qrc20_tests.rs | 4 +-- mm2src/mm2_net/Cargo.toml | 2 +- 11 files changed, 53 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de1f0b3704..099ee681b1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4270,6 +4270,7 @@ dependencies = [ "primitives", "prost", "prost-build", + "rand 0.6.5", "rand 0.7.3", "rcgen", "regex", @@ -4361,7 +4362,7 @@ dependencies = [ "cfg-if 1.0.0", "common", "derive_more", - "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", "futures 0.3.28", "futures-util", "gstuff", diff --git a/mm2src/coins/eth/eth_tests.rs b/mm2src/coins/eth/eth_tests.rs index c7f1e51d13..6c7c7d4f8c 100644 --- a/mm2src/coins/eth/eth_tests.rs +++ b/mm2src/coins/eth/eth_tests.rs @@ -226,6 +226,7 @@ fn test_withdraw_impl_manual_fee() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; block_on_f01(coin.get_balance()).unwrap(); @@ -275,6 +276,7 @@ fn test_withdraw_impl_fee_details() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; block_on_f01(coin.get_balance()).unwrap(); diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index c725bac29b..246aadf38f 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -321,11 +321,17 @@ where gas_price, }; - let (tx, bytes) = self - .coin() - .wc_sign_tx(&wc, params) - .await - .mm_err(|err| WithdrawError::SigningError(err.to_string()))?; + let (tx, bytes) = if req.broadcast { + self.coin() + .wc_send_tx(&wc, params) + .await + .mm_err(|err| WithdrawError::SigningError(err.to_string()))? + } else { + self.coin() + .wc_sign_tx(&wc, params) + .await + .mm_err(|err| WithdrawError::SigningError(err.to_string()))? + }; (tx.tx_hash(), bytes) }, diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 8fc18fd78a..f04cf9c08f 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -1,3 +1,4 @@ +/// https://docs.reown.com/advanced/multichain/rpc-reference/ethereum-rpc use crate::common::Future01CompatExt; use crate::Eip1559Ops; use crate::{BytesJson, TransactionErr}; @@ -223,7 +224,7 @@ fn extract_pubkey_from_signature( Ok((uncompressed, recovered_address)) } -pub fn recover(signature: &Signature, message: &Message) -> Result { +pub(crate) fn recover(signature: &Signature, message: &Message) -> Result { let recovery_id = { let recovery_id = (signature[64] as i32) .checked_sub(27) diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index bc532fa5aa..da599999b2 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -2122,8 +2122,7 @@ pub struct WithdrawRequest { memo: Option, /// Tendermint specific field used for manually providing the IBC channel IDs. ibc_source_channel: Option, - /// Currently, this flag is used by ETH/ERC20 coins activated with MetaMask **only**. - #[cfg(target_arch = "wasm32")] + /// Currently, this flag is used by ETH/ERC20 coins activated with MetaMask/WalletConnect **only**. #[serde(default)] broadcast: bool, } @@ -2177,7 +2176,6 @@ impl WithdrawRequest { fee: None, memo: None, ibc_source_channel: None, - #[cfg(target_arch = "wasm32")] broadcast: false, } } @@ -5600,6 +5598,7 @@ pub mod for_tests { fee, memo: None, ibc_source_channel: None, + broadcast: false, }; let init = init_withdraw(ctx.clone(), withdraw_req).await.unwrap(); let timeout = wait_until_ms(150000); diff --git a/mm2src/coins/qrc20/qrc20_tests.rs b/mm2src/coins/qrc20/qrc20_tests.rs index 930f078c53..1da173cfa1 100644 --- a/mm2src/coins/qrc20/qrc20_tests.rs +++ b/mm2src/coins/qrc20/qrc20_tests.rs @@ -95,6 +95,7 @@ fn test_withdraw_to_p2sh_address_should_fail() { fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; let err = block_on_f01(coin.withdraw(req)).unwrap_err().into_inner(); let expect = WithdrawError::InvalidAddress("QRC20 can be sent to P2PKH addresses only".to_owned()); @@ -142,6 +143,7 @@ fn test_withdraw_impl_fee_details() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap(); diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 432881ee53..9544defaca 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -1,3 +1,4 @@ +/// https://docs.reown.com/advanced/multichain/rpc-reference/cosmos-rpc use base64::engine::general_purpose; use base64::Engine; use cosmrs::proto::cosmos::tx::v1beta1::TxRaw; @@ -13,33 +14,33 @@ use std::str::FromStr; use super::{CosmosTransaction, TendermintCoin}; #[derive(Debug, Serialize, Deserialize, PartialEq)] -pub struct CosmosTxSignedData { - pub signature: CosmosTxSignature, - pub signed: CosmosSignData, +pub(crate) struct CosmosTxSignedData { + pub(crate) signature: CosmosTxSignature, + pub(crate) signed: CosmosSignData, } #[derive(Debug, Serialize, Deserialize, PartialEq)] -pub struct CosmosTxSignature { - pub pub_key: CosmosTxPublicKey, - pub signature: String, +pub(crate) struct CosmosTxSignature { + pub(crate) pub_key: CosmosTxPublicKey, + pub(crate) signature: String, } #[derive(Debug, Serialize, Deserialize, PartialEq)] -pub struct CosmosTxPublicKey { +pub(crate) struct CosmosTxPublicKey { #[serde(rename = "type")] - pub key_type: String, - pub value: String, + pub(crate) key_type: String, + pub(crate) value: String, } #[derive(Debug, Serialize, Deserialize, PartialEq)] #[serde(rename_all = "camelCase")] -pub struct CosmosSignData { - pub chain_id: String, - pub account_number: String, +pub(crate) struct CosmosSignData { + pub(crate) chain_id: String, + pub(crate) account_number: String, #[serde(deserialize_with = "deserialize_vec_field")] - pub auth_info_bytes: Vec, + pub(crate) auth_info_bytes: Vec, #[serde(deserialize_with = "deserialize_vec_field")] - pub body_bytes: Vec, + pub(crate) body_bytes: Vec, } #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)] diff --git a/mm2src/coins/utxo/utxo_tests.rs b/mm2src/coins/utxo/utxo_tests.rs index 8148cd4ce9..29a3a1875f 100644 --- a/mm2src/coins/utxo/utxo_tests.rs +++ b/mm2src/coins/utxo/utxo_tests.rs @@ -612,6 +612,7 @@ fn test_withdraw_impl_set_fixed_fee() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; let expected = Some( UtxoFeeDetails { @@ -661,6 +662,7 @@ fn test_withdraw_impl_sat_per_kb_fee() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; // The resulting transaction size might be 244 or 245 bytes depending on signature size // MM2 always expects the worst case during fee calculation @@ -713,6 +715,7 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap(); // The resulting transaction size might be 210 or 211 bytes depending on signature size @@ -767,6 +770,7 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_equal_to_max_dust_included_to_fee() }), memo: None, ibc_source_channel: None, + broadcast: false, }; let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap(); // The resulting transaction size might be 210 or 211 bytes depending on signature size @@ -821,6 +825,7 @@ fn test_withdraw_impl_sat_per_kb_fee_amount_over_max() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; block_on_f01(coin.withdraw(withdraw_req)).unwrap_err(); } @@ -862,6 +867,7 @@ fn test_withdraw_impl_sat_per_kb_fee_max() { }), memo: None, ibc_source_channel: None, + broadcast: false, }; // The resulting transaction size might be 210 or 211 bytes depending on signature size // MM2 always expects the worst case during fee calculation @@ -929,6 +935,7 @@ fn test_withdraw_kmd_rewards_impl( fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { coin: Some("KMD".into()), @@ -1011,6 +1018,7 @@ fn test_withdraw_rick_rewards_none() { fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; let expected_fee = TxFeeDetails::Utxo(UtxoFeeDetails { coin: Some(TEST_COIN_NAME.into()), @@ -3211,6 +3219,7 @@ fn test_withdraw_to_p2pk_fails() { fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; assert!(matches!( @@ -3269,6 +3278,7 @@ fn test_withdraw_to_p2pkh() { fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap(); let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap(); @@ -3329,6 +3339,7 @@ fn test_withdraw_to_p2sh() { fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap(); let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap(); @@ -3389,6 +3400,7 @@ fn test_withdraw_to_p2wpkh() { fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap(); let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap(); @@ -3444,6 +3456,7 @@ fn test_withdraw_p2pk_balance() { fee: None, memo: None, ibc_source_channel: None, + broadcast: false, }; let tx_details = block_on_f01(coin.withdraw(withdraw_req)).unwrap(); let transaction: UtxoTx = deserialize(tx_details.tx.tx_hex().unwrap().as_slice()).unwrap(); diff --git a/mm2src/mm2_main/Cargo.toml b/mm2src/mm2_main/Cargo.toml index d4af0213bd..5cfb8f0515 100644 --- a/mm2src/mm2_main/Cargo.toml +++ b/mm2src/mm2_main/Cargo.toml @@ -85,6 +85,7 @@ parking_lot = { version = "0.12.0", features = ["nightly"] } primitives = { path = "../mm2_bitcoin/primitives" } prost = "0.12" rand = { version = "0.7", features = ["std", "small_rng"] } +rand6 = { version = "0.6", package = "rand" } rmp-serde = "0.14.3" rpc = { path = "../mm2_bitcoin/rpc" } rpc_task = { path = "../rpc_task" } diff --git a/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs b/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs index 4ed3772f03..352b383941 100644 --- a/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs +++ b/mm2src/mm2_main/tests/docker_tests/qrc20_tests.rs @@ -20,7 +20,7 @@ use mm2_main::lp_swap::{dex_fee_amount, max_taker_vol_from_available}; use mm2_number::BigDecimal; use mm2_rpc::data::legacy::{CoinInitResponse, OrderbookResponse}; use mm2_test_helpers::structs::{trade_preimage_error, RpcErrorResponse, RpcSuccessResponse, TransactionDetails}; -use rand::Rng; +use rand6::Rng; use serde_json::{self as json, Value as Json}; use std::convert::TryFrom; use std::process::Command; @@ -1104,7 +1104,7 @@ fn test_max_taker_vol_dynamic_trade_fee() { // generate QTUM coin with the dynamic fee and fill the wallet by 2 Qtums let (_ctx, coin, priv_key) = generate_qtum_coin_with_random_privkey("QTUM", 2.into(), Some(0)); let my_address = coin.my_address().expect("!my_address"); - let mut rng = rand::thread_rng(); + let mut rng = rand6::thread_rng(); let mut qtum_balance = BigDecimal::from(2); let mut qtum_balance_steps = "2".to_owned(); for _ in 0..4 { diff --git a/mm2src/mm2_net/Cargo.toml b/mm2src/mm2_net/Cargo.toml index 380ed760eb..1f2b61551b 100644 --- a/mm2src/mm2_net/Cargo.toml +++ b/mm2src/mm2_net/Cargo.toml @@ -15,7 +15,7 @@ bytes = "1.1" cfg-if = "1.0" common = { path = "../common" } derive_more = "0.99" -ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } +ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } futures = { version = "0.3", package = "futures", features = ["compat", "async-await", "thread-pool"] } gstuff = "0.7" http = "0.2" From eea15326197e1ae6bcf32bc3dd549b6a190c5d8f Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 6 Nov 2024 14:57:59 +0100 Subject: [PATCH 100/125] remove unused --- mm2src/coins/eth.rs | 2 + mm2src/kdf_walletconnect/src/lib.rs | 7 -- .../src/session/rpc/delete.rs | 4 - .../src/session/rpc/propose.rs | 115 +++++++++--------- .../src/session/rpc/settle.rs | 3 +- 5 files changed, 60 insertions(+), 71 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index d43f4dc616..ebe66b5070 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2694,6 +2694,8 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw .map_to_mm(|err| RawTransactionError::TransactionError(err.get_plain_text_format())) }, EthPrivKeyPolicy::WalletConnect { .. } => { + //NOTE: doesn't work with wallets that doesn't support `eth_signTransaction` e.g + //Metamask let wc = { let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!") diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 7427a70eb7..8f7cf9bfda 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -77,7 +77,6 @@ pub struct WalletConnectCtx { relay: Relay, metadata: Metadata, - subscriptions: Arc>>, inbound_message_rx: Arc>>, connection_live_rx: Arc>>, message_tx: UnboundedSender, @@ -112,7 +111,6 @@ impl WalletConnectCtx { metadata: generate_metadata(), key_pair: SymKeyPair::new(), session: SessionManager::new(), - subscriptions: Default::default(), inbound_message_rx: Arc::new(inbound_message_rx.into()), connection_live_rx: Arc::new(conn_live_receiver.into()), @@ -166,11 +164,6 @@ impl WalletConnectCtx { send_proposal_request(self, &topic, namespaces).await?; - { - let mut subs = self.subscriptions.lock().await; - subs.push(topic); - }; - Ok(url) } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 270ff078fc..75843e3dcc 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -48,10 +48,6 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu ctx.client.unsubscribe(session.pairing_topic.clone()).await?; // Attempt to disconnect the pairing ctx.pairing.delete(session.pairing_topic.as_ref()).await; - // Remove subscriptions - let mut subs = ctx.subscriptions.lock().await; - subs.retain(|s| s != &session.topic); - subs.retain(|s| s != &session.pairing_topic); // delete session from storage as well. ctx.storage diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 917a2f9198..eee8c90b8a 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -14,7 +14,7 @@ use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{session_propose::{Proposer, SessionProposeRequest, SessionProposeResponse}, RequestParams, ResponseParamsSuccess}}; -/// Creates a new session proposal form topic and metadata. +/// Creates a new session proposal from topic and metadata. pub(crate) async fn send_proposal_request( ctx: &WalletConnectCtx, topic: &Topic, @@ -43,28 +43,29 @@ pub async fn reply_session_proposal_request( topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectError> { - let sender_public_key = const_hex::decode(&proposal.proposer.public_key)? - .as_slice() - .try_into() - .map_to_mm(|_| WalletConnectError::InternalError("Invalid sender_public_key".to_owned()))?; - - let session_key = SessionKey::from_osrng(&sender_public_key)?; - let session_topic: Topic = session_key.generate_topic().into(); - let subscription_id = ctx - .client - .subscribe(session_topic.clone()) - .await - .map_to_mm(|err| WalletConnectError::SubscriptionError(err.to_string()))?; - - let session = Session::new( - ctx, - session_topic.clone(), - subscription_id, - session_key, - topic.clone(), - proposal.proposer.metadata, - SessionType::Controller, - ); + let session = { + let sender_public_key = const_hex::decode(&proposal.proposer.public_key)? + .as_slice() + .try_into() + .map_to_mm(|_| WalletConnectError::InternalError("Invalid sender_public_key".to_owned()))?; + let session_key = SessionKey::from_osrng(&sender_public_key)?; + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectError::SubscriptionError(err.to_string()))?; + + Session::new( + ctx, + session_topic.clone(), + subscription_id, + session_key, + topic.clone(), + proposal.proposer.metadata, + SessionType::Controller, + ) + }; session .propose_namespaces .supported(&proposal.required_namespaces) @@ -79,14 +80,9 @@ pub async fn reply_session_proposal_request( // Add session to session lists ctx.session.add_session(session.clone()).await; - // Add topic to subscription list - let mut subs = ctx.subscriptions.lock().await; - subs.push(session_topic); } - { - send_session_settle_request(ctx, &session).await?; - }; + send_session_settle_request(ctx, &session).await?; // Respond to incoming session propose. let param = ResponseParamsSuccess::SessionPropose(SessionProposeResponse { @@ -105,34 +101,38 @@ pub(crate) async fn process_session_propose_response( pairing_topic: &Topic, response: &SessionProposeResponse, ) -> MmResult<(), WalletConnectError> { - let other_public_key = const_hex::decode(&response.responder_public_key)? - .as_slice() - .try_into() - .unwrap(); - - let mut session_key = SessionKey::new(ctx.key_pair.public_key); - session_key.generate_symmetric_key(&ctx.key_pair.secret, &other_public_key)?; - - let session_topic: Topic = session_key.generate_topic().into(); - let subscription_id = ctx - .client - .subscribe(session_topic.clone()) - .await - .map_to_mm(|err| WalletConnectError::SubscriptionError(err.to_string()))?; - - let mut session = Session::new( - ctx, - session_topic.clone(), - subscription_id, - session_key, - pairing_topic.clone(), - generate_metadata(), - SessionType::Proposer, - ); - session.relay = response.relay.clone(); - session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; - session.controller.public_key = response.responder_public_key.clone(); + let session_key = { + let other_public_key = const_hex::decode(&response.responder_public_key)? + .as_slice() + .try_into() + .unwrap(); + let mut session_key = SessionKey::new(ctx.key_pair.public_key); + session_key.generate_symmetric_key(&ctx.key_pair.secret, &other_public_key)?; + session_key + }; + let session = { + let session_topic: Topic = session_key.generate_topic().into(); + let subscription_id = ctx + .client + .subscribe(session_topic.clone()) + .await + .map_to_mm(|err| WalletConnectError::SubscriptionError(err.to_string()))?; + + let mut session = Session::new( + ctx, + session_topic.clone(), + subscription_id, + session_key, + pairing_topic.clone(), + generate_metadata(), + SessionType::Proposer, + ); + session.relay = response.relay.clone(); + session.expiry = Utc::now().timestamp() as u64 + THIRTY_DAYS; + session.controller.public_key = response.responder_public_key.clone(); + session + }; { // save session to storage ctx.storage @@ -142,9 +142,6 @@ pub(crate) async fn process_session_propose_response( // Add session to session lists ctx.session.add_session(session.clone()).await; - // Add topic to subscription list - let mut subs = ctx.subscriptions.lock().await; - subs.push(session_topic.clone()); }; // Activate pairing_topic diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 4cdf9ef407..3205872fc3 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -43,7 +43,7 @@ pub(crate) async fn reply_session_settle_request( { let session = ctx.session.get_session_mut(topic); if let Some(mut session) = session { - session.namespaces = settle.namespaces.0.clone(); + session.namespaces = settle.namespaces.0; session.controller = settle.controller.clone(); session.relay = settle.relay; session.expiry = settle.expiry; @@ -66,6 +66,7 @@ pub(crate) async fn reply_session_settle_request( ctx.publish_response_ok(topic, param, message_id).await?; // Delete other sessions with same controller + // TODO: we might not want to do this! let all_sessions = ctx.session.get_sessions_full(); for session in all_sessions { if session.controller == settle.controller && session.topic.as_ref() != topic.as_ref() { From fb9f8c163fa289b77780566cfaa854a6723effe1 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 6 Nov 2024 16:41:57 +0100 Subject: [PATCH 101/125] fix: handle unexpected end of file --- .../src/connection_handler.rs | 19 +++++++++++++------ mm2src/kdf_walletconnect/src/lib.rs | 2 +- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index c07b01c066..70ef3e37e6 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -19,14 +19,14 @@ const RETRY_INCREMENT: f64 = 5.0; pub struct Handler { name: &'static str, msg_sender: UnboundedSender, - conn_live_sender: UnboundedSender<()>, + conn_live_sender: UnboundedSender>, } impl Handler { pub fn new( name: &'static str, msg_sender: UnboundedSender, - conn_live_sender: UnboundedSender<()>, + conn_live_sender: UnboundedSender>, ) -> Self { Self { name, @@ -44,7 +44,7 @@ impl ConnectionHandler for Handler { fn disconnected(&mut self, frame: Option>) { info!("\n[{}] connection closed: frame={frame:?}", self.name); - if let Err(e) = self.conn_live_sender.start_send(()) { + if let Err(e) = self.conn_live_sender.start_send(None) { error!("\n[{}] failed to send to the receiver: {e}", self.name); } } @@ -62,14 +62,14 @@ impl ConnectionHandler for Handler { fn inbound_error(&mut self, error: ClientError) { info!("\n[{}] inbound error: {error}", self.name); - if let Err(e) = self.conn_live_sender.start_send(()) { + if let Err(e) = self.conn_live_sender.start_send(Some(error.to_string())) { error!("\n[{}] failed to send to the receiver: {e}", self.name); } } fn outbound_error(&mut self, error: ClientError) { info!("\n[{}] outbound error: {error}", self.name); - if let Err(e) = self.conn_live_sender.start_send(()) { + if let Err(e) = self.conn_live_sender.start_send(Some(error.to_string())) { error!("\n[{}] failed to send to the receiver: {e}", self.name); } } @@ -114,8 +114,15 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { let mut recv = this.connection_live_rx.lock().await; let mut backoff = 1; - while let Some(_msg) = recv.next().await { + while let Some(msg) = recv.next().await { info!("Connection disconnected. Attempting to reconnect..."); + // In some rare occasion, WalletConnect websocket client returns + // `Websocket transport error: IO error: unexpected end of file` + // probably a problem with the relay server. + let msg = msg.map_or("".to_string(), |m| m); + if msg.contains("unexpected end of file") { + this.client.disconnect().await.ok(); + } loop { match this.connect_client().await { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 8f7cf9bfda..4cc52c17bd 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -78,7 +78,7 @@ pub struct WalletConnectCtx { relay: Relay, metadata: Metadata, inbound_message_rx: Arc>>, - connection_live_rx: Arc>>, + connection_live_rx: Arc>>>, message_tx: UnboundedSender, message_rx: Arc>>, From d58b18f90aff848789cc27f07e3f195b7f370b64 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 6 Nov 2024 17:26:27 +0100 Subject: [PATCH 102/125] re-enable use_watcher --- Cargo.lock | 2 +- .../src/tendermint_with_assets_activation.rs | 7 ------- mm2src/mm2_core/src/mm_ctx.rs | 2 +- mm2src/mm2_eth/Cargo.toml | 2 +- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 099ee681b1..ee1f1772d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4131,7 +4131,7 @@ name = "mm2_eth" version = "0.1.0" dependencies = [ "ethabi", - "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?branch=fix-pubkey-recover-from-sig)", + "ethkey 0.3.0 (git+https://github.com/KomodoPlatform/mm2-parity-ethereum.git?rev=mm2-v2.1.1)", "hex", "indexmap 1.9.3", "itertools", diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index ce32ec8750..3def8beb84 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -309,13 +309,6 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { TendermintActivationPolicy::with_public_key(pubkey) }, TendermintPubkeyActivationParams::WalletConnect(_params) => { - if ctx.is_watcher() || ctx.use_watchers() { - return MmError::err(TendermintInitError { - ticker: ticker.to_string(), - kind: TendermintInitErrorKind::CantUseWatchersWithPubkeyPolicy, - }); - }; - activate_with_walletconnect( &ctx, protocol_conf.chain_id.as_ref(), diff --git a/mm2src/mm2_core/src/mm_ctx.rs b/mm2src/mm2_core/src/mm_ctx.rs index 22673c71ad..e2e02c70f7 100644 --- a/mm2src/mm2_core/src/mm_ctx.rs +++ b/mm2src/mm2_core/src/mm_ctx.rs @@ -327,7 +327,7 @@ impl MmCtx { pub fn is_watcher(&self) -> bool { self.conf["is_watcher"].as_bool().unwrap_or_default() } - pub fn use_watchers(&self) -> bool { self.conf["use_watchers"].as_bool().unwrap_or(false) } + pub fn use_watchers(&self) -> bool { self.conf["use_watchers"].as_bool().unwrap_or(true) } pub fn netid(&self) -> u16 { let netid = self.conf["netid"].as_u64().unwrap_or(0); diff --git a/mm2src/mm2_eth/Cargo.toml b/mm2src/mm2_eth/Cargo.toml index 8f84e2cf76..5992896424 100644 --- a/mm2src/mm2_eth/Cargo.toml +++ b/mm2src/mm2_eth/Cargo.toml @@ -8,7 +8,7 @@ doctest = false [dependencies] ethabi = { version = "17.0.0" } -ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", branch = "fix-pubkey-recover-from-sig" } +ethkey = { git = "https://github.com/KomodoPlatform/mm2-parity-ethereum.git", rev = "mm2-v2.1.1" } hex = "0.4.2" indexmap = "1.7.0" itertools = "0.10" From 045625b810f8b7252a5b7e036bcd5485e758499c Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 6 Nov 2024 21:38:00 +0100 Subject: [PATCH 103/125] cleanups --- mm2src/coins/eth.rs | 14 ++++- mm2src/coins/eth/wallet_connect.rs | 63 ++++++------------- mm2src/coins/tendermint/wallet_connect.rs | 9 +-- .../src/tendermint_with_assets_activation.rs | 39 ++++++------ 4 files changed, 53 insertions(+), 72 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index ebe66b5070..8e644d75e4 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2694,8 +2694,8 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw .map_to_mm(|err| RawTransactionError::TransactionError(err.get_plain_text_format())) }, EthPrivKeyPolicy::WalletConnect { .. } => { - //NOTE: doesn't work with wallets that doesn't support `eth_signTransaction` e.g - //Metamask + // NOTE: doesn't work with wallets that doesn't support `eth_signTransaction`. + // e.g Metamask let wc = { let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!") @@ -2722,6 +2722,7 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw .await .map_to_mm(RawTransactionError::InvalidParam)?; + info!(target: "sign-and-send", "WalletConnect signing and sending tx…"); let (signed_tx, _) = coin .wc_sign_tx(&wc, WcEthTxParams { my_address, @@ -3688,6 +3689,7 @@ impl EthCoin { .single_addr_or_err() .await .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; + sign_and_send_transaction_with_keypair(&coin, key_pair, address, value, action, data, gas).await }, EthPrivKeyPolicy::WalletConnect { .. } => { @@ -3695,7 +3697,13 @@ impl EthCoin { let ctx = MmArc::from_weak(&coin.ctx).expect("No context"); WalletConnectCtx::from_ctx(&ctx).expect("WalletConnectCtx should be initialized by now!") }; - send_transaction_with_walletconnect(coin, &wc, value, action, &data, gas).await + let address = coin + .derivation_method + .single_addr_or_err() + .await + .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))?; + + send_transaction_with_walletconnect(coin, &wc, address, value, action, &data, gas).await }, EthPrivKeyPolicy::Trezor => Err(TransactionErr::Plain(ERRL!("Trezor is not supported for swaps yet!"))), #[cfg(target_arch = "wasm32")] diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index f04cf9c08f..83b9da46c0 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -5,6 +5,7 @@ use crate::{BytesJson, TransactionErr}; use common::log::info; use derive_more::Display; +use enum_derives::EnumFromStringify; use ethcore_transaction::{Action, SignedTransaction}; use ethereum_types::H256; use ethereum_types::{Address, Public, H160, H520, U256}; @@ -21,12 +22,14 @@ use web3::signing::hash_message; use super::EthCoin; -#[derive(Display, Debug)] +#[derive(Display, Debug, EnumFromStringify)] pub enum EthWalletConnectError { UnsupportedChainId(WcChainId), InvalidSignature(String), AccoountMisMatch(String), + #[from_stringify("rlp::DecoderError", "hex::FromHexError")] TxDecodingFailed(String), + #[from_stringify("ethkey::Error")] InternalError(String), InvalidTxData(String), WalletConnectError(WalletConnectError), @@ -36,22 +39,6 @@ impl From for EthWalletConnectError { fn from(value: WalletConnectError) -> Self { Self::WalletConnectError(value) } } -impl From for WalletConnectError { - fn from(value: EthWalletConnectError) -> Self { Self::SessionError(value.to_string()) } -} - -impl From for EthWalletConnectError { - fn from(value: rlp::DecoderError) -> Self { Self::TxDecodingFailed(value.to_string()) } -} - -impl From for EthWalletConnectError { - fn from(value: ethkey::Error) -> Self { Self::InternalError(value.to_string()) } -} - -impl From for EthWalletConnectError { - fn from(value: hex::FromHexError) -> Self { Self::TxDecodingFailed(value.to_string()) } -} - pub struct WcEthTxParams<'a> { pub(crate) gas: U256, pub(crate) nonce: U256, @@ -124,7 +111,6 @@ impl WalletConnectOps for EthCoin { // First 4 bytes from WalletConnect represents Protoc info hex::decode(&tx_hex[4..])? }; - let unverified = rlp::decode(&bytes)?; let signed = SignedTransaction::new(unverified)?; let bytes = rlp::encode(&signed); @@ -144,22 +130,14 @@ impl WalletConnectOps for EthCoin { .await? }; let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); - let maybe_signed_tx = { // Wait for 10 seconds for the transaction to appear on the RPC node. let wait_rpc_timeout = 10_000; let check_every = 1.; - self.wait_for_tx_appears_on_rpc( - H256::from_slice( - &hex::decode(tx_hash).map_to_mm(|err| EthWalletConnectError::InvalidTxData(err.to_string()))?, - ), - wait_rpc_timeout, - check_every, - ) - .await - .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))? + self.wait_for_tx_appears_on_rpc(H256::from_slice(&hex::decode(tx_hash)?), wait_rpc_timeout, check_every) + .await + .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))? }; - let signed_tx = match maybe_signed_tx { Some(signed_tx) => signed_tx, None => { @@ -184,15 +162,18 @@ pub async fn eth_request_wc_personal_sign( let account_str = wc.get_account_for_chain_id(&chain_id).await?; let message = "Authenticate with Komodefi"; - let message_hex = format!("0x{}", hex::encode(message)); - let params = json!(&[&message_hex, &account_str]); - let result = wc + let params = { + let message_hex = format!("0x{}", hex::encode(message)); + json!(&[&message_hex, &account_str]) + }; + let data = wc .send_session_request_and_wait(&chain_id, WcRequestMethods::PersonalSign, params, |data: String| { - Ok(extract_pubkey_from_signature(&data, message, &account_str)?) + extract_pubkey_from_signature(&data, message, &account_str) + .mm_err(|err| WalletConnectError::SessionError(err.to_string())) }) .await?; - Ok(result) + Ok(data) } fn extract_pubkey_from_signature( @@ -211,7 +192,6 @@ fn extract_pubkey_from_signature( EthWalletConnectError::InvalidSignature(error) })? }; - let mut public = Public::default(); public.as_mut().copy_from_slice(&uncompressed[1..65]); @@ -243,35 +223,30 @@ pub(crate) fn recover(signature: &Signature, message: &Message) -> Result Result { - let address = try_tx_s!(coin - .derivation_method - .single_addr_or_err() - .await - .map_err(|e| TransactionErr::Plain(ERRL!("{}", e)))); - info!(target: "sign-and-send", "get_gas_price…"); let pay_for_gas_option = try_tx_s!( coin.get_swap_pay_for_gas_option(coin.get_swap_transaction_fee_policy()) .await ); - let (nonce, _) = try_tx_s!(coin.clone().get_addr_nonce(address).compat().await); + let (nonce, _) = try_tx_s!(coin.clone().get_addr_nonce(my_address).compat().await); let params = WcEthTxParams { gas, nonce, data, - my_address: address, + my_address, action, value, gas_price: pay_for_gas_option.get_gas_price(), }; // Please note that this method may take a long time // due to `eth_sendTransaction` requests. - info!(target: "sign-and-send", "wallet signing and sending tx…"); + info!(target: "sign-and-send", "WalletConnect signing and sending tx…"); let (signed_tx, _) = try_tx_s!(coin.wc_send_tx(wc, params).await); Ok(signed_tx) diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 9544defaca..b01e074977 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -53,7 +53,6 @@ pub enum CosmosAccountAlgo { impl FromStr for CosmosAccountAlgo { type Err = String; - fn from_str(s: &str) -> Result { match s { "secp256k1" => Ok(Self::Secp256k1), @@ -83,7 +82,6 @@ impl WalletConnectOps for TendermintCoin { async fn wc_chain_id(&self, wc: &WalletConnectCtx) -> Result { let chain_id = WcChainId::new_cosmos(self.chain_id.to_string()); wc.validate_update_active_chain_id(&chain_id).await?; - Ok(chain_id) } @@ -103,6 +101,7 @@ impl WalletConnectOps for TendermintCoin { let signature = general_purpose::STANDARD .decode(data.signature.signature) .map_to_mm(|err| WalletConnectError::PayloadError(err.to_string()))?; + Ok(TxRaw { body_bytes: data.signed.body_bytes, auth_info_bytes: data.signed.auth_info_bytes, @@ -234,7 +233,8 @@ mod test_cosmos_walletconnect { #[test] fn test_decode_base64() { - let base64_data = "SGVsbG8gd29ybGQ="; // "Hello world" in base64 + // "Hello world" in base64 + let base64_data = "SGVsbG8gd29ybGQ="; let expected = b"Hello world".to_vec(); let result = decode_data(base64_data); assert_eq!(result.unwrap(), expected, "Base64 decoding failed"); @@ -242,7 +242,8 @@ mod test_cosmos_walletconnect { #[test] fn test_decode_hex() { - let hex_data = "48656c6c6f20776f726c64"; // "Hello world" in hex + // "Hello world" in hex + let hex_data = "48656c6c6f20776f726c64"; let expected = b"Hello world".to_vec(); let result = decode_data(hex_data); assert_eq!(result.unwrap(), expected, "Hex decoding failed"); diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 3def8beb84..1c4cb113fe 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -40,12 +40,6 @@ impl RegisterTokenInfo for TendermintCoin { } } -#[derive(Debug, Clone, Default, Serialize, Deserialize)] -pub struct WalletConnectParams { - #[serde(default)] - pub enabled: bool, -} - #[derive(Debug, Clone, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum TendermintPubkeyActivationParams { @@ -56,7 +50,7 @@ pub enum TendermintPubkeyActivationParams { is_ledger_connection: bool, }, /// Activation via WalletConnect - WalletConnect(WalletConnectParams), + WalletConnect, } #[derive(Clone, Deserialize)] @@ -241,13 +235,22 @@ async fn activate_with_walletconnect( ticker: &str, wallet_type: &mut TendermintWalletConnectionType, ) -> MmResult { - let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); - let account = cosmos_get_accounts_impl(&wc, chain_id) - .await - .mm_err(|err| TendermintInitError { - ticker: ticker.to_string(), - kind: TendermintInitErrorKind::UnableToFetchChainAccount(err.to_string()), - })?; + let account = { + let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + + if wc.is_ledger_connection().await { + *wallet_type = TendermintWalletConnectionType::WcLedger; + } else { + *wallet_type = TendermintWalletConnectionType::Wc; + }; + + cosmos_get_accounts_impl(&wc, chain_id) + .await + .mm_err(|err| TendermintInitError { + ticker: ticker.to_string(), + kind: TendermintInitErrorKind::UnableToFetchChainAccount(err.to_string()), + })? + }; let pubkey = match account.algo { CosmosAccountAlgo::Secp256k1 | CosmosAccountAlgo::TendermintSecp256k1 => { @@ -259,12 +262,6 @@ async fn activate_with_walletconnect( kind: TendermintInitErrorKind::Internal(e), })?; - if wc.is_ledger_connection().await { - *wallet_type = TendermintWalletConnectionType::WcLedger; - } else { - *wallet_type = TendermintWalletConnectionType::Wc; - }; - Ok(TendermintActivationPolicy::with_public_key(pubkey)) } @@ -308,7 +305,7 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { TendermintActivationPolicy::with_public_key(pubkey) }, - TendermintPubkeyActivationParams::WalletConnect(_params) => { + TendermintPubkeyActivationParams::WalletConnect => { activate_with_walletconnect( &ctx, protocol_conf.chain_id.as_ref(), From 65c7f902d9cb669b849f0692ae6489e55acc3e99 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 12 Nov 2024 11:40:28 +0100 Subject: [PATCH 104/125] fix websocket connection drop --- Cargo.lock | 9 +- .../src/connection_handler.rs | 68 +++------ .../kdf_walletconnect/src/inbound_message.rs | 4 +- mm2src/kdf_walletconnect/src/lib.rs | 138 +++++++++++------- mm2src/kdf_walletconnect/src/pairing.rs | 5 +- .../src/session/rpc/delete.rs | 4 +- .../kdf_walletconnect/src/session/rpc/ping.rs | 5 +- .../src/session/rpc/propose.rs | 2 +- 8 files changed, 114 insertions(+), 121 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ee1f1772d8..a934484167 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4798,10 +4798,11 @@ dependencies = [ [[package]] name = "pairing_api" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#d208b549a0e12e6c232551269e7bc564a6cee004" dependencies = [ "anyhow", "chrono", + "dashmap", "getrandom 0.2.9", "hex", "lazy_static", @@ -5730,7 +5731,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "relay_client" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#d208b549a0e12e6c232551269e7bc564a6cee004" dependencies = [ "chrono", "data-encoding", @@ -5758,7 +5759,7 @@ dependencies = [ [[package]] name = "relay_rpc" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#d208b549a0e12e6c232551269e7bc564a6cee004" dependencies = [ "anyhow", "bs58 0.4.0", @@ -8133,7 +8134,7 @@ dependencies = [ [[package]] name = "wc_common" version = "0.1.0" -source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#2372fa5f4a7b5f22c6489ecb4938970f6a37dea0" +source = "git+https://github.com/komodoplatform/walletconnectrust?branch=pairing-api#d208b549a0e12e6c232551269e7bc564a6cee004" dependencies = [ "base64 0.21.7", "chacha20poly1305", diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 70ef3e37e6..eb5cb2fd53 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -1,16 +1,13 @@ -use std::sync::Arc; - use crate::storage::WalletConnectStorageOps; -use crate::{WalletConnectCtx, WalletConnectError}; +use crate::WalletConnectCtx; use common::executor::Timer; -use common::log::{error, info}; +use common::log::{debug, error, info}; use futures::channel::mpsc::UnboundedSender; use futures::StreamExt; -use mm2_err_handle::prelude::*; use relay_client::error::ClientError; use relay_client::websocket::{CloseFrame, ConnectionHandler, PublishedMessage}; -use relay_rpc::domain::Topic; +use std::sync::Arc; const INITIAL_RETRY_SECS: f64 = 5.0; const MAX_BACKOFF: u64 = 60; @@ -38,39 +35,39 @@ impl Handler { impl ConnectionHandler for Handler { fn connected(&mut self) { - info!("\n[{}] connection to WalletConnect relay server successful", self.name); + debug!("[{}] connection to WalletConnect relay server successful", self.name); } fn disconnected(&mut self, frame: Option>) { - info!("\n[{}] connection closed: frame={frame:?}", self.name); + debug!("[{}] connection closed: frame={frame:?}", self.name); if let Err(e) = self.conn_live_sender.start_send(None) { - error!("\n[{}] failed to send to the receiver: {e}", self.name); + error!("[{}] failed to send to the receiver: {e}", self.name); } } fn message_received(&mut self, message: PublishedMessage) { - info!( - "\n[{}] inbound message: message_id={} topic={} tag={} message={}", + debug!( + "[{}] inbound message: message_id={} topic={} tag={} message={}", self.name, message.message_id, message.topic, message.tag, message.message, ); if let Err(e) = self.msg_sender.start_send(message) { - error!("\n[{}] failed to send to the receiver: {e}", self.name); + error!("[{}] failed to send to the receiver: {e}", self.name); } } fn inbound_error(&mut self, error: ClientError) { - info!("\n[{}] inbound error: {error}", self.name); + debug!("[{}] inbound error: {error}", self.name); if let Err(e) = self.conn_live_sender.start_send(Some(error.to_string())) { - error!("\n[{}] failed to send to the receiver: {e}", self.name); + error!("[{}] failed to send to the receiver: {e}", self.name); } } fn outbound_error(&mut self, error: ClientError) { - info!("\n[{}] outbound error: {error}", self.name); + debug!("[{}] outbound error: {error}", self.name); if let Err(e) = self.conn_live_sender.start_send(Some(error.to_string())) { - error!("\n[{}] failed to send to the receiver: {e}", self.name); + error!("[{}] failed to send to the receiver: {e}", self.name); } } } @@ -85,7 +82,7 @@ pub(crate) async fn initialize_connection(this: Arc) { while let Err(err) = this.connect_client().await { retry_count += 1; - error!( + info!( "Error during initial connection attempt {}: {:?}. Retrying in {retry_secs} seconds...", retry_count, err ); @@ -115,27 +112,17 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { let mut backoff = 1; while let Some(msg) = recv.next().await { - info!("Connection disconnected. Attempting to reconnect..."); - // In some rare occasion, WalletConnect websocket client returns - // `Websocket transport error: IO error: unexpected end of file` - // probably a problem with the relay server. - let msg = msg.map_or("".to_string(), |m| m); - if msg.contains("unexpected end of file") { - this.client.disconnect().await.ok(); - } + info!("WalletConnect disconnected with message: {msg:?}. Attempting to reconnect..."); loop { - match this.connect_client().await { + match this.reconnect_and_subscribe().await { Ok(_) => { - if let Err(e) = resubscribe_to_topics(this, None).await { - error!("Failed to resubscribe after reconnection: {:?}", e); - } info!("Reconnection process complete."); backoff = 1; break; }, Err(e) => { - error!("Reconnection attempt failed: {:?}. Retrying in {:?}...", e, backoff); + info!("Reconnection attempt failed: {:?}. Retrying in {:?}...", e, backoff); Timer::sleep(backoff as f64).await; backoff = std::cmp::min(backoff * 2, MAX_BACKOFF); }, @@ -143,24 +130,3 @@ pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { } } } - -/// Resubscribes to previously active topics after reconnection. -/// Called by handle_disconnections to restore subscription state. -async fn resubscribe_to_topics(this: &WalletConnectCtx, topic: Option<&Topic>) -> MmResult<(), WalletConnectError> { - if let Some(topic) = topic { - if let Some(session) = this.session.get_session(topic) { - this.client - .batch_subscribe(vec![session.topic.clone(), session.pairing_topic.clone()]) - .await?; - return Ok(()); - } - } - let sessions = this.session.get_sessions(); - for session in sessions { - this.client - .batch_subscribe(vec![session.topic.into(), session.pairing_topic.into()]) - .await?; - } - - Ok(()) -} diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 828adc9a61..0fd3545cb4 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -59,8 +59,8 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: R let result = match response { Response::Success(value) => match serde_json::from_value::(value.result) { Ok(data) => { - // Probably the best place to handle session propose response - // as we might not get a feedback for a long time or even at all + // TODO: move to session::proposal mod and spawn in a different thread to avoid + // blocking if let ResponseParamsSuccess::SessionPropose(propose) = &data { process_session_propose_response(ctx, topic, propose).await.error_log(); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 4cc52c17bd..fb4d2e917a 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -12,7 +12,7 @@ use crate::session::rpc::propose::send_proposal_request; use chain::{WcChainId, WcRequestMethods, SUPPORTED_PROTOCOL}; use chrono::Utc; use common::custom_futures::timeout::FutureTimerExt; -use common::executor::{spawn_abortable, AbortOnDropHandle}; +use common::executor::{spawn_abortable, AbortOnDropHandle, Timer}; use common::log::{debug, info}; use common::{executor::SpawnFuture, log::error}; use connection_handler::{initialize_connection, Handler}; @@ -99,9 +99,10 @@ impl WalletConnectCtx { let storage = SessionStorageDb::init(ctx)?; - let handler = Handler::new("Komodefi", inbound_message_tx, conn_live_sender); - let (client, _abort_handle) = - Client::new_with_callback(handler, |r, h| spawn_abortable(client_event_loop(r, h))); + let (client, _abort_handle) = Client::new_with_callback( + Handler::new("Komodefi", inbound_message_tx, conn_live_sender), + |r, h| spawn_abortable(client_event_loop(r, h)), + ); Ok(Self { client, @@ -144,15 +145,28 @@ impl WalletConnectCtx { Ok(()) } + pub(crate) async fn reconnect_and_subscribe(&self) -> MmResult<(), WalletConnectError> { + self.connect_client().await?; + // Resubscribes to previously active session topics after reconnection. + let sessions = self.session.get_sessions(); + for session in sessions { + self.client + .batch_subscribe(vec![session.topic.into(), session.pairing_topic.into()]) + .await?; + } + + Ok(()) + } + /// Create a WalletConnect pairing connection url. pub async fn new_connection(&self, namespaces: Option) -> MmResult { let namespaces = match namespaces { Some(value) => Some(serde_json::from_value(value)?), None => None, }; - let (topic, url) = self.pairing.create(self.metadata.clone(), None).await?; + let (topic, url) = self.pairing.create(self.metadata.clone(), None)?; - info!("Subscribing to topic: {topic:?}"); + info!("[topic] Subscribing to topic"); self.client .subscribe(topic.clone()) @@ -160,7 +174,7 @@ impl WalletConnectCtx { .await .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))??; - info!("Subscribed to topic: {topic:?}"); + info!("[topic] Subscribed to topic"); send_proposal_request(self, &topic, namespaces).await?; @@ -168,12 +182,12 @@ impl WalletConnectCtx { } /// Retrieves the symmetric key associated with a given `topic`. - async fn sym_key(&self, topic: &Topic) -> MmResult { + fn sym_key(&self, topic: &Topic) -> MmResult { if let Some(key) = self.session.sym_key(topic) { return Ok(key); } - if let Ok(key) = self.pairing.sym_key(topic.as_ref()).await { + if let Ok(key) = self.pairing.sym_key(topic) { return Ok(key); } @@ -185,18 +199,18 @@ impl WalletConnectCtx { /// Handles an inbound published message by decrypting, decoding, and processing it. async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectError> { let message = { - let key = self.sym_key(&msg.topic).await?; + let key = self.sym_key(&msg.topic)?; decode_and_decrypt_type0(msg.message.as_bytes(), &key)? }; - info!("Inbound message payload={message}"); + info!("[{}] Inbound message payload={message}", msg.topic); match serde_json::from_str(&message)? { Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await, } - info!("Inbound message was handled successfully"); + info!("[{}] Inbound message was handled successfully", msg.topic); Ok(()) } @@ -218,16 +232,16 @@ impl WalletConnectCtx { if now > session.expiry { debug!("Session {} expired, trying to delete from storage", session.topic); if let Err(err) = self.storage.delete_session(&session.topic).await { - error!("Unable to delete session: {:?} from storage", err); + error!("[{}] Unable to delete session from storage: {err:?}", session.topic); } continue; }; let topic = session.topic.clone(); let pairing_topic = session.pairing_topic.clone(); - debug!("Session found! activating :{}", topic); + debug!("[{topic}] Session found! activating"); self.session.add_session(session).await; - self.client.batch_subscribe(vec![topic.clone(), pairing_topic]).await?; + self.client.batch_subscribe(vec![topic, pairing_topic]).await?; } Ok(()) @@ -290,51 +304,63 @@ impl WalletConnectCtx { irn_metadata: IrnMetadata, payload: Payload, ) -> MmResult<(), WalletConnectError> { - debug!("Publishing message={:?} to topic: {topic}", payload); + const MAX_RETRIES: usize = 5; + const PUBLISH_TIMEOUT_SECS: f64 = 5.0; + + info!("[{topic}] Publishing message={payload:?}"); let message = { - let sym_key = self.sym_key(topic).await?; + let sym_key = self.sym_key(topic)?; let payload = serde_json::to_string(&payload)?; encrypt_and_encode(EnvelopeType::Type0, payload, &sym_key)? }; - // Attempt to publish, retrying once on NotConnected error - match self - .client - .publish( - topic.clone(), - message.clone(), - None, - irn_metadata.tag, - Duration::from_secs(irn_metadata.ttl), - irn_metadata.prompt, - ) - .await - { - Ok(_) => { - info!("Message published successfully to topic: {topic}"); - Ok(()) - }, - Err(err) => { - if err.to_string().contains("WebsocketClient") { - debug!("Reconnecting client after NotConnected error..."); - self.connect_client().await?; - self.client - .publish( - topic.clone(), - message, - None, - irn_metadata.tag, - Duration::from_secs(irn_metadata.ttl), - irn_metadata.prompt, - ) - .await?; - info!("Message published successfully after reconnect"); - Ok(()) - } else { - MmError::err(err.into()) - } - }, + for attempt in 0..MAX_RETRIES { + match self + .client + .publish( + topic.clone(), + message.clone(), + None, + irn_metadata.tag, + Duration::from_secs(irn_metadata.ttl), + irn_metadata.prompt, + ) + .timeout_secs(PUBLISH_TIMEOUT_SECS) + .await + { + Ok(Ok(_)) => { + info!("[{topic}] Message published successfully"); + return Ok(()); + }, + Ok(Err(err)) => return MmError::err(err.into()), + Err(timeout_err) => { + // This persistent reconnection and retry strategy keeps the WebSocket connection active, + // allowing the client to automatically resume operations after network interruptions or disconnections. + // Since TCP handles connection timeouts (which can be lengthy), we're using a shorter timeout here + // to detect issues quickly and reconnect as needed. + if attempt >= MAX_RETRIES - 1 { + return MmError::err(WalletConnectError::InternalError(timeout_err.to_string())); + } + debug!("Attempt {} failed due to timeout. Reconnecting...", attempt + 1); + loop { + match self.reconnect_and_subscribe().await { + Ok(_) => { + info!("Reconnected and subscribed successfully."); + break; + }, + Err(reconnect_err) => { + error!("Reconnection attempt failed: {reconnect_err:?}. Retrying..."); + Timer::sleep(1.5).await; + }, + } + } + }, + } } + + info!("[{topic}] Message published successfully"); + + Ok(()) } /// Checks if the current session is connected to a Ledger device. @@ -499,7 +525,7 @@ impl WalletConnectCtx { if let Some(session) = self.session.delete_session(topic).await { self.pairing - .disconnect(session.pairing_topic.as_ref(), &self.client) + .disconnect_rpc(&session.pairing_topic, &self.client) .await?; }; @@ -526,7 +552,7 @@ pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnect let mut recv = wallet_connect.inbound_message_rx.lock().await; while let Some(msg) = recv.next().await { if let Err(e) = wallet_connect.handle_published_message(msg).await { - info!("Error processing message: {:?}", e); + debug!("Error processing message: {:?}", e); } } }); diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index 9fc3973d57..3e4411305b 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -28,8 +28,7 @@ pub(crate) async fn reply_pairing_extend_response( extend: PairingExtendRequest, ) -> MmResult<(), WalletConnectError> { { - let mut pairings = ctx.pairing.pairings.lock().await; - if let Some(pairing) = pairings.get_mut(topic.as_ref()) { + if let Some(mut pairing) = ctx.pairing.pairings.get_mut(topic) { pairing.pairing.expiry = extend.expiry; pairing.pairing.active = true; }; @@ -48,7 +47,7 @@ pub(crate) async fn reply_pairing_delete_response( _delete: PairingDeleteRequest, ) -> MmResult<(), WalletConnectError> { { - ctx.pairing.disconnect(topic.as_ref(), &ctx.client).await?; + ctx.pairing.disconnect_rpc(topic, &ctx.client).await?; } let param = ResponseParamsSuccess::PairingDelete(true); diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 75843e3dcc..46374cc30e 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -41,13 +41,13 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu if let Some(session) = ctx.session.delete_session(topic).await { debug!( - "No active sessions left for pairing {}, disconnecting", + "[{}] No active sessions for pairing disconnecting", session.pairing_topic ); //Attempt to unsubscribe from topic ctx.client.unsubscribe(session.pairing_topic.clone()).await?; // Attempt to disconnect the pairing - ctx.pairing.delete(session.pairing_topic.as_ref()).await; + ctx.pairing.delete(&session.pairing_topic); // delete session from storage as well. ctx.storage diff --git a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs index 640465bebf..ad0e8eda10 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs @@ -6,7 +6,7 @@ use common::custom_futures::timeout::FutureTimerExt; use futures::StreamExt; use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{RequestParams, ResponseParamsSuccess}}; + rpc::params::{RelayProtocolMetadata, RequestParams, ResponseParamsSuccess}}; pub(crate) async fn reply_session_ping_request( ctx: &WalletConnectCtx, @@ -21,9 +21,10 @@ pub(crate) async fn reply_session_ping_request( pub async fn send_session_ping_request(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { let param = RequestParams::SessionPing(()); + let ttl = param.irn_metadata().ttl; ctx.publish_request(topic, param).await?; - let wait_duration = Duration::from_secs(30); + let wait_duration = Duration::from_secs(ttl); if let Ok(Some(resp)) = ctx.message_rx.lock().await.next().timeout(wait_duration).await { resp.mm_err(WalletConnectError::InternalError)?; return Ok(()); diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index eee8c90b8a..f941fb6dd3 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -145,7 +145,7 @@ pub(crate) async fn process_session_propose_response( }; // Activate pairing_topic - ctx.pairing.activate(pairing_topic.as_ref()).await?; + ctx.pairing.activate(pairing_topic)?; Ok(()) } From 2326959e4a3c32cfc0d304c7e094d74318ef3f3e Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 12 Nov 2024 14:05:20 +0100 Subject: [PATCH 105/125] handle conn drop for session creation --- mm2src/kdf_walletconnect/src/lib.rs | 83 ++++++++++++++++------------- 1 file changed, 45 insertions(+), 38 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index fb4d2e917a..bcc933815e 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -44,6 +44,8 @@ use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType, SymKey}; const WAIT_DURATION: Duration = Duration::from_secs(60); +const PUBLISH_TIMEOUT_SECS: f64 = 5.0; +const MAX_RETRIES: usize = 5; #[async_trait::async_trait] pub trait WalletConnectOps { @@ -168,17 +170,26 @@ impl WalletConnectCtx { info!("[topic] Subscribing to topic"); - self.client - .subscribe(topic.clone()) - .timeout(WAIT_DURATION) - .await - .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))??; - - info!("[topic] Subscribed to topic"); - - send_proposal_request(self, &topic, namespaces).await?; + for attempt in 0..MAX_RETRIES { + match self + .client + .subscribe(topic.clone()) + .timeout_secs(PUBLISH_TIMEOUT_SECS) + .await + { + Ok(Ok(_)) => { + info!("[topic] Subscribed to topic"); + send_proposal_request(self, &topic, namespaces).await?; + return Ok(url); + }, + Ok(Err(err)) => return MmError::err(err.into()), + Err(_) => self.wait_until_client_is_online(attempt).await, + } + } - Ok(url) + MmError::err(WalletConnectError::InternalError( + "client connection timeout".to_string(), + )) } /// Retrieves the symmetric key associated with a given `topic`. @@ -225,7 +236,7 @@ impl WalletConnectCtx { .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; - // bring last active session to the back. + // bring most recent active session to the back. sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); for session in sessions { // delete expired session @@ -304,9 +315,6 @@ impl WalletConnectCtx { irn_metadata: IrnMetadata, payload: Payload, ) -> MmResult<(), WalletConnectError> { - const MAX_RETRIES: usize = 5; - const PUBLISH_TIMEOUT_SECS: f64 = 5.0; - info!("[{topic}] Publishing message={payload:?}"); let message = { let sym_key = self.sym_key(topic)?; @@ -333,34 +341,33 @@ impl WalletConnectCtx { return Ok(()); }, Ok(Err(err)) => return MmError::err(err.into()), - Err(timeout_err) => { - // This persistent reconnection and retry strategy keeps the WebSocket connection active, - // allowing the client to automatically resume operations after network interruptions or disconnections. - // Since TCP handles connection timeouts (which can be lengthy), we're using a shorter timeout here - // to detect issues quickly and reconnect as needed. - if attempt >= MAX_RETRIES - 1 { - return MmError::err(WalletConnectError::InternalError(timeout_err.to_string())); - } - debug!("Attempt {} failed due to timeout. Reconnecting...", attempt + 1); - loop { - match self.reconnect_and_subscribe().await { - Ok(_) => { - info!("Reconnected and subscribed successfully."); - break; - }, - Err(reconnect_err) => { - error!("Reconnection attempt failed: {reconnect_err:?}. Retrying..."); - Timer::sleep(1.5).await; - }, - } - } - }, + Err(_) => self.wait_until_client_is_online(attempt).await, } } - info!("[{topic}] Message published successfully"); + MmError::err(WalletConnectError::InternalError( + "client connection timeout".to_string(), + )) + } - Ok(()) + /// This persistent reconnection and retry strategy keeps the WebSocket connection active, + /// allowing the client to automatically resume operations after network interruptions or disconnections. + /// Since TCP handles connection timeouts (which can be lengthy), we're using a shorter timeout here + /// to detect issues quickly and reconnect as needed. + async fn wait_until_client_is_online(&self, attempt: usize) { + debug!("Attempt {} failed due to timeout. Reconnecting...", attempt + 1); + loop { + match self.reconnect_and_subscribe().await { + Ok(_) => { + info!("Reconnected and subscribed successfully."); + break; + }, + Err(reconnect_err) => { + error!("Reconnection attempt failed: {reconnect_err:?}. Retrying..."); + Timer::sleep(1.5).await; + }, + } + } } /// Checks if the current session is connected to a Ledger device. From 42eaa2959912ee20e3df9a539a98de80c439cf62 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 12 Nov 2024 14:37:36 +0100 Subject: [PATCH 106/125] nits --- mm2src/kdf_walletconnect/src/session.rs | 36 +++++++++++-------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 6943cd5680..517f8799c9 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -218,6 +218,7 @@ impl From for SessionRpcInfo { impl SessionManager { pub fn new() -> Self { Self(Default::default()) } + /// Get active session topic or return error if no session has been activated. pub async fn get_active_topic_or_err(&self) -> MmResult { self.0 .active_topic @@ -229,17 +230,16 @@ impl SessionManager { ))) } - /// Inserts the provided `Session` into the session store, associated with the specified topic. + /// Inserts `Session` into the session store, associated with the specified topic. /// If a session with the same topic already exists, it will be overwritten. pub(crate) async fn add_session(&self, session: Session) { // set active session topic. *self.0.active_topic.lock().await = Some(session.topic.clone()); - // insert session self.0.sessions.insert(session.topic.clone(), session); } - /// Removes the session corresponding to the specified topic from the session store. + /// Removes session corresponding to the specified topic from the session store. /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { info!("Deleting session with topic: {topic}"); @@ -265,12 +265,14 @@ impl SessionManager { pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { let mut active_topic = self.0.active_topic.lock().await; - if let Some(session) = self.get_session(topic) { - *active_topic = Some(session.topic); - return Ok(()); - } + let session = self + .get_session(topic) + .ok_or(MmError::new(WalletConnectError::SessionError( + "Session not found".to_owned(), + )))?; - MmError::err(WalletConnectError::SessionError("Session not found".to_owned())) + *active_topic = Some(session.topic); + Ok(()) } /// Retrieves a cloned session associated with a given topic. @@ -283,12 +285,12 @@ impl SessionManager { /// returns an `option` containing the active session if it exists; otherwise, returns `none`. pub async fn get_session_active(&self) -> Option { - let active_topic = self.0.active_topic.lock().await; - if let Some(ref topic) = *active_topic { - self.get_session(topic) - } else { - None - } + self.0 + .active_topic + .lock() + .await + .as_ref() + .and_then(|topic| self.get_session(topic)) } /// Retrieves all sessions(active and inactive) @@ -342,12 +344,6 @@ impl SessionManager { pub(crate) fn sym_key(&self, topic: &Topic) -> Option { self.get_session(topic).map(|sess| sess.session_key.symmetric_key()) } - - async fn disconnect_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { - self.delete_session(topic).await; - - Ok(()) - } } #[cfg(test)] From e82083af19804261d648d2b3915c8da53a0e2d5f Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 12 Nov 2024 14:43:54 +0100 Subject: [PATCH 107/125] fix conflict after merge --- Cargo.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 41f1c11359..27e344c724 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4702,7 +4702,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote 1.0.37", - "syn 2.0.38", + "syn 2.0.77", ] [[package]] From ad3824128a0860376971a38721368c2881ece216 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 12 Nov 2024 21:49:35 +0100 Subject: [PATCH 108/125] nits --- mm2src/kdf_walletconnect/src/lib.rs | 34 ++++++++++--------------- mm2src/kdf_walletconnect/src/session.rs | 1 + 2 files changed, 15 insertions(+), 20 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index bcc933815e..21c07b504b 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -183,7 +183,7 @@ impl WalletConnectCtx { return Ok(url); }, Ok(Err(err)) => return MmError::err(err.into()), - Err(_) => self.wait_until_client_is_online(attempt).await, + Err(_) => self.wait_until_client_is_online_loop(attempt).await, } } @@ -269,9 +269,7 @@ impl WalletConnectCtx { let request = Request::new(message_id, param.into()); self.publish_payload(topic, irn_metadata, Payload::Request(request)) - .await?; - - Ok(()) + .await } /// Private function to publish a success request response. @@ -286,9 +284,7 @@ impl WalletConnectCtx { let response = Response::Success(SuccessfulResponse::new(*message_id, value)); self.publish_payload(topic, irn_metadata, Payload::Response(response)) - .await?; - - Ok(()) + .await } /// Private function to publish an error request response. @@ -303,9 +299,7 @@ impl WalletConnectCtx { let response = Response::Error(ErrorResponse::new(*message_id, error)); self.publish_payload(topic, irn_metadata, Payload::Response(response)) - .await?; - - Ok(()) + .await } /// Private function to publish a payload. @@ -327,7 +321,7 @@ impl WalletConnectCtx { .client .publish( topic.clone(), - message.clone(), + &*message, None, irn_metadata.tag, Duration::from_secs(irn_metadata.ttl), @@ -341,7 +335,7 @@ impl WalletConnectCtx { return Ok(()); }, Ok(Err(err)) => return MmError::err(err.into()), - Err(_) => self.wait_until_client_is_online(attempt).await, + Err(_) => self.wait_until_client_is_online_loop(attempt).await, } } @@ -354,7 +348,7 @@ impl WalletConnectCtx { /// allowing the client to automatically resume operations after network interruptions or disconnections. /// Since TCP handles connection timeouts (which can be lengthy), we're using a shorter timeout here /// to detect issues quickly and reconnect as needed. - async fn wait_until_client_is_online(&self, attempt: usize) { + async fn wait_until_client_is_online_loop(&self, attempt: usize) { debug!("Attempt {} failed due to timeout. Reconnecting...", attempt + 1); loop { match self.reconnect_and_subscribe().await { @@ -389,12 +383,13 @@ impl WalletConnectCtx { session: &Session, chain_id: &WcChainId, ) -> MmResult<(), WalletConnectError> { - if let Some(ns) = session.namespaces.get(chain_id.chain.as_ref()) { - if let Some(chains) = &ns.chains { - if chains.contains(&chain_id.to_string()) { - return Ok(()); - }; - } + if let Some(Namespace { + chains: Some(chains), .. + }) = session.namespaces.get(chain_id.chain.as_ref()) + { + if chains.contains(&chain_id.to_string()) { + return Ok(()); + }; } // https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces @@ -440,7 +435,6 @@ impl WalletConnectCtx { // // let wait_duration = Duration::from_secs(60); // if let Ok(Some(resp)) = self.message_rx.lock().await.next().timeout(wait_duration).await { - // println!("{resp:?}"); // let result = resp.mm_err(WalletConnectError::InternalError)?; // if let ResponseParamsSuccess::SessionEvent(data) = result.data { // if !data { diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 517f8799c9..98a9a508cb 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -272,6 +272,7 @@ impl SessionManager { )))?; *active_topic = Some(session.topic); + Ok(()) } From 59db165d9fd99e8cb98ac30e33dd7a691b40e89d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 13 Nov 2024 12:00:31 +0100 Subject: [PATCH 109/125] move storage to session manager and minor improvements --- mm2src/kdf_walletconnect/src/chain.rs | 74 +++++++++---------- .../src/connection_handler.rs | 12 +-- .../kdf_walletconnect/src/inbound_message.rs | 3 +- mm2src/kdf_walletconnect/src/lib.rs | 18 ++--- mm2src/kdf_walletconnect/src/session.rs | 72 ++++++------------ .../src/session/rpc/delete.rs | 3 +- .../src/session/rpc/event.rs | 5 +- .../src/session/rpc/propose.rs | 6 +- .../src/session/rpc/settle.rs | 14 ++-- .../src/session/rpc/update.rs | 3 +- .../src/storage/indexed_db.rs | 8 +- mm2src/kdf_walletconnect/src/storage/mod.rs | 50 ++++++++----- .../kdf_walletconnect/src/storage/sqlite.rs | 15 ++-- 13 files changed, 135 insertions(+), 148 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index d1b2361d50..cad6a225f8 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -15,6 +15,43 @@ pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "pers pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:137"]; pub(crate) const ETH_SUPPORTED_EVENTS: &[&str] = &["accountsChanged", "chainChanged"]; +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub enum WcChain { + Eip155, + Cosmos, +} + +impl FromStr for WcChain { + type Err = MmError; + fn from_str(s: &str) -> Result { + match s { + "eip155" => Ok(WcChain::Eip155), + "cosmos" => Ok(WcChain::Cosmos), + _ => MmError::err(WalletConnectError::InvalidChainId(format!( + "chain_id not supported: {s}" + ))), + } + } +} + +impl AsRef for WcChain { + fn as_ref(&self) -> &str { + match self { + Self::Eip155 => "eip155", + Self::Cosmos => "cosmos", + } + } +} + +impl WcChain { + pub(crate) fn derive_chain_id(&self, id: String) -> WcChainId { + WcChainId { + chain: self.clone(), + id, + } + } +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct WcChainId { pub chain: WcChain, @@ -55,43 +92,6 @@ impl WcChainId { } } -#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] -pub enum WcChain { - Eip155, - Cosmos, -} - -impl FromStr for WcChain { - type Err = MmError; - fn from_str(s: &str) -> Result { - match s { - "eip155" => Ok(WcChain::Eip155), - "cosmos" => Ok(WcChain::Cosmos), - _ => MmError::err(WalletConnectError::InvalidChainId(format!( - "chain_id not supported: {s}" - ))), - } - } -} - -impl AsRef for WcChain { - fn as_ref(&self) -> &str { - match self { - Self::Eip155 => "eip155", - Self::Cosmos => "cosmos", - } - } -} - -impl WcChain { - pub(crate) fn derive_chain_id(&self, id: String) -> WcChainId { - WcChainId { - chain: self.clone(), - id, - } - } -} - #[derive(Debug, Clone)] pub enum WcRequestMethods { CosmosSignDirect, diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index eb5cb2fd53..8c4c0feb61 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -41,7 +41,7 @@ impl ConnectionHandler for Handler { fn disconnected(&mut self, frame: Option>) { debug!("[{}] connection closed: frame={frame:?}", self.name); - if let Err(e) = self.conn_live_sender.start_send(None) { + if let Err(e) = self.conn_live_sender.start_send(frame.map(|f| f.to_string())) { error!("[{}] failed to send to the receiver: {e}", self.name); } } @@ -75,12 +75,12 @@ impl ConnectionHandler for Handler { /// Establishes initial connection to WalletConnect relay server with linear retry mechanism. /// Uses increasing delay between retry attempts starting from INITIAL_RETRY_SECS. /// After successful connection, attempts to restore previous session state from storage. -pub(crate) async fn initialize_connection(this: Arc) { +pub(crate) async fn initialize_connection(wc: Arc) { info!("Initializing WalletConnect connection"); let mut retry_count = 0; let mut retry_secs = INITIAL_RETRY_SECS; - while let Err(err) = this.connect_client().await { + while let Err(err) = wc.connect_client().await { retry_count += 1; info!( "Error during initial connection attempt {}: {:?}. Retrying in {retry_secs} seconds...", @@ -91,17 +91,17 @@ pub(crate) async fn initialize_connection(this: Arc) { } // Initialize storage - if let Err(err) = this.storage.init().await { + if let Err(err) = wc.session.storage().init().await { error!("Unable to initialize WalletConnect persistent storage: {err:?}. Only inmemory storage will be utilized for this Session."); }; // load session from storage - if let Err(err) = this.load_session_from_storage().await { + if let Err(err) = wc.load_session_from_storage().await { error!("Unable to load session from storage: {err:?}"); }; // Spawn session disconnection watcher. - handle_disconnections(&this).await; + handle_disconnections(&wc).await; } /// Handles unexpected disconnections from WalletConnect relay server. diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 0fd3545cb4..176d8e51bd 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -34,7 +34,7 @@ pub(crate) async fn process_inbound_request( Params::SessionExtend(param) => reply_session_extend_request(ctx, topic, &message_id, param).await?, Params::SessionDelete(param) => reply_session_delete_request(ctx, topic, &message_id, param).await?, Params::SessionPing(()) => reply_session_ping_request(ctx, topic, &message_id).await?, - Params::SessionSettle(param) => reply_session_settle_request(ctx, topic, &message_id, param).await?, + Params::SessionSettle(param) => reply_session_settle_request(ctx, topic, param).await?, Params::SessionUpdate(param) => reply_session_update_request(ctx, topic, &message_id, param).await?, Params::SessionEvent(param) => handle_session_event(ctx, topic, &message_id, param).await?, Params::SessionRequest(_param) => { @@ -60,7 +60,6 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: R Response::Success(value) => match serde_json::from_value::(value.result) { Ok(data) => { // TODO: move to session::proposal mod and spawn in a different thread to avoid - // blocking if let ResponseParamsSuccess::SessionPropose(propose) = &data { process_session_propose_response(ctx, topic, propose).await.error_log(); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 21c07b504b..c6c4d3320d 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -75,7 +75,6 @@ pub struct WalletConnectCtx { pub session: SessionManager, pub(crate) key_pair: SymKeyPair, - pub(crate) storage: SessionStorageDb, relay: Relay, metadata: Metadata, @@ -110,10 +109,9 @@ impl WalletConnectCtx { client, pairing, relay, - storage, metadata: generate_metadata(), key_pair: SymKeyPair::new(), - session: SessionManager::new(), + session: SessionManager::new(storage), inbound_message_rx: Arc::new(inbound_message_rx.into()), connection_live_rx: Arc::new(conn_live_receiver.into()), @@ -153,7 +151,7 @@ impl WalletConnectCtx { let sessions = self.session.get_sessions(); for session in sessions { self.client - .batch_subscribe(vec![session.topic.into(), session.pairing_topic.into()]) + .batch_subscribe(vec![session.topic, session.pairing_topic]) .await?; } @@ -231,7 +229,8 @@ impl WalletConnectCtx { info!("Loading WalletConnect session from storage"); let now = chrono::Utc::now().timestamp() as u64; let mut sessions = self - .storage + .session + .storage() .get_all_sessions() .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; @@ -242,7 +241,7 @@ impl WalletConnectCtx { // delete expired session if now > session.expiry { debug!("Session {} expired, trying to delete from storage", session.topic); - if let Err(err) = self.storage.delete_session(&session.topic).await { + if let Err(err) = self.session.storage().delete_session(&session.topic).await { error!("[{}] Unable to delete session from storage: {err:?}", session.topic); } continue; @@ -509,10 +508,6 @@ impl WalletConnectCtx { let result = resp.mm_err(WalletConnectError::InternalError)?; if let ResponseParamsSuccess::Arbitrary(data) = result.data { let data = serde_json::from_value::(data)?; - let response = ResponseParamsSuccess::SessionEvent(true); - self.publish_response_ok(&result.topic, response, &result.message_id) - .await?; - return callback(data); } } @@ -530,7 +525,8 @@ impl WalletConnectCtx { .await?; }; - self.storage + self.session + .storage() .delete_session(topic) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 98a9a508cb..0a6f9eb25a 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -2,6 +2,7 @@ pub(crate) mod key; pub mod rpc; use crate::chain::WcChainId; +use crate::storage::SessionStorageDb; use crate::{error::WalletConnectError, WalletConnectCtx}; use chrono::Utc; @@ -52,13 +53,14 @@ impl ToString for SessionType { #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] pub struct SessionRpcInfo { - pub topic: String, + pub topic: Topic, pub metadata: Metadata, pub peer_pubkey: String, - pub pairing_topic: String, + pub pairing_topic: Topic, pub namespaces: BTreeMap, pub subscription_id: SubscriptionId, pub properties: Option, + pub expiry: u64, } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] @@ -186,37 +188,45 @@ impl Session { } /// Internal implementation of session management. -#[derive(Default, Debug)] struct SessionManagerImpl { /// The currently active session topic. active_topic: Mutex>, /// A thread-safe map of sessions indexed by topic. sessions: DashMap, + pub(crate) storage: SessionStorageDb, } pub struct SessionManager(Arc); -impl Default for SessionManager { - fn default() -> Self { Self::new() } -} - impl From for SessionRpcInfo { fn from(value: Session) -> Self { Self { - topic: value.topic.to_string(), + topic: value.topic, metadata: value.controller.metadata, peer_pubkey: value.controller.public_key, - pairing_topic: value.pairing_topic.to_string(), + pairing_topic: value.pairing_topic, namespaces: value.namespaces, subscription_id: value.subscription_id, properties: value.session_properties, + expiry: value.expiry, } } } #[allow(unused)] impl SessionManager { - pub fn new() -> Self { Self(Default::default()) } + pub(crate) fn new(storage: SessionStorageDb) -> Self { + Self( + SessionManagerImpl { + active_topic: Default::default(), + sessions: Default::default(), + storage, + } + .into(), + ) + } + + pub(crate) fn storage(&self) -> &SessionStorageDb { &self.0.storage } /// Get active session topic or return error if no session has been activated. pub async fn get_active_topic_or_err(&self) -> MmResult { @@ -242,7 +252,7 @@ impl SessionManager { /// Removes session corresponding to the specified topic from the session store. /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { - info!("Deleting session with topic: {topic}"); + info!("[{topic}] Deleting session with topic"); let mut active_topic = self.0.active_topic.lock().await; // Remove the session and get the removed session (if any) @@ -254,9 +264,7 @@ impl SessionManager { *active_topic = self.0.sessions.iter().next().map(|session| session.topic.clone()); if let Some(new_active_topic) = active_topic.as_ref() { - info!("New session with topic: {} activated!", new_active_topic); - } else { - info!("No active sessions remaining"); + info!("[{new_active_topic}] New session with topic activated!"); } } @@ -296,51 +304,19 @@ impl SessionManager { /// Retrieves all sessions(active and inactive) pub fn get_sessions(&self) -> impl Iterator { - self.0 - .sessions - .clone() - .into_iter() - .map(|(topic, session)| SessionRpcInfo { - topic: topic.to_string(), - metadata: session.controller.metadata, - peer_pubkey: session.controller.public_key, - pairing_topic: session.pairing_topic.to_string(), - namespaces: session.namespaces, - subscription_id: session.subscription_id, - properties: session.session_properties, - }) + self.0.sessions.clone().into_iter().map(|(_, session)| session.into()) } pub(crate) fn get_sessions_full(&self) -> impl Iterator> { self.0.sessions.iter() } /// Updates the expiry time of the session associated with the given topic to the specified timestamp. /// If the session does not exist, this method does nothing. pub(crate) fn extend_session(&self, topic: &Topic, till: u64) { - info!("Extending session with topic: {topic}"); + info!("[{topic}] Extending session with topic"); if let Some(mut session) = self.0.sessions.get_mut(topic) { session.extend(till); } } - /// This method checks all sessions for expiration based on the current time. - /// Expired sessions are removed from the session store and returned. - /// If the active session is expired, it is also removed, and the active session is set to `None`. - pub(crate) async fn delete_expired_sessions(&self) -> Vec { - let now = Utc::now().timestamp() as u64; - let mut expired_sessions = Vec::new(); - - // Collect session arcs for processing - for session in self.0.sessions.iter() { - if session.expiry <= now { - // Remove the session from the map - if let Some(session) = self.delete_session(&session.topic).await { - expired_sessions.push(session); - } - } - } - - expired_sessions - } - /// Retrieves the symmetric key associated with a given topic. pub(crate) fn sym_key(&self, topic: &Topic) -> Option { self.get_session(topic).map(|sess| sess.session_key.symmetric_key()) diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 46374cc30e..6f2dee2f43 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -50,7 +50,8 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu ctx.pairing.delete(&session.pairing_topic); // delete session from storage as well. - ctx.storage + ctx.session + .storage() .delete_session(topic) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 55f8c7404c..78642f8327 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -5,7 +5,7 @@ use crate::{chain::{WcChain, WcChainId}, use common::log::{error, info}; use mm2_err_handle::prelude::*; use relay_rpc::{domain::{MessageId, Topic}, - rpc::{params::{session_event::SessionEventRequest, ResponseParamsError, ResponseParamsSuccess}, + rpc::{params::{session_event::SessionEventRequest, ResponseParamsError}, ErrorData}}; pub async fn handle_session_event( @@ -60,9 +60,6 @@ pub async fn handle_session_event( .set_active_chain_id(chain_id.clone()) .await; } - - let params = ResponseParamsSuccess::SessionEvent(true); - ctx.publish_response_ok(topic, params, message_id).await?; }; }, "accountsChanged" => { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index f941fb6dd3..c429b5f0f2 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -73,7 +73,8 @@ pub async fn reply_session_proposal_request( { // save session to storage - ctx.storage + ctx.session + .storage() .save_session(&session) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; @@ -135,7 +136,8 @@ pub(crate) async fn process_session_propose_response( }; { // save session to storage - ctx.storage + ctx.session + .storage() .save_session(&session) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index 3205872fc3..df0bb6e50f 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -4,8 +4,8 @@ use crate::{error::WalletConnectError, WalletConnectCtx}; use common::log::{debug, info}; use mm2_err_handle::prelude::{MapMmError, MmResult}; -use relay_rpc::{domain::{MessageId, Topic}, - rpc::params::{session_settle::SessionSettleRequest, ResponseParamsSuccess}}; +use relay_rpc::domain::Topic; +use relay_rpc::rpc::params::session_settle::SessionSettleRequest; pub(crate) async fn send_session_settle_request( _ctx: &WalletConnectCtx, @@ -37,7 +37,6 @@ pub(crate) async fn send_session_settle_request( pub(crate) async fn reply_session_settle_request( ctx: &WalletConnectCtx, topic: &Topic, - message_id: &MessageId, settle: SessionSettleRequest, ) -> MmResult<(), WalletConnectError> { { @@ -54,7 +53,8 @@ pub(crate) async fn reply_session_settle_request( } // Update storage session. - ctx.storage + ctx.session + .storage() .update_session(&session) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; @@ -62,9 +62,6 @@ pub(crate) async fn reply_session_settle_request( } info!("Session successfully settled for topic: {:?}", topic); - let param = ResponseParamsSuccess::SessionSettle(true); - ctx.publish_response_ok(topic, param, message_id).await?; - // Delete other sessions with same controller // TODO: we might not want to do this! let all_sessions = ctx.session.get_sessions_full(); @@ -72,7 +69,8 @@ pub(crate) async fn reply_session_settle_request( if session.controller == settle.controller && session.topic.as_ref() != topic.as_ref() { ctx.client.unsubscribe(session.topic.clone()).await?; ctx.client.unsubscribe(session.pairing_topic.clone()).await?; - ctx.storage + ctx.session + .storage() .delete_session(&session.topic.clone()) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index 077d7d96e2..7aa8083cf3 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -23,7 +23,8 @@ pub(crate) async fn reply_session_update_request( //TODO: session.namespaces.supported(update.namespaces.0) session.namespaces = update.namespaces.0; // Update storage session. - ctx.storage + ctx.session + .storage() .update_session(&session) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; diff --git a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs index 6dd6baf765..ac9205600f 100644 --- a/mm2src/kdf_walletconnect/src/storage/indexed_db.rs +++ b/mm2src/kdf_walletconnect/src/storage/indexed_db.rs @@ -75,7 +75,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { async fn is_initialized(&self) -> MmResult { Ok(true) } async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { - debug!("Saving WalletConnect session: {} to storage", session.topic); + debug!("[{}] Saving WalletConnect session to storage", session.topic); let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -87,7 +87,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { } async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { - debug!("Retrieving WalletConnect session: {topic} from storage"); + debug!("[{topic}] Retrieving WalletConnect session from storage"); let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -113,7 +113,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { } async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { - debug!("Deleting WalletConnect session: {topic} from storage"); + debug!("[{topic}] Deleting WalletConnect session from storage"); let lock_db = self.lock_db().await?; let transaction = lock_db.get_inner().transaction().await?; let session_table = transaction.table::().await?; @@ -123,7 +123,7 @@ impl WalletConnectStorageOps for IDBSessionStorage { } async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { - debug!("Updating WalletConnect session: {} in storage", session.topic); + debug!("[{}] Updating WalletConnect session in storage", session.topic); self.save_session(session).await } } diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 4ceba70965..f94b5502cc 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -38,11 +38,7 @@ impl Deref for SessionStorageDb { impl SessionStorageDb { pub(crate) fn init(ctx: &MmArc) -> MmResult { - #[cfg(target_arch = "wasm32")] - let db = - indexed_db::IDBSessionStorage::new(ctx).mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; - #[cfg(not(target_arch = "wasm32"))] - let db = sqlite::SqliteSessionStorage::new(ctx).mm_err(WalletConnectError::StorageError)?; + let db = DB::new(ctx).mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; Ok(SessionStorageDb(db)) } @@ -90,31 +86,37 @@ pub(crate) mod session_storage_tests { cross_test!(save_and_get_session_test, { let mm_ctx = mm_ctx_with_custom_async_db().await; let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); - wc_ctx.storage.init().await.unwrap(); + wc_ctx.session.storage().init().await.unwrap(); let sample_session = sample_test_session(&wc_ctx); // try save session - wc_ctx.storage.save_session(&sample_session).await.unwrap(); + wc_ctx.session.storage().save_session(&sample_session).await.unwrap(); // try get session - let db_session = wc_ctx.storage.get_session(&sample_session.topic).await.unwrap(); + let db_session = wc_ctx + .session + .storage() + .get_session(&sample_session.topic) + .await + .unwrap(); assert_eq!(sample_session, db_session.unwrap()); }); cross_test!(delete_session_test, { let mm_ctx = mm_ctx_with_custom_async_db().await; let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); - wc_ctx.storage.init().await.unwrap(); + wc_ctx.session.storage().init().await.unwrap(); let sample_session = sample_test_session(&wc_ctx); // try save session - wc_ctx.storage.save_session(&sample_session).await.unwrap(); + wc_ctx.session.storage().save_session(&sample_session).await.unwrap(); // try get session let db_session = wc_ctx - .storage + .session + .storage() .get_session(&sample_session.topic) .await .unwrap() @@ -122,26 +124,32 @@ pub(crate) mod session_storage_tests { assert_eq!(sample_session, db_session); // try delete session - wc_ctx.storage.delete_session(&db_session.topic).await.unwrap(); + wc_ctx + .session + .storage() + .delete_session(&db_session.topic) + .await + .unwrap(); // try get_session deleted again - let db_session = wc_ctx.storage.get_session(&db_session.topic).await; + let db_session = wc_ctx.session.storage().get_session(&db_session.topic).await; assert!(db_session.is_err()); }); cross_test!(update_session_test, { let mm_ctx = mm_ctx_with_custom_async_db().await; let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); - wc_ctx.storage.init().await.unwrap(); + wc_ctx.session.storage().init().await.unwrap(); let sample_session = sample_test_session(&wc_ctx); // try save session - wc_ctx.storage.save_session(&sample_session).await.unwrap(); + wc_ctx.session.storage().save_session(&sample_session).await.unwrap(); // try get session let db_session = wc_ctx - .storage + .session + .storage() .get_session(&sample_session.topic) .await .unwrap() @@ -156,11 +164,17 @@ pub(crate) mod session_storage_tests { assert_ne!(sample_session.expiry, modified_sample_session.expiry); // try update session - wc_ctx.storage.update_session(&modified_sample_session).await.unwrap(); + wc_ctx + .session + .storage() + .update_session(&modified_sample_session) + .await + .unwrap(); // try get_session again with new updated expiry let db_session = wc_ctx - .storage + .session + .storage() .get_session(&sample_session.topic) .await .unwrap() diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index a4dabfb6f2..6820bffdc7 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; use common::log::debug; +use db_common::async_sql_conn::InternalError; use db_common::sqlite::rusqlite::Result as SqlResult; use db_common::sqlite::{query_single_row, string_from_row, CHECK_TABLE_EXISTS_SQL}; use db_common::{async_sql_conn::{AsyncConnError, AsyncConnection}, @@ -33,10 +34,12 @@ pub(crate) struct SqliteSessionStorage { } impl SqliteSessionStorage { - pub(crate) fn new(ctx: &MmArc) -> MmResult { + pub(crate) fn new(ctx: &MmArc) -> MmResult { let conn = ctx .async_sqlite_connection - .ok_or("async_sqlite_connection is not initialized".to_owned())?; + .ok_or(AsyncConnError::Internal(InternalError( + "async_sqlite_connection is not initialized".to_owned(), + )))?; Ok(Self { conn: conn.clone() }) } @@ -72,7 +75,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { - debug!("Saving WalletConnect session: {} to storage", session.topic); + debug!("[{}] Saving WalletConnect session to storage", session.topic); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; @@ -98,7 +101,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { - debug!("Retrieving WalletConnect session: {topic} from storage"); + debug!("[{topic}] Retrieving WalletConnect session from storage"); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; let topic = topic.clone(); @@ -141,7 +144,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { - debug!("Deleting WalletConnect session: {topic} from storage"); + debug!("[{topic}] Deleting WalletConnect session from storage"); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let topic = topic.clone(); let lock = self.lock_db().await; @@ -157,7 +160,7 @@ impl WalletConnectStorageOps for SqliteSessionStorage { } async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { - debug!("Updating WalletConnect session: {} in storage", session.topic); + debug!("[{}] Updating WalletConnect session in storage", session.topic); validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let session = session.clone(); let lock = self.lock_db().await; From f5caa1918b437b2593e55013a270f4b83f210c21 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 13 Nov 2024 14:52:03 +0100 Subject: [PATCH 110/125] fix review notes --- mm2src/coins/tendermint/tendermint_coin.rs | 10 +-- .../src/tendermint_with_assets_activation.rs | 71 +++++++++---------- 2 files changed, 38 insertions(+), 43 deletions(-) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index 2926c45790..c7c0707290 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -363,11 +363,12 @@ pub enum TendermintWalletConnectionType { Wc, WcLedger, KeplrLedger, - Internal, + Keplr, + Native, } impl Default for TendermintWalletConnectionType { - fn default() -> Self { Self::Internal } + fn default() -> Self { Self::Native } } pub struct TendermintCoinImpl { @@ -1380,9 +1381,8 @@ impl TendermintCoin { let tx_json = if self.is_wallet_connect() { // if wallet_type is WalletConnect, update tx_json to use WalletConnect type. - let my_address = self.my_address().unwrap(); json!({ - "signerAddress": my_address, + "signerAddress": self.my_address()?, "signDoc": { "accountNumber": sign_doc.account_number.to_string(), "chainId": sign_doc.chain_id, @@ -1407,7 +1407,7 @@ impl TendermintCoin { }) } - /// This should only be used for Keplr from Ledger! + /// This should only be used for Keplr/WalletConnect from Ledger! /// When using Keplr from Ledger, they don't accept `SING_MODE_DIRECT` transactions. /// /// Visit https://docs.cosmos.network/main/build/architecture/adr-050-sign-mode-textual#context for more context. diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index 1c4cb113fe..a8008db76a 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -233,36 +233,30 @@ async fn activate_with_walletconnect( ctx: &MmArc, chain_id: &str, ticker: &str, - wallet_type: &mut TendermintWalletConnectionType, -) -> MmResult { - let account = { - let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); - - if wc.is_ledger_connection().await { - *wallet_type = TendermintWalletConnectionType::WcLedger; - } else { - *wallet_type = TendermintWalletConnectionType::Wc; - }; - - cosmos_get_accounts_impl(&wc, chain_id) - .await - .mm_err(|err| TendermintInitError { - ticker: ticker.to_string(), - kind: TendermintInitErrorKind::UnableToFetchChainAccount(err.to_string()), - })? +) -> MmResult<(TendermintActivationPolicy, TendermintWalletConnectionType), TendermintInitError> { + let wc = WalletConnectCtx::from_ctx(ctx).expect("WalletConnectCtx should be initialized by now!"); + let account = cosmos_get_accounts_impl(&wc, chain_id) + .await + .mm_err(|err| TendermintInitError { + ticker: ticker.to_string(), + kind: TendermintInitErrorKind::UnableToFetchChainAccount(err.to_string()), + })?; + let wallet_type = if wc.is_ledger_connection().await { + TendermintWalletConnectionType::WcLedger + } else { + TendermintWalletConnectionType::Wc }; let pubkey = match account.algo { CosmosAccountAlgo::Secp256k1 | CosmosAccountAlgo::TendermintSecp256k1 => { - TendermintPublicKey::from_raw_secp256k1(&account.pubkey).ok_or("Invalid secp256k1 pubkey".to_owned()) + TendermintPublicKey::from_raw_secp256k1(&account.pubkey).ok_or(TendermintInitError { + ticker: ticker.to_string(), + kind: TendermintInitErrorKind::Internal("Invalid secp256k1 pubkey".to_owned()), + })? }, - } - .map_to_mm(|e| TendermintInitError { - ticker: ticker.to_string(), - kind: TendermintInitErrorKind::Internal(e), - })?; + }; - Ok(TendermintActivationPolicy::with_public_key(pubkey)) + Ok((TendermintActivationPolicy::with_public_key(pubkey), wallet_type)) } #[async_trait] @@ -284,9 +278,8 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { protocol_conf: Self::PlatformProtocolInfo, ) -> Result> { let conf = TendermintConf::try_from_json(&ticker, coin_conf)?; - let mut wallet_connectin_type = TendermintWalletConnectionType::Internal; - let activation_policy = if let Some(params) = activation_request.activation_params { + let (activation_policy, wallet_connection_type) = if let Some(params) = activation_request.activation_params { if ctx.is_watcher() || ctx.use_watchers() { return MmError::err(TendermintInitError { ticker: ticker.clone(), @@ -299,20 +292,19 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { pubkey, is_ledger_connection, } => { - if is_ledger_connection { - wallet_connectin_type = TendermintWalletConnectionType::KeplrLedger; + let wallet_connection_type = if is_ledger_connection { + TendermintWalletConnectionType::KeplrLedger + } else { + TendermintWalletConnectionType::Keplr }; - TendermintActivationPolicy::with_public_key(pubkey) + ( + TendermintActivationPolicy::with_public_key(pubkey), + wallet_connection_type, + ) }, TendermintPubkeyActivationParams::WalletConnect => { - activate_with_walletconnect( - &ctx, - protocol_conf.chain_id.as_ref(), - &ticker, - &mut wallet_connectin_type, - ) - .await? + activate_with_walletconnect(&ctx, protocol_conf.chain_id.as_ref(), &ticker).await? }, } } else { @@ -325,7 +317,10 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { let tendermint_private_key_policy = tendermint_priv_key_policy(&conf, &ticker, private_key_policy, activation_request.path_to_address)?; - TendermintActivationPolicy::with_private_key_policy(tendermint_private_key_policy) + ( + TendermintActivationPolicy::with_private_key_policy(tendermint_private_key_policy), + TendermintWalletConnectionType::Native, + ) }; TendermintCoin::init( @@ -336,7 +331,7 @@ impl PlatformCoinWithTokensActivationOps for TendermintCoin { activation_request.nodes, activation_request.tx_history, activation_policy, - Some(wallet_connectin_type), + Some(wallet_connection_type), ) .await } From bb186c2450e1b33fc0783cd236076da46a87125f Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Fri, 15 Nov 2024 14:31:58 +0100 Subject: [PATCH 111/125] fix: self review --- mm2src/coins/eth.rs | 2 +- .../src/connection_handler.rs | 2 +- mm2src/kdf_walletconnect/src/lib.rs | 37 +++++++------------ mm2src/kdf_walletconnect/src/session.rs | 17 ++------- .../src/session/rpc/event.rs | 23 +++++++----- mm2src/kdf_walletconnect/src/storage/mod.rs | 2 +- 6 files changed, 34 insertions(+), 49 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 0a5f327c82..247c90af91 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -2956,7 +2956,7 @@ async fn sign_raw_eth_tx(coin: &EthCoin, args: &SignEthTransactionParams) -> Raw }) }, EthPrivKeyPolicy::Trezor => MmError::err(RawTransactionError::InvalidParam( - "sign raw eth tx not implemented for Metamask".into(), + "sign raw eth tx not implemented for Trezor".into(), )), #[cfg(target_arch = "wasm32")] EthPrivKeyPolicy::Metamask(_) => MmError::err(RawTransactionError::InvalidParam( diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 8c4c0feb61..28a52b0072 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -82,7 +82,7 @@ pub(crate) async fn initialize_connection(wc: Arc) { while let Err(err) = wc.connect_client().await { retry_count += 1; - info!( + error!( "Error during initial connection attempt {}: {:?}. Retrying in {retry_secs} seconds...", retry_count, err ); diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index c6c4d3320d..9b8ebcb4d7 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -43,8 +43,7 @@ use storage::SessionStorageDb; use storage::WalletConnectStorageOps; use wc_common::{decode_and_decrypt_type0, encrypt_and_encode, EnvelopeType, SymKey}; -const WAIT_DURATION: Duration = Duration::from_secs(60); -const PUBLISH_TIMEOUT_SECS: f64 = 5.0; +const PUBLISH_TIMEOUT_SECS: f64 = 6.; const MAX_RETRIES: usize = 5; #[async_trait::async_trait] @@ -70,36 +69,30 @@ pub trait WalletConnectOps { } pub struct WalletConnectCtx { - pub client: Client, - pub pairing: PairingClient, + pub(crate) client: Client, + pub(crate) pairing: PairingClient, pub session: SessionManager, - pub(crate) key_pair: SymKeyPair, - relay: Relay, metadata: Metadata, inbound_message_rx: Arc>>, connection_live_rx: Arc>>>, message_tx: UnboundedSender, message_rx: Arc>>, - _abort_handle: AbortOnDropHandle, } impl WalletConnectCtx { pub fn try_init(ctx: &MmArc) -> MmResult { - let (inbound_message_tx, inbound_message_rx) = unbounded(); - let (conn_live_sender, conn_live_receiver) = unbounded(); - let (message_tx, session_request_receiver) = unbounded(); - + let storage = SessionStorageDb::new(ctx)?; let pairing = PairingClient::new(); let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), data: None, }; - - let storage = SessionStorageDb::init(ctx)?; - + let (inbound_message_tx, inbound_message_rx) = unbounded(); + let (conn_live_sender, conn_live_receiver) = unbounded(); + let (message_tx, session_request_receiver) = unbounded(); let (client, _abort_handle) = Client::new_with_callback( Handler::new("Komodefi", inbound_message_tx, conn_live_sender), |r, h| spawn_abortable(client_event_loop(r, h)), @@ -112,12 +105,10 @@ impl WalletConnectCtx { metadata: generate_metadata(), key_pair: SymKeyPair::new(), session: SessionManager::new(storage), - inbound_message_rx: Arc::new(inbound_message_rx.into()), connection_live_rx: Arc::new(conn_live_receiver.into()), message_rx: Arc::new(session_request_receiver.into()), message_tx, - _abort_handle, }) } @@ -134,7 +125,7 @@ impl WalletConnectCtx { let key = SigningKey::generate(&mut rand::thread_rng()); AuthToken::new(AUTH_TOKEN_SUB) .aud(RELAY_ADDRESS) - .ttl(Duration::from_secs(8 * 60 * 60)) + .ttl(Duration::from_secs(5 * 60 * 60)) .as_jwt(&key) .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))? }; @@ -339,7 +330,7 @@ impl WalletConnectCtx { } MmError::err(WalletConnectError::InternalError( - "client connection timeout".to_string(), + "[{topic}] client connection timeout".to_string(), )) } @@ -501,10 +492,11 @@ impl WalletConnectCtx { params, }, }; - self.publish_request(&active_topic, RequestParams::SessionRequest(request)) - .await?; - // Wait for response - if let Ok(Some(resp)) = self.message_rx.lock().await.next().timeout(WAIT_DURATION).await { + let request = RequestParams::SessionRequest(request); + let ttl = request.irn_metadata().ttl; + self.publish_request(&active_topic, request).await?; + + if let Ok(Some(resp)) = self.message_rx.lock().await.next().timeout_secs(ttl as f64).await { let result = resp.mm_err(WalletConnectError::InternalError)?; if let ResponseParamsSuccess::Arbitrary(data) = result.data { let data = serde_json::from_value::(data)?; @@ -512,7 +504,6 @@ impl WalletConnectCtx { } } - // QUESTION: should we consider retrying request instead of returning error immediately. MmError::err(WalletConnectError::NoWalletFeedback) } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session.rs index 0a6f9eb25a..967de77af8 100644 --- a/mm2src/kdf_walletconnect/src/session.rs +++ b/mm2src/kdf_walletconnect/src/session.rs @@ -10,6 +10,7 @@ use common::log::info; use dashmap::mapref::multiple::RefMulti; use dashmap::mapref::one::RefMut; use dashmap::DashMap; +use derive_more::Display; use key::SessionKey; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::domain::Topic; @@ -26,15 +27,15 @@ use std::sync::Arc; use tokio::sync::Mutex; use wc_common::SymKey; -pub(crate) const FIVE_MINUTES: u64 = 300; -pub(crate) const THIRTY_DAYS: u64 = 60 * 60 * 30; +pub(crate) const FIVE_MINUTES: u64 = 5 * 60; +pub(crate) const THIRTY_DAYS: u64 = 30 * 24 * 60 * 60; pub(crate) type WcRequestResponseResult = MmResult<(Value, IrnMetadata), WalletConnectError>; /// In the WalletConnect protocol, a session involves two parties: a controller /// (typically a wallet) and a proposer (typically a dApp). This enum is used /// to distinguish between these two roles. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Display, Clone, Serialize, Deserialize, PartialEq, Eq)] pub enum SessionType { /// Represents the controlling party in a session, typically a wallet. Controller, @@ -42,15 +43,6 @@ pub enum SessionType { Proposer, } -impl ToString for SessionType { - fn to_string(&self) -> String { - match self { - Self::Controller => "Controller".to_string(), - Self::Proposer => "Proposer".to_string(), - } - } -} - #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)] pub struct SessionRpcInfo { pub topic: Topic, @@ -146,7 +138,6 @@ impl Session { metadata: Metadata, session_type: SessionType, ) -> Self { - // handle proposer or controller let (proposer, controller) = match session_type { SessionType::Proposer => ( Proposer { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 78642f8327..a70ebf2ca3 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -32,17 +32,20 @@ pub async fn handle_session_event( ctx.validate_chain_id(&session, &chain_id).await?; - if let Some(active_chain_id) = session.get_active_chain_id().await { - if &chain_id == active_chain_id { - return Ok(()); - } + if session + .get_active_chain_id() + .await + .as_ref() + .map_or(false, |c| c == &chain_id) + { + return Ok(()); }; - // check if chain_id is supported. - let id_string = serde_json::from_value::(event.event.data)?; - let new_chain = chain_id.chain.derive_chain_id(id_string.to_string()); + // check if if new chain_id is supported. + let new_id = serde_json::from_value::(event.event.data)?; + let new_chain = chain_id.chain.derive_chain_id(new_id.to_string()); if let Err(err) = ctx.validate_chain_id(&session, &new_chain).await { - error!("{err:?}"); + error!("[{topic}] {err:?}"); let error_data = ErrorData { code: UNSUPPORTED_CHAINS, message: "Unsupported chain id".to_string(), @@ -57,7 +60,7 @@ pub async fn handle_session_event( .ok_or(MmError::new(WalletConnectError::SessionError( "No active WalletConnect session found".to_string(), )))? - .set_active_chain_id(chain_id.clone()) + .set_active_chain_id(chain_id) .await; } }; @@ -70,6 +73,6 @@ pub async fn handle_session_event( }, }; - info!("chainChanged event handled successfully"); + info!("[{topic}] chainChanged event handled successfully"); Ok(()) } diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index f94b5502cc..1c8c41fd78 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -37,7 +37,7 @@ impl Deref for SessionStorageDb { } impl SessionStorageDb { - pub(crate) fn init(ctx: &MmArc) -> MmResult { + pub(crate) fn new(ctx: &MmArc) -> MmResult { let db = DB::new(ctx).mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; Ok(SessionStorageDb(db)) From 77d79097dc05af922800e7ee3d0dcb0b799d2e4d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Sat, 16 Nov 2024 12:02:51 +0100 Subject: [PATCH 112/125] fix review notes --- mm2src/coins/eth/v2_activation.rs | 3 --- mm2src/coins/lp_coins.rs | 6 ++---- mm2src/coins/utxo/utxo_common.rs | 4 ++-- mm2src/mm2_main/src/rpc.rs | 2 +- mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs | 11 ----------- .../src/rpc/wc_commands/{wc_commands.rs => mod.rs} | 0 6 files changed, 5 insertions(+), 21 deletions(-) rename mm2src/mm2_main/src/rpc/wc_commands/{wc_commands.rs => mod.rs} (100%) diff --git a/mm2src/coins/eth/v2_activation.rs b/mm2src/coins/eth/v2_activation.rs index 278986e24f..6a97cac477 100644 --- a/mm2src/coins/eth/v2_activation.rs +++ b/mm2src/coins/eth/v2_activation.rs @@ -311,8 +311,6 @@ pub enum EthTokenActivationParams { #[derive(Clone, Deserialize)] pub struct Erc20TokenActivationRequest { pub required_confirmations: Option, - // #[serde(default)] - // pub use_walletconnect: Option, } /// Holds ERC-20 token-specific activation parameters when using the task manager for activation. @@ -805,7 +803,6 @@ pub(crate) async fn build_address_and_priv_key_policy( let public_key = compress_public_key(public_key_uncompressed)?; Ok(( EthPrivKeyPolicy::WalletConnect { - address, public_key, public_key_uncompressed, }, diff --git a/mm2src/coins/lp_coins.rs b/mm2src/coins/lp_coins.rs index f0a435a0fb..9c9d631fa3 100644 --- a/mm2src/coins/lp_coins.rs +++ b/mm2src/coins/lp_coins.rs @@ -54,8 +54,7 @@ use crypto::{derive_secp256k1_secret, Bip32Error, Bip44Chain, CryptoCtx, CryptoC Secp256k1ExtendedPublicKey, Secp256k1Secret, WithHwRpcError}; use derive_more::Display; use enum_derives::{EnumFromStringify, EnumFromTrait}; -use ethereum_types::{H160, H256}; -use ethereum_types::{H264, H520}; +use ethereum_types::{H256, H264, H520}; use futures::compat::Future01CompatExt; use futures::lock::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; use futures::{FutureExt, TryFutureExt}; @@ -2123,7 +2122,7 @@ pub struct WithdrawRequest { memo: Option, /// Tendermint specific field used for manually providing the IBC channel IDs. ibc_source_channel: Option, - /// Currently, this flag is used by ETH/ERC20 coins activated with MetaMask/WalletConnect **only**. + /// Currently, this flag is used by ETH/ERC20 coins activated with MetaMask/WalletConnect(Some wallets e.g Metamask) **only**. #[serde(default)] broadcast: bool, } @@ -3903,7 +3902,6 @@ pub enum PrivKeyPolicy { Metamask(EthMetamaskPolicy), WalletConnect { - address: H160, public_key: H264, public_key_uncompressed: H520, }, diff --git a/mm2src/coins/utxo/utxo_common.rs b/mm2src/coins/utxo/utxo_common.rs index c4b0b5cf92..a0c9662e86 100644 --- a/mm2src/coins/utxo/utxo_common.rs +++ b/mm2src/coins/utxo/utxo_common.rs @@ -4745,10 +4745,10 @@ pub fn derive_htlc_key_pair(coin: &UtxoCoinFields, _swap_unique_data: &[u8]) -> activated_key: activated_key_pair, .. } => activated_key_pair, - PrivKeyPolicy::Trezor => todo!(), + PrivKeyPolicy::Trezor => panic!("`PrivKeyPolicy::Trezor` is not supported for UTXO coins"), #[cfg(target_arch = "wasm32")] PrivKeyPolicy::Metamask(_) => panic!("`PrivKeyPolicy::Metamask` is not supported for UTXO coins"), - PrivKeyPolicy::WalletConnect { .. } => todo!(), + PrivKeyPolicy::WalletConnect { .. } => panic!("`PrivKeyPolicy::WalletConnect` is not supported for UTXO coins"), } } diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index 64996cdb44..45b2279c54 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -48,7 +48,7 @@ mod dispatcher_legacy; #[path = "rpc/lp_commands/lp_commands_legacy.rs"] pub mod lp_commands_legacy; mod rate_limiter; -#[path = "rpc/wc_commands/wc_commands.rs"] pub mod wc_commands; +pub mod wc_commands; /// Lists the RPC method not requiring the "userpass" authentication. /// None is also public to skip auth and display proper error in case of method is missing diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index c5e6295523..89a7ffb6a3 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -226,17 +226,6 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, disconnect_session).await, "wc_set_active_session" => handle_mmrpc(ctx, request, set_active_session).await, "wc_ping_session" => handle_mmrpc(ctx, request, ping_session).await, - #[cfg(not(target_arch = "wasm32"))] - native_only_methods => match native_only_methods { - #[cfg(all(feature = "enable-solana", not(target_os = "ios"), not(target_os = "android")))] - "enable_solana_with_tokens" => { - handle_mmrpc(ctx, request, enable_platform_coin_with_tokens::).await - }, - #[cfg(all(feature = "enable-solana", not(target_os = "ios"), not(target_os = "android")))] - "enable_spl" => handle_mmrpc(ctx, request, enable_token::).await, - _ => MmError::err(DispatcherError::NoSuchMethod), - }, - #[cfg(target_arch = "wasm32")] _ => MmError::err(DispatcherError::NoSuchMethod), } } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs b/mm2src/mm2_main/src/rpc/wc_commands/mod.rs similarity index 100% rename from mm2src/mm2_main/src/rpc/wc_commands/wc_commands.rs rename to mm2src/mm2_main/src/rpc/wc_commands/mod.rs From 0d3fdfea13af76447ae683b6e7ab4ed2616b1b14 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 18 Nov 2024 09:27:05 +0100 Subject: [PATCH 113/125] increase rpc timeout and return PublicKey from recover --- mm2src/coins/eth/wallet_connect.rs | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 83b9da46c0..d87823039e 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -15,6 +15,7 @@ use kdf_walletconnect::{chain::{WcChainId, WcRequestMethods}, error::WalletConnectError, WalletConnectCtx}; use mm2_err_handle::prelude::*; +use secp256k1::PublicKey; use secp256k1::{recovery::{RecoverableSignature, RecoveryId}, Secp256k1}; use std::str::FromStr; @@ -22,6 +23,9 @@ use web3::signing::hash_message; use super::EthCoin; +// Wait for 20 seconds for the transaction to appear on the RPC node. +const WAIT_RPC_TIMEOUT: u64 = 30_000; + #[derive(Display, Debug, EnumFromStringify)] pub enum EthWalletConnectError { UnsupportedChainId(WcChainId), @@ -131,10 +135,8 @@ impl WalletConnectOps for EthCoin { }; let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); let maybe_signed_tx = { - // Wait for 10 seconds for the transaction to appear on the RPC node. - let wait_rpc_timeout = 10_000; let check_every = 1.; - self.wait_for_tx_appears_on_rpc(H256::from_slice(&hex::decode(tx_hash)?), wait_rpc_timeout, check_every) + self.wait_for_tx_appears_on_rpc(H256::from_slice(&hex::decode(tx_hash)?), WAIT_RPC_TIMEOUT, check_every) .await .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))? }; @@ -183,15 +185,17 @@ fn extract_pubkey_from_signature( ) -> MmResult<(H520, Address), EthWalletConnectError> { let account = H160::from_str(&account[2..]).map_to_mm(|err| EthWalletConnectError::InternalError(err.to_string()))?; - let uncompressed = { + let uncompressed: H520 = { let message_hash = hash_message(message.to_string()); let signature = Signature::from_str(&signature_str[2..]) .map_to_mm(|err| EthWalletConnectError::InvalidSignature(err.to_string()))?; - recover(&signature, &message_hash).map_to_mm(|err| { + let pubkey = recover(&signature, &message_hash).map_to_mm(|err| { let error = format!("Couldn't recover a public key from the signature: '{signature:?}, error: {err:?}'"); EthWalletConnectError::InvalidSignature(error) - })? + })?; + pubkey.serialize_uncompressed().into() }; + let mut public = Public::default(); public.as_mut().copy_from_slice(&uncompressed[1..65]); @@ -204,7 +208,7 @@ fn extract_pubkey_from_signature( Ok((uncompressed, recovered_address)) } -pub(crate) fn recover(signature: &Signature, message: &Message) -> Result { +pub(crate) fn recover(signature: &Signature, message: &Message) -> Result { let recovery_id = { let recovery_id = (signature[64] as i32) .checked_sub(27) @@ -213,9 +217,8 @@ pub(crate) fn recover(signature: &Signature, message: &Message) -> Result Date: Mon, 18 Nov 2024 18:02:57 +0100 Subject: [PATCH 114/125] fix review notes --- mm2src/coins/tendermint/tendermint_coin.rs | 8 ++------ mm2src/kdf_walletconnect/src/lib.rs | 16 ++++++++-------- .../src/{session.rs => session/mod.rs} | 0 mm2src/mm2_main/src/rpc.rs | 15 --------------- 4 files changed, 10 insertions(+), 29 deletions(-) rename mm2src/kdf_walletconnect/src/{session.rs => session/mod.rs} (100%) diff --git a/mm2src/coins/tendermint/tendermint_coin.rs b/mm2src/coins/tendermint/tendermint_coin.rs index c7c0707290..99db217441 100644 --- a/mm2src/coins/tendermint/tendermint_coin.rs +++ b/mm2src/coins/tendermint/tendermint_coin.rs @@ -272,14 +272,10 @@ impl TendermintActivationPolicy { .ok_or_else(|| io::Error::new(io::ErrorKind::InvalidData, "Couldn't generate public key")) }, - PrivKeyPolicy::Trezor => Err(io::Error::new( + _ => Err(io::Error::new( io::ErrorKind::Unsupported, - "Trezor is not supported yet!", + "UnsupportedModeForPrivKeyPolicy", )), - - #[cfg(target_arch = "wasm32")] - PrivKeyPolicy::Metamask(_) => unreachable!(), - PrivKeyPolicy::WalletConnect { .. } => unreachable!(), }, Self::PublicKey(account_public_key) => Ok(*account_public_key), } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 9b8ebcb4d7..2825d86bc3 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -139,12 +139,13 @@ impl WalletConnectCtx { pub(crate) async fn reconnect_and_subscribe(&self) -> MmResult<(), WalletConnectError> { self.connect_client().await?; // Resubscribes to previously active session topics after reconnection. - let sessions = self.session.get_sessions(); - for session in sessions { - self.client - .batch_subscribe(vec![session.topic, session.pairing_topic]) - .await?; - } + let sessions = self + .session + .get_sessions() + .flat_map(|s| vec![s.topic, s.pairing_topic]) + .collect::>(); + + self.client.batch_subscribe(sessions).await?; Ok(()) } @@ -382,8 +383,7 @@ impl WalletConnectCtx { }; } - // https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces - // #13-chains-might-be-omitted-if-the-caip-2-is-defined-in-the-index + // https://specs.walletconnect.com/2.0/specs/clients/sign/namespaces#13-chains-might-be-omitted-if-the-caip-2-is-defined-in-the-index if session.namespaces.contains_key(&chain_id.to_string()) { return Ok(()); } diff --git a/mm2src/kdf_walletconnect/src/session.rs b/mm2src/kdf_walletconnect/src/session/mod.rs similarity index 100% rename from mm2src/kdf_walletconnect/src/session.rs rename to mm2src/kdf_walletconnect/src/session/mod.rs diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index 45b2279c54..e24d960076 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -205,8 +205,6 @@ async fn process_single_request(ctx: MmArc, req: Json, client: SocketAddr) -> Re #[cfg(not(target_arch = "wasm32"))] async fn rpc_service(req: Request, ctx_h: u32, client: SocketAddr) -> Response { - const NON_ALLOWED_CHARS: &[char] = &['Ã’']; - /// Unwraps a result or propagates its error 500 response with the specified headers (if they are present). macro_rules! try_sf { ($value: expr $(, $header_key:expr => $header_val:expr)*) => { @@ -265,19 +263,6 @@ async fn rpc_service(req: Request, ctx_h: u32, client: SocketAddr) -> Resp let req_json = { let req_bytes = try_sf!(hyper::body::to_bytes(req_body).await, ACCESS_CONTROL_ALLOW_ORIGIN => rpc_cors); - let req_str = String::from_utf8_lossy(req_bytes.as_ref()); - let is_invalid_input = req_str.chars().any(|c| NON_ALLOWED_CHARS.contains(&c)); - if is_invalid_input { - return Response::builder() - .status(500) - .header(ACCESS_CONTROL_ALLOW_ORIGIN, rpc_cors) - .header(CONTENT_TYPE, APPLICATION_JSON) - .body(Body::from(err_to_rpc_json_string(&format!( - "Invalid input: contains one or more of the following non-allowed characters: {:?}", - NON_ALLOWED_CHARS - )))) - .unwrap(); - } try_sf!(json::from_slice(&req_bytes), ACCESS_CONTROL_ALLOW_ORIGIN => rpc_cors) }; From db1e687bbd7dae5d212182aa99f4129194d0a79d Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Mon, 18 Nov 2024 18:40:17 +0100 Subject: [PATCH 115/125] fmt --- mm2src/mm2_main/src/rpc.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm2src/mm2_main/src/rpc.rs b/mm2src/mm2_main/src/rpc.rs index e24d960076..6d9e5fcf56 100644 --- a/mm2src/mm2_main/src/rpc.rs +++ b/mm2src/mm2_main/src/rpc.rs @@ -22,10 +22,10 @@ use crate::rpc::rate_limiter::RateLimitError; use common::log::{error, info}; -use common::{err_to_rpc_json_string, err_tp_rpc_json, HttpStatusCode, APPLICATION_JSON}; +use common::{err_to_rpc_json_string, err_tp_rpc_json, HttpStatusCode}; use derive_more::Display; use futures::future::{join_all, FutureExt}; -use http::header::{HeaderValue, ACCESS_CONTROL_ALLOW_ORIGIN, CONTENT_TYPE}; +use http::header::{HeaderValue, ACCESS_CONTROL_ALLOW_ORIGIN}; use http::request::Parts; use http::{Method, Request, Response, StatusCode}; use mm2_core::mm_ctx::MmArc; From 11d114d81d6e5d77493fe21f1bd90af5b6eb3a34 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 19 Nov 2024 12:25:03 +0100 Subject: [PATCH 116/125] remove dup session delete rpc --- mm2src/kdf_walletconnect/src/lib.rs | 17 ++-------- .../src/session/rpc/delete.rs | 2 +- .../mm2_main/src/rpc/dispatcher/dispatcher.rs | 5 ++- .../src/rpc/wc_commands/delete_connection.rs | 31 ------------------- mm2src/mm2_main/src/rpc/wc_commands/mod.rs | 2 -- 5 files changed, 5 insertions(+), 52 deletions(-) delete mode 100644 mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 2825d86bc3..d652524976 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -35,6 +35,7 @@ use relay_rpc::rpc::params::{session_request::Request as SessionRequest, IrnMeta RelayProtocolMetadata, RequestParams, ResponseParamsError, ResponseParamsSuccess}; use relay_rpc::rpc::{ErrorResponse, Payload, Request, Response, SuccessfulResponse}; use serde::de::DeserializeOwned; +use session::rpc::delete::send_session_delete_request; use session::Session; use session::{key::SymKeyPair, SessionManager}; use std::collections::BTreeSet; @@ -508,21 +509,7 @@ impl WalletConnectCtx { } pub async fn drop_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { - self.client.unsubscribe(topic.clone()).await?; - - if let Some(session) = self.session.delete_session(topic).await { - self.pairing - .disconnect_rpc(&session.pairing_topic, &self.client) - .await?; - }; - - self.session - .storage() - .delete_session(topic) - .await - .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; - - Ok(()) + send_session_delete_request(self, topic).await } } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 6f2dee2f43..6a79e2165f 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -19,7 +19,7 @@ pub(crate) async fn reply_session_delete_request( session_delete_cleanup(ctx, topic).await } -pub async fn send_session_delete_request( +pub(crate) async fn send_session_delete_request( ctx: &WalletConnectCtx, session_topic: &Topic, ) -> MmResult<(), WalletConnectError> { diff --git a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs index 89a7ffb6a3..0632af3adc 100644 --- a/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs +++ b/mm2src/mm2_main/src/rpc/dispatcher/dispatcher.rs @@ -9,7 +9,7 @@ use crate::lp_ordermatch::{best_orders_rpc_v2, orderbook_rpc_v2, start_simple_ma use crate::lp_swap::swap_v2_rpcs::{active_swaps_rpc, my_recent_swaps_rpc, my_swap_status_rpc}; use crate::lp_wallet::{get_mnemonic_rpc, get_wallet_names_rpc}; use crate::rpc::rate_limiter::{process_rate_limit, RateLimitContext}; -use crate::rpc::wc_commands::{delete_connection, new_connection, ping_session}; +use crate::rpc::wc_commands::{new_connection, ping_session}; use crate::{lp_stats::{add_node_to_version_stat, remove_node_from_version_stat, start_version_stat_collection, stop_version_stat_collection, update_version_stat_collection}, lp_swap::{get_locked_amount_rpc, max_maker_vol, recreate_swap_data, trade_preimage_rpc}, @@ -220,10 +220,9 @@ async fn dispatcher_v2(request: MmRpcRequest, ctx: MmArc) -> DispatcherResult handle_mmrpc(ctx, request, send_asked_data_rpc).await, "z_coin_tx_history" => handle_mmrpc(ctx, request, coins::my_tx_history_v2::z_coin_tx_history_rpc).await, "wc_new_connection" => handle_mmrpc(ctx, request, new_connection).await, - "wc_delete_connection" => handle_mmrpc(ctx, request, delete_connection).await, "wc_get_session" => handle_mmrpc(ctx, request, get_session).await, "wc_get_sessions" => handle_mmrpc(ctx, request, get_all_sessions).await, - "wc_disconnect_session" => handle_mmrpc(ctx, request, disconnect_session).await, + "wc_delete_session" => handle_mmrpc(ctx, request, disconnect_session).await, "wc_set_active_session" => handle_mmrpc(ctx, request, set_active_session).await, "wc_ping_session" => handle_mmrpc(ctx, request, ping_session).await, _ => MmError::err(DispatcherError::NoSuchMethod), diff --git a/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs deleted file mode 100644 index 266dde7233..0000000000 --- a/mm2src/mm2_main/src/rpc/wc_commands/delete_connection.rs +++ /dev/null @@ -1,31 +0,0 @@ -use kdf_walletconnect::session::rpc::delete::send_session_delete_request; -use kdf_walletconnect::WalletConnectCtx; -use mm2_core::mm_ctx::MmArc; -use mm2_err_handle::prelude::*; -use serde::{Deserialize, Serialize}; - -use super::WalletConnectRpcError; - -#[derive(Debug, PartialEq, Serialize)] -pub struct DeleteConnectionResponse { - pub successful: bool, -} - -#[derive(Deserialize)] -pub struct DeleteConnectionRequest { - topic: String, -} - -/// `delete connection` RPC command implementation. -pub async fn delete_connection( - ctx: MmArc, - req: DeleteConnectionRequest, -) -> MmResult { - let ctx = - WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - send_session_delete_request(&ctx, &req.topic.into()) - .await - .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; - - Ok(DeleteConnectionResponse { successful: true }) -} diff --git a/mm2src/mm2_main/src/rpc/wc_commands/mod.rs b/mm2src/mm2_main/src/rpc/wc_commands/mod.rs index 5dfc605516..08df545f8a 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/mod.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/mod.rs @@ -1,9 +1,7 @@ -mod delete_connection; mod new_connection; mod sessions; use common::HttpStatusCode; -pub use delete_connection::delete_connection; use derive_more::Display; use http::StatusCode; pub use new_connection::new_connection; From af91d47711ee03fd353a529aa5a59b254be52823 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 19 Nov 2024 12:40:31 +0100 Subject: [PATCH 117/125] rename var and remove unnecessary sorting from storage sessions loading --- mm2src/kdf_walletconnect/src/chain.rs | 4 ++-- mm2src/kdf_walletconnect/src/lib.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index cad6a225f8..78775e6f42 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -126,11 +126,11 @@ pub(crate) fn build_default_required_namespaces() -> ProposeNamespaces { } pub(crate) fn build_optional_namespaces() -> ProposeNamespaces { - let required = BTreeMap::from([(WcChain::Cosmos.as_ref().to_string(), ProposeNamespace { + let optional = BTreeMap::from([(WcChain::Cosmos.as_ref().to_string(), ProposeNamespace { methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), events: BTreeSet::default(), })]); - ProposeNamespaces(required) + ProposeNamespaces(optional) } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index d652524976..b369a6fbea 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -221,7 +221,7 @@ impl WalletConnectCtx { async fn load_session_from_storage(&self) -> MmResult<(), WalletConnectError> { info!("Loading WalletConnect session from storage"); let now = chrono::Utc::now().timestamp() as u64; - let mut sessions = self + let sessions = self .session .storage() .get_all_sessions() @@ -229,8 +229,7 @@ impl WalletConnectCtx { .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // bring most recent active session to the back. - sessions.sort_by(|a, b| a.expiry.cmp(&b.expiry)); - for session in sessions { + for session in sessions.into_iter().rev() { // delete expired session if now > session.expiry { debug!("Session {} expired, trying to delete from storage", session.topic); From 10e9e677ab9242342b9168061b87546c748089d0 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 19 Nov 2024 13:15:46 +0100 Subject: [PATCH 118/125] refactor wait_for_tx_appears_on_rpc to use secs for time --- mm2src/coins/eth.rs | 11 +++++------ mm2src/coins/eth/eth_withdraw.rs | 2 +- mm2src/coins/eth/wallet_connect.rs | 14 +++++++++----- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 247c90af91..8339624c63 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -59,7 +59,7 @@ use common::executor::{abortable_queue::AbortableQueue, AbortOnDropHandle, Abort AbortedError, SpawnAbortable, Timer}; use common::log::{debug, error, info, warn}; use common::number_type_casting::SafeTypeCastingNumbers; -use common::{now_ms, wait_until_ms}; +use common::{now_ms, wait_until_sec}; use common::{now_sec, small_rng, DEX_FEE_ADDR_RAW_PUBKEY}; use crypto::privkey::key_pair_from_secret; use crypto::{Bip44Chain, CryptoCtx, CryptoCtxError, GlobalHDAccountArc, KeyPairPolicy}; @@ -2841,7 +2841,7 @@ async fn sign_and_send_transaction_with_metamask( // It's important to return the transaction hex for the swap, // so wait up to 60 seconds for the transaction to appear on the RPC node. - let wait_rpc_timeout = 60_000; + let wait_rpc_timeout = 60; let check_every = 1.; // Please note that this method may take a long time @@ -5535,10 +5535,10 @@ impl EthCoin { async fn wait_for_tx_appears_on_rpc( &self, tx_hash: H256, - wait_rpc_timeout_ms: u64, + wait_rpc_timeout_s: u64, check_every: f64, ) -> Web3RpcResult> { - let wait_until = wait_until_ms(wait_rpc_timeout_ms); + let wait_until = wait_until_sec(wait_rpc_timeout_s); while now_ms() < wait_until { let maybe_tx = self.transaction(TransactionId::Hash(tx_hash)).await?; if let Some(tx) = maybe_tx { @@ -5549,9 +5549,8 @@ impl EthCoin { Timer::sleep(check_every).await; } - let timeout_s = wait_rpc_timeout_ms / 1000; warn!( - "Couldn't fetch the '{tx_hash:02x}' transaction hex as it hasn't appeared on the RPC node in {timeout_s}s" + "Couldn't fetch the '{tx_hash:02x}' transaction hex as it hasn't appeared on the RPC node in {wait_rpc_timeout_s}s" ); Ok(None) diff --git a/mm2src/coins/eth/eth_withdraw.rs b/mm2src/coins/eth/eth_withdraw.rs index 246aadf38f..30676758aa 100644 --- a/mm2src/coins/eth/eth_withdraw.rs +++ b/mm2src/coins/eth/eth_withdraw.rs @@ -167,7 +167,7 @@ where } // Wait for 10 seconds for the transaction to appear on the RPC node. - let wait_rpc_timeout = 10_000; + let wait_rpc_timeout = 10; let check_every = 1.; // Please note that this method may take a long time diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index d87823039e..984de054c7 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -23,8 +23,8 @@ use web3::signing::hash_message; use super::EthCoin; -// Wait for 20 seconds for the transaction to appear on the RPC node. -const WAIT_RPC_TIMEOUT: u64 = 30_000; +// Wait for 30 seconds for the transaction to appear on the RPC node. +const WAIT_RPC_TIMEOUT_SECS: u64 = 30; #[derive(Display, Debug, EnumFromStringify)] pub enum EthWalletConnectError { @@ -136,9 +136,13 @@ impl WalletConnectOps for EthCoin { let tx_hash = tx_hash.strip_prefix("0x").unwrap_or(&tx_hash); let maybe_signed_tx = { let check_every = 1.; - self.wait_for_tx_appears_on_rpc(H256::from_slice(&hex::decode(tx_hash)?), WAIT_RPC_TIMEOUT, check_every) - .await - .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))? + self.wait_for_tx_appears_on_rpc( + H256::from_slice(&hex::decode(tx_hash)?), + WAIT_RPC_TIMEOUT_SECS, + check_every, + ) + .await + .mm_err(|err| EthWalletConnectError::InternalError(err.to_string()))? }; let signed_tx = match maybe_signed_tx { Some(signed_tx) => signed_tx, From b9075ce28b0c95548a7a18930dc42cac79243e92 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 26 Nov 2024 17:12:53 +0100 Subject: [PATCH 119/125] batch subscribe to topics --- mm2src/kdf_walletconnect/src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index b369a6fbea..bddbadc702 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -227,6 +227,8 @@ impl WalletConnectCtx { .get_all_sessions() .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; + let mut valid_topics = Vec::with_capacity(sessions.len()); + let mut pairing_topics = Vec::with_capacity(sessions.len()); // bring most recent active session to the back. for session in sessions.into_iter().rev() { @@ -243,9 +245,14 @@ impl WalletConnectCtx { let pairing_topic = session.pairing_topic.clone(); debug!("[{topic}] Session found! activating"); self.session.add_session(session).await; - self.client.batch_subscribe(vec![topic, pairing_topic]).await?; + + valid_topics.push(topic); + pairing_topics.push(pairing_topic); } + let all_topics: Vec<_> = valid_topics.into_iter().chain(pairing_topics.into_iter()).collect(); + self.client.batch_subscribe(all_topics).await?; + Ok(()) } From 1ff17cd3e779054b5ff456ab709b63d37d2dda79 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Tue, 26 Nov 2024 17:40:04 +0100 Subject: [PATCH 120/125] rename ctx.session to ctx.session_manager --- mm2src/coins/tendermint/wallet_connect.rs | 2 +- .../src/connection_handler.rs | 2 +- mm2src/kdf_walletconnect/src/lib.rs | 34 +++++++-------- .../src/session/rpc/delete.rs | 4 +- .../src/session/rpc/event.rs | 14 +++---- .../src/session/rpc/extend.rs | 2 +- .../src/session/rpc/propose.rs | 8 ++-- .../src/session/rpc/settle.rs | 10 ++--- .../src/session/rpc/update.rs | 4 +- mm2src/kdf_walletconnect/src/storage/mod.rs | 41 +++++++++++++------ .../mm2_main/src/rpc/wc_commands/sessions.rs | 13 ++++-- 11 files changed, 78 insertions(+), 56 deletions(-) diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index b01e074977..3956e1c3e3 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -129,7 +129,7 @@ pub async fn cosmos_get_accounts_impl( let account = wc.get_account_for_chain_id(&chain_id).await?; let session = wc - .session + .session_manager .get_session_active() .await .ok_or(WalletConnectError::NotInitialized)?; diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 28a52b0072..5c15d4b249 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -91,7 +91,7 @@ pub(crate) async fn initialize_connection(wc: Arc) { } // Initialize storage - if let Err(err) = wc.session.storage().init().await { + if let Err(err) = wc.session_manager.storage().init().await { error!("Unable to initialize WalletConnect persistent storage: {err:?}. Only inmemory storage will be utilized for this Session."); }; diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index bddbadc702..105ce91c71 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -72,7 +72,7 @@ pub trait WalletConnectOps { pub struct WalletConnectCtx { pub(crate) client: Client, pub(crate) pairing: PairingClient, - pub session: SessionManager, + pub session_manager: SessionManager, pub(crate) key_pair: SymKeyPair, relay: Relay, metadata: Metadata, @@ -105,7 +105,7 @@ impl WalletConnectCtx { relay, metadata: generate_metadata(), key_pair: SymKeyPair::new(), - session: SessionManager::new(storage), + session_manager: SessionManager::new(storage), inbound_message_rx: Arc::new(inbound_message_rx.into()), connection_live_rx: Arc::new(conn_live_receiver.into()), message_rx: Arc::new(session_request_receiver.into()), @@ -141,7 +141,7 @@ impl WalletConnectCtx { self.connect_client().await?; // Resubscribes to previously active session topics after reconnection. let sessions = self - .session + .session_manager .get_sessions() .flat_map(|s| vec![s.topic, s.pairing_topic]) .collect::>(); @@ -185,7 +185,7 @@ impl WalletConnectCtx { /// Retrieves the symmetric key associated with a given `topic`. fn sym_key(&self, topic: &Topic) -> MmResult { - if let Some(key) = self.session.sym_key(topic) { + if let Some(key) = self.session_manager.sym_key(topic) { return Ok(key); } @@ -222,7 +222,7 @@ impl WalletConnectCtx { info!("Loading WalletConnect session from storage"); let now = chrono::Utc::now().timestamp() as u64; let sessions = self - .session + .session_manager .storage() .get_all_sessions() .await @@ -235,7 +235,7 @@ impl WalletConnectCtx { // delete expired session if now > session.expiry { debug!("Session {} expired, trying to delete from storage", session.topic); - if let Err(err) = self.session.storage().delete_session(&session.topic).await { + if let Err(err) = self.session_manager.storage().delete_session(&session.topic).await { error!("[{}] Unable to delete session from storage: {err:?}", session.topic); } continue; @@ -244,7 +244,7 @@ impl WalletConnectCtx { let topic = session.topic.clone(); let pairing_topic = session.pairing_topic.clone(); debug!("[{topic}] Session found! activating"); - self.session.add_session(session).await; + self.session_manager.add_session(session).await; valid_topics.push(topic); pairing_topics.push(pairing_topic); @@ -365,7 +365,7 @@ impl WalletConnectCtx { /// Checks if the current session is connected to a Ledger device. /// NOTE: for COSMOS chains only. pub async fn is_ledger_connection(&self) -> bool { - self.session + self.session_manager .get_session_active() .await .and_then(|session| session.session_properties) @@ -399,13 +399,13 @@ impl WalletConnectCtx { } pub async fn validate_update_active_chain_id(&self, chain_id: &WcChainId) -> MmResult<(), WalletConnectError> { - let session = self - .session - .get_session_active() - .await - .ok_or(MmError::new(WalletConnectError::SessionError( - "No active WalletConnect session found".to_string(), - )))?; + let session = + self.session_manager + .get_session_active() + .await + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active WalletConnect session found".to_string(), + )))?; self.validate_chain_id(&session, chain_id).await?; @@ -457,7 +457,7 @@ impl WalletConnectCtx { /// Retrieves the available account for a given chain ID. pub async fn get_account_for_chain_id(&self, chain_id: &WcChainId) -> MmResult { let namespaces = &self - .session + .session_manager .get_session_active() .await .ok_or(MmError::new(WalletConnectError::SessionError( @@ -490,7 +490,7 @@ impl WalletConnectCtx { T: DeserializeOwned, F: Fn(T) -> MmResult, { - let active_topic = self.session.get_active_topic_or_err().await?; + let active_topic = self.session_manager.get_active_topic_or_err().await?; let request = SessionRequestRequest { chain_id: chain_id.to_string(), request: SessionRequest { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 6a79e2165f..1419c19bd9 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -39,7 +39,7 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu ctx.client.unsubscribe(topic.clone()).await?; }; - if let Some(session) = ctx.session.delete_session(topic).await { + if let Some(session) = ctx.session_manager.delete_session(topic).await { debug!( "[{}] No active sessions for pairing disconnecting", session.pairing_topic @@ -50,7 +50,7 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResu ctx.pairing.delete(&session.pairing_topic); // delete session from storage as well. - ctx.session + ctx.session_manager .storage() .delete_session(topic) .await diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index a70ebf2ca3..b84f64edad 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -19,12 +19,12 @@ pub async fn handle_session_event( match event_name { "chainChanged" => { - let session = ctx - .session - .get_session(topic) - .ok_or(MmError::new(WalletConnectError::SessionError( - "No active WalletConnect session found".to_string(), - )))?; + let session = + ctx.session_manager + .get_session(topic) + .ok_or(MmError::new(WalletConnectError::SessionError( + "No active WalletConnect session found".to_string(), + )))?; if WcChain::Eip155 != chain_id.chain { return Ok(()); @@ -55,7 +55,7 @@ pub async fn handle_session_event( ctx.publish_response_err(topic, params, message_id).await?; } else { { - ctx.session + ctx.session_manager .get_session_mut(topic) .ok_or(MmError::new(WalletConnectError::SessionError( "No active WalletConnect session found".to_string(), diff --git a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs index 2b566755aa..57970983f4 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs @@ -11,7 +11,7 @@ pub(crate) async fn reply_session_extend_request( message_id: &MessageId, extend: SessionExtendRequest, ) -> MmResult<(), WalletConnectError> { - ctx.session.extend_session(topic, extend.expiry); + ctx.session_manager.extend_session(topic, extend.expiry); let param = ResponseParamsSuccess::SessionExtend(true); ctx.publish_response_ok(topic, param, message_id).await?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index c429b5f0f2..4cfc545103 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -73,14 +73,14 @@ pub async fn reply_session_proposal_request( { // save session to storage - ctx.session + ctx.session_manager .storage() .save_session(&session) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Add session to session lists - ctx.session.add_session(session.clone()).await; + ctx.session_manager.add_session(session.clone()).await; } send_session_settle_request(ctx, &session).await?; @@ -136,14 +136,14 @@ pub(crate) async fn process_session_propose_response( }; { // save session to storage - ctx.session + ctx.session_manager .storage() .save_session(&session) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Add session to session lists - ctx.session.add_session(session.clone()).await; + ctx.session_manager.add_session(session.clone()).await; }; // Activate pairing_topic diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index df0bb6e50f..a4b951dbfc 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -40,7 +40,7 @@ pub(crate) async fn reply_session_settle_request( settle: SessionSettleRequest, ) -> MmResult<(), WalletConnectError> { { - let session = ctx.session.get_session_mut(topic); + let session = ctx.session_manager.get_session_mut(topic); if let Some(mut session) = session { session.namespaces = settle.namespaces.0; session.controller = settle.controller.clone(); @@ -53,7 +53,7 @@ pub(crate) async fn reply_session_settle_request( } // Update storage session. - ctx.session + ctx.session_manager .storage() .update_session(&session) .await @@ -64,19 +64,19 @@ pub(crate) async fn reply_session_settle_request( // Delete other sessions with same controller // TODO: we might not want to do this! - let all_sessions = ctx.session.get_sessions_full(); + let all_sessions = ctx.session_manager.get_sessions_full(); for session in all_sessions { if session.controller == settle.controller && session.topic.as_ref() != topic.as_ref() { ctx.client.unsubscribe(session.topic.clone()).await?; ctx.client.unsubscribe(session.pairing_topic.clone()).await?; - ctx.session + ctx.session_manager .storage() .delete_session(&session.topic.clone()) .await .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Optionally: Remove from active sessions in memory too - ctx.session.delete_session(&session.topic).await; + ctx.session_manager.delete_session(&session.topic).await; ctx.drop_session(&session.topic).await?; debug!("Deleted previous session with topic: {:?}", session.topic); } diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index 7aa8083cf3..89c0acba22 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -15,7 +15,7 @@ pub(crate) async fn reply_session_update_request( update: SessionUpdateRequest, ) -> MmResult<(), WalletConnectError> { { - if let Some(mut session) = ctx.session.get_session_mut(topic) { + if let Some(mut session) = ctx.session_manager.get_session_mut(topic) { update .namespaces .caip2_validate() @@ -23,7 +23,7 @@ pub(crate) async fn reply_session_update_request( //TODO: session.namespaces.supported(update.namespaces.0) session.namespaces = update.namespaces.0; // Update storage session. - ctx.session + ctx.session_manager .storage() .update_session(&session) .await diff --git a/mm2src/kdf_walletconnect/src/storage/mod.rs b/mm2src/kdf_walletconnect/src/storage/mod.rs index 1c8c41fd78..088e052e2f 100644 --- a/mm2src/kdf_walletconnect/src/storage/mod.rs +++ b/mm2src/kdf_walletconnect/src/storage/mod.rs @@ -86,16 +86,21 @@ pub(crate) mod session_storage_tests { cross_test!(save_and_get_session_test, { let mm_ctx = mm_ctx_with_custom_async_db().await; let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); - wc_ctx.session.storage().init().await.unwrap(); + wc_ctx.session_manager.storage().init().await.unwrap(); let sample_session = sample_test_session(&wc_ctx); // try save session - wc_ctx.session.storage().save_session(&sample_session).await.unwrap(); + wc_ctx + .session_manager + .storage() + .save_session(&sample_session) + .await + .unwrap(); // try get session let db_session = wc_ctx - .session + .session_manager .storage() .get_session(&sample_session.topic) .await @@ -106,16 +111,21 @@ pub(crate) mod session_storage_tests { cross_test!(delete_session_test, { let mm_ctx = mm_ctx_with_custom_async_db().await; let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); - wc_ctx.session.storage().init().await.unwrap(); + wc_ctx.session_manager.storage().init().await.unwrap(); let sample_session = sample_test_session(&wc_ctx); // try save session - wc_ctx.session.storage().save_session(&sample_session).await.unwrap(); + wc_ctx + .session_manager + .storage() + .save_session(&sample_session) + .await + .unwrap(); // try get session let db_session = wc_ctx - .session + .session_manager .storage() .get_session(&sample_session.topic) .await @@ -125,30 +135,35 @@ pub(crate) mod session_storage_tests { // try delete session wc_ctx - .session + .session_manager .storage() .delete_session(&db_session.topic) .await .unwrap(); // try get_session deleted again - let db_session = wc_ctx.session.storage().get_session(&db_session.topic).await; + let db_session = wc_ctx.session_manager.storage().get_session(&db_session.topic).await; assert!(db_session.is_err()); }); cross_test!(update_session_test, { let mm_ctx = mm_ctx_with_custom_async_db().await; let wc_ctx = WalletConnectCtx::try_init(&mm_ctx).unwrap(); - wc_ctx.session.storage().init().await.unwrap(); + wc_ctx.session_manager.storage().init().await.unwrap(); let sample_session = sample_test_session(&wc_ctx); // try save session - wc_ctx.session.storage().save_session(&sample_session).await.unwrap(); + wc_ctx + .session_manager + .storage() + .save_session(&sample_session) + .await + .unwrap(); // try get session let db_session = wc_ctx - .session + .session_manager .storage() .get_session(&sample_session.topic) .await @@ -165,7 +180,7 @@ pub(crate) mod session_storage_tests { // try update session wc_ctx - .session + .session_manager .storage() .update_session(&modified_sample_session) .await @@ -173,7 +188,7 @@ pub(crate) mod session_storage_tests { // try get_session again with new updated expiry let db_session = wc_ctx - .session + .session_manager .storage() .get_session(&sample_session.topic) .await diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 104a14a8d5..a374a7f927 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -24,7 +24,11 @@ pub async fn get_all_sessions( ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let sessions = ctx.session.get_sessions().map(SessionRpcInfo::from).collect::>(); + let sessions = ctx + .session_manager + .get_sessions() + .map(SessionRpcInfo::from) + .collect::>(); Ok(GetSessionsResponse { sessions }) } @@ -43,7 +47,10 @@ pub struct GetSessionRequest { pub async fn get_session(ctx: MmArc, req: GetSessionRequest) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - let session = ctx.session.get_session(&req.topic.into()).map(SessionRpcInfo::from); + let session = ctx + .session_manager + .get_session(&req.topic.into()) + .map(SessionRpcInfo::from); Ok(GetSessionResponse { session }) } @@ -55,7 +62,7 @@ pub async fn set_active_session( ) -> MmResult { let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; - ctx.session + ctx.session_manager .set_active_session(&req.topic.into()) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; From 5e89b9f9885c4e91a206ae2526795ae7489c76d2 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 27 Nov 2024 02:45:42 +0100 Subject: [PATCH 121/125] use weak spawner to spawn wc related task/event loops --- mm2src/coins/eth.rs | 4 +- mm2src/coins/eth/wallet_connect.rs | 2 +- .../src/connection_handler.rs | 19 +++-- .../kdf_walletconnect/src/inbound_message.rs | 6 +- mm2src/kdf_walletconnect/src/lib.rs | 78 ++++++++++--------- mm2src/kdf_walletconnect/src/pairing.rs | 8 +- mm2src/kdf_walletconnect/src/session/mod.rs | 4 +- .../src/session/rpc/delete.rs | 8 +- .../src/session/rpc/event.rs | 4 +- .../src/session/rpc/extend.rs | 4 +- .../kdf_walletconnect/src/session/rpc/ping.rs | 6 +- .../src/session/rpc/propose.rs | 8 +- .../src/session/rpc/settle.rs | 6 +- .../src/session/rpc/update.rs | 4 +- mm2src/mm2_main/src/lp_native_dex.rs | 9 +-- .../mm2_main/src/rpc/wc_commands/sessions.rs | 3 +- 16 files changed, 90 insertions(+), 83 deletions(-) diff --git a/mm2src/coins/eth.rs b/mm2src/coins/eth.rs index 8339624c63..76ca3787da 100644 --- a/mm2src/coins/eth.rs +++ b/mm2src/coins/eth.rs @@ -59,7 +59,7 @@ use common::executor::{abortable_queue::AbortableQueue, AbortOnDropHandle, Abort AbortedError, SpawnAbortable, Timer}; use common::log::{debug, error, info, warn}; use common::number_type_casting::SafeTypeCastingNumbers; -use common::{now_ms, wait_until_sec}; +use common::wait_until_sec; use common::{now_sec, small_rng, DEX_FEE_ADDR_RAW_PUBKEY}; use crypto::privkey::key_pair_from_secret; use crypto::{Bip44Chain, CryptoCtx, CryptoCtxError, GlobalHDAccountArc, KeyPairPolicy}; @@ -5539,7 +5539,7 @@ impl EthCoin { check_every: f64, ) -> Web3RpcResult> { let wait_until = wait_until_sec(wait_rpc_timeout_s); - while now_ms() < wait_until { + while now_sec() < wait_until { let maybe_tx = self.transaction(TransactionId::Hash(tx_hash)).await?; if let Some(tx) = maybe_tx { let signed_tx = signed_tx_from_web3_tx(tx).map_to_mm(Web3RpcError::InvalidResponse)?; diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 984de054c7..8630f4a361 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -24,7 +24,7 @@ use web3::signing::hash_message; use super::EthCoin; // Wait for 30 seconds for the transaction to appear on the RPC node. -const WAIT_RPC_TIMEOUT_SECS: u64 = 30; +const WAIT_RPC_TIMEOUT_SECS: u64 = 60; #[derive(Display, Debug, EnumFromStringify)] pub enum EthWalletConnectError { diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 5c15d4b249..7a4c1e0acd 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -1,9 +1,9 @@ use crate::storage::WalletConnectStorageOps; -use crate::WalletConnectCtx; +use crate::WalletConnectCtxImpl; use common::executor::Timer; use common::log::{debug, error, info}; -use futures::channel::mpsc::UnboundedSender; +use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender}; use futures::StreamExt; use relay_client::error::ClientError; use relay_client::websocket::{CloseFrame, ConnectionHandler, PublishedMessage}; @@ -75,7 +75,10 @@ impl ConnectionHandler for Handler { /// Establishes initial connection to WalletConnect relay server with linear retry mechanism. /// Uses increasing delay between retry attempts starting from INITIAL_RETRY_SECS. /// After successful connection, attempts to restore previous session state from storage. -pub(crate) async fn initialize_connection(wc: Arc) { +pub(crate) async fn spawn_connection_initialization( + wc: Arc, + connection_live_rx: UnboundedReceiver>, +) { info!("Initializing WalletConnect connection"); let mut retry_count = 0; let mut retry_secs = INITIAL_RETRY_SECS; @@ -101,17 +104,19 @@ pub(crate) async fn initialize_connection(wc: Arc) { }; // Spawn session disconnection watcher. - handle_disconnections(&wc).await; + handle_disconnections(&wc, connection_live_rx).await; } /// Handles unexpected disconnections from WalletConnect relay server. /// Implements exponential backoff retry mechanism for reconnection attempts. /// After successful reconnection, resubscribes to previous topics to restore full functionality. -pub(crate) async fn handle_disconnections(this: &WalletConnectCtx) { - let mut recv = this.connection_live_rx.lock().await; +pub(crate) async fn handle_disconnections( + this: &WalletConnectCtxImpl, + mut connection_live_rx: UnboundedReceiver>, +) { let mut backoff = 1; - while let Some(msg) = recv.next().await { + while let Some(msg) = connection_live_rx.next().await { info!("WalletConnect disconnected with message: {msg:?}. Attempting to reconnect..."); loop { diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 176d8e51bd..8144cc76d8 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -7,7 +7,7 @@ use crate::{error::WalletConnectError, propose::{process_session_propose_response, reply_session_proposal_request}, settle::reply_session_settle_request, update::reply_session_update_request}, - WalletConnectCtx}; + WalletConnectCtxImpl}; use common::log::{info, LogOnError}; use futures::sink::SinkExt; @@ -24,7 +24,7 @@ pub struct SessionMessage { } pub(crate) async fn process_inbound_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, request: Request, topic: &Topic, ) -> MmResult<(), WalletConnectError> { @@ -54,7 +54,7 @@ pub(crate) async fn process_inbound_request( Ok(()) } -pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtx, response: Response, topic: &Topic) { +pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtxImpl, response: Response, topic: &Topic) { let message_id = response.id(); let result = match response { Response::Success(value) => match serde_json::from_value::(value.result) { diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 105ce91c71..85e71cb947 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -12,10 +12,11 @@ use crate::session::rpc::propose::send_proposal_request; use chain::{WcChainId, WcRequestMethods, SUPPORTED_PROTOCOL}; use chrono::Utc; use common::custom_futures::timeout::FutureTimerExt; -use common::executor::{spawn_abortable, AbortOnDropHandle, Timer}; +use common::executor::abortable_queue::AbortableQueue; +use common::executor::{AbortableSystem, Timer}; use common::log::{debug, info}; use common::{executor::SpawnFuture, log::error}; -use connection_handler::{initialize_connection, Handler}; +use connection_handler::{spawn_connection_initialization, Handler}; use error::WalletConnectError; use futures::channel::mpsc::{unbounded, UnboundedReceiver, UnboundedSender}; use futures::lock::Mutex; @@ -39,6 +40,7 @@ use session::rpc::delete::send_session_delete_request; use session::Session; use session::{key::SymKeyPair, SessionManager}; use std::collections::BTreeSet; +use std::ops::Deref; use std::{sync::Arc, time::Duration}; use storage::SessionStorageDb; use storage::WalletConnectStorageOps; @@ -69,49 +71,69 @@ pub trait WalletConnectOps { ) -> Result; } -pub struct WalletConnectCtx { +pub struct WalletConnectCtxImpl { pub(crate) client: Client, pub(crate) pairing: PairingClient, pub session_manager: SessionManager, pub(crate) key_pair: SymKeyPair, relay: Relay, metadata: Metadata, - inbound_message_rx: Arc>>, - connection_live_rx: Arc>>>, message_tx: UnboundedSender, message_rx: Arc>>, - _abort_handle: AbortOnDropHandle, + pub abortable_system: AbortableQueue, +} + +pub struct WalletConnectCtx(pub Arc); +impl Deref for WalletConnectCtx { + type Target = WalletConnectCtxImpl; + fn deref(&self) -> &Self::Target { &self.0 } } impl WalletConnectCtx { pub fn try_init(ctx: &MmArc) -> MmResult { + let abortable_system = ctx.abortable_system.create_subsystem::().unwrap(); let storage = SessionStorageDb::new(ctx)?; let pairing = PairingClient::new(); let relay = Relay { protocol: SUPPORTED_PROTOCOL.to_string(), data: None, }; - let (inbound_message_tx, inbound_message_rx) = unbounded(); + let (inbound_message_tx, mut inbound_message_rx) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); let (message_tx, session_request_receiver) = unbounded(); - let (client, _abort_handle) = Client::new_with_callback( + let (client, _) = Client::new_with_callback( Handler::new("Komodefi", inbound_message_tx, conn_live_sender), - |r, h| spawn_abortable(client_event_loop(r, h)), + |r, h| abortable_system.weak_spawner().spawn(client_event_loop(r, h)), ); - Ok(Self { + let inner = Arc::new(WalletConnectCtxImpl { client, pairing, relay, metadata: generate_metadata(), key_pair: SymKeyPair::new(), session_manager: SessionManager::new(storage), - inbound_message_rx: Arc::new(inbound_message_rx.into()), - connection_live_rx: Arc::new(conn_live_receiver.into()), message_rx: Arc::new(session_request_receiver.into()), message_tx, - _abort_handle, - }) + abortable_system, + }); + + // Connect to relayer client and spawn a watcher loop for disconnection. + inner + .abortable_system + .weak_spawner() + .spawn(spawn_connection_initialization(inner.clone(), conn_live_receiver)); + // spawn message handler event loop + let inner_clone = inner.clone(); + inner_clone.abortable_system.weak_spawner().spawn(async move { + while let Some(msg) = inbound_message_rx.next().await { + if let Err(e) = inner_clone.handle_published_message(msg).await { + debug!("Error processing message: {:?}", e); + } + } + }); + + Ok(Self(inner)) } pub fn from_ctx(ctx: &MmArc) -> MmResult, WalletConnectError> { @@ -120,7 +142,9 @@ impl WalletConnectCtx { }) .map_to_mm(WalletConnectError::InternalError) } +} +impl WalletConnectCtxImpl { pub async fn connect_client(&self) -> MmResult<(), WalletConnectError> { let auth = { let key = SigningKey::generate(&mut rand::thread_rng()); @@ -146,7 +170,9 @@ impl WalletConnectCtx { .flat_map(|s| vec![s.topic, s.pairing_topic]) .collect::>(); - self.client.batch_subscribe(sessions).await?; + if !sessions.is_empty() { + self.client.batch_subscribe(sessions).await?; + } Ok(()) } @@ -519,28 +545,6 @@ impl WalletConnectCtx { } } -/// This function spwans related WalletConnect related tasks and needed initialization before -/// WalletConnect can be usable in KDF. -pub async fn initialize_walletconnect(ctx: &MmArc) -> MmResult<(), WalletConnectError> { - // Initialized WalletConnectCtx - let wallet_connect = WalletConnectCtx::from_ctx(ctx)?; - // WalletConnectCtx is initialized, now we can connect to relayer client and spawn a watcher - // loop for disconnection. - ctx.spawner().spawn(initialize_connection(wallet_connect.clone())); - - // spawn message handler event loop - ctx.spawner().spawn(async move { - let mut recv = wallet_connect.inbound_message_rx.lock().await; - while let Some(msg) = recv.next().await { - if let Err(e) = wallet_connect.handle_published_message(msg).await { - debug!("Error processing message: {:?}", e); - } - } - }); - - Ok(()) -} - fn find_account_in_namespace<'a>(accounts: &'a BTreeSet, chain_id: &'a str) -> Option { accounts.iter().find_map(move |account_name| { let parts: Vec<&str> = account_name.split(':').collect(); diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index 3e4411305b..3fb7ce6010 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -1,5 +1,5 @@ use crate::session::{WcRequestResponseResult, THIRTY_DAYS}; -use crate::{error::WalletConnectError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use chrono::Utc; use mm2_err_handle::prelude::MmResult; @@ -11,7 +11,7 @@ use relay_rpc::{domain::Topic, ResponseParamsSuccess}}; pub(crate) async fn reply_pairing_ping_response( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectError> { @@ -22,7 +22,7 @@ pub(crate) async fn reply_pairing_ping_response( } pub(crate) async fn reply_pairing_extend_response( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, extend: PairingExtendRequest, @@ -41,7 +41,7 @@ pub(crate) async fn reply_pairing_extend_response( } pub(crate) async fn reply_pairing_delete_response( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, _delete: PairingDeleteRequest, diff --git a/mm2src/kdf_walletconnect/src/session/mod.rs b/mm2src/kdf_walletconnect/src/session/mod.rs index 967de77af8..0a2474b5f7 100644 --- a/mm2src/kdf_walletconnect/src/session/mod.rs +++ b/mm2src/kdf_walletconnect/src/session/mod.rs @@ -3,7 +3,7 @@ pub mod rpc; use crate::chain::WcChainId; use crate::storage::SessionStorageDb; -use crate::{error::WalletConnectError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use chrono::Utc; use common::log::info; @@ -130,7 +130,7 @@ pub struct Session { impl Session { pub fn new( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, session_topic: Topic, subscription_id: SubscriptionId, session_key: SessionKey, diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 1419c19bd9..1154ff2c4a 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -1,6 +1,6 @@ use crate::{error::{WalletConnectError, USER_REQUESTED}, storage::WalletConnectStorageOps, - WalletConnectCtx}; + WalletConnectCtxImpl}; use common::log::debug; use mm2_err_handle::prelude::{MapMmError, MmResult}; @@ -8,7 +8,7 @@ use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::params::{session_delete::SessionDeleteRequest, RequestParams, ResponseParamsSuccess}; pub(crate) async fn reply_session_delete_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, _delete_params: SessionDeleteRequest, @@ -20,7 +20,7 @@ pub(crate) async fn reply_session_delete_request( } pub(crate) async fn send_session_delete_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, session_topic: &Topic, ) -> MmResult<(), WalletConnectError> { let delete_request = SessionDeleteRequest { @@ -34,7 +34,7 @@ pub(crate) async fn send_session_delete_request( session_delete_cleanup(ctx, session_topic).await } -async fn session_delete_cleanup(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { +async fn session_delete_cleanup(ctx: &WalletConnectCtxImpl, topic: &Topic) -> MmResult<(), WalletConnectError> { { ctx.client.unsubscribe(topic.clone()).await?; }; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index b84f64edad..9759c29de7 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -1,6 +1,6 @@ use crate::{chain::{WcChain, WcChainId}, error::{WalletConnectError, UNSUPPORTED_CHAINS}, - WalletConnectCtx}; + WalletConnectCtxImpl}; use common::log::{error, info}; use mm2_err_handle::prelude::*; @@ -9,7 +9,7 @@ use relay_rpc::{domain::{MessageId, Topic}, ErrorData}}; pub async fn handle_session_event( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, event: SessionEventRequest, diff --git a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs index 57970983f4..0574277af1 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/extend.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/extend.rs @@ -1,4 +1,4 @@ -use crate::{error::WalletConnectError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use mm2_err_handle::prelude::MmResult; use relay_rpc::{domain::{MessageId, Topic}, @@ -6,7 +6,7 @@ use relay_rpc::{domain::{MessageId, Topic}, /// Process session extend request. pub(crate) async fn reply_session_extend_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, extend: SessionExtendRequest, diff --git a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs index ad0e8eda10..3007a58ca7 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/ping.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/ping.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use crate::{error::WalletConnectError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use common::custom_futures::timeout::FutureTimerExt; use futures::StreamExt; @@ -9,7 +9,7 @@ use relay_rpc::{domain::{MessageId, Topic}, rpc::params::{RelayProtocolMetadata, RequestParams, ResponseParamsSuccess}}; pub(crate) async fn reply_session_ping_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, ) -> MmResult<(), WalletConnectError> { @@ -19,7 +19,7 @@ pub(crate) async fn reply_session_ping_request( Ok(()) } -pub async fn send_session_ping_request(ctx: &WalletConnectCtx, topic: &Topic) -> MmResult<(), WalletConnectError> { +pub async fn send_session_ping_request(ctx: &WalletConnectCtxImpl, topic: &Topic) -> MmResult<(), WalletConnectError> { let param = RequestParams::SessionPing(()); let ttl = param.irn_metadata().ttl; ctx.publish_request(topic, param).await?; diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 4cfc545103..2d3c30a44f 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -4,7 +4,7 @@ use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, metadata::generate_metadata, session::{Session, SessionKey, SessionType, THIRTY_DAYS}, - WalletConnectCtx}; + WalletConnectCtxImpl}; use chrono::Utc; use mm2_err_handle::map_to_mm::MapToMmResult; @@ -16,7 +16,7 @@ use relay_rpc::{domain::{MessageId, Topic}, /// Creates a new session proposal from topic and metadata. pub(crate) async fn send_proposal_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, namespaces: Option, ) -> MmResult<(), WalletConnectError> { @@ -38,7 +38,7 @@ pub(crate) async fn send_proposal_request( /// Process session proposal request /// https://specs.walletconnect.com/2.0/specs/clients/sign/session-proposal pub async fn reply_session_proposal_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, proposal: SessionProposeRequest, topic: &Topic, message_id: &MessageId, @@ -98,7 +98,7 @@ pub async fn reply_session_proposal_request( /// Process session propose reponse. pub(crate) async fn process_session_propose_response( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, pairing_topic: &Topic, response: &SessionProposeResponse, ) -> MmResult<(), WalletConnectError> { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index a4b951dbfc..c94f09e84e 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -1,6 +1,6 @@ use crate::session::{Session, SessionProperties}; use crate::storage::WalletConnectStorageOps; -use crate::{error::WalletConnectError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use common::log::{debug, info}; use mm2_err_handle::prelude::{MapMmError, MmResult}; @@ -8,7 +8,7 @@ use relay_rpc::domain::Topic; use relay_rpc::rpc::params::session_settle::SessionSettleRequest; pub(crate) async fn send_session_settle_request( - _ctx: &WalletConnectCtx, + _ctx: &WalletConnectCtxImpl, _session_info: &Session, ) -> MmResult<(), WalletConnectError> { // let mut settled_namespaces = BTreeMap::::new(); @@ -35,7 +35,7 @@ pub(crate) async fn send_session_settle_request( /// Process session settle request. pub(crate) async fn reply_session_settle_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, settle: SessionSettleRequest, ) -> MmResult<(), WalletConnectError> { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/update.rs b/mm2src/kdf_walletconnect/src/session/rpc/update.rs index 89c0acba22..35e2ae05e5 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/update.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/update.rs @@ -1,5 +1,5 @@ use crate::storage::WalletConnectStorageOps; -use crate::{error::WalletConnectError, WalletConnectCtx}; +use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use common::log::info; use mm2_err_handle::prelude::*; @@ -9,7 +9,7 @@ use relay_rpc::rpc::params::{session_update::SessionUpdateRequest, ResponseParam // TODO: Handle properly when multi chain is supported. // Hanlding for only cosmos support. pub(crate) async fn reply_session_update_request( - ctx: &WalletConnectCtx, + ctx: &WalletConnectCtxImpl, topic: &Topic, message_id: &MessageId, update: SessionUpdateRequest, diff --git a/mm2src/mm2_main/src/lp_native_dex.rs b/mm2src/mm2_main/src/lp_native_dex.rs index 634d3e2586..61c5f1852e 100644 --- a/mm2src/mm2_main/src/lp_native_dex.rs +++ b/mm2src/mm2_main/src/lp_native_dex.rs @@ -25,7 +25,7 @@ use common::log::{info, warn}; use crypto::{from_hw_error, CryptoCtx, HwError, HwProcessingError, HwRpcError, WithHwRpcError}; use derive_more::Display; use enum_derives::EnumFromTrait; -use kdf_walletconnect::initialize_walletconnect; +use kdf_walletconnect::WalletConnectCtx; use mm2_core::mm_ctx::{MmArc, MmCtx}; use mm2_err_handle::common_errors::InternalError; use mm2_err_handle::prelude::*; @@ -492,10 +492,9 @@ pub async fn lp_init_continue(ctx: MmArc) -> MmInitResult<()> { #[cfg(target_arch = "wasm32")] init_wasm_event_streaming(&ctx); - // Initialize WalletConnect - initialize_walletconnect(&ctx) - .await - .mm_err(|err| MmInitError::WalletInitError(err.to_string()))?; + // This function spwans related WalletConnect related tasks and needed initialization before + // WalletConnect can be usable in KDF. + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| MmInitError::WalletInitError(err.to_string()))?; ctx.spawner().spawn(clean_memory_loop(ctx.weak())); diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index a374a7f927..64389d198e 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -60,8 +60,7 @@ pub async fn set_active_session( ctx: MmArc, req: GetSessionRequest, ) -> MmResult { - let ctx = - WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; ctx.session_manager .set_active_session(&req.topic.into()) .await From 1fec24feb8a5d0d440b564260b0bf5582772ef26 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 27 Nov 2024 02:53:58 +0100 Subject: [PATCH 122/125] validate table name only during initialization --- mm2src/kdf_walletconnect/src/storage/sqlite.rs | 6 ------ mm2src/mm2_main/src/rpc/wc_commands/sessions.rs | 3 ++- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/storage/sqlite.rs b/mm2src/kdf_walletconnect/src/storage/sqlite.rs index 6820bffdc7..8d0d7b419b 100644 --- a/mm2src/kdf_walletconnect/src/storage/sqlite.rs +++ b/mm2src/kdf_walletconnect/src/storage/sqlite.rs @@ -65,7 +65,6 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn is_initialized(&self) -> MmResult { let lock = self.lock_db().await; validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; - lock.call(move |conn| { let initialized = query_single_row(conn, CHECK_TABLE_EXISTS_SQL, [SESSION_TABLE_NAME], string_from_row)?; Ok(initialized.is_some()) @@ -76,7 +75,6 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn save_session(&self, session: &Session) -> MmResult<(), Self::Error> { debug!("[{}] Saving WalletConnect session to storage", session.topic); - validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; let session = session.clone(); @@ -102,7 +100,6 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn get_session(&self, topic: &Topic) -> MmResult, Self::Error> { debug!("[{topic}] Retrieving WalletConnect session from storage"); - validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; let topic = topic.clone(); let session_str = lock @@ -121,7 +118,6 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn get_all_sessions(&self) -> MmResult, Self::Error> { debug!("Loading WalletConnect sessions from storage"); - validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let lock = self.lock_db().await; let sessions_str = lock .call(move |conn| { @@ -145,7 +141,6 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn delete_session(&self, topic: &Topic) -> MmResult<(), Self::Error> { debug!("[{topic}] Deleting WalletConnect session from storage"); - validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let topic = topic.clone(); let lock = self.lock_db().await; lock.call(move |conn| { @@ -161,7 +156,6 @@ impl WalletConnectStorageOps for SqliteSessionStorage { async fn update_session(&self, session: &Session) -> MmResult<(), Self::Error> { debug!("[{}] Updating WalletConnect session in storage", session.topic); - validate_table_name(SESSION_TABLE_NAME).map_err(AsyncConnError::from)?; let session = session.clone(); let lock = self.lock_db().await; lock.call(move |conn| { diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index 64389d198e..a374a7f927 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -60,7 +60,8 @@ pub async fn set_active_session( ctx: MmArc, req: GetSessionRequest, ) -> MmResult { - let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; + let ctx = + WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; ctx.session_manager .set_active_session(&req.topic.into()) .await From bdf963686699dfcf03b19548da05c6f0aa79f5c5 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 27 Nov 2024 03:09:43 +0100 Subject: [PATCH 123/125] make required_namespaces required for wc activation and remove defaults --- mm2src/kdf_walletconnect/src/chain.rs | 31 +------------------ mm2src/kdf_walletconnect/src/lib.rs | 13 +++++--- .../src/session/rpc/propose.rs | 8 ++--- .../src/rpc/wc_commands/new_connection.rs | 5 +-- 4 files changed, 17 insertions(+), 40 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/chain.rs b/mm2src/kdf_walletconnect/src/chain.rs index 78775e6f42..20e1acd6a8 100644 --- a/mm2src/kdf_walletconnect/src/chain.rs +++ b/mm2src/kdf_walletconnect/src/chain.rs @@ -1,20 +1,11 @@ use mm2_err_handle::prelude::{MmError, MmResult}; -use relay_rpc::rpc::params::session::{ProposeNamespace, ProposeNamespaces}; use serde::{Deserialize, Serialize}; -use std::{collections::{BTreeMap, BTreeSet}, - str::FromStr}; +use std::str::FromStr; use crate::error::WalletConnectError; pub(crate) const SUPPORTED_PROTOCOL: &str = "irn"; -pub(crate) const COSMOS_SUPPORTED_METHODS: &[&str] = &["cosmos_getAccounts", "cosmos_signDirect", "cosmos_signAmino"]; -pub(crate) const COSMOS_SUPPORTED_CHAINS: &[&str] = &["cosmos:cosmoshub-4"]; - -pub(crate) const ETH_SUPPORTED_METHODS: &[&str] = &["eth_signTransaction", "personal_sign", "eth_sendTransaction"]; -pub(crate) const ETH_SUPPORTED_CHAINS: &[&str] = &["eip155:1", "eip155:137"]; -pub(crate) const ETH_SUPPORTED_EVENTS: &[&str] = &["accountsChanged", "chainChanged"]; - #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub enum WcChain { Eip155, @@ -114,23 +105,3 @@ impl AsRef for WcRequestMethods { } } } - -pub(crate) fn build_default_required_namespaces() -> ProposeNamespaces { - let required = BTreeMap::from([(WcChain::Eip155.as_ref().to_string(), ProposeNamespace { - events: ETH_SUPPORTED_EVENTS.iter().map(|m| m.to_string()).collect(), - chains: ETH_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - methods: ETH_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - })]); - - ProposeNamespaces(required) -} - -pub(crate) fn build_optional_namespaces() -> ProposeNamespaces { - let optional = BTreeMap::from([(WcChain::Cosmos.as_ref().to_string(), ProposeNamespace { - methods: COSMOS_SUPPORTED_METHODS.iter().map(|m| m.to_string()).collect(), - chains: COSMOS_SUPPORTED_CHAINS.iter().map(|c| c.to_string()).collect(), - events: BTreeSet::default(), - })]); - - ProposeNamespaces(optional) -} diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 85e71cb947..355b329081 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -80,7 +80,7 @@ pub struct WalletConnectCtxImpl { metadata: Metadata, message_tx: UnboundedSender, message_rx: Arc>>, - pub abortable_system: AbortableQueue, + abortable_system: AbortableQueue, } pub struct WalletConnectCtx(pub Arc); @@ -178,8 +178,13 @@ impl WalletConnectCtxImpl { } /// Create a WalletConnect pairing connection url. - pub async fn new_connection(&self, namespaces: Option) -> MmResult { - let namespaces = match namespaces { + pub async fn new_connection( + &self, + required_namespaces: serde_json::Value, + optional_namespaces: Option, + ) -> MmResult { + let required_namespaces = serde_json::from_value(required_namespaces)?; + let optional_namespaces = match optional_namespaces { Some(value) => Some(serde_json::from_value(value)?), None => None, }; @@ -196,7 +201,7 @@ impl WalletConnectCtxImpl { { Ok(Ok(_)) => { info!("[topic] Subscribed to topic"); - send_proposal_request(self, &topic, namespaces).await?; + send_proposal_request(self, &topic, required_namespaces, optional_namespaces).await?; return Ok(url); }, Ok(Err(err)) => return MmError::err(err.into()), diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index 2d3c30a44f..f2b3f7c03c 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -1,5 +1,4 @@ use super::settle::send_session_settle_request; -use crate::chain::{build_default_required_namespaces, build_optional_namespaces}; use crate::storage::WalletConnectStorageOps; use crate::{error::WalletConnectError, metadata::generate_metadata, @@ -18,7 +17,8 @@ use relay_rpc::{domain::{MessageId, Topic}, pub(crate) async fn send_proposal_request( ctx: &WalletConnectCtxImpl, topic: &Topic, - namespaces: Option, + required_namespaces: ProposeNamespaces, + optional_namespaces: Option, ) -> MmResult<(), WalletConnectError> { let proposer = Proposer { metadata: ctx.metadata.clone(), @@ -27,8 +27,8 @@ pub(crate) async fn send_proposal_request( let session_proposal = RequestParams::SessionPropose(SessionProposeRequest { relays: vec![ctx.relay.clone()], proposer, - required_namespaces: namespaces.unwrap_or_else(build_default_required_namespaces), - optional_namespaces: Some(build_optional_namespaces()), + required_namespaces, + optional_namespaces, }); ctx.publish_request(topic, session_proposal).await?; diff --git a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs index 2ba1d60469..410deae5d7 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/new_connection.rs @@ -12,7 +12,8 @@ pub struct CreateConnectionResponse { #[derive(Deserialize)] pub struct NewConnectionRequest { - namespaces: Option, + required_namespaces: serde_json::Value, + optional_namespaces: Option, } /// `new_connection` RPC command implementation. @@ -23,7 +24,7 @@ pub async fn new_connection( let ctx = WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; let url = ctx - .new_connection(req.namespaces) + .new_connection(req.required_namespaces, req.optional_namespaces) .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; From 31c9594804b4ee864a21f4a1776548d0d80daec0 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Wed, 27 Nov 2024 15:12:00 +0100 Subject: [PATCH 124/125] use sync mutex for active topic --- mm2src/kdf_walletconnect/src/session/mod.rs | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/mm2src/kdf_walletconnect/src/session/mod.rs b/mm2src/kdf_walletconnect/src/session/mod.rs index 0a2474b5f7..9e6e060325 100644 --- a/mm2src/kdf_walletconnect/src/session/mod.rs +++ b/mm2src/kdf_walletconnect/src/session/mod.rs @@ -23,8 +23,7 @@ use serde::{Deserialize, Deserializer, Serialize}; use serde_json::Value; use std::collections::BTreeMap; use std::fmt::Debug; -use std::sync::Arc; -use tokio::sync::Mutex; +use std::sync::{Arc, Mutex}; use wc_common::SymKey; pub(crate) const FIVE_MINUTES: u64 = 5 * 60; @@ -224,7 +223,7 @@ impl SessionManager { self.0 .active_topic .lock() - .await + .unwrap() .clone() .ok_or(MmError::new(WalletConnectError::SessionError( "No active session".to_owned(), @@ -235,7 +234,7 @@ impl SessionManager { /// If a session with the same topic already exists, it will be overwritten. pub(crate) async fn add_session(&self, session: Session) { // set active session topic. - *self.0.active_topic.lock().await = Some(session.topic.clone()); + *self.0.active_topic.lock().unwrap() = Some(session.topic.clone()); // insert session self.0.sessions.insert(session.topic.clone(), session); } @@ -244,7 +243,7 @@ impl SessionManager { /// If the session does not exist, this method does nothing. pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { info!("[{topic}] Deleting session with topic"); - let mut active_topic = self.0.active_topic.lock().await; + let mut active_topic = self.0.active_topic.lock().unwrap(); // Remove the session and get the removed session (if any) let removed_session = self.0.sessions.remove(topic).map(|(_, session)| session); @@ -263,7 +262,7 @@ impl SessionManager { } pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { - let mut active_topic = self.0.active_topic.lock().await; + let mut active_topic = self.0.active_topic.lock().unwrap(); let session = self .get_session(topic) .ok_or(MmError::new(WalletConnectError::SessionError( @@ -288,7 +287,7 @@ impl SessionManager { self.0 .active_topic .lock() - .await + .unwrap() .as_ref() .and_then(|topic| self.get_session(topic)) } From 37a36f7ce4b11f08593ad79f3855700192cedd65 Mon Sep 17 00:00:00 2001 From: Samuel Onoja Date: Thu, 28 Nov 2024 15:20:26 +0100 Subject: [PATCH 125/125] fix review notes --- mm2src/coins/eth/wallet_connect.rs | 2 +- mm2src/coins/tendermint/wallet_connect.rs | 5 +-- .../src/tendermint_with_assets_activation.rs | 2 +- .../src/connection_handler.rs | 8 ++-- .../kdf_walletconnect/src/inbound_message.rs | 12 ++++-- mm2src/kdf_walletconnect/src/lib.rs | 42 ++++++++++--------- mm2src/kdf_walletconnect/src/pairing.rs | 2 +- mm2src/kdf_walletconnect/src/session/mod.rs | 15 +++---- .../src/session/rpc/delete.rs | 2 +- .../src/session/rpc/event.rs | 14 ++----- .../src/session/rpc/propose.rs | 4 +- .../src/session/rpc/settle.rs | 2 +- .../mm2_main/src/rpc/wc_commands/sessions.rs | 1 - 13 files changed, 55 insertions(+), 56 deletions(-) diff --git a/mm2src/coins/eth/wallet_connect.rs b/mm2src/coins/eth/wallet_connect.rs index 8630f4a361..4b1eccc530 100644 --- a/mm2src/coins/eth/wallet_connect.rs +++ b/mm2src/coins/eth/wallet_connect.rs @@ -166,7 +166,7 @@ pub async fn eth_request_wc_personal_sign( let chain_id = WcChainId::new_eip155(chain_id.to_string()); wc.validate_update_active_chain_id(&chain_id).await?; - let account_str = wc.get_account_for_chain_id(&chain_id).await?; + let account_str = wc.get_account_for_chain_id(&chain_id)?; let message = "Authenticate with Komodefi"; let params = { let message_hex = format!("0x{}", hex::encode(message)); diff --git a/mm2src/coins/tendermint/wallet_connect.rs b/mm2src/coins/tendermint/wallet_connect.rs index 3956e1c3e3..b1de91ba0a 100644 --- a/mm2src/coins/tendermint/wallet_connect.rs +++ b/mm2src/coins/tendermint/wallet_connect.rs @@ -91,7 +91,7 @@ impl WalletConnectOps for TendermintCoin { params: Self::Params<'a>, ) -> Result { let chain_id = self.wc_chain_id(wc).await?; - let method = if wc.is_ledger_connection().await { + let method = if wc.is_ledger_connection() { WcRequestMethods::CosmosSignAmino } else { WcRequestMethods::CosmosSignDirect @@ -127,11 +127,10 @@ pub async fn cosmos_get_accounts_impl( let chain_id = WcChainId::new_cosmos(chain_id.to_string()); wc.validate_update_active_chain_id(&chain_id).await?; - let account = wc.get_account_for_chain_id(&chain_id).await?; + let account = wc.get_account_for_chain_id(&chain_id)?; let session = wc .session_manager .get_session_active() - .await .ok_or(WalletConnectError::NotInitialized)?; // Check iexisting session has session_properties and return wallet account; diff --git a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs index a8008db76a..645e7dbcef 100644 --- a/mm2src/coins_activation/src/tendermint_with_assets_activation.rs +++ b/mm2src/coins_activation/src/tendermint_with_assets_activation.rs @@ -241,7 +241,7 @@ async fn activate_with_walletconnect( ticker: ticker.to_string(), kind: TendermintInitErrorKind::UnableToFetchChainAccount(err.to_string()), })?; - let wallet_type = if wc.is_ledger_connection().await { + let wallet_type = if wc.is_ledger_connection() { TendermintWalletConnectionType::WcLedger } else { TendermintWalletConnectionType::Wc diff --git a/mm2src/kdf_walletconnect/src/connection_handler.rs b/mm2src/kdf_walletconnect/src/connection_handler.rs index 7a4c1e0acd..351a46c359 100644 --- a/mm2src/kdf_walletconnect/src/connection_handler.rs +++ b/mm2src/kdf_walletconnect/src/connection_handler.rs @@ -41,7 +41,7 @@ impl ConnectionHandler for Handler { fn disconnected(&mut self, frame: Option>) { debug!("[{}] connection closed: frame={frame:?}", self.name); - if let Err(e) = self.conn_live_sender.start_send(frame.map(|f| f.to_string())) { + if let Err(e) = self.conn_live_sender.unbounded_send(frame.map(|f| f.to_string())) { error!("[{}] failed to send to the receiver: {e}", self.name); } } @@ -52,21 +52,21 @@ impl ConnectionHandler for Handler { self.name, message.message_id, message.topic, message.tag, message.message, ); - if let Err(e) = self.msg_sender.start_send(message) { + if let Err(e) = self.msg_sender.unbounded_send(message) { error!("[{}] failed to send to the receiver: {e}", self.name); } } fn inbound_error(&mut self, error: ClientError) { debug!("[{}] inbound error: {error}", self.name); - if let Err(e) = self.conn_live_sender.start_send(Some(error.to_string())) { + if let Err(e) = self.conn_live_sender.unbounded_send(Some(error.to_string())) { error!("[{}] failed to send to the receiver: {e}", self.name); } } fn outbound_error(&mut self, error: ClientError) { debug!("[{}] outbound error: {error}", self.name); - if let Err(e) = self.conn_live_sender.start_send(Some(error.to_string())) { + if let Err(e) = self.conn_live_sender.unbounded_send(Some(error.to_string())) { error!("[{}] failed to send to the receiver: {e}", self.name); } } diff --git a/mm2src/kdf_walletconnect/src/inbound_message.rs b/mm2src/kdf_walletconnect/src/inbound_message.rs index 8144cc76d8..ec7e09ded4 100644 --- a/mm2src/kdf_walletconnect/src/inbound_message.rs +++ b/mm2src/kdf_walletconnect/src/inbound_message.rs @@ -10,7 +10,7 @@ use crate::{error::WalletConnectError, WalletConnectCtxImpl}; use common::log::{info, LogOnError}; -use futures::sink::SinkExt; +use futures::{channel::mpsc::UnboundedSender, sink::SinkExt}; use mm2_err_handle::prelude::{MmError, MmResult}; use relay_rpc::domain::{MessageId, Topic}; use relay_rpc::rpc::{params::ResponseParamsSuccess, Params, Request, Response}; @@ -54,7 +54,12 @@ pub(crate) async fn process_inbound_request( Ok(()) } -pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtxImpl, response: Response, topic: &Topic) { +pub(crate) async fn process_inbound_response( + ctx: &WalletConnectCtxImpl, + response: Response, + topic: &Topic, + mut message_tx: UnboundedSender, +) { let message_id = response.id(); let result = match response { Response::Success(value) => match serde_json::from_value::(value.result) { @@ -75,6 +80,5 @@ pub(crate) async fn process_inbound_response(ctx: &WalletConnectCtxImpl, respons Response::Error(err) => MmError::err(format!("{err:?}")), }; - let mut sender = ctx.message_tx.clone(); - sender.send(result).await.error_log(); + message_tx.send(result).await.error_log(); } diff --git a/mm2src/kdf_walletconnect/src/lib.rs b/mm2src/kdf_walletconnect/src/lib.rs index 355b329081..1086942bda 100644 --- a/mm2src/kdf_walletconnect/src/lib.rs +++ b/mm2src/kdf_walletconnect/src/lib.rs @@ -78,8 +78,7 @@ pub struct WalletConnectCtxImpl { pub(crate) key_pair: SymKeyPair, relay: Relay, metadata: Metadata, - message_tx: UnboundedSender, - message_rx: Arc>>, + message_rx: Mutex>, abortable_system: AbortableQueue, } @@ -91,7 +90,10 @@ impl Deref for WalletConnectCtx { impl WalletConnectCtx { pub fn try_init(ctx: &MmArc) -> MmResult { - let abortable_system = ctx.abortable_system.create_subsystem::().unwrap(); + let abortable_system = ctx + .abortable_system + .create_subsystem::() + .map_to_mm(|err| WalletConnectError::InternalError(err.to_string()))?; let storage = SessionStorageDb::new(ctx)?; let pairing = PairingClient::new(); let relay = Relay { @@ -100,7 +102,7 @@ impl WalletConnectCtx { }; let (inbound_message_tx, mut inbound_message_rx) = unbounded(); let (conn_live_sender, conn_live_receiver) = unbounded(); - let (message_tx, session_request_receiver) = unbounded(); + let (message_tx, message_rx) = unbounded(); let (client, _) = Client::new_with_callback( Handler::new("Komodefi", inbound_message_tx, conn_live_sender), |r, h| abortable_system.weak_spawner().spawn(client_event_loop(r, h)), @@ -113,8 +115,7 @@ impl WalletConnectCtx { metadata: generate_metadata(), key_pair: SymKeyPair::new(), session_manager: SessionManager::new(storage), - message_rx: Arc::new(session_request_receiver.into()), - message_tx, + message_rx: message_rx.into(), abortable_system, }); @@ -127,7 +128,7 @@ impl WalletConnectCtx { let inner_clone = inner.clone(); inner_clone.abortable_system.weak_spawner().spawn(async move { while let Some(msg) = inbound_message_rx.next().await { - if let Err(e) = inner_clone.handle_published_message(msg).await { + if let Err(e) = inner_clone.handle_published_message(msg, message_tx.clone()).await { debug!("Error processing message: {:?}", e); } } @@ -190,7 +191,7 @@ impl WalletConnectCtxImpl { }; let (topic, url) = self.pairing.create(self.metadata.clone(), None)?; - info!("[topic] Subscribing to topic"); + info!("[{topic}] Subscribing to topic"); for attempt in 0..MAX_RETRIES { match self @@ -200,7 +201,7 @@ impl WalletConnectCtxImpl { .await { Ok(Ok(_)) => { - info!("[topic] Subscribed to topic"); + info!("[{topic}] Subscribed to topic"); send_proposal_request(self, &topic, required_namespaces, optional_namespaces).await?; return Ok(url); }, @@ -230,7 +231,11 @@ impl WalletConnectCtxImpl { } /// Handles an inbound published message by decrypting, decoding, and processing it. - async fn handle_published_message(&self, msg: PublishedMessage) -> MmResult<(), WalletConnectError> { + async fn handle_published_message( + &self, + msg: PublishedMessage, + message_tx: UnboundedSender, + ) -> MmResult<(), WalletConnectError> { let message = { let key = self.sym_key(&msg.topic)?; decode_and_decrypt_type0(msg.message.as_bytes(), &key)? @@ -240,7 +245,7 @@ impl WalletConnectCtxImpl { match serde_json::from_str(&message)? { Payload::Request(request) => process_inbound_request(self, request, &msg.topic).await?, - Payload::Response(response) => process_inbound_response(self, response, &msg.topic).await, + Payload::Response(response) => process_inbound_response(self, response, &msg.topic, message_tx).await, } info!("[{}] Inbound message was handled successfully", msg.topic); @@ -275,7 +280,7 @@ impl WalletConnectCtxImpl { let topic = session.topic.clone(); let pairing_topic = session.pairing_topic.clone(); debug!("[{topic}] Session found! activating"); - self.session_manager.add_session(session).await; + self.session_manager.add_session(session); valid_topics.push(topic); pairing_topics.push(pairing_topic); @@ -395,10 +400,9 @@ impl WalletConnectCtxImpl { /// Checks if the current session is connected to a Ledger device. /// NOTE: for COSMOS chains only. - pub async fn is_ledger_connection(&self) -> bool { + pub fn is_ledger_connection(&self) -> bool { self.session_manager .get_session_active() - .await .and_then(|session| session.session_properties) .and_then(|props| props.keys.as_ref().cloned()) .and_then(|keys| keys.first().cloned()) @@ -407,7 +411,7 @@ impl WalletConnectCtxImpl { } /// Checks if a given chain ID is supported. - pub(crate) async fn validate_chain_id( + pub(crate) fn validate_chain_id( &self, session: &Session, chain_id: &WcChainId, @@ -433,12 +437,11 @@ impl WalletConnectCtxImpl { let session = self.session_manager .get_session_active() - .await .ok_or(MmError::new(WalletConnectError::SessionError( "No active WalletConnect session found".to_string(), )))?; - self.validate_chain_id(&session, chain_id).await?; + self.validate_chain_id(&session, chain_id)?; // TODO: uncomment when WalletConnect wallets start listening to chainChanged event // if WcChain::Eip155 != chain_id.chain { @@ -486,11 +489,10 @@ impl WalletConnectCtxImpl { /// TODO: accept WcChainId /// Retrieves the available account for a given chain ID. - pub async fn get_account_for_chain_id(&self, chain_id: &WcChainId) -> MmResult { + pub fn get_account_for_chain_id(&self, chain_id: &WcChainId) -> MmResult { let namespaces = &self .session_manager .get_session_active() - .await .ok_or(MmError::new(WalletConnectError::SessionError( "No active WalletConnect session found".to_string(), )))? @@ -521,7 +523,7 @@ impl WalletConnectCtxImpl { T: DeserializeOwned, F: Fn(T) -> MmResult, { - let active_topic = self.session_manager.get_active_topic_or_err().await?; + let active_topic = self.session_manager.get_active_topic_or_err()?; let request = SessionRequestRequest { chain_id: chain_id.to_string(), request: SessionRequest { diff --git a/mm2src/kdf_walletconnect/src/pairing.rs b/mm2src/kdf_walletconnect/src/pairing.rs index 3fb7ce6010..259c533e46 100644 --- a/mm2src/kdf_walletconnect/src/pairing.rs +++ b/mm2src/kdf_walletconnect/src/pairing.rs @@ -34,7 +34,7 @@ pub(crate) async fn reply_pairing_extend_response( }; } - let param = ResponseParamsSuccess::PairingPing(true); + let param = ResponseParamsSuccess::PairingExtend(true); ctx.publish_response_ok(topic, param, message_id).await?; Ok(()) diff --git a/mm2src/kdf_walletconnect/src/session/mod.rs b/mm2src/kdf_walletconnect/src/session/mod.rs index 9e6e060325..0d5c1df61b 100644 --- a/mm2src/kdf_walletconnect/src/session/mod.rs +++ b/mm2src/kdf_walletconnect/src/session/mod.rs @@ -171,10 +171,10 @@ impl Session { pub(crate) fn extend(&mut self, till: u64) { self.expiry = till; } /// Get the active chain ID for the current session. - pub async fn get_active_chain_id(&self) -> &Option { &self.active_chain_id } + pub fn get_active_chain_id(&self) -> &Option { &self.active_chain_id } /// Sets the active chain ID for the current session. - pub async fn set_active_chain_id(&mut self, chain_id: WcChainId) { self.active_chain_id = Some(chain_id); } + pub fn set_active_chain_id(&mut self, chain_id: WcChainId) { self.active_chain_id = Some(chain_id); } } /// Internal implementation of session management. @@ -219,7 +219,7 @@ impl SessionManager { pub(crate) fn storage(&self) -> &SessionStorageDb { &self.0.storage } /// Get active session topic or return error if no session has been activated. - pub async fn get_active_topic_or_err(&self) -> MmResult { + pub fn get_active_topic_or_err(&self) -> MmResult { self.0 .active_topic .lock() @@ -232,7 +232,7 @@ impl SessionManager { /// Inserts `Session` into the session store, associated with the specified topic. /// If a session with the same topic already exists, it will be overwritten. - pub(crate) async fn add_session(&self, session: Session) { + pub(crate) fn add_session(&self, session: Session) { // set active session topic. *self.0.active_topic.lock().unwrap() = Some(session.topic.clone()); // insert session @@ -241,7 +241,7 @@ impl SessionManager { /// Removes session corresponding to the specified topic from the session store. /// If the session does not exist, this method does nothing. - pub(crate) async fn delete_session(&self, topic: &Topic) -> Option { + pub(crate) fn delete_session(&self, topic: &Topic) -> Option { info!("[{topic}] Deleting session with topic"); let mut active_topic = self.0.active_topic.lock().unwrap(); @@ -261,7 +261,7 @@ impl SessionManager { removed_session } - pub async fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { + pub fn set_active_session(&self, topic: &Topic) -> MmResult<(), WalletConnectError> { let mut active_topic = self.0.active_topic.lock().unwrap(); let session = self .get_session(topic) @@ -283,7 +283,7 @@ impl SessionManager { } /// returns an `option` containing the active session if it exists; otherwise, returns `none`. - pub async fn get_session_active(&self) -> Option { + pub fn get_session_active(&self) -> Option { self.0 .active_topic .lock() @@ -298,6 +298,7 @@ impl SessionManager { } pub(crate) fn get_sessions_full(&self) -> impl Iterator> { self.0.sessions.iter() } + /// Updates the expiry time of the session associated with the given topic to the specified timestamp. /// If the session does not exist, this method does nothing. pub(crate) fn extend_session(&self, topic: &Topic, till: u64) { diff --git a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs index 1154ff2c4a..c865272884 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/delete.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/delete.rs @@ -39,7 +39,7 @@ async fn session_delete_cleanup(ctx: &WalletConnectCtxImpl, topic: &Topic) -> Mm ctx.client.unsubscribe(topic.clone()).await?; }; - if let Some(session) = ctx.session_manager.delete_session(topic).await { + if let Some(session) = ctx.session_manager.delete_session(topic) { debug!( "[{}] No active sessions for pairing disconnecting", session.pairing_topic diff --git a/mm2src/kdf_walletconnect/src/session/rpc/event.rs b/mm2src/kdf_walletconnect/src/session/rpc/event.rs index 9759c29de7..e3fe87ca9c 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/event.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/event.rs @@ -30,21 +30,16 @@ pub async fn handle_session_event( return Ok(()); }; - ctx.validate_chain_id(&session, &chain_id).await?; + ctx.validate_chain_id(&session, &chain_id)?; - if session - .get_active_chain_id() - .await - .as_ref() - .map_or(false, |c| c == &chain_id) - { + if session.get_active_chain_id().as_ref().map_or(false, |c| c == &chain_id) { return Ok(()); }; // check if if new chain_id is supported. let new_id = serde_json::from_value::(event.event.data)?; let new_chain = chain_id.chain.derive_chain_id(new_id.to_string()); - if let Err(err) = ctx.validate_chain_id(&session, &new_chain).await { + if let Err(err) = ctx.validate_chain_id(&session, &new_chain) { error!("[{topic}] {err:?}"); let error_data = ErrorData { code: UNSUPPORTED_CHAINS, @@ -60,8 +55,7 @@ pub async fn handle_session_event( .ok_or(MmError::new(WalletConnectError::SessionError( "No active WalletConnect session found".to_string(), )))? - .set_active_chain_id(chain_id) - .await; + .set_active_chain_id(chain_id); } }; }, diff --git a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs index f2b3f7c03c..69eb352605 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/propose.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/propose.rs @@ -80,7 +80,7 @@ pub async fn reply_session_proposal_request( .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Add session to session lists - ctx.session_manager.add_session(session.clone()).await; + ctx.session_manager.add_session(session.clone()); } send_session_settle_request(ctx, &session).await?; @@ -143,7 +143,7 @@ pub(crate) async fn process_session_propose_response( .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Add session to session lists - ctx.session_manager.add_session(session.clone()).await; + ctx.session_manager.add_session(session.clone()); }; // Activate pairing_topic diff --git a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs index c94f09e84e..12dcf9a5b0 100644 --- a/mm2src/kdf_walletconnect/src/session/rpc/settle.rs +++ b/mm2src/kdf_walletconnect/src/session/rpc/settle.rs @@ -76,7 +76,7 @@ pub(crate) async fn reply_session_settle_request( .mm_err(|err| WalletConnectError::StorageError(err.to_string()))?; // Optionally: Remove from active sessions in memory too - ctx.session_manager.delete_session(&session.topic).await; + ctx.session_manager.delete_session(&session.topic); ctx.drop_session(&session.topic).await?; debug!("Deleted previous session with topic: {:?}", session.topic); } diff --git a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs index a374a7f927..4e9642473e 100644 --- a/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs +++ b/mm2src/mm2_main/src/rpc/wc_commands/sessions.rs @@ -64,7 +64,6 @@ pub async fn set_active_session( WalletConnectCtx::from_ctx(&ctx).mm_err(|err| WalletConnectRpcError::InitializationError(err.to_string()))?; ctx.session_manager .set_active_session(&req.topic.into()) - .await .mm_err(|err| WalletConnectRpcError::SessionRequestError(err.to_string()))?; Ok(SessionResponse {