icepick-cosmos: initial commit
This commit is contained in:
parent
85adc05429
commit
db5ca73d10
|
@ -395,6 +395,22 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bip32"
|
||||||
|
version = "0.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aa13fae8b6255872fd86f7faf4b41168661d7d78609f7bfe6771b85c6739a15b"
|
||||||
|
dependencies = [
|
||||||
|
"bs58",
|
||||||
|
"hmac 0.12.1",
|
||||||
|
"k256",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
"ripemd",
|
||||||
|
"sha2 0.10.8",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bitflags"
|
name = "bitflags"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
@ -442,6 +458,31 @@ dependencies = [
|
||||||
"generic-array",
|
"generic-array",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bon"
|
||||||
|
version = "3.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fe7acc34ff59877422326db7d6f2d845a582b16396b6b08194942bf34c6528ab"
|
||||||
|
dependencies = [
|
||||||
|
"bon-macros",
|
||||||
|
"rustversion",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bon-macros"
|
||||||
|
version = "3.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4159dd617a7fbc9be6a692fe69dc2954f8e6bb6bb5e4d7578467441390d77fd0"
|
||||||
|
dependencies = [
|
||||||
|
"darling",
|
||||||
|
"ident_case",
|
||||||
|
"prettyplease",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"rustversion",
|
||||||
|
"syn 2.0.92",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "borsh"
|
name = "borsh"
|
||||||
version = "0.10.4"
|
version = "0.10.4"
|
||||||
|
@ -537,6 +578,7 @@ version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
|
checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"sha2 0.10.8",
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -587,6 +629,9 @@ name = "bytes"
|
||||||
version = "1.9.0"
|
version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
|
@ -754,6 +799,38 @@ version = "0.8.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cosmos-sdk-proto"
|
||||||
|
version = "0.26.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "462e1f6a8e005acc8835d32d60cbd7973ed65ea2a8d8473830e675f050956427"
|
||||||
|
dependencies = [
|
||||||
|
"prost",
|
||||||
|
"tendermint-proto",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cosmrs"
|
||||||
|
version = "0.21.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "210fbe6f98594963b46cc980f126a9ede5db9a3848ca65b71303bebdb01afcd9"
|
||||||
|
dependencies = [
|
||||||
|
"bip32",
|
||||||
|
"cosmos-sdk-proto",
|
||||||
|
"ecdsa",
|
||||||
|
"eyre",
|
||||||
|
"k256",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"signature 2.2.0",
|
||||||
|
"subtle-encoding",
|
||||||
|
"tendermint",
|
||||||
|
"tendermint-rpc",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cpufeatures"
|
name = "cpufeatures"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
|
@ -877,6 +954,19 @@ dependencies = [
|
||||||
"syn 2.0.92",
|
"syn 2.0.92",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "curve25519-dalek-ng"
|
||||||
|
version = "4.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"digest 0.9.0",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
"subtle-ng",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.20.10"
|
version = "0.20.10"
|
||||||
|
@ -922,6 +1012,15 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "deranged"
|
||||||
|
version = "0.3.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||||
|
dependencies = [
|
||||||
|
"powerfmt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derivation-path"
|
name = "derivation-path"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -955,6 +1054,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"block-buffer 0.10.4",
|
"block-buffer 0.10.4",
|
||||||
|
"const-oid",
|
||||||
"crypto-common",
|
"crypto-common",
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
@ -983,7 +1083,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
|
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"der",
|
"der",
|
||||||
|
"digest 0.10.7",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
|
"rfc6979",
|
||||||
"signature 2.2.0",
|
"signature 2.2.0",
|
||||||
"spki",
|
"spki",
|
||||||
]
|
]
|
||||||
|
@ -1007,6 +1109,19 @@ dependencies = [
|
||||||
"signature 2.2.0",
|
"signature 2.2.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ed25519-consensus"
|
||||||
|
version = "2.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b"
|
||||||
|
dependencies = [
|
||||||
|
"curve25519-dalek-ng",
|
||||||
|
"hex",
|
||||||
|
"rand_core 0.6.4",
|
||||||
|
"sha2 0.9.9",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ed25519-dalek"
|
name = "ed25519-dalek"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -1107,6 +1222,16 @@ version = "1.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "eyre"
|
||||||
|
version = "0.6.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec"
|
||||||
|
dependencies = [
|
||||||
|
"indenter",
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "feature-probe"
|
name = "feature-probe"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -1154,6 +1279,16 @@ dependencies = [
|
||||||
"miniz_oxide",
|
"miniz_oxide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flex-error"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b"
|
||||||
|
dependencies = [
|
||||||
|
"eyre",
|
||||||
|
"paste",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
@ -1387,6 +1522,12 @@ version = "0.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hex"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hmac"
|
name = "hmac"
|
||||||
version = "0.8.1"
|
version = "0.8.1"
|
||||||
|
@ -1527,6 +1668,19 @@ dependencies = [
|
||||||
"toml 0.8.19",
|
"toml 0.8.19",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icepick-cosmos"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bon",
|
||||||
|
"cosmrs",
|
||||||
|
"icepick-module",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror 2.0.9",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "icepick-internal"
|
name = "icepick-internal"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -1541,6 +1695,7 @@ dependencies = [
|
||||||
name = "icepick-module"
|
name = "icepick-module"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bon",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
]
|
]
|
||||||
|
@ -1713,6 +1868,12 @@ dependencies = [
|
||||||
"icu_properties",
|
"icu_properties",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "indenter"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "indexmap"
|
name = "indexmap"
|
||||||
version = "2.7.0"
|
version = "2.7.0"
|
||||||
|
@ -1812,6 +1973,7 @@ dependencies = [
|
||||||
"ecdsa",
|
"ecdsa",
|
||||||
"elliptic-curve",
|
"elliptic-curve",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
"sha2 0.10.8",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2094,6 +2256,12 @@ dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-conv"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-derive"
|
name = "num-derive"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
@ -2214,6 +2382,12 @@ dependencies = [
|
||||||
"syn 2.0.92",
|
"syn 2.0.92",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "openssl-probe"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.104"
|
version = "0.9.104"
|
||||||
|
@ -2274,6 +2448,33 @@ dependencies = [
|
||||||
"hmac 0.12.1",
|
"hmac 0.12.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peg"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "295283b02df346d1ef66052a757869b2876ac29a6bb0ac3f5f7cd44aebe40e8f"
|
||||||
|
dependencies = [
|
||||||
|
"peg-macros",
|
||||||
|
"peg-runtime",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peg-macros"
|
||||||
|
version = "0.8.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdad6a1d9cf116a059582ce415d5f5566aabcd4008646779dab7fdc2a9a9d426"
|
||||||
|
dependencies = [
|
||||||
|
"peg-runtime",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "peg-runtime"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e3aeb8f54c078314c2065ee649a7241f46b9d8e418e1a9581ba0546657d7aa3a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.1"
|
version = "2.3.1"
|
||||||
|
@ -2289,6 +2490,26 @@ dependencies = [
|
||||||
"num",
|
"num",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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",
|
||||||
|
"syn 2.0.92",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -2329,6 +2550,12 @@ dependencies = [
|
||||||
"universal-hash",
|
"universal-hash",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "powerfmt"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ppv-lite86"
|
name = "ppv-lite86"
|
||||||
version = "0.2.20"
|
version = "0.2.20"
|
||||||
|
@ -2338,6 +2565,16 @@ dependencies = [
|
||||||
"zerocopy",
|
"zerocopy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prettyplease"
|
||||||
|
version = "0.2.25"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"syn 2.0.92",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro-crate"
|
name = "proc-macro-crate"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -2365,6 +2602,29 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost"
|
||||||
|
version = "0.13.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2c0fef6c4230e4ccf618a35c59d7ede15dea37de8427500f50aff708806e42ec"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"prost-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "prost-derive"
|
||||||
|
version = "0.13.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "157c5a9d7ea5c2ed2d9fb8f495b64759f7816c7eaea54ba3978f0d63000162e3"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"itertools 0.12.1",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.92",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "qstring"
|
name = "qstring"
|
||||||
version = "0.7.2"
|
version = "0.7.2"
|
||||||
|
@ -2518,6 +2778,7 @@ dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"rustls",
|
"rustls",
|
||||||
|
"rustls-native-certs",
|
||||||
"rustls-pemfile",
|
"rustls-pemfile",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
@ -2551,6 +2812,16 @@ dependencies = [
|
||||||
"thiserror 1.0.69",
|
"thiserror 1.0.69",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rfc6979"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
|
||||||
|
dependencies = [
|
||||||
|
"hmac 0.12.1",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.17.8"
|
version = "0.17.8"
|
||||||
|
@ -2602,6 +2873,18 @@ dependencies = [
|
||||||
"sct",
|
"sct",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-native-certs"
|
||||||
|
version = "0.6.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00"
|
||||||
|
dependencies = [
|
||||||
|
"openssl-probe",
|
||||||
|
"rustls-pemfile",
|
||||||
|
"schannel",
|
||||||
|
"security-framework",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls-pemfile"
|
name = "rustls-pemfile"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -2621,12 +2904,36 @@ dependencies = [
|
||||||
"untrusted",
|
"untrusted",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustversion"
|
||||||
|
version = "1.0.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
|
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.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
|
||||||
|
dependencies = [
|
||||||
|
"windows-sys 0.59.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scopeguard"
|
name = "scopeguard"
|
||||||
version = "1.2.0"
|
version = "1.2.0"
|
||||||
|
@ -2663,6 +2970,29 @@ dependencies = [
|
||||||
"zeroize",
|
"zeroize",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[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.12.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2"
|
||||||
|
dependencies = [
|
||||||
|
"core-foundation-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.24"
|
version = "1.0.24"
|
||||||
|
@ -2710,6 +3040,17 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_repr"
|
||||||
|
version = "0.1.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.92",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.8"
|
version = "0.6.8"
|
||||||
|
@ -2815,6 +3156,7 @@ version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"digest 0.10.7",
|
||||||
"rand_core 0.6.4",
|
"rand_core 0.6.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -4429,6 +4771,21 @@ version = "2.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle-encoding"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945"
|
||||||
|
dependencies = [
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "subtle-ng"
|
||||||
|
version = "2.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.109"
|
version = "1.0.109"
|
||||||
|
@ -4498,6 +4855,98 @@ dependencies = [
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tendermint"
|
||||||
|
version = "0.40.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d9703e34d940c2a293804752555107f8dbe2b84ec4c6dd5203831235868105d2"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"digest 0.10.7",
|
||||||
|
"ed25519 2.2.3",
|
||||||
|
"ed25519-consensus",
|
||||||
|
"flex-error",
|
||||||
|
"futures",
|
||||||
|
"k256",
|
||||||
|
"num-traits",
|
||||||
|
"once_cell",
|
||||||
|
"prost",
|
||||||
|
"ripemd",
|
||||||
|
"serde",
|
||||||
|
"serde_bytes",
|
||||||
|
"serde_json",
|
||||||
|
"serde_repr",
|
||||||
|
"sha2 0.10.8",
|
||||||
|
"signature 2.2.0",
|
||||||
|
"subtle",
|
||||||
|
"subtle-encoding",
|
||||||
|
"tendermint-proto",
|
||||||
|
"time",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tendermint-config"
|
||||||
|
version = "0.40.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "89cc3ea9a39b7ee34eefcff771cc067ecaa0c988c1c5ac08defd878471a06f76"
|
||||||
|
dependencies = [
|
||||||
|
"flex-error",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tendermint",
|
||||||
|
"toml 0.8.19",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tendermint-proto"
|
||||||
|
version = "0.40.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ae9e1705aa0fa5ecb2c6aa7fb78c2313c4a31158ea5f02048bf318f849352eb"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"flex-error",
|
||||||
|
"prost",
|
||||||
|
"serde",
|
||||||
|
"serde_bytes",
|
||||||
|
"subtle-encoding",
|
||||||
|
"time",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tendermint-rpc"
|
||||||
|
version = "0.40.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "835a52aa504c63ec05519e31348d3f4ba2fe79493c588e2cad5323d5e81b161a"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"bytes",
|
||||||
|
"flex-error",
|
||||||
|
"futures",
|
||||||
|
"getrandom 0.2.15",
|
||||||
|
"peg",
|
||||||
|
"pin-project",
|
||||||
|
"rand 0.8.5",
|
||||||
|
"reqwest",
|
||||||
|
"semver",
|
||||||
|
"serde",
|
||||||
|
"serde_bytes",
|
||||||
|
"serde_json",
|
||||||
|
"subtle",
|
||||||
|
"subtle-encoding",
|
||||||
|
"tendermint",
|
||||||
|
"tendermint-config",
|
||||||
|
"tendermint-proto",
|
||||||
|
"thiserror 1.0.69",
|
||||||
|
"time",
|
||||||
|
"tokio",
|
||||||
|
"tracing",
|
||||||
|
"url",
|
||||||
|
"uuid",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.69"
|
version = "1.0.69"
|
||||||
|
@ -4538,6 +4987,36 @@ dependencies = [
|
||||||
"syn 2.0.92",
|
"syn 2.0.92",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.3.37"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
|
||||||
|
dependencies = [
|
||||||
|
"deranged",
|
||||||
|
"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.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
|
||||||
|
dependencies = [
|
||||||
|
"num-conv",
|
||||||
|
"time-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinystr"
|
name = "tinystr"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
@ -4565,9 +5044,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.42.0"
|
version = "1.43.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551"
|
checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -4583,9 +5062,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-macros"
|
name = "tokio-macros"
|
||||||
version = "2.4.0"
|
version = "2.5.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -4771,6 +5250,12 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uuid"
|
||||||
|
version = "1.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vcpkg"
|
name = "vcpkg"
|
||||||
version = "0.2.15"
|
version = "0.2.15"
|
||||||
|
@ -4789,6 +5274,16 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
|
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]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
@ -4909,6 +5404,15 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
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]]
|
[[package]]
|
||||||
name = "winapi-x86_64-pc-windows-gnu"
|
name = "winapi-x86_64-pc-windows-gnu"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
|
|
@ -5,7 +5,7 @@ members = [
|
||||||
"crates/icepick",
|
"crates/icepick",
|
||||||
"crates/icepick-module",
|
"crates/icepick-module",
|
||||||
"crates/builtins/icepick-internal",
|
"crates/builtins/icepick-internal",
|
||||||
"crates/by-chain/icepick-solana",
|
"crates/by-chain/icepick-solana", "crates/by-chain/icepick-cosmos",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "icepick-cosmos"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
bon = "3.3.2"
|
||||||
|
cosmrs = { version = "0.21.0", features = ["rpc", "tokio"] }
|
||||||
|
icepick-module = { version = "0.1.0", path = "../../icepick-module" }
|
||||||
|
serde.workspace = true
|
||||||
|
serde_json.workspace = true
|
||||||
|
thiserror = "2.0.9"
|
||||||
|
tokio = { version = "1.43.0", features = ["rt"] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
cosmrs = { version = "0.21.0", features = ["dev"] }
|
|
@ -0,0 +1,199 @@
|
||||||
|
use bon::{bon, Builder};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, Builder)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Bip44Config {
|
||||||
|
pub coin_type: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: Are `public` variants used?
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Bech32Config {
|
||||||
|
#[serde(rename = "bech32PrefixAccAddress")]
|
||||||
|
pub account_address_prefix: String,
|
||||||
|
|
||||||
|
#[serde(rename = "bech32PrefixAccPub")]
|
||||||
|
pub account_address_public_prefix: String,
|
||||||
|
|
||||||
|
#[serde(rename = "bech32PrefixValOper")]
|
||||||
|
pub validator_operator_prefix: String,
|
||||||
|
|
||||||
|
#[serde(rename = "bech32PrefixValPub")]
|
||||||
|
pub validator_operator_public_prefix: String,
|
||||||
|
|
||||||
|
#[serde(rename = "bech32PrefixConsAddr")]
|
||||||
|
pub consensus_node_prefix: String,
|
||||||
|
|
||||||
|
#[serde(rename = "bech32PrefixConsPub")]
|
||||||
|
pub consensus_node_public_prefix: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bon]
|
||||||
|
impl Bech32Config {
|
||||||
|
#[builder]
|
||||||
|
fn new(
|
||||||
|
account_address_prefix: &'static str,
|
||||||
|
account_address_public_prefix: &'static str,
|
||||||
|
validator_operator_prefix: &'static str,
|
||||||
|
validator_operator_public_prefix: &'static str,
|
||||||
|
consensus_node_prefix: &'static str,
|
||||||
|
consensus_node_public_prefix: &'static str,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
account_address_prefix: account_address_prefix.to_string(),
|
||||||
|
account_address_public_prefix: account_address_public_prefix.to_string(),
|
||||||
|
validator_operator_prefix: validator_operator_prefix.to_string(),
|
||||||
|
validator_operator_public_prefix: validator_operator_public_prefix.to_string(),
|
||||||
|
consensus_node_prefix: consensus_node_prefix.to_string(),
|
||||||
|
consensus_node_public_prefix: consensus_node_public_prefix.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, Builder)]
|
||||||
|
pub struct GasPriceStep {
|
||||||
|
pub low: f64,
|
||||||
|
pub average: f64,
|
||||||
|
pub high: f64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Currency {
|
||||||
|
pub coin_denom: String,
|
||||||
|
pub coin_minimal_denom: String,
|
||||||
|
pub coin_decimals: u8,
|
||||||
|
pub coin_gecko_id: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bon]
|
||||||
|
impl Currency {
|
||||||
|
#[builder]
|
||||||
|
fn new(
|
||||||
|
coin_denom: &'static str,
|
||||||
|
coin_minimal_denom: &'static str,
|
||||||
|
coin_decimals: u8,
|
||||||
|
coin_gecko_id: &'static str,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
coin_denom: coin_denom.to_string(),
|
||||||
|
coin_minimal_denom: coin_minimal_denom.to_string(),
|
||||||
|
coin_decimals,
|
||||||
|
coin_gecko_id: coin_gecko_id.to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, Builder)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct CurrencyWithGas {
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub currency: Currency,
|
||||||
|
|
||||||
|
pub gas_price_step: GasPriceStep,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Blockchain {
|
||||||
|
pub chain_name: String,
|
||||||
|
pub chain_id: String,
|
||||||
|
|
||||||
|
pub rpc_url: String,
|
||||||
|
pub rest_url: String,
|
||||||
|
|
||||||
|
pub explorer_url_format: String,
|
||||||
|
|
||||||
|
#[serde(rename = "bip44")]
|
||||||
|
pub bip44_config: Bip44Config,
|
||||||
|
|
||||||
|
#[serde(rename = "bech32Config")]
|
||||||
|
pub bech32_config: Bech32Config,
|
||||||
|
|
||||||
|
pub currencies: Vec<Currency>,
|
||||||
|
pub fee_currencies: Vec<CurrencyWithGas>,
|
||||||
|
|
||||||
|
pub gas_price_step: GasPriceStep,
|
||||||
|
|
||||||
|
pub stake_currency: Currency,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bon]
|
||||||
|
impl Blockchain {
|
||||||
|
#[builder]
|
||||||
|
fn new(
|
||||||
|
chain_id: &'static str,
|
||||||
|
chain_name: &'static str,
|
||||||
|
rpc_url: &'static str,
|
||||||
|
rest_url: &'static str,
|
||||||
|
explorer_url_format: &'static str,
|
||||||
|
bip44_config: Bip44Config,
|
||||||
|
bech32_config: Bech32Config,
|
||||||
|
currencies: &[Currency],
|
||||||
|
fee_currencies: &[CurrencyWithGas],
|
||||||
|
gas_price_step: GasPriceStep,
|
||||||
|
stake_currency: Currency,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
chain_id: chain_id.to_string(),
|
||||||
|
chain_name: chain_name.to_string(),
|
||||||
|
rpc_url: rpc_url.to_string(),
|
||||||
|
rest_url: rest_url.to_string(),
|
||||||
|
explorer_url_format: explorer_url_format.to_string(),
|
||||||
|
bip44_config,
|
||||||
|
bech32_config,
|
||||||
|
currencies: currencies.to_vec(),
|
||||||
|
fee_currencies: fee_currencies.to_vec(),
|
||||||
|
gas_price_step,
|
||||||
|
stake_currency,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_chains() -> Vec<Blockchain> {
|
||||||
|
let mut chains = vec![];
|
||||||
|
|
||||||
|
let tkyve = Currency::builder()
|
||||||
|
.coin_denom("KYVE")
|
||||||
|
.coin_minimal_denom("tkyve")
|
||||||
|
.coin_decimals(6)
|
||||||
|
.coin_gecko_id("unknown")
|
||||||
|
.build();
|
||||||
|
// NOTE: high is listed as 0.03 on devnet, but simulating tx actually cost 30915 tkyve.
|
||||||
|
let tkyve_gas = GasPriceStep::builder()
|
||||||
|
.low(0.01)
|
||||||
|
.average(0.05)
|
||||||
|
.high(0.1)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
chains.push(
|
||||||
|
Blockchain::builder()
|
||||||
|
.chain_id("korellia-2")
|
||||||
|
.chain_name("korellia")
|
||||||
|
.rpc_url("https://rpc.korellia.kyve.network")
|
||||||
|
.rest_url("https://api.korellia.kyve.network")
|
||||||
|
.explorer_url_format("https://explorer.kyve.network/korellia/tx/%s")
|
||||||
|
.bip44_config(Bip44Config::builder().coin_type(118).build())
|
||||||
|
.bech32_config(
|
||||||
|
Bech32Config::builder()
|
||||||
|
.account_address_prefix("kyve")
|
||||||
|
.account_address_public_prefix("kyvepub")
|
||||||
|
.validator_operator_prefix("kyvevaloper")
|
||||||
|
.validator_operator_public_prefix("kyvevaloperpub")
|
||||||
|
.consensus_node_prefix("kyvevalcons")
|
||||||
|
.consensus_node_public_prefix("kyvevalconspub")
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.currencies(&[tkyve.clone()])
|
||||||
|
.fee_currencies(&[CurrencyWithGas::builder()
|
||||||
|
.currency(tkyve.clone())
|
||||||
|
.gas_price_step(tkyve_gas.clone())
|
||||||
|
.build()])
|
||||||
|
.gas_price_step(tkyve_gas.clone())
|
||||||
|
.stake_currency(tkyve.clone())
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
chains
|
||||||
|
}
|
|
@ -0,0 +1,578 @@
|
||||||
|
use cosmrs::{
|
||||||
|
proto::prost::Message,
|
||||||
|
rpc::Client,
|
||||||
|
tx::{self, BodyBuilder, Fee, Msg, SignDoc, SignerInfo},
|
||||||
|
AccountId, Any,
|
||||||
|
};
|
||||||
|
use icepick_module::Module;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
use cosmrs::crypto::secp256k1;
|
||||||
|
|
||||||
|
mod coin_denoms;
|
||||||
|
mod remote_serde;
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetChainInfo {
|
||||||
|
chain_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GenerateWallet {
|
||||||
|
account: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetWalletAddress {
|
||||||
|
address_prefix: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct GetAccountInfo {
|
||||||
|
account_id: String,
|
||||||
|
|
||||||
|
blockchain_config: coin_denoms::Blockchain,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct AwaitFunds {
|
||||||
|
address: String,
|
||||||
|
denom_name: String,
|
||||||
|
amount: String,
|
||||||
|
|
||||||
|
blockchain_config: coin_denoms::Blockchain,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Transfer {
|
||||||
|
amount: String,
|
||||||
|
denom: String,
|
||||||
|
to_address: String,
|
||||||
|
from_account: Option<String>,
|
||||||
|
from_address: String,
|
||||||
|
// TODO: find a way to simulate transaction and calculate gas necessary
|
||||||
|
// for now, 0.01KYVE seems to be a reasonable mainnet number?
|
||||||
|
// for testing purposes, i'm gonna go much lower. 0.0001.
|
||||||
|
gas: Option<String>,
|
||||||
|
|
||||||
|
blockchain_config: coin_denoms::Blockchain,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Sign {
|
||||||
|
fee: remote_serde::Fee,
|
||||||
|
tx_messages: Vec<Any>,
|
||||||
|
account_number: String,
|
||||||
|
sequence_number: String,
|
||||||
|
|
||||||
|
blockchain_config: coin_denoms::Blockchain,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
|
pub struct Broadcast {
|
||||||
|
transaction: Vec<u8>,
|
||||||
|
|
||||||
|
blockchain_config: coin_denoms::Blockchain,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Request {
|
||||||
|
derived_keys: Option<Vec<[u8; 32]>>,
|
||||||
|
|
||||||
|
#[serde(flatten)]
|
||||||
|
operation: Operation,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(tag = "operation", content = "values", rename_all = "kebab-case")]
|
||||||
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
pub enum Operation {
|
||||||
|
GetChainInfo(GetChainInfo),
|
||||||
|
GenerateWallet(GenerateWallet),
|
||||||
|
GetWalletAddress(GetWalletAddress),
|
||||||
|
GetAccountInfo(GetAccountInfo),
|
||||||
|
AwaitFunds(AwaitFunds),
|
||||||
|
Transfer(Transfer),
|
||||||
|
Sign(Sign),
|
||||||
|
Broadcast(Broadcast),
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run_async<F: std::future::Future>(f: F) -> F::Output {
|
||||||
|
tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.worker_threads(2)
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap()
|
||||||
|
.block_on(f)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn decode<T: cosmrs::proto::prost::Message + cosmrs::proto::prost::Name + std::default::Default>(
|
||||||
|
_type: &str,
|
||||||
|
value: &[u8],
|
||||||
|
) -> Result<T, String> {
|
||||||
|
// move past the first `/`.
|
||||||
|
let _type = &_type[1..];
|
||||||
|
let full_name = T::full_name();
|
||||||
|
if _type != full_name {
|
||||||
|
return Err(format!(
|
||||||
|
"given type {_type} does not match expected type {full_name}"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
T::decode(value).map_err(|e| e.to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn abci_query<
|
||||||
|
Response: cosmrs::proto::prost::Message + cosmrs::proto::prost::Name + std::default::Default,
|
||||||
|
>(
|
||||||
|
client: &(impl Client + Sync),
|
||||||
|
path: &'static str,
|
||||||
|
request_data: Option<&impl cosmrs::proto::prost::Message>,
|
||||||
|
height: Option<cosmrs::tendermint::block::Height>,
|
||||||
|
prove: bool,
|
||||||
|
) -> Result<Response, Box<dyn std::error::Error>> {
|
||||||
|
let data = request_data.map(Message::encode_to_vec).unwrap_or_default();
|
||||||
|
let response = client
|
||||||
|
.abci_query(Some(path.to_string()), data, height, prove)
|
||||||
|
.await?;
|
||||||
|
let parsed = Response::decode(&*response.value)?;
|
||||||
|
Ok(parsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Cosmos;
|
||||||
|
|
||||||
|
impl Module for Cosmos {
|
||||||
|
type Error = Error;
|
||||||
|
type Request = Request;
|
||||||
|
|
||||||
|
fn describe_operations() -> Vec<icepick_module::help::Operation> {
|
||||||
|
use icepick_module::help::*;
|
||||||
|
let account = Argument::builder()
|
||||||
|
.name("account")
|
||||||
|
.description("The derivation index for the account.")
|
||||||
|
.r#type(ArgumentType::Optional)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let address_prefix = Argument::builder()
|
||||||
|
.name("address_prefix")
|
||||||
|
.description("Prefix for the wallet (`cosmos`, `kyve`, etc.).")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
let get_chain_info = Operation::builder()
|
||||||
|
.name("get-chain-info")
|
||||||
|
.description("Get information for a given chain")
|
||||||
|
.build()
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("chain_name")
|
||||||
|
.description("Name of the blockchain")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let generate_wallet = Operation::builder()
|
||||||
|
.name("generate-wallet")
|
||||||
|
.description("Generate a wallet for the given account.")
|
||||||
|
.build()
|
||||||
|
.argument(&account);
|
||||||
|
|
||||||
|
let get_wallet_address = Operation::builder()
|
||||||
|
.name("get-wallet-address")
|
||||||
|
.description("Get the address for a given wallet.")
|
||||||
|
.build()
|
||||||
|
.argument(&address_prefix);
|
||||||
|
|
||||||
|
let get_account_info = Operation::builder()
|
||||||
|
.name("get-account-info")
|
||||||
|
.description("Get the account number and sequence number for an account.")
|
||||||
|
.build()
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("account_id")
|
||||||
|
.description("The account ID to get account information for.")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let await_funds = icepick_module::help::Operation {
|
||||||
|
name: "await-funds".to_string(),
|
||||||
|
description: "Await a minimum amount of funds in an account".to_string(),
|
||||||
|
arguments: vec![
|
||||||
|
Argument {
|
||||||
|
name: "address".to_string(),
|
||||||
|
description: "The address to monitor".to_string(),
|
||||||
|
r#type: ArgumentType::Required,
|
||||||
|
},
|
||||||
|
Argument {
|
||||||
|
name: "denom_name".to_string(),
|
||||||
|
description: "The denomination of coin to monitor".to_string(),
|
||||||
|
r#type: ArgumentType::Required,
|
||||||
|
},
|
||||||
|
Argument {
|
||||||
|
name: "amount".to_string(),
|
||||||
|
description: "The amount of the minimum denomination to await".to_string(),
|
||||||
|
r#type: ArgumentType::Required,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
let transfer = Operation::builder()
|
||||||
|
.name("transfer")
|
||||||
|
.description("Transfer coins from one address to another.")
|
||||||
|
.build()
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("from_address")
|
||||||
|
.description("The address to send coins from.")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("to_address")
|
||||||
|
.description("The address to send coins to.")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("amount")
|
||||||
|
.description("The amount of coins to send.")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("denom")
|
||||||
|
.description("The denomination of coin to send.")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("gas")
|
||||||
|
.description("The amount of gas to supply.")
|
||||||
|
.r#type(ArgumentType::Optional)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let sign = Operation::builder()
|
||||||
|
.name("sign")
|
||||||
|
.description("Sign a previously-generated transaction.")
|
||||||
|
.build()
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("account_number")
|
||||||
|
.description("The sequence number for the given public key")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
.argument(
|
||||||
|
&Argument::builder()
|
||||||
|
.name("sequence_number")
|
||||||
|
.description("The account number for the given public key")
|
||||||
|
.r#type(ArgumentType::Required)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
|
|
||||||
|
let broadcast = Operation::builder()
|
||||||
|
.name("broadcast")
|
||||||
|
.description("Broadcast a transaction.")
|
||||||
|
.build();
|
||||||
|
|
||||||
|
vec![
|
||||||
|
get_chain_info,
|
||||||
|
generate_wallet,
|
||||||
|
get_wallet_address,
|
||||||
|
get_account_info,
|
||||||
|
await_funds,
|
||||||
|
transfer,
|
||||||
|
sign,
|
||||||
|
broadcast,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_request(request: Self::Request) -> Result<serde_json::Value, Self::Error> {
|
||||||
|
let Request {
|
||||||
|
operation,
|
||||||
|
derived_keys: _,
|
||||||
|
} = request;
|
||||||
|
|
||||||
|
match operation {
|
||||||
|
Operation::GetChainInfo(GetChainInfo { chain_name }) => {
|
||||||
|
let chains = coin_denoms::default_chains();
|
||||||
|
|
||||||
|
let chain = chains
|
||||||
|
.iter()
|
||||||
|
.find(|chain| chain.chain_name == chain_name || chain.chain_id == chain_name);
|
||||||
|
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"blockchain_config": chain,
|
||||||
|
},
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Operation::GenerateWallet(GenerateWallet { account }) => {
|
||||||
|
let account = u32::from_str(account.as_deref().unwrap_or("0")).unwrap();
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {},
|
||||||
|
"derivation_accounts": [(account | 1 << 31)],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Operation::GetWalletAddress(GetWalletAddress { address_prefix }) => {
|
||||||
|
// NOTE: panics if doesn't exist
|
||||||
|
let key = request.derived_keys.unwrap()[0];
|
||||||
|
let privkey = secp256k1::SigningKey::from_slice(&key).unwrap();
|
||||||
|
let pubkey = privkey.public_key();
|
||||||
|
let sender_account_id = pubkey.account_id(&address_prefix).unwrap();
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"pubkey": sender_account_id,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Operation::GetAccountInfo(GetAccountInfo {
|
||||||
|
account_id,
|
||||||
|
blockchain_config,
|
||||||
|
}) => {
|
||||||
|
use cosmrs::proto::cosmos::auth::v1beta1::*;
|
||||||
|
|
||||||
|
let response = run_async(async {
|
||||||
|
let client =
|
||||||
|
cosmrs::rpc::HttpClient::new(blockchain_config.rpc_url.as_str()).unwrap();
|
||||||
|
let query = QueryAccountRequest {
|
||||||
|
address: account_id,
|
||||||
|
};
|
||||||
|
let response: QueryAccountResponse = abci_query(
|
||||||
|
&client,
|
||||||
|
"/cosmos.auth.v1beta1.Query/Account",
|
||||||
|
Some(&query),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
response
|
||||||
|
});
|
||||||
|
let Any { type_url, value } = response.account.unwrap();
|
||||||
|
let account: BaseAccount = decode(&type_url, &value).unwrap();
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"account_number": account.account_number,
|
||||||
|
"sequence_number": account.sequence,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Operation::AwaitFunds(AwaitFunds {
|
||||||
|
address,
|
||||||
|
denom_name,
|
||||||
|
amount,
|
||||||
|
blockchain_config,
|
||||||
|
}) => {
|
||||||
|
use cosmrs::proto::cosmos::bank::v1beta1::*;
|
||||||
|
|
||||||
|
// Check if given denom is min denom or normal and adjust accordingly
|
||||||
|
let Some(relevant_denom) = blockchain_config.currencies.iter().find(|c| {
|
||||||
|
[&c.coin_denom, &c.coin_minimal_denom]
|
||||||
|
.iter()
|
||||||
|
.any(|name| **name == denom_name)
|
||||||
|
}) else {
|
||||||
|
panic!("{denom_name} not in {blockchain_config:?}");
|
||||||
|
};
|
||||||
|
|
||||||
|
let amount = f64::from_str(&amount).unwrap();
|
||||||
|
let adjusted_amount = if relevant_denom.coin_denom == denom_name {
|
||||||
|
amount * 10f64.powi(i32::from(relevant_denom.coin_decimals))
|
||||||
|
} else if relevant_denom.coin_minimal_denom == denom_name {
|
||||||
|
amount
|
||||||
|
} else {
|
||||||
|
unreachable!("broke invariant: check denom checker");
|
||||||
|
} as u128;
|
||||||
|
|
||||||
|
let coin = run_async(async {
|
||||||
|
let client =
|
||||||
|
cosmrs::rpc::HttpClient::new(blockchain_config.rpc_url.as_str()).unwrap();
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let response: QueryBalanceResponse = abci_query(
|
||||||
|
&client,
|
||||||
|
"/cosmos.bank.v1beta1.Query/Balance",
|
||||||
|
Some(&QueryBalanceRequest {
|
||||||
|
address: address.clone(),
|
||||||
|
denom: relevant_denom.coin_minimal_denom.clone(),
|
||||||
|
}),
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
if let Some(coin) = response.balance {
|
||||||
|
let amount = u128::from_str(&coin.amount).unwrap();
|
||||||
|
if amount >= adjusted_amount {
|
||||||
|
break coin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tokio::time::sleep(std::time::Duration::from_secs(10)).await;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let cosmrs::proto::cosmos::base::v1beta1::Coin { denom, amount } = coin;
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"balance": {
|
||||||
|
"denom": denom,
|
||||||
|
"amount": u128::from_str(&amount).unwrap(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Operation::Transfer(Transfer {
|
||||||
|
amount,
|
||||||
|
denom,
|
||||||
|
to_address,
|
||||||
|
from_account: _,
|
||||||
|
from_address,
|
||||||
|
gas: _,
|
||||||
|
blockchain_config,
|
||||||
|
}) => {
|
||||||
|
// Check if given denom is min denom or normal and adjust accordingly
|
||||||
|
let Some(relevant_denom) = blockchain_config.currencies.iter().find(|c| {
|
||||||
|
[&c.coin_denom, &c.coin_minimal_denom]
|
||||||
|
.iter()
|
||||||
|
.any(|name| **name == denom)
|
||||||
|
}) else {
|
||||||
|
panic!("{denom} not in {blockchain_config:?}");
|
||||||
|
};
|
||||||
|
|
||||||
|
let amount = f64::from_str(&amount).unwrap();
|
||||||
|
let adjusted_amount = if relevant_denom.coin_denom == denom {
|
||||||
|
amount * 10f64.powi(i32::from(relevant_denom.coin_decimals))
|
||||||
|
} else if relevant_denom.coin_minimal_denom == denom {
|
||||||
|
amount
|
||||||
|
} else {
|
||||||
|
unreachable!("broke invariant: check denom checker");
|
||||||
|
} as u128;
|
||||||
|
|
||||||
|
let from_id = AccountId::from_str(&from_address).unwrap();
|
||||||
|
let to_id = AccountId::from_str(&to_address).unwrap();
|
||||||
|
|
||||||
|
let coin = cosmrs::Coin {
|
||||||
|
denom: relevant_denom.coin_minimal_denom.parse().unwrap(),
|
||||||
|
amount: adjusted_amount,
|
||||||
|
};
|
||||||
|
|
||||||
|
let msg_send = cosmrs::bank::MsgSend {
|
||||||
|
from_address: from_id,
|
||||||
|
to_address: to_id,
|
||||||
|
amount: vec![coin.clone()],
|
||||||
|
}
|
||||||
|
.to_any()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let fee = Fee::from_amount_and_gas(
|
||||||
|
coin,
|
||||||
|
(blockchain_config.gas_price_step.high
|
||||||
|
* 10f64.powi(relevant_denom.coin_decimals as i32))
|
||||||
|
as u64,
|
||||||
|
);
|
||||||
|
|
||||||
|
#[allow(clippy::identity_op)]
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"fee": remote_serde::Fee::from(&fee),
|
||||||
|
// TODO: Body does not implement Serialize and
|
||||||
|
// needs to be constructed in Sign
|
||||||
|
"tx_messages": [msg_send],
|
||||||
|
// re-export, but in general this should be copied over
|
||||||
|
// using workflows
|
||||||
|
"blockchain_config": blockchain_config,
|
||||||
|
},
|
||||||
|
"derivation_accounts": [0u32 | 1 << 31],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Operation::Sign(Sign {
|
||||||
|
fee,
|
||||||
|
tx_messages,
|
||||||
|
account_number,
|
||||||
|
sequence_number,
|
||||||
|
blockchain_config,
|
||||||
|
}) => {
|
||||||
|
let key = request.derived_keys.unwrap()[0];
|
||||||
|
let privkey = secp256k1::SigningKey::from_slice(&key).unwrap();
|
||||||
|
|
||||||
|
let fee = cosmrs::tx::Fee::from(&fee);
|
||||||
|
let tx_body = BodyBuilder::new().msgs(tx_messages).finish();
|
||||||
|
|
||||||
|
// TODO: these should be gained by the `broadcast` workflow, similar to
|
||||||
|
// how nonce data is acquired in Solana
|
||||||
|
let account_number: u64 = account_number.parse().unwrap();
|
||||||
|
let sequence_number: u64 = sequence_number.parse().unwrap();
|
||||||
|
|
||||||
|
let auth_info =
|
||||||
|
SignerInfo::single_direct(Some(privkey.public_key()), sequence_number)
|
||||||
|
.auth_info(fee);
|
||||||
|
let sign_doc = SignDoc::new(
|
||||||
|
&tx_body,
|
||||||
|
&auth_info,
|
||||||
|
&blockchain_config.chain_id.parse().unwrap(),
|
||||||
|
account_number,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let signed_tx = sign_doc.sign(&privkey).unwrap();
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"transaction": signed_tx.to_bytes().unwrap(),
|
||||||
|
"blockchain_config": blockchain_config,
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
Operation::Broadcast(Broadcast {
|
||||||
|
transaction,
|
||||||
|
blockchain_config,
|
||||||
|
}) => {
|
||||||
|
let tx = tx::Raw::from_bytes(&transaction).unwrap();
|
||||||
|
|
||||||
|
let response = run_async(async {
|
||||||
|
let client =
|
||||||
|
cosmrs::rpc::HttpClient::new(blockchain_config.rpc_url.as_str()).unwrap();
|
||||||
|
|
||||||
|
// broadcast_tx_sync awaits CheckTx, so we know that, at the bare minimum, the
|
||||||
|
// transaction is valid.
|
||||||
|
//
|
||||||
|
// TODO: make this expect() into a keyfork_bug!(). An error in this area of
|
||||||
|
// code may represent a bug in either our code or the blockchain's code.
|
||||||
|
// We _should_ get an Err code if the error was with the transaction data, such
|
||||||
|
// as us being out of gas, or the transaction being malformed.
|
||||||
|
client
|
||||||
|
.broadcast_tx_sync(tx.to_bytes().unwrap())
|
||||||
|
.await
|
||||||
|
.expect("The server encountered a fatal error while processing the request")
|
||||||
|
});
|
||||||
|
match response.code {
|
||||||
|
cosmrs::tendermint::abci::Code::Ok => {
|
||||||
|
// attempt to get transaction URL / blockchain explorer URL
|
||||||
|
Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"status": "send_and_confirm",
|
||||||
|
"success": response.hash.to_string(),
|
||||||
|
"url": blockchain_config.explorer_url_format.replace("%s", response.hash.to_string().as_str()),
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
cosmrs::tendermint::abci::Code::Err(non_zero) => Ok(serde_json::json!({
|
||||||
|
"blob": {
|
||||||
|
"status": "send_and_confirm",
|
||||||
|
"error": response.log,
|
||||||
|
"error_code": non_zero.get(),
|
||||||
|
}
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
use icepick_module::Module;
|
||||||
|
use icepick_cosmos::Cosmos;
|
||||||
|
|
||||||
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
Cosmos::run_responder()
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Coin {
|
||||||
|
amount: [u8; 16],
|
||||||
|
denom: cosmrs::Denom,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&cosmrs::Coin> for Coin {
|
||||||
|
fn from(value: &cosmrs::Coin) -> Self {
|
||||||
|
let cosmrs::Coin { denom, amount } = value;
|
||||||
|
Coin {
|
||||||
|
denom: denom.clone(),
|
||||||
|
amount: amount.to_be_bytes(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Coin> for cosmrs::Coin {
|
||||||
|
fn from(value: &Coin) -> Self {
|
||||||
|
let Coin { amount, denom } = value;
|
||||||
|
cosmrs::Coin {
|
||||||
|
denom: denom.clone(),
|
||||||
|
amount: u128::from_be_bytes(*amount),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Fee {
|
||||||
|
amount: Vec<Coin>,
|
||||||
|
gas_limit: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&cosmrs::tx::Fee> for Fee {
|
||||||
|
fn from(value: &cosmrs::tx::Fee) -> Self {
|
||||||
|
let cosmrs::tx::Fee {
|
||||||
|
amount,
|
||||||
|
gas_limit,
|
||||||
|
payer,
|
||||||
|
granter,
|
||||||
|
} = value;
|
||||||
|
|
||||||
|
assert!(payer.is_none(), "unimplemented: payer");
|
||||||
|
assert!(granter.is_none(), "unimplemented: granter");
|
||||||
|
|
||||||
|
let amounts = amount.iter().map(Coin::from).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
Fee {
|
||||||
|
amount: amounts,
|
||||||
|
gas_limit: *gas_limit,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&Fee> for cosmrs::tx::Fee {
|
||||||
|
fn from(value: &Fee) -> Self {
|
||||||
|
let Fee { amount, gas_limit } = value;
|
||||||
|
let amounts = amount.iter().map(cosmrs::Coin::from).collect::<Vec<_>>();
|
||||||
|
|
||||||
|
cosmrs::tx::Fee {
|
||||||
|
amount: amounts,
|
||||||
|
gas_limit: *gas_limit,
|
||||||
|
payer: None,
|
||||||
|
granter: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,5 +4,6 @@ version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
bon = "3.3.2"
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
|
|
|
@ -16,6 +16,26 @@ pub mod help {
|
||||||
pub arguments: Vec<Argument>,
|
pub arguments: Vec<Argument>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bon::bon]
|
||||||
|
impl Operation {
|
||||||
|
|
||||||
|
#[builder]
|
||||||
|
pub fn new(name: &'static str, description: &'static str) -> Self {
|
||||||
|
Operation {
|
||||||
|
name: name.into(),
|
||||||
|
description: description.into(),
|
||||||
|
arguments: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Operation {
|
||||||
|
pub fn argument(mut self, arg: &Argument) -> Self {
|
||||||
|
self.arguments.push(arg.clone());
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
/// The context of whether a signature is signed, needs to be signed, or has been signed.
|
/// The context of whether a signature is signed, needs to be signed, or has been signed.
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone)]
|
||||||
|
@ -50,6 +70,19 @@ pub mod help {
|
||||||
/// The type of argument - this may affect how it displays in the frontend.
|
/// The type of argument - this may affect how it displays in the frontend.
|
||||||
pub r#type: ArgumentType,
|
pub r#type: ArgumentType,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[bon::bon]
|
||||||
|
impl Argument {
|
||||||
|
|
||||||
|
#[builder]
|
||||||
|
pub fn new(name: &'static str, description: &'static str, r#type: ArgumentType) -> Self {
|
||||||
|
Argument {
|
||||||
|
name: name.into(),
|
||||||
|
description: description.into(),
|
||||||
|
r#type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation methods for Icepick Modules, performed over command I/O using JSON.
|
/// Implementation methods for Icepick Modules, performed over command I/O using JSON.
|
||||||
|
|
|
@ -308,10 +308,17 @@ pub fn do_cli_thing() {
|
||||||
let mut input = child.stdin.take().unwrap();
|
let mut input = child.stdin.take().unwrap();
|
||||||
serde_json::to_writer(&mut input, &json).unwrap();
|
serde_json::to_writer(&mut input, &json).unwrap();
|
||||||
input.write_all(b"\n{\"operation\": \"exit\"}\n").unwrap();
|
input.write_all(b"\n{\"operation\": \"exit\"}\n").unwrap();
|
||||||
let output = child.wait_with_output().unwrap().stdout;
|
let output = child.wait_with_output().unwrap();
|
||||||
let json: serde_json::Value = serde_json::from_slice(&output).expect("valid json");
|
let stdout = &output.stdout;
|
||||||
let json_as_str = serde_json::to_string(&json).unwrap();
|
if output.status.success() {
|
||||||
println!("{json_as_str}");
|
let json: serde_json::Value =
|
||||||
|
serde_json::from_slice(stdout).expect("valid json");
|
||||||
|
let json_as_str = serde_json::to_string(&json).unwrap();
|
||||||
|
println!("{json_as_str}");
|
||||||
|
} else {
|
||||||
|
eprintln!("Error while invoking operation, check logs");
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,7 +155,7 @@ impl Workflow {
|
||||||
// Check if we have the keys we want to pass into the module.
|
// Check if we have the keys we want to pass into the module.
|
||||||
for in_memory_name in step.inputs.values() {
|
for in_memory_name in step.inputs.values() {
|
||||||
if !data.contains(in_memory_name) && !step.values.contains_key(in_memory_name) {
|
if !data.contains(in_memory_name) && !step.values.contains_key(in_memory_name) {
|
||||||
panic!("Failed simulation: step #{step_index} ({step_type}): missing value {in_memory_name}");
|
eprintln!("Failed simulation: step #{step_index} ({step_type}): missing value {in_memory_name}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -220,3 +220,8 @@ type = "internal-save-file"
|
||||||
|
|
||||||
values = { filename = "transaction.json" }
|
values = { filename = "transaction.json" }
|
||||||
inputs = { transaction = "signed_transaction" }
|
inputs = { transaction = "signed_transaction" }
|
||||||
|
|
||||||
|
[[module]]
|
||||||
|
name = "cosmos"
|
||||||
|
derivation_prefix = "m/44'/118'/0'"
|
||||||
|
algorithm = "Secp256k1"
|
||||||
|
|
Loading…
Reference in New Issue