diff --git a/Cargo.lock b/Cargo.lock
index da5fd8b..3ce7064 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -159,15 +159,66 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
+[[package]]
+name = "alloy"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2e2a5d689ccd182f1d138a61f081841b905034e0089f5278f6c200f2bcdab00a"
+dependencies = [
+ "alloy-consensus",
+ "alloy-core",
+ "alloy-eips",
+ "alloy-genesis",
+ "alloy-serde",
+ "alloy-trie",
+]
+
+[[package]]
+name = "alloy-consensus"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d213580c17d239ae83c0d897ac3315db7cda83d2d4936a9823cc3517552f2e24"
+dependencies = [
+ "alloy-eips",
+ "alloy-primitives 1.4.1",
+ "alloy-rlp",
+ "alloy-serde",
+ "alloy-trie",
+ "alloy-tx-macros",
+ "auto_impl",
+ "c-kzg",
+ "derive_more 2.0.1",
+ "either",
+ "k256",
+ "once_cell",
+ "secp256k1 0.30.0",
+ "serde",
+ "serde_with",
+ "thiserror 2.0.16",
+]
+
+[[package]]
+name = "alloy-core"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5ca96214615ec8cf3fa2a54b32f486eb49100ca7fe7eb0b8c1137cd316e7250a"
+dependencies = [
+ "alloy-dyn-abi 1.4.1",
+ "alloy-json-abi 1.4.1",
+ "alloy-primitives 1.4.1",
+ "alloy-rlp",
+ "alloy-sol-types 1.4.1",
+]
+
[[package]]
name = "alloy-dyn-abi"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf69d3061e2e908a4370bda5d8d6529d5080232776975489eec0b49ce971027e"
dependencies = [
- "alloy-json-abi",
+ "alloy-json-abi 0.8.26",
"alloy-primitives 0.8.26",
- "alloy-sol-type-parser",
+ "alloy-sol-type-parser 0.8.26",
"alloy-sol-types 0.8.26",
"const-hex",
"itoa",
@@ -176,6 +227,96 @@ dependencies = [
"winnow",
]
+[[package]]
+name = "alloy-dyn-abi"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdff496dd4e98a81f4861e66f7eaf5f2488971848bb42d9c892f871730245c8"
+dependencies = [
+ "alloy-json-abi 1.4.1",
+ "alloy-primitives 1.4.1",
+ "alloy-sol-type-parser 1.4.1",
+ "alloy-sol-types 1.4.1",
+ "itoa",
+ "serde",
+ "serde_json",
+ "winnow",
+]
+
+[[package]]
+name = "alloy-eip2124"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "741bdd7499908b3aa0b159bba11e71c8cddd009a2c2eb7a06e825f1ec87900a5"
+dependencies = [
+ "alloy-primitives 1.4.1",
+ "alloy-rlp",
+ "crc",
+ "serde",
+ "thiserror 2.0.16",
+]
+
+[[package]]
+name = "alloy-eip2930"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9441120fa82df73e8959ae0e4ab8ade03de2aaae61be313fbf5746277847ce25"
+dependencies = [
+ "alloy-primitives 1.4.1",
+ "alloy-rlp",
+ "borsh",
+ "serde",
+]
+
+[[package]]
+name = "alloy-eip7702"
+version = "0.6.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2919c5a56a1007492da313e7a3b6d45ef5edc5d33416fdec63c0d7a2702a0d20"
+dependencies = [
+ "alloy-primitives 1.4.1",
+ "alloy-rlp",
+ "borsh",
+ "serde",
+ "thiserror 2.0.16",
+]
+
+[[package]]
+name = "alloy-eips"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2a15b4b0f6bab47aae017d52bb5a739bda381553c09fb9918b7172721ef5f5de"
+dependencies = [
+ "alloy-eip2124",
+ "alloy-eip2930",
+ "alloy-eip7702",
+ "alloy-primitives 1.4.1",
+ "alloy-rlp",
+ "alloy-serde",
+ "auto_impl",
+ "c-kzg",
+ "derive_more 2.0.1",
+ "either",
+ "serde",
+ "serde_with",
+ "sha2 0.10.9",
+ "thiserror 2.0.16",
+]
+
+[[package]]
+name = "alloy-genesis"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "33ba1cbc25a07e0142e8875fcbe80e1fdb02be8160ae186b90f4b9a69a72ed2b"
+dependencies = [
+ "alloy-eips",
+ "alloy-primitives 1.4.1",
+ "alloy-serde",
+ "alloy-trie",
+ "serde",
+ "serde_with",
+]
+
[[package]]
name = "alloy-json-abi"
version = "0.8.26"
@@ -183,7 +324,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4584e3641181ff073e9d5bec5b3b8f78f9749d9fb108a1cfbc4399a4a139c72a"
dependencies = [
"alloy-primitives 0.8.26",
- "alloy-sol-type-parser",
+ "alloy-sol-type-parser 0.8.26",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "alloy-json-abi"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5513d5e6bd1cba6bdcf5373470f559f320c05c8c59493b6e98912fbe6733943f"
+dependencies = [
+ "alloy-primitives 1.4.1",
+ "alloy-sol-type-parser 1.4.1",
"serde",
"serde_json",
]
@@ -257,16 +410,66 @@ dependencies = [
"tiny-keccak",
]
+[[package]]
+name = "alloy-primitives"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "355bf68a433e0fd7f7d33d5a9fc2583fde70bf5c530f63b80845f8da5505cf28"
+dependencies = [
+ "alloy-rlp",
+ "bytes",
+ "cfg-if",
+ "const-hex",
+ "derive_more 2.0.1",
+ "foldhash 0.2.0",
+ "hashbrown 0.16.0",
+ "indexmap 2.11.0",
+ "itoa",
+ "k256",
+ "keccak-asm",
+ "paste",
+ "proptest",
+ "rand 0.9.2",
+ "ruint",
+ "rustc-hash 2.1.1",
+ "serde",
+ "sha3",
+ "tiny-keccak",
+]
+
[[package]]
name = "alloy-rlp"
version = "0.3.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f70d83b765fdc080dbcd4f4db70d8d23fe4761f2f02ebfa9146b833900634b4"
dependencies = [
+ "alloy-rlp-derive",
"arrayvec 0.7.6",
"bytes",
]
+[[package]]
+name = "alloy-rlp-derive"
+version = "0.3.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64b728d511962dda67c1bc7ea7c03736ec275ed2cf4c35d9585298ac9ccf3b73"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
+[[package]]
+name = "alloy-serde"
+version = "1.0.30"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f1b3b1078b8775077525bc9fe9f6577e815ceaecd6c412a4f3b4d8aa2836e8f6"
+dependencies = [
+ "alloy-primitives 1.4.1",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "alloy-sol-macro"
version = "0.4.2"
@@ -312,6 +515,20 @@ dependencies = [
"syn 2.0.106",
]
+[[package]]
+name = "alloy-sol-macro"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f3ce480400051b5217f19d6e9a82d9010cdde20f1ae9c00d53591e4a1afbb312"
+dependencies = [
+ "alloy-sol-macro-expander 1.4.1",
+ "alloy-sol-macro-input 1.4.1",
+ "proc-macro-error2",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
[[package]]
name = "alloy-sol-macro-expander"
version = "0.7.7"
@@ -348,6 +565,24 @@ dependencies = [
"tiny-keccak",
]
+[[package]]
+name = "alloy-sol-macro-expander"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6d792e205ed3b72f795a8044c52877d2e6b6e9b1d13f431478121d8d4eaa9028"
+dependencies = [
+ "alloy-sol-macro-input 1.4.1",
+ "const-hex",
+ "heck 0.5.0",
+ "indexmap 2.11.0",
+ "proc-macro-error2",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "syn-solidity 1.4.1",
+ "tiny-keccak",
+]
+
[[package]]
name = "alloy-sol-macro-input"
version = "0.7.7"
@@ -379,6 +614,22 @@ dependencies = [
"syn-solidity 0.8.26",
]
+[[package]]
+name = "alloy-sol-macro-input"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bd1247a8f90b465ef3f1207627547ec16940c35597875cdc09c49d58b19693c"
+dependencies = [
+ "const-hex",
+ "dunce",
+ "heck 0.5.0",
+ "macro-string",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+ "syn-solidity 1.4.1",
+]
+
[[package]]
name = "alloy-sol-type-parser"
version = "0.8.26"
@@ -389,6 +640,16 @@ dependencies = [
"winnow",
]
+[[package]]
+name = "alloy-sol-type-parser"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "954d1b2533b9b2c7959652df3076954ecb1122a28cc740aa84e7b0a49f6ac0a9"
+dependencies = [
+ "serde",
+ "winnow",
+]
+
[[package]]
name = "alloy-sol-types"
version = "0.4.2"
@@ -418,13 +679,53 @@ version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e960c4b52508ef2ae1e37cae5058e905e9ae099b107900067a503f8c454036f"
dependencies = [
- "alloy-json-abi",
+ "alloy-json-abi 0.8.26",
"alloy-primitives 0.8.26",
"alloy-sol-macro 0.8.26",
"const-hex",
"serde",
]
+[[package]]
+name = "alloy-sol-types"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70319350969a3af119da6fb3e9bddb1bce66c9ea933600cb297c8b1850ad2a3c"
+dependencies = [
+ "alloy-json-abi 1.4.1",
+ "alloy-primitives 1.4.1",
+ "alloy-sol-macro 1.4.1",
+ "serde",
+]
+
+[[package]]
+name = "alloy-trie"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3412d52bb97c6c6cc27ccc28d4e6e8cf605469101193b50b0bd5813b1f990b5"
+dependencies = [
+ "alloy-primitives 1.4.1",
+ "alloy-rlp",
+ "arrayvec 0.7.6",
+ "derive_more 2.0.1",
+ "nybbles",
+ "serde",
+ "smallvec",
+ "tracing",
+]
+
+[[package]]
+name = "alloy-tx-macros"
+version = "1.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ccf423f6de62e8ce1d6c7a11fb7508ae3536d02e0d68aaeb05c8669337d0937"
+dependencies = [
+ "darling 0.21.3",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
[[package]]
name = "always-assert"
version = "0.1.3"
@@ -1731,7 +2032,7 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43d193de1f7487df1914d3a568b772458861d33f9c54249612cc2893d6915054"
dependencies = [
- "bitcoin_hashes",
+ "bitcoin_hashes 0.13.0",
"serde",
"unicode-normalization",
]
@@ -1757,6 +2058,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9425c3bf7089c983facbae04de54513cce73b41c7f9ff8c845b54e7bc64ebbfb"
+[[package]]
+name = "bitcoin-io"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b47c4ab7a93edb0c7198c5535ed9b52b63095f4e9b45279c6736cec4b856baf"
+
[[package]]
name = "bitcoin_hashes"
version = "0.13.0"
@@ -1764,7 +2071,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1930a4dabfebb8d7d9992db18ebe3ae2876f0a305fab206fd168df931ede293b"
dependencies = [
"bitcoin-internals",
- "hex-conservative",
+ "hex-conservative 0.1.2",
+]
+
+[[package]]
+name = "bitcoin_hashes"
+version = "0.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb18c03d0db0247e147a21a6faafd5a7eb851c743db062de72018b6b7e8e4d16"
+dependencies = [
+ "bitcoin-io",
+ "hex-conservative 0.2.1",
]
[[package]]
@@ -1895,6 +2212,18 @@ dependencies = [
"piper",
]
+[[package]]
+name = "blst"
+version = "0.3.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcdb4c7013139a150f9fc55d123186dbfaba0d912817466282c73ac49e71fb45"
+dependencies = [
+ "cc",
+ "glob",
+ "threadpool",
+ "zeroize",
+]
+
[[package]]
name = "borsh"
version = "1.5.7"
@@ -2305,6 +2634,21 @@ dependencies = [
"pkg-config",
]
+[[package]]
+name = "c-kzg"
+version = "2.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e00bf4b112b07b505472dbefd19e37e53307e2bfed5a79e0cc161d58ccd0e687"
+dependencies = [
+ "blst",
+ "cc",
+ "glob",
+ "hex",
+ "libc",
+ "once_cell",
+ "serde",
+]
+
[[package]]
name = "c2-chacha"
version = "0.3.3"
@@ -3875,6 +4219,16 @@ dependencies = [
"darling_macro 0.20.11",
]
+[[package]]
+name = "darling"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
+dependencies = [
+ "darling_core 0.21.3",
+ "darling_macro 0.21.3",
+]
+
[[package]]
name = "darling_core"
version = "0.14.4"
@@ -3903,6 +4257,20 @@ dependencies = [
"syn 2.0.106",
]
+[[package]]
+name = "darling_core"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim 0.11.1",
+ "syn 2.0.106",
+]
+
[[package]]
name = "darling_macro"
version = "0.14.4"
@@ -3925,6 +4293,17 @@ dependencies = [
"syn 2.0.106",
]
+[[package]]
+name = "darling_macro"
+version = "0.21.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
+dependencies = [
+ "darling_core 0.21.3",
+ "quote",
+ "syn 2.0.106",
+]
+
[[package]]
name = "dashmap"
version = "5.5.3"
@@ -4024,6 +4403,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc"
dependencies = [
"powerfmt",
+ "serde",
]
[[package]]
@@ -4521,7 +4901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -6198,6 +6578,16 @@ dependencies = [
"serde",
]
+[[package]]
+name = "hashbrown"
+version = "0.16.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
+dependencies = [
+ "foldhash 0.2.0",
+ "serde",
+]
+
[[package]]
name = "hashlink"
version = "0.8.4"
@@ -6249,6 +6639,15 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "212ab92002354b4819390025006c897e8140934349e8635c9b077f47b4dcbd20"
+[[package]]
+name = "hex-conservative"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5313b072ce3c597065a808dbf612c4c8e8590bdbf8b579508bf7a762c5eae6cd"
+dependencies = [
+ "arrayvec 0.7.6",
+]
+
[[package]]
name = "hex-literal"
version = "0.4.1"
@@ -7618,7 +8017,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
- "windows-targets 0.48.5",
+ "windows-targets 0.53.3",
]
[[package]]
@@ -9435,12 +9834,26 @@ version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d"
dependencies = [
- "proc-macro-crate 1.1.3",
+ "proc-macro-crate 3.3.0",
"proc-macro2",
"quote",
"syn 2.0.106",
]
+[[package]]
+name = "nybbles"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa11e84403164a9f12982ab728f3c67c6fd4ab5b5f0254ffc217bdbd3b28ab0"
+dependencies = [
+ "alloy-rlp",
+ "cfg-if",
+ "proptest",
+ "ruint",
+ "serde",
+ "smallvec",
+]
+
[[package]]
name = "objc"
version = "0.2.7"
@@ -10927,7 +11340,7 @@ name = "pallet-hyperbridge-aggregations"
version = "0.1.0"
source = "git+https://github.com/zkVerify/zkVerify.git?tag=1.0.0-1.0.0#e6ac3c7242f12aa04dd3b9d0704969f4ab6393a6"
dependencies = [
- "alloy-dyn-abi",
+ "alloy-dyn-abi 0.8.26",
"alloy-primitives 0.8.26",
"anyhow",
"frame-benchmarking",
@@ -12285,7 +12698,7 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e69bf016dc406eff7d53a7d3f7cf1c2e72c82b9088aac1118591e36dd2cd3e9"
dependencies = [
- "bitcoin_hashes",
+ "bitcoin_hashes 0.13.0",
"rand 0.8.5",
"rand_core 0.6.4",
"serde",
@@ -14577,7 +14990,7 @@ version = "0.13.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be769465445e8c1474e9c5dac2018218498557af32d9ed057325ec9a41ae81bf"
dependencies = [
- "heck 0.4.1",
+ "heck 0.5.0",
"itertools 0.14.0",
"log",
"multimap",
@@ -14779,7 +15192,7 @@ dependencies = [
"once_cell",
"socket2 0.6.0",
"tracing",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -14823,6 +15236,7 @@ checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
+ "serde",
]
[[package]]
@@ -14861,6 +15275,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.3",
+ "serde",
]
[[package]]
@@ -15725,7 +16140,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.9.4",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -17415,6 +17830,30 @@ dependencies = [
"windows-sys 0.59.0",
]
+[[package]]
+name = "schemars"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
+dependencies = [
+ "dyn-clone",
+ "ref-cast",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "schemars"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9558e172d4e8533736ba97870c4b2cd63f84b382a3d6eb063da41b91cce17289"
+dependencies = [
+ "dyn-clone",
+ "ref-cast",
+ "serde",
+ "serde_json",
+]
+
[[package]]
name = "schnellru"
version = "0.2.4"
@@ -17531,6 +17970,17 @@ dependencies = [
"secp256k1-sys 0.9.2",
]
+[[package]]
+name = "secp256k1"
+version = "0.30.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252"
+dependencies = [
+ "bitcoin_hashes 0.14.0",
+ "rand 0.8.5",
+ "secp256k1-sys 0.10.1",
+]
+
[[package]]
name = "secp256k1-sys"
version = "0.8.2"
@@ -17549,6 +17999,15 @@ dependencies = [
"cc",
]
+[[package]]
+name = "secp256k1-sys"
+version = "0.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9"
+dependencies = [
+ "cc",
+]
+
[[package]]
name = "secrecy"
version = "0.8.0"
@@ -17725,6 +18184,10 @@ dependencies = [
"base64 0.22.1",
"chrono",
"hex",
+ "indexmap 1.9.3",
+ "indexmap 2.11.0",
+ "schemars 0.9.0",
+ "schemars 1.1.0",
"serde",
"serde_derive",
"serde_json",
@@ -18199,7 +18662,7 @@ version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1c97747dbf44bb1ca44a561ece23508e99cb592e862f22222dcf42f51d1e451"
dependencies = [
- "heck 0.4.1",
+ "heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.106",
@@ -20340,6 +20803,18 @@ dependencies = [
"syn 2.0.106",
]
+[[package]]
+name = "syn-solidity"
+version = "1.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ff790eb176cc81bb8936aed0f7b9f14fc4670069a2d371b3e3b0ecce908b2cb3"
+dependencies = [
+ "paste",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.106",
+]
+
[[package]]
name = "synstructure"
version = "0.12.6"
@@ -20412,7 +20887,7 @@ dependencies = [
"getrandom 0.3.3",
"once_cell",
"rustix 1.0.8",
- "windows-sys 0.52.0",
+ "windows-sys 0.60.2",
]
[[package]]
@@ -21418,6 +21893,8 @@ dependencies = [
name = "vflow-runtime"
version = "1.0.0"
dependencies = [
+ "alloy",
+ "alloy-sol-types 1.4.1",
"cfg-if",
"cumulus-pallet-aura-ext",
"cumulus-pallet-parachain-system",
@@ -22380,7 +22857,7 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0978bf7171b3d90bac376700cb56d606feb40f251a475a5d6634613564460b22"
dependencies = [
- "windows-sys 0.48.0",
+ "windows-sys 0.60.2",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 80bfcb7..4c30ce0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -181,6 +181,8 @@ xcm-primitives = {git = "https://github.com/moonbeam-foundation/moonbeam/", tag
# Other
rstest = {version = "0.26"}
tokio = {version = "1.13"}
+alloy = { version = "1", default-features = false }
+alloy-sol-types = { version = "1" }
[workspace.metadata.cargo-machete]
ignored = ["num_enum"]
diff --git a/runtime/common/src/xcm_teleport.rs b/runtime/common/src/xcm_teleport.rs
index a444eab..0634850 100644
--- a/runtime/common/src/xcm_teleport.rs
+++ b/runtime/common/src/xcm_teleport.rs
@@ -13,17 +13,35 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+use crate::alloc::borrow::ToOwned;
use frame_support::dispatch::{DispatchInfo, PostDispatchInfo};
use pallet_evm::AddressMapping;
use precompile_utils::prelude::*;
use sp_core::{H256, U256};
use sp_runtime::traits::{Dispatchable, Get};
use sp_std::{boxed::Box, marker::PhantomData, vec};
-use xcm::v5::{Asset, AssetId, Assets, Fungibility, Junction, Location};
-use xcm::{VersionedAssets, VersionedLocation};
+use xcm::{
+ v5::{
+ Asset,
+ AssetFilter::Wild,
+ AssetId, Assets, Fungibility,
+ Instruction::{BuyExecution, ClearOrigin, DepositAsset, ReceiveTeleportedAsset},
+ Junction, Location, Reanchorable, WeightLimit,
+ WildAsset::AllCounted,
+ Xcm,
+ },
+ VersionedAssets, VersionedLocation, VersionedXcm,
+};
pub struct XcmTeleportPrecompile(PhantomData<(R, O, C, L, A)>);
+struct TeleportCallParams {
+ destination: Location,
+ beneficiary: Location,
+ assets: Assets,
+ fee_asset_item: u32,
+}
+
#[precompile_utils::precompile]
impl XcmTeleportPrecompile
where
@@ -55,35 +73,134 @@ where
::AddressMapping::into_account_id(handle.context().caller);
let origin: O = frame_system::RawOrigin::Signed(account_id).into();
- let destination = VersionedLocation::V5(L::get());
+ let TeleportCallParams {
+ destination,
+ beneficiary,
+ assets,
+ fee_asset_item,
+ } = Self::build_teleport_params(destination_account, amount)?;
- let beneficiary = VersionedLocation::V5(Location::new(
+ let call: C = pallet_xcm::Call::::teleport_assets {
+ dest: Box::new(VersionedLocation::V5(destination)),
+ beneficiary: Box::new(VersionedLocation::V5(beneficiary)),
+ assets: Box::new(VersionedAssets::V5(assets)),
+ fee_asset_item,
+ }
+ .into();
+
+ RuntimeHelper::::try_dispatch::(handle, origin, call, 0)?;
+
+ Ok(())
+ }
+
+ #[precompile::public("deliveryFee(bytes32,uint256)")]
+ fn delivery_fee(
+ handle: &mut impl PrecompileHandle,
+ destination_account: H256,
+ amount: U256,
+ ) -> EvmResult {
+ // No benchmarks availabe yet for precompiles, so charge some arbitrary gas as a spam
+ // prevention mechanism.
+ handle.record_cost(1000)?;
+
+ let TeleportCallParams {
+ destination,
+ beneficiary,
+ assets,
+ fee_asset_item,
+ } = Self::build_teleport_params(destination_account, amount)?;
+
+ let program = Self::teleport_assets_program(
+ destination.clone(),
+ beneficiary,
+ assets,
+ fee_asset_item,
+ )?;
+
+ let versioned_fees = pallet_xcm::Pallet::::query_delivery_fees(
+ VersionedLocation::V5(destination),
+ VersionedXcm::V5(program),
+ )
+ .map_err(|_| revert("cannot query delivery fees"))?;
+
+ let fees: Assets = versioned_fees
+ .try_into()
+ .map_err(|_| RevertReason::custom("xcm conversion error"))?;
+ match fees
+ .get(fee_asset_item as usize)
+ .ok_or_else(|| RevertReason::read_out_of_bounds("fees"))?
+ .fun
+ {
+ Fungibility::Fungible(amount) => Ok(U256::from(amount)),
+ Fungibility::NonFungible(_asset_instance) => {
+ Err(RevertReason::custom("delivery fee is not fungible"))?
+ }
+ }
+ }
+
+ fn teleport_assets_program(
+ dest: Location,
+ beneficiary: Location,
+ assets: Assets,
+ fee_asset_item: u32,
+ ) -> EvmResult> {
+ let fees = assets
+ .get(fee_asset_item as usize)
+ .ok_or_else(|| RevertReason::read_out_of_bounds("fees"))?
+ .to_owned();
+ let max_assets = assets.len() as u32;
+ let context = R::UniversalLocation::get();
+ let reanchored_assets = assets
+ .reanchored(&dest, &context)
+ .map_err(|_| revert("cannot reanchor assets"))?;
+ let reanchored_fees = fees
+ .reanchored(&dest, &context)
+ .map_err(|_| revert("cannot reanchor fees"))?;
+
+ Ok(Xcm(vec![
+ ReceiveTeleportedAsset(reanchored_assets),
+ ClearOrigin,
+ BuyExecution {
+ fees: reanchored_fees,
+ weight_limit: WeightLimit::Unlimited,
+ },
+ DepositAsset {
+ assets: Wild(AllCounted(max_assets)),
+ beneficiary,
+ },
+ ]))
+ }
+
+ fn build_teleport_params(
+ destination_account: H256,
+ amount: U256,
+ ) -> EvmResult {
+ let destination = L::get();
+
+ let beneficiary = Location::new(
0,
[Junction::AccountId32 {
network: None,
id: destination_account.into(),
}],
- ));
+ );
- let amount_u128: u128 = amount.try_into().map_err(|_| revert("Amount too large"))?;
+ let amount_u128 = amount
+ .try_into()
+ .map_err(|_| RevertReason::value_is_too_large("amount"))?;
- let assets = VersionedAssets::V5(Assets::from(vec![Asset {
+ let assets = Assets::from(vec![Asset {
id: A::get(),
fun: Fungibility::Fungible(amount_u128),
- }]));
+ }]);
let fee_asset_item = 0;
- let call: C = pallet_xcm::Call::::teleport_assets {
- dest: Box::new(destination),
- beneficiary: Box::new(beneficiary),
- assets: Box::new(assets),
+ Ok(TeleportCallParams {
+ destination,
+ beneficiary,
+ assets,
fee_asset_item,
- }
- .into();
-
- RuntimeHelper::::try_dispatch::(handle, origin, call, 0)?;
-
- Ok(())
+ })
}
}
diff --git a/runtime/vflow/Cargo.toml b/runtime/vflow/Cargo.toml
index c954a28..c687f55 100644
--- a/runtime/vflow/Cargo.toml
+++ b/runtime/vflow/Cargo.toml
@@ -105,13 +105,17 @@ xcm-primitives = {workspace = true}
substrate-wasm-builder = {workspace = true}
[dev-dependencies]
+alloy = {workspace = true}
+alloy-sol-types = {workspace = true}
ethereum = {workspace = true}
hex = {workspace = true, features = ["std"]}
rstest = {workspace = true}
+serde_json = {workspace = true}
[features]
default = [ "std" ]
std = [
+ "alloy/std",
"cumulus-pallet-aura-ext/std",
"cumulus-pallet-parachain-system/std",
"cumulus-pallet-session-benchmarking/std",
diff --git a/runtime/vflow/src/tests/xcm_teleport_integration.rs b/runtime/vflow/src/tests/xcm_teleport_integration.rs
index 8ad025a..c5d0c2c 100644
--- a/runtime/vflow/src/tests/xcm_teleport_integration.rs
+++ b/runtime/vflow/src/tests/xcm_teleport_integration.rs
@@ -1,10 +1,16 @@
use crate::{
configs::xcm::{NativeAssetId, RelayLocation},
- currency::VFY,
+ constants::currency::VFY,
tests::ALICE,
- AccountId, Runtime, RuntimeOrigin, ZKVXcm,
+ AccountId, Runtime, RuntimeCall, RuntimeOrigin, ZKVXcm, U256,
};
+use alloy::primitives::U256 as Uint256;
+use alloy_sol_types::{sol, SolCall, SolValue};
+use fp_evm::CallInfo;
+use fp_rpc::runtime_decl_for_ethereum_runtime_rpc_api::EthereumRuntimeRPCApiV5;
use frame_support::assert_ok;
+use precompile_utils::precompile_set::AddressU64;
+use sp_core::Get;
use sp_runtime::BuildStorage;
use xcm::v5::{Asset, Assets, Fungibility, Junction, Location, WeightLimit};
use xcm::{VersionedAssets, VersionedLocation};
@@ -77,3 +83,116 @@ fn can_teleport_vfy_to_relay() {
));
});
}
+
+#[test]
+fn xcm_teleport_precompile_delivery_fee_computation_is_correct() {
+ new_test_ext().execute_with(|| {
+ let from = ALICE;
+ let to = [0x42u8; 32];
+ let amount = VFY;
+
+ let fees_from_precompile = compute_teleport_delivery_fees_via_precompile(from, to, amount);
+ let fees_from_dry_run = compute_teleport_delivery_fees_via_dry_run(from, to, amount);
+
+ assert_eq!(fees_from_precompile, fees_from_dry_run);
+ });
+}
+
+fn compute_teleport_delivery_fees_via_precompile(
+ from: [u8; 20],
+ account: [u8; 32],
+ amount: u128,
+) -> u128 {
+ sol! {
+ contract IXcmTeleportPrecompile {
+ function deliveryFee(bytes32 id, uint256 amount) external returns (uint256);
+ }
+ }
+
+ let precompile_address = AddressU64::<2060>::get();
+ let calldata = IXcmTeleportPrecompile::deliveryFeeCall {
+ id: account.into(),
+ amount: Uint256::from(amount),
+ }
+ .abi_encode();
+
+ let CallInfo { value, .. } = Runtime::call(
+ from.into(),
+ precompile_address,
+ calldata,
+ U256::zero(),
+ U256::from(1_000_000),
+ None,
+ None,
+ None,
+ false,
+ None,
+ )
+ .unwrap();
+
+ Uint256::abi_decode(&value).unwrap().to()
+}
+
+fn compute_teleport_delivery_fees_via_dry_run(
+ from: [u8; 20],
+ account: [u8; 32],
+ amount: u128,
+) -> u128 {
+ let destination = VersionedLocation::V5(RelayLocation::get());
+
+ let beneficiary = VersionedLocation::V5(Location::new(
+ 0,
+ [Junction::AccountId32 {
+ network: None,
+ id: account,
+ }],
+ ));
+
+ let assets = VersionedAssets::V5(Assets::from(vec![Asset {
+ id: NativeAssetId::get(),
+ fun: Fungibility::Fungible(amount),
+ }]));
+
+ let call = pallet_xcm::Call::::teleport_assets {
+ dest: Box::new(destination.clone()),
+ beneficiary: Box::new(beneficiary.clone()),
+ assets: Box::new(assets.clone()),
+ fee_asset_item: 0,
+ }
+ .into();
+
+ compute_delivery_fees_for_call(
+ RuntimeOrigin::signed(from.into()),
+ call,
+ destination.clone(),
+ )
+}
+
+fn compute_delivery_fees_for_call(
+ origin: RuntimeOrigin,
+ call: RuntimeCall,
+ destination: VersionedLocation,
+) -> u128 {
+ ZKVXcm::dry_run_call::<
+ Runtime,
+ ::XcmRouter,
+ ::RuntimeOrigin,
+ ::RuntimeCall,
+ >(origin, call, 5)
+ .unwrap()
+ .forwarded_xcms
+ .into_iter()
+ .filter(|(location, _xcms)| location == &destination)
+ .flat_map(|(_location, xcms)| xcms.into_iter())
+ .map(|xcm| -> Assets {
+ pallet_xcm::Pallet::::query_delivery_fees(destination.clone(), xcm)
+ .unwrap()
+ .try_into()
+ .unwrap()
+ })
+ .flat_map(|assets| assets.into_inner())
+ .fold(0, |acc, asset: Asset| match asset.fun {
+ Fungibility::Fungible(amount) => acc + amount,
+ Fungibility::NonFungible(_) => acc,
+ })
+}