diff --git a/tools/usdt-bridge/Cargo.lock b/tools/usdt-bridge/Cargo.lock index 1b5b5f44..b7578a04 100644 --- a/tools/usdt-bridge/Cargo.lock +++ b/tools/usdt-bridge/Cargo.lock @@ -256,7 +256,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand", + "rand 0.8.5", ] [[package]] @@ -482,7 +482,7 @@ dependencies = [ "bs58", "hmac 0.12.1", "k256", - "rand_core", + "rand_core 0.6.4", "ripemd", "secp256k1 0.27.0", "sha2 0.10.9", @@ -686,6 +686,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chacha20" version = "0.9.1" @@ -694,7 +700,18 @@ checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", +] + +[[package]] +name = "chacha20" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d524456ba66e72eb8b115ff89e01e497f8e6d11d78b70b1aa13c0fbd97540a81" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", ] [[package]] @@ -871,6 +888,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crossbeam-queue" version = "0.3.12" @@ -899,7 +925,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -911,7 +937,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -947,7 +973,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", @@ -1253,7 +1279,7 @@ dependencies = [ "ed25519", "hashbrown 0.15.5", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sha2 0.10.9", "subtle", "zeroize", @@ -1278,7 +1304,7 @@ dependencies = [ "generic-array", "group", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", "serdect", "subtle", @@ -1355,7 +1381,7 @@ version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1388,7 +1414,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" dependencies = [ "byteorder", - "rand", + "rand 0.8.5", "rustc-hex", "static_assertions", ] @@ -1617,8 +1643,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] @@ -1629,18 +1657,32 @@ checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasm-bindgen", +] + [[package]] name = "getrandom_or_panic" version = "0.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9" dependencies = [ - "rand", - "rand_core", + "rand 0.8.5", + "rand_core 0.6.4", ] [[package]] @@ -1656,7 +1698,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1793,12 +1835,94 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca2a8f2913ee65f60facd6a5905613afaa448497a0230cc41ce022d93290bc2c" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9f41fd6a08e4d4ec69df65976da761afd5ad5e58a9d4acb46bd1c953a9e3ff2" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + [[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ca68d021ef39cf6463ab54c1d0f5daf03377b70561305bb89a8f83aab66e0f" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.64" @@ -2023,6 +2147,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "ipnet" +version = "2.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" + [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -2203,7 +2333,7 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -2247,7 +2377,7 @@ dependencies = [ "libsecp256k1-core", "libsecp256k1-gen-ecmult", "libsecp256k1-gen-genmult", - "rand", + "rand 0.8.5", "serde", "sha2 0.9.9", "typenum", @@ -2318,6 +2448,12 @@ dependencies = [ "hashbrown 0.15.5", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "matchers" version = "0.2.0" @@ -2350,7 +2486,7 @@ checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d" dependencies = [ "byteorder", "keccak", - "rand_core", + "rand_core 0.6.4", "zeroize", ] @@ -2542,8 +2678,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9" dependencies = [ "bitcoin_hashes 0.13.0", - "rand", - "rand_core", + "rand 0.8.5", + "rand_core 0.6.4", "serde", "unicode-normalization", ] @@ -2613,7 +2749,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" dependencies = [ "base64ct", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2983,7 +3119,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -3089,6 +3225,62 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quinn" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" +dependencies = [ + "bytes", + "cfg_aliases", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2", + "thiserror 2.0.18", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-proto" +version = "0.11.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f4bfc015262b9df63c8845072ce59068853ff5872180c2ce2f13038b970e560" +dependencies = [ + "bytes", + "getrandom 0.4.3", + "lru-slab", + "rand 0.10.2", + "rand_pcg", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.18", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35a133f956daabe89a61a685c2649f13d82d5aa4bd5d12d1277e1072a21c0694" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2", + "tracing", + "windows-sys 0.52.0", +] + [[package]] name = "quote" version = "1.0.44" @@ -3104,6 +3296,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -3118,7 +3316,18 @@ checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", "rand_chacha", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7f5fa3a058cd35567ef9bfa5e75732bee0f9e4c55fa90477bef2dfcdbc4be80" +dependencies = [ + "chacha20 0.10.1", + "getrandom 0.4.3", + "rand_core 0.10.1", ] [[package]] @@ -3128,7 +3337,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -3140,6 +3349,21 @@ dependencies = [ "getrandom 0.2.17", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + +[[package]] +name = "rand_pcg" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caa0f4137e1c0a72f4c651489402276c8e8e1cf081f3b0ba156d2cbeef09e86a" +dependencies = [ + "rand_core 0.10.1", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -3198,6 +3422,44 @@ version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -3304,6 +3566,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ + "web-time", "zeroize", ] @@ -3367,6 +3630,12 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7c1c839d570d835527c9a5e4db7cb2198683a988cb9d7293fc8674e6bd58fc8" +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + [[package]] name = "salsa20" version = "0.10.2" @@ -3667,7 +3936,7 @@ dependencies = [ "curve25519-dalek", "getrandom_or_panic", "merlin", - "rand_core", + "rand_core 0.6.4", "serde_bytes", "sha2 0.10.9", "subtle", @@ -3732,7 +4001,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252" dependencies = [ "bitcoin_hashes 0.14.1", - "rand", + "rand 0.8.5", "secp256k1-sys 0.10.1", ] @@ -3872,6 +4141,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + [[package]] name = "serdect" version = "0.2.0" @@ -3889,7 +4170,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -3901,7 +4182,7 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.9.0", "opaque-debug", ] @@ -3913,7 +4194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -3959,7 +4240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest 0.10.7", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -4025,7 +4306,7 @@ dependencies = [ "bip39", "blake2-rfc", "bs58", - "chacha20", + "chacha20 0.9.1", "crossbeam-queue", "derive_more 0.99.20", "ed25519-zebra", @@ -4048,7 +4329,7 @@ dependencies = [ "pbkdf2", "pin-project", "poly1305", - "rand", + "rand 0.8.5", "rand_chacha", "ruzstd 0.6.0", "schnorrkel", @@ -4079,7 +4360,7 @@ dependencies = [ "bip39", "blake2-rfc", "bs58", - "chacha20", + "chacha20 0.9.1", "crossbeam-queue", "derive_more 2.1.1", "ed25519-zebra", @@ -4102,7 +4383,7 @@ dependencies = [ "pbkdf2", "pin-project", "poly1305", - "rand", + "rand 0.8.5", "rand_chacha", "ruzstd 0.8.3", "schnorrkel", @@ -4145,7 +4426,7 @@ dependencies = [ "lru", "parking_lot", "pin-project", - "rand", + "rand 0.8.5", "rand_chacha", "serde", "serde_json", @@ -4181,7 +4462,7 @@ dependencies = [ "lru", "parking_lot", "pin-project", - "rand", + "rand 0.8.5", "rand_chacha", "serde", "serde_json", @@ -4213,7 +4494,7 @@ dependencies = [ "futures", "httparse", "log", - "rand", + "rand 0.8.5", "sha1", ] @@ -4272,7 +4553,7 @@ dependencies = [ "parking_lot", "paste", "primitive-types 0.12.2", - "rand", + "rand 0.8.5", "scale-info", "schnorrkel", "secp256k1 0.28.2", @@ -4402,7 +4683,7 @@ dependencies = [ "num-traits", "parity-scale-codec", "paste", - "rand", + "rand 0.8.5", "scale-info", "serde", "simple-mermaid", @@ -4459,7 +4740,7 @@ dependencies = [ "log", "parity-scale-codec", "parking_lot", - "rand", + "rand 0.8.5", "smallvec", "sp-core", "sp-externalities", @@ -4514,7 +4795,7 @@ dependencies = [ "nohash-hasher", "parity-scale-codec", "parking_lot", - "rand", + "rand 0.8.5", "scale-info", "schnellru", "sp-core", @@ -4842,6 +5123,15 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + [[package]] name = "synstructure" version = "0.13.2" @@ -5116,6 +5406,51 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags 2.10.0", + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "url", +] + +[[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.44" @@ -5200,6 +5535,12 @@ dependencies = [ "hash-db", ] +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + [[package]] name = "twox-hash" version = "1.6.3" @@ -5208,7 +5549,7 @@ checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" dependencies = [ "cfg-if", "digest 0.10.7", - "rand", + "rand 0.8.5", "static_assertions", ] @@ -5315,6 +5656,7 @@ dependencies = [ "hex", "pezkuwi-subxt", "pezkuwi-subxt-signer", + "reqwest", "serde", "serde_json", "sp-core", @@ -5366,9 +5708,9 @@ dependencies = [ "ark-serialize-derive", "arrayref", "digest 0.10.7", - "rand", + "rand 0.8.5", "rand_chacha", - "rand_core", + "rand_core 0.6.4", "sha2 0.10.9", "sha3", "zeroize", @@ -5384,6 +5726,15 @@ dependencies = [ "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.11.1+wasi-snapshot-preview1" @@ -5595,6 +5946,15 @@ dependencies = [ "rustls-pki-types", ] +[[package]] +name = "webpki-roots" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf85cb06032201fa7c6f829d7db5a7e5aa45bcc0655327713065f6f0576731bf" +dependencies = [ + "rustls-pki-types", +] + [[package]] name = "winapi" version = "0.3.9" @@ -5953,7 +6313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" dependencies = [ "curve25519-dalek", - "rand_core", + "rand_core 0.6.4", "serde", "zeroize", ] diff --git a/tools/usdt-bridge/Cargo.toml b/tools/usdt-bridge/Cargo.toml index f2ea6fc3..7ab57b6c 100644 --- a/tools/usdt-bridge/Cargo.toml +++ b/tools/usdt-bridge/Cargo.toml @@ -12,6 +12,10 @@ license = "Apache-2.0" name = "usdt-bridge" path = "src/main.rs" +[[bin]] +name = "pezbridge-bot" +path = "src/bin/pezbridge_bot.rs" + [dependencies] # Async runtime tokio = { version = "1.36", features = ["full"] } @@ -54,6 +58,10 @@ chrono = { version = "0.4", features = ["serde"] } # Async streams futures = "0.3" +# Telegram Bot API HTTP client (pezbridge-bot only). rustls instead of native-tls/OpenSSL so +# this cross-compiles cleanly to a static musl binary (no OpenSSL sysroot needed for the target). +reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] } + # Error handling anyhow = "1.0" thiserror = "1.0" diff --git a/tools/usdt-bridge/deploy/pezbridge-bot.service b/tools/usdt-bridge/deploy/pezbridge-bot.service new file mode 100644 index 00000000..8c0fdb11 --- /dev/null +++ b/tools/usdt-bridge/deploy/pezbridge-bot.service @@ -0,0 +1,53 @@ +[Unit] +Description=PezbridgeBot - USDT bridge automation-key allowance renewal notifier (holds no key) +After=network-online.target +Wants=network-online.target + +[Service] +Type=simple +User=pezbridgebot +Group=pezbridgebot +WorkingDirectory=/opt/pezbridgebot/data +ExecStart=/opt/pezbridgebot/bin/pezbridge-bot +Environment=PEZBRIDGE_CONFIG=/opt/pezbridgebot/bin/pezbridge_bot_config.json +Environment=RUST_LOG=info +EnvironmentFile=/etc/pezbridgebot/telegram_token.env +Restart=on-failure +RestartSec=10 + +# --- Hardening --- +# Deployed 2026-07-13 on NEW-10 (89.116.25.180), simplified 2026-07-14: this process used to +# also hold Noter's (Validator_04's) mnemonic via LoadCredential so it could automate 1-of-3 +# required signatures. That stopped being worth the risk once pwap-web shipped a real signing +# UI (any of the 5 signers can now approve directly with their own wallet extension at +# /multisig/pending) - the bot-held key only ever saved "2 humans click instead of 3", not +# enough to justify a private key living on a server. Noter's mnemonic was removed from this +# host entirely; this unit now only reads chain state and sends Telegram messages - it has no +# LoadCredential, no signing capability, and nothing worth exfiltrating. The hardening below is +# kept anyway as good baseline practice, not because there's a key to protect anymore. +NoNewPrivileges=yes +ProtectSystem=strict +ProtectHome=yes +PrivateTmp=yes +PrivateDevices=yes +ProtectKernelTunables=yes +ProtectKernelModules=yes +ProtectKernelLogs=yes +ProtectControlGroups=yes +ProtectClock=yes +ProtectHostname=yes +RestrictSUIDSGID=yes +RemoveIPC=yes +LockPersonality=yes +RestrictRealtime=yes +RestrictNamespaces=yes +MemoryDenyWriteExecute=yes +SystemCallFilter=@system-service +SystemCallArchitectures=native +CapabilityBoundingSet= +AmbientCapabilities= +ReadWritePaths=/opt/pezbridgebot/data +UMask=0077 + +[Install] +WantedBy=multi-user.target diff --git a/tools/usdt-bridge/examples/gen_automation_key.rs b/tools/usdt-bridge/examples/gen_automation_key.rs new file mode 100644 index 00000000..6ea7a2f8 --- /dev/null +++ b/tools/usdt-bridge/examples/gen_automation_key.rs @@ -0,0 +1,27 @@ +use anyhow::Result; + +fn main() -> Result<()> { + let (pair, phrase, _) = sp_core::sr25519::Pair::generate_with_phrase(None); + use sp_core::Pair as _; + let public = pair.public(); + let account = sp_core::crypto::AccountId32::from(public.0); + let ss58 = sp_core::crypto::Ss58Codec::to_ss58check_with_version( + &account, + sp_core::crypto::Ss58AddressFormat::custom(42), + ); + + let out = serde_json::json!({ + "warning": "CONTAINS PRIVATE SEED PHRASE - KEEP SECURE - NOT IN GIT - NOT IN LOGS", + "role": "usdt-bridge relayer automation key - LIMITED delegated allowance only via Assets.approve_transfer, never asset owner/admin", + "ss58_address_pezkuwi": ss58, + "scheme": "sr25519", + "mnemonic": phrase, + }); + std::fs::write("/home/myhez/res/bridge_automation_key.json", serde_json::to_string_pretty(&out)?)?; + + println!("Generated automation key."); + println!("Address (never the mnemonic): {}", ss58); + println!("Saved to /home/myhez/res/bridge_automation_key.json"); + + Ok(()) +} diff --git a/tools/usdt-bridge/pezbridge_bot_config.json b/tools/usdt-bridge/pezbridge_bot_config.json new file mode 100644 index 00000000..7395de2d --- /dev/null +++ b/tools/usdt-bridge/pezbridge_bot_config.json @@ -0,0 +1,9 @@ +{ + "pezkuwi_rpc": "wss://asset-hub-rpc.pezkuwichain.io", + "serok_chat_id": 5362991649, + "ops_chat_id": -5420200114, + "poll_interval_secs": 600, + "renewal_threshold": 3000000000, + "topup_amount": 10000000000, + "state_path": "/opt/pezbridgebot/data/pezbridge_bot_state.json" +} diff --git a/tools/usdt-bridge/src/bin/pezbridge_bot.rs b/tools/usdt-bridge/src/bin/pezbridge_bot.rs new file mode 100644 index 00000000..68e041df --- /dev/null +++ b/tools/usdt-bridge/src/bin/pezbridge_bot.rs @@ -0,0 +1,240 @@ +//! PezbridgeBot - notifies signers when the USDT bridge automation key's `Assets.approve_transfer` +//! spending allowance needs renewal (see /home/myhez/res/validators-tiki.md and the +//! usdt-bridge-multisig-migration memory for the full custody model). +//! +//! This process holds NO private key and cannot sign or submit anything. An earlier version of +//! this bot held Noter's (Validator_04's) key so it could automate 1-of-3 required signatures - +//! that made sense when it was written, since pwap-web had no working signing UI at all and +//! every approval required a hand-written script. It stopped making sense once pwap-web's real +//! multisig operations UI shipped (shared/lib/multisig.ts + web/src/components/ +//! MultisigOperations.tsx, at /multisig/pending): any of the 5 signers can now approve directly +//! with their own wallet extension, so the only thing a bot-held key still bought was "2 humans +//! click instead of 3" - not worth a private key sitting on a server for. Simplified back down +//! to detect-and-notify only; Noter's mnemonic was removed from this host entirely. +//! +//! Flow: +//! 1. Poll the automation key's remaining Assets.Approvals allowance for wUSDT (asset 1000). +//! 2. When it drops below `renewal_threshold`, send ONE Telegram notification (to Serok's chat +//! and the ops group) pointing signers at pwap-web's /multisig/pending page, where any 3 of +//! the 5 real signatories can approve the renewal with their own wallets. +//! 3. Suppress repeat notifications until the allowance is actually renewed (goes back above +//! threshold) - avoids spamming every poll cycle while humans coordinate. + +use anyhow::{anyhow, Context, Result}; +use serde::{Deserialize, Serialize}; +use sp_core::crypto::Ss58Codec; +use std::path::PathBuf; +use std::time::Duration; +use subxt::dynamic::{At, Value}; +use subxt::{OnlineClient, SubstrateConfig}; +use tracing::{error, info, warn}; + +const WUSDT_ASSET_ID: u32 = 1000; +const MULTISIG_ADDR: &str = "5GvwxmCDp3PC33KHoeWSgj3S7ocE7nzk1jiCCZMPSDBFeNcj"; +const AUTOMATION_KEY_ADDR: &str = "5GQu4PFUb1f3MTJ7i7c1CtLgDk3TVvpSW1VbQCRmfkMoC8cM"; +const MULTISIG_THRESHOLD: u16 = 3; +const PWAP_WEB_OPERATIONS_URL: &str = "https://app.pezkuwichain.io/multisig/pending"; + +// ============================================================================ +// Config / state +// ============================================================================ + +#[derive(Debug, Clone, Serialize, Deserialize)] +struct BotConfig { + pezkuwi_rpc: String, + serok_chat_id: i64, + ops_chat_id: i64, + poll_interval_secs: u64, + renewal_threshold: u128, + topup_amount: u128, + state_path: PathBuf, +} + +impl Default for BotConfig { + fn default() -> Self { + Self { + pezkuwi_rpc: "wss://asset-hub-rpc.pezkuwichain.io".to_string(), + serok_chat_id: 0, + ops_chat_id: 0, + poll_interval_secs: 600, + renewal_threshold: 3_000_000_000, // 3,000 wUSDT + topup_amount: 10_000_000_000, // 10,000 wUSDT + state_path: PathBuf::from("pezbridge_bot_state.json"), + } + } +} + +fn load_config() -> Result { + let path = std::env::var("PEZBRIDGE_CONFIG").unwrap_or_else(|_| "pezbridge_bot_config.json".to_string()); + if std::path::Path::new(&path).exists() { + let content = std::fs::read_to_string(&path).context("reading config file")?; + Ok(serde_json::from_str(&content).context("parsing config file")?) + } else { + warn!("No config file at {path}, using defaults - serok_chat_id/ops_chat_id MUST be set for this to be useful"); + Ok(BotConfig::default()) + } +} + +#[derive(Debug, Default, Serialize, Deserialize)] +struct BotState { + /// Whether a notification has already been sent for the CURRENT low-allowance episode - + /// reset back to false once the allowance rises back above threshold (meaning humans + /// renewed it via pwap-web), so the next depletion gets its own fresh notification. + already_notified: bool, +} + +fn load_state(path: &PathBuf) -> Result { + if path.exists() { + let content = std::fs::read_to_string(path)?; + Ok(serde_json::from_str(&content).unwrap_or_default()) + } else { + Ok(BotState::default()) + } +} + +fn save_state(path: &PathBuf, state: &BotState) -> Result<()> { + std::fs::write(path, serde_json::to_string_pretty(state)?)?; + Ok(()) +} + +// ============================================================================ +// Chain read +// ============================================================================ + +async fn get_approval_remaining( + client: &OnlineClient, + asset_id: u32, + owner: &str, + delegate: &str, +) -> Result { + let owner_bytes = sp_core::crypto::AccountId32::from_ss58check(owner) + .map_err(|e| anyhow!("invalid owner address: {e:?}"))?; + let delegate_bytes = sp_core::crypto::AccountId32::from_ss58check(delegate) + .map_err(|e| anyhow!("invalid delegate address: {e:?}"))?; + + let storage_query = subxt::dynamic::storage( + "Assets", + "Approvals", + vec![ + Value::primitive(asset_id.into()), + Value::from_bytes(>::as_ref(&owner_bytes)), + Value::from_bytes(>::as_ref(&delegate_bytes)), + ], + ); + + let result = client.storage().at_latest().await?.fetch(&storage_query).await?; + if let Some(v) = result { + if let Some(amount) = v.to_value()?.at("amount").and_then(|a| a.as_u128()) { + return Ok(amount); + } + } + // No approval entry at all = the allowance is fully exhausted (or was never granted) - + // treat identically to "0 remaining" so it triggers a notification. + Ok(0) +} + +// ============================================================================ +// Telegram (send-only - no polling/callbacks needed anymore, there's no action this bot takes) +// ============================================================================ + +async fn tg_send_message(http: &reqwest::Client, token: &str, chat_id: i64, text: &str) -> Result<()> { + if chat_id == 0 { + return Ok(()); + } + let url = format!("https://api.telegram.org/bot{token}/sendMessage"); + let body = serde_json::json!({ "chat_id": chat_id, "text": text }); + let resp = http.post(&url).json(&body).send().await?; + let json: serde_json::Value = resp.json().await?; + if json["ok"].as_bool() != Some(true) { + return Err(anyhow!("sendMessage failed: {json}")); + } + Ok(()) +} + +async fn notify(http: &reqwest::Client, token: &str, config: &BotConfig, msg: &str) { + info!("[pezbridge-bot] {msg}"); + if let Err(e) = tg_send_message(http, token, config.serok_chat_id, msg).await { + error!("failed to notify Serok: {e:#}"); + } + if let Err(e) = tg_send_message(http, token, config.ops_chat_id, msg).await { + error!("failed to notify ops chat: {e:#}"); + } +} + +// ============================================================================ +// Core logic +// ============================================================================ + +async fn check_allowance_and_maybe_notify( + read_client: &OnlineClient, + http: &reqwest::Client, + token: &str, + config: &BotConfig, + state: &mut BotState, +) -> Result<()> { + let remaining = get_approval_remaining(read_client, WUSDT_ASSET_ID, MULTISIG_ADDR, AUTOMATION_KEY_ADDR).await?; + info!("Automation key remaining allowance: {:.2} wUSDT", remaining as f64 / 1_000_000.0); + + if remaining >= config.renewal_threshold { + if state.already_notified { + info!("Allowance is back above threshold - renewal happened, resetting notification state"); + state.already_notified = false; + save_state(&config.state_path, state)?; + } + return Ok(()); + } + + if state.already_notified { + return Ok(()); // already told everyone, don't spam while they coordinate + } + + let topup = config.topup_amount; + let text = format!( + "\u{26A0}\u{FE0F} USDT Bridge - otomasyon anahtarı izni azaldı\n\n\ + Kalan izin: {:.2} wUSDT\nEşik: {:.2} wUSDT\n\n\ + Önerilen yenileme: {:.2} wUSDT (Assets.approve_transfer, multisig'den otomasyon anahtarına).\n\n\ + {} imzacının (5'ten herhangi 3'ü) pwap-web üzerinden kendi cüzdanlarıyla onaylaması gerekiyor:\n{}", + remaining as f64 / 1_000_000.0, + config.renewal_threshold as f64 / 1_000_000.0, + topup as f64 / 1_000_000.0, + MULTISIG_THRESHOLD, + PWAP_WEB_OPERATIONS_URL + ); + + notify(http, token, config, &text).await; + + state.already_notified = true; + save_state(&config.state_path, state)?; + + Ok(()) +} + +#[tokio::main] +async fn main() -> Result<()> { + tracing_subscriber::fmt().with_env_filter(tracing_subscriber::EnvFilter::from_default_env()).init(); + + let config = load_config()?; + if config.serok_chat_id == 0 && config.ops_chat_id == 0 { + return Err(anyhow!("both serok_chat_id and ops_chat_id are unset - this bot would notify no one")); + } + + let token = std::env::var("PEZBRIDGE_TELEGRAM_TOKEN").context("PEZBRIDGE_TELEGRAM_TOKEN env var not set")?; + + info!("Connecting to {}...", config.pezkuwi_rpc); + let read_client = OnlineClient::::from_url(&config.pezkuwi_rpc) + .await + .context("failed to connect")?; + + let http = reqwest::Client::new(); + let mut state = load_state(&config.state_path)?; + + notify(&http, &token, &config, "PezbridgeBot started (notify-only, holds no key).").await; + + let mut poll_timer = tokio::time::interval(Duration::from_secs(config.poll_interval_secs)); + loop { + poll_timer.tick().await; + if let Err(e) = check_allowance_and_maybe_notify(&read_client, &http, &token, &config, &mut state).await { + error!("allowance check failed: {e:#}"); + } + } +}