From 4fbdb38e65ffe8884bc62a9649a7acde71e175c8 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 5 Aug 2025 11:35:18 -0700 Subject: [PATCH 1/9] hyperwallet: change types to remove generics --- .DS_Store | Bin 6148 -> 0 bytes .gitignore | 3 +- Cargo.lock | 4058 +++++++++++++++++++++++++++++++ src/.DS_Store | Bin 6148 -> 0 bytes src/hyperwallet_client/api.rs | 355 +-- src/hyperwallet_client/mod.rs | 68 +- src/hyperwallet_client/types.rs | 191 +- 7 files changed, 4391 insertions(+), 284 deletions(-) delete mode 100644 .DS_Store create mode 100644 Cargo.lock delete mode 100644 src/.DS_Store diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 09bf23a6998f704b3768c0c09d9d572dd5aaa4dd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKJxc>Y5S`T!gCeA`P;3r6k%%dRh0Phx#!5(MrBR7uLV_lUg>ZH@>VL7f5w*3l zw@+aiL=fNXu5mYKf>?;i4D7zW`PhAV$=&3LNEKV#d7>;4WiS|1qnN%hj`K*^ko8Oe z74K24QPj#*30l^qO;u9>FfQn zAKxArZ|pkHhQbp{Y2@Qv+NBniz0+y@BAMZGxQ+`qv$vW<&px&KCzJkJ9v=#s&p3D- zQ-gNsfR1Pr^A6>(>Q#p3PX=eZJolg1FRfMs_IEjdufpfQ#{7rr5S+I>9n%lfpAnZ= zyVK=m>s$`WsCQn5`vs+`sa2{#C-1lOHudt@8+Xs{%q^X-w)J=C?cp-$m*en2&sks| zVn0&=`mtrk49YADhytQOR{?%L1Q?8=#n_;JbYRl20KgR7+OXEW0T{3Y7+Q=C!UI#L z6lhA7eZ^3w9R9%Og%)Fjrks>M8T;6im3>1|`gHgMolYt=D6=Ra3it{Po69Ws|CRpl z|9+8Ni2|a)zfwS@qEb}EN3y*&@!`1F1{fO{Y@8Px)Fqf~JJt(s#giD?5DRz#3@ye6 R;ep8?0WE_}qQI{z@DAL=wc7vy diff --git a/.gitignore b/.gitignore index ce26a92..9fbba68 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ target *.swp -.vscode \ No newline at end of file +.vscode +.DS_Store diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..40a8b47 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4058 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.3", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "alloy" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59febb24956a41c29bb5f450978fbe825bd6456b3f80586c8bd558dc882e7b6a" +dependencies = [ + "alloy-consensus", + "alloy-core", + "alloy-eips", + "alloy-genesis", + "alloy-json-rpc", + "alloy-network", + "alloy-provider", + "alloy-rpc-client", + "alloy-rpc-types", + "alloy-serde", + "alloy-signer", + "alloy-signer-local", + "alloy-transport", + "alloy-transport-http", +] + +[[package]] +name = "alloy-chains" +version = "0.1.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28e2652684758b0d9b389d248b209ed9fd9989ef489a550265fe4bb8454fe7eb" +dependencies = [ + "alloy-primitives", + "num_enum", + "strum", +] + +[[package]] +name = "alloy-consensus" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88e1edea70787c33e11197d3f32ae380f3db19e6e061e539a5bcf8184a6b326" +dependencies = [ + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-trie", + "auto_impl", + "c-kzg", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-consensus-any" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57b1bb53f40c0273cd1975573cd457b39213e68584e36d1401d25fd0398a1d65" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-core" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d8bcce99ad10fe02640cfaec1c6bc809b837c783c1d52906aa5af66e2a196f6" +dependencies = [ + "alloy-dyn-abi", + "alloy-json-abi", + "alloy-primitives", + "alloy-rlp", + "alloy-sol-types", +] + +[[package]] +name = "alloy-dyn-abi" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb8e762aefd39a397ff485bc86df673465c4ad3ec8819cc60833a8a3ba5cdc87" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-type-parser", + "alloy-sol-types", + "const-hex", + "itoa", + "serde", + "serde_json", + "winnow", +] + +[[package]] +name = "alloy-eip2930" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0069cf0642457f87a01a014f6dc29d5d893cd4fd8fddf0c3cdfad1bb3ebafc41" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "serde", +] + +[[package]] +name = "alloy-eip7702" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c986539255fb839d1533c128e190e557e52ff652c9ef62939e233a81dd93f7e" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "derive_more 1.0.0", + "serde", +] + +[[package]] +name = "alloy-eips" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9fadfe089e9ccc0650473f2d4ef0a28bc015bbca5631d9f0f09e49b557fdb3" +dependencies = [ + "alloy-eip2930", + "alloy-eip7702", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "c-kzg", + "derive_more 1.0.0", + "once_cell", + "serde", + "sha2", +] + +[[package]] +name = "alloy-genesis" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2a4cf7b70f3495788e74ce1c765260ffe38820a2a774ff4aacb62e31ea73f9" +dependencies = [ + "alloy-primitives", + "alloy-serde", + "alloy-trie", + "serde", +] + +[[package]] +name = "alloy-json-abi" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe6beff64ad0aa6ad1019a3db26fef565aefeb011736150ab73ed3366c3cfd1b" +dependencies = [ + "alloy-primitives", + "alloy-sol-type-parser", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-json-rpc" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e29040b9d5fe2fb70415531882685b64f8efd08dfbd6cc907120650504821105" +dependencies = [ + "alloy-primitives", + "alloy-sol-types", + "serde", + "serde_json", + "thiserror 2.0.12", + "tracing", +] + +[[package]] +name = "alloy-network" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510cc00b318db0dfccfdd2d032411cfae64fc144aef9679409e014145d3dacc4" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-json-rpc", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-types-any", + "alloy-rpc-types-eth", + "alloy-serde", + "alloy-signer", + "alloy-sol-types", + "async-trait", + "auto_impl", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-network-primitives" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9081c099e798b8a2bba2145eb82a9a146f01fc7a35e9ab6e7b43305051f97550" +dependencies = [ + "alloy-consensus", + "alloy-eips", + "alloy-primitives", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-primitives" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c77490fe91a0ce933a1f219029521f20fc28c2c0ca95d53fa4da9c00b8d9d4e" +dependencies = [ + "alloy-rlp", + "bytes", + "cfg-if", + "const-hex", + "derive_more 2.0.1", + "foldhash", + "hashbrown 0.15.4", + "indexmap", + "itoa", + "k256", + "keccak-asm", + "paste", + "proptest", + "rand 0.8.5", + "ruint", + "rustc-hash", + "serde", + "sha3", + "tiny-keccak", +] + +[[package]] +name = "alloy-provider" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc2dfaddd9a30aa870a78a4e1316e3e115ec1e12e552cbc881310456b85c1f24" +dependencies = [ + "alloy-chains", + "alloy-consensus", + "alloy-eips", + "alloy-json-rpc", + "alloy-network", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rpc-client", + "alloy-rpc-types-eth", + "alloy-transport", + "alloy-transport-http", + "async-stream", + "async-trait", + "auto_impl", + "dashmap", + "futures", + "futures-utils-wasm", + "lru", + "parking_lot", + "pin-project", + "reqwest", + "schnellru", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tracing", + "url", + "wasmtimer", +] + +[[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", + "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.104", +] + +[[package]] +name = "alloy-rpc-client" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "531137b283547d5b9a5cafc96b006c64ef76810c681d606f28be9781955293b6" +dependencies = [ + "alloy-json-rpc", + "alloy-primitives", + "alloy-transport", + "alloy-transport-http", + "futures", + "pin-project", + "reqwest", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tower", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-rpc-types" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3410a472ce26c457e9780f708ee6bd540b30f88f1f31fdab7a11d00bd6aa1aee" +dependencies = [ + "alloy-primitives", + "alloy-rpc-types-eth", + "alloy-serde", + "serde", +] + +[[package]] +name = "alloy-rpc-types-any" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed98e1af55a7d856bfa385f30f63d8d56be2513593655c904a8f4a7ec963aa3e" +dependencies = [ + "alloy-consensus-any", + "alloy-rpc-types-eth", + "alloy-serde", +] + +[[package]] +name = "alloy-rpc-types-eth" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8737d7a6e37ca7bba9c23e9495c6534caec6760eb24abc9d5ffbaaba147818e1" +dependencies = [ + "alloy-consensus", + "alloy-consensus-any", + "alloy-eips", + "alloy-network-primitives", + "alloy-primitives", + "alloy-rlp", + "alloy-serde", + "alloy-sol-types", + "derive_more 1.0.0", + "itertools 0.13.0", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-serde" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5851bf8d5ad33014bd0c45153c603303e730acc8a209450a7ae6b4a12c2789e2" +dependencies = [ + "alloy-primitives", + "serde", + "serde_json", +] + +[[package]] +name = "alloy-signer" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e10ca565da6500cca015ba35ee424d59798f2e1b85bc0dd8f81dafd401f029a" +dependencies = [ + "alloy-primitives", + "async-trait", + "auto_impl", + "elliptic-curve", + "k256", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-signer-local" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47fababf5a745133490cde927d48e50267f97d3d1209b9fc9f1d1d666964d172" +dependencies = [ + "alloy-consensus", + "alloy-network", + "alloy-primitives", + "alloy-signer", + "async-trait", + "k256", + "rand 0.8.5", + "thiserror 2.0.12", +] + +[[package]] +name = "alloy-sol-macro" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10ae8e9a91d328ae954c22542415303919aabe976fe7a92eb06db1b68fd59f2" +dependencies = [ + "alloy-sol-macro-expander", + "alloy-sol-macro-input", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "alloy-sol-macro-expander" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83ad5da86c127751bc607c174d6c9fe9b85ef0889a9ca0c641735d77d4f98f26" +dependencies = [ + "alloy-sol-macro-input", + "const-hex", + "heck", + "indexmap", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.104", + "syn-solidity", + "tiny-keccak", +] + +[[package]] +name = "alloy-sol-macro-input" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3d30f0d3f9ba3b7686f3ff1de9ee312647aac705604417a2f40c604f409a9e" +dependencies = [ + "const-hex", + "dunce", + "heck", + "macro-string", + "proc-macro2", + "quote", + "syn 2.0.104", + "syn-solidity", +] + +[[package]] +name = "alloy-sol-type-parser" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d162f8524adfdfb0e4bd0505c734c985f3e2474eb022af32eef0d52a4f3935c" +dependencies = [ + "serde", + "winnow", +] + +[[package]] +name = "alloy-sol-types" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d43d5e60466a440230c07761aa67671d4719d46f43be8ea6e7ed334d8db4a9ab" +dependencies = [ + "alloy-json-abi", + "alloy-primitives", + "alloy-sol-macro", + "const-hex", + "serde", +] + +[[package]] +name = "alloy-transport" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "538a04a37221469cac0ce231b737fd174de2fdfcdd843bdd068cb39ed3e066ad" +dependencies = [ + "alloy-json-rpc", + "base64", + "futures-util", + "futures-utils-wasm", + "serde", + "serde_json", + "thiserror 2.0.12", + "tokio", + "tower", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "alloy-transport-http" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ed40eb1e1265b2911512f6aa1dcece9702d078f5a646730c45e39e2be00ac1c" +dependencies = [ + "alloy-json-rpc", + "alloy-transport", + "reqwest", + "serde_json", + "tower", + "tracing", + "url", +] + +[[package]] +name = "alloy-trie" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d95a94854e420f07e962f7807485856cde359ab99ab6413883e15235ad996e8b" +dependencies = [ + "alloy-primitives", + "alloy-rlp", + "arrayvec", + "derive_more 1.0.0", + "nybbles", + "serde", + "smallvec", + "tracing", +] + +[[package]] +name = "anyhow" +version = "1.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" + +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +dependencies = [ + "serde", +] + +[[package]] +name = "async-stream" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "async-trait" +version = "0.1.88" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blst" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fd49896f12ac9b6dcd7a5998466b9b58263a695a3dd1ecc1aaca2e12a90b080" +dependencies = [ + "cc", + "glob", + "threadpool", + "zeroize", +] + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "byte-slice-cast" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" +dependencies = [ + "serde", +] + +[[package]] +name = "c-kzg" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0307f72feab3300336fb803a57134159f6e20139af1357f36c54cb90d8e8928" +dependencies = [ + "blst", + "cc", + "glob", + "hex", + "libc", + "once_cell", + "serde", +] + +[[package]] +name = "cc" +version = "1.2.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268" + +[[package]] +name = "color-eyre" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5920befb47832a6d61ee3a3a846565cfa39b331331e68a3b1d1116630f2f26d" +dependencies = [ + "backtrace", + "color-spantrace", + "eyre", + "indenter", + "once_cell", + "owo-colors", + "tracing-error", +] + +[[package]] +name = "color-spantrace" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b88ea9df13354b55bc7234ebcce36e6ef896aca2e42a15de9e10edce01b427" +dependencies = [ + "once_cell", + "owo-colors", + "tracing-core", + "tracing-error", +] + +[[package]] +name = "const-hex" +version = "1.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e22e0ed40b96a48d3db274f72fd365bd78f67af39b6bbd47e8a15e1c6207ff" +dependencies = [ + "cfg-if", + "cpufeatures", + "hex", + "proptest", + "serde", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const_format" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +dependencies = [ + "const_format_proc_macros", +] + +[[package]] +name = "const_format_proc_macros" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crunchy" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "unicode-xid", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fixed-hash" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534" +dependencies = [ + "byteorder", + "rand 0.8.5", + "rustc-hex", + "static_assertions", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "futures-utils-wasm" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42012b0f064e01aa58b545fe3727f90f7dd4020f4a3ea735b50344965f5a57e9" + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", + "serde", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "hyperware_process_lib" +version = "1.2.0" +dependencies = [ + "alloy", + "alloy-primitives", + "alloy-sol-macro", + "alloy-sol-types", + "anyhow", + "base64", + "bincode", + "color-eyre", + "hex", + "http", + "mime_guess", + "rand 0.8.5", + "regex", + "rmp-serde", + "serde", + "serde_json", + "sha3", + "thiserror 1.0.69", + "tracing", + "tracing-error", + "tracing-subscriber", + "url", + "wit-bindgen", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "id-arena" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25a2bc672d1148e28034f176e01fffebb08b35768468cc954630da77a1449005" + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + +[[package]] +name = "impl-trait-for-tuples" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +dependencies = [ + "equivalent", + "hashbrown 0.15.4", + "serde", +] + +[[package]] +name = "io-uring" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" +dependencies = [ + "bitflags", + "cfg-if", + "libc", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "keccak-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "505d1856a39b200489082f90d897c3f07c455563880bc5952e38eabf731c83b6" +dependencies = [ + "digest 0.10.7", + "sha3-asm", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" + +[[package]] +name = "libc" +version = "0.2.174" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" + +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.4", +] + +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "nybbles" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983bb634df7248924ee0c4c3a749609b5abcb082c28fffe3254b3eb3602b307" +dependencies = [ + "alloy-rlp", + "const-hex", + "proptest", + "serde", + "smallvec", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "owo-colors" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48dd4f4a2c8405440fd0462561f0e5806bd0f77e86f51c761481bdd4018b545e" + +[[package]] +name = "parity-scale-codec" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa" +dependencies = [ + "arrayvec", + "bitvec", + "byte-slice-cast", + "const_format", + "impl-trait-for-tuples", + "parity-scale-codec-derive", + "rustversion", + "serde", +] + +[[package]] +name = "parity-scale-codec-derive" +version = "3.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "parking_lot" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.52.6", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" +dependencies = [ + "memchr", + "thiserror 2.0.12", + "ucd-trie", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +dependencies = [ + "zerovec", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +dependencies = [ + "proc-macro2", + "syn 2.0.104", +] + +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec", + "uint", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "proc-macro2" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags", + "lazy_static", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax 0.8.5", + "rusty-fork", + "tempfile", + "unarray", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + +[[package]] +name = "redox_syscall" +version = "0.5.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "reqwest" +version = "0.12.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531" +dependencies = [ + "base64", + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + +[[package]] +name = "rmp" +version = "0.8.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "228ed7c16fa39782c3b3468e974aec2795e9089153cd08ee2e9aefb3613334c4" +dependencies = [ + "byteorder", + "num-traits", + "paste", +] + +[[package]] +name = "rmp-serde" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e599a477cf9840e92f2cde9a7189e67b42c57532749bf90aea6ec10facd4db" +dependencies = [ + "byteorder", + "rmp", + "serde", +] + +[[package]] +name = "ruint" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecb38f82477f20c5c3d62ef52d7c4e536e38ea9b73fb570a20c5cae0e14bcf6" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types", + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "rlp", + "ruint-macro", + "serde", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + +[[package]] +name = "rustc-demangle" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc-hex" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6" + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver 1.0.26", +] + +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.60.2", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustversion" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" + +[[package]] +name = "rusty-fork" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[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]] +name = "schnellru" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "356285bbf17bea63d9e52e96bd18f039672ac92b55b8cb997d6162a2a37d1649" +dependencies = [ + "ahash", + "cfg-if", + "hashbrown 0.13.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.219" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "serde_json" +version = "1.0.142" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "030fedb782600dcbd6f02d479bf0d817ac3bb40d644745b769d6a96bc3afc5a7" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "sha3-asm" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28efc5e327c837aa837c59eae585fc250715ef939ac32881bcc11677cd02d46" +dependencies = [ + "cc", + "cfg-if", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "slab" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spdx" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e17e880bafaeb362a7b751ec46bdc5b61445a188f80e0606e68167cd540fa3" +dependencies = [ + "smallvec", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn-solidity" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4560533fbd6914b94a8fb5cc803ed6801c3455668db3b810702c57612bac9412" +dependencies = [ + "paste", + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix", + "windows-sys 0.59.0", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.47.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +dependencies = [ + "backtrace", + "bytes", + "io-uring", + "libc", + "mio", + "pin-project-lite", + "slab", + "socket2", + "tokio-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "tracing-core" +version = "0.1.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d12581f227e93f094d3af2ae690a574abb8a2b9b7a96e7cfe9647b2b617678" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-error" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db" +dependencies = [ + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicase" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt 0.39.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.104", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.220.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e913f9242315ca39eff82aee0e19ee7a372155717ff0eb082c741e435ce25ed1" +dependencies = [ + "leb128", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.220.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185dfcd27fa5db2e6a23906b54c28199935f71d9a27a1a27b3a88d6fee2afae7" +dependencies = [ + "anyhow", + "indexmap", + "serde", + "serde_derive", + "serde_json", + "spdx", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.220.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d07b6a3b550fefa1a914b6d54fc175dd11c3392da11eee604e6ffc759805d25" +dependencies = [ + "ahash", + "bitflags", + "hashbrown 0.14.5", + "indexmap", + "semver 1.0.26", +] + +[[package]] +name = "wasmtimer" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8d49b5d6c64e8558d9b1b065014426f35c18de636895d24893dbbd329743446" +dependencies = [ + "futures", + "js-sys", + "parking_lot", + "pin-utils", + "slab", + "wasm-bindgen", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a2b3e15cd6068f233926e7d8c7c588b2ec4fb7cc7bf3824115e7c7e2a8485a3" +dependencies = [ + "wit-bindgen-rt 0.36.0", + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b632a5a0fa2409489bd49c9e6d99fcc61bb3d4ce9d1907d44662e75a28c71172" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7947d0131c7c9da3f01dfde0ab8bd4c4cf3c5bd49b6dba0ae640f1fa752572ea" +dependencies = [ + "bitflags", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4329de4186ee30e2ef30a0533f9b3c123c019a237a7c82d692807bf1b3ee2697" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn 2.0.104", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177fb7ee1484d113b4792cc480b1ba57664bbc951b42a4beebe573502135b1fc" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.104", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.220.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b505603761ed400c90ed30261f44a768317348e49f1864e82ecdc3b2744e5627" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.220.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae2a7999ed18efe59be8de2db9cb2b7f84d88b27818c79353dfc53131840fe1a" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver 1.0.26", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdbb9122ea75b11bf96e7492afb723e8a7fbe12c67417aa95e7e3d18144d37cd" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index 5e14423ccbaece3851f9fc893214aa4b215f3025..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO-sZu5Pi`-Ea+j69`g%aym+p43kr)aE+U?)`vER2xNKX``RTsNM6p;sN|Bk8 zyy;|SGI`LX0pRjxbq0(84A}&oC>` zagChz9rL_m$+(J7$xIt8Xs>8r5`VAhCe`#~-F+n5YBC0l0b{@z=nVrrvqgqSiq;zg z#(**K$$;z+o=q@I7!>2y!7g3_hy$9VP?x)e#Q20+!l1|ziqlY{hPrgca2ig#Pkvd# zps3++ac1U8Gk;uOT%4VDAKl?HMeB_LW1!8zp}vmf{4e;)bYAk?A@*hr7z6)|0XLY; zCpj0D&em_sle5;dJ+X<1Ul4^tz4a5o7uiQn;-HRu(dm~Z42qIP>@l2ZKLU{u>x_Xv GVBj75>NNxa diff --git a/src/hyperwallet_client/api.rs b/src/hyperwallet_client/api.rs index 11a2602..03fa821 100644 --- a/src/hyperwallet_client/api.rs +++ b/src/hyperwallet_client/api.rs @@ -1,9 +1,9 @@ use super::types::{ self, Balance, BuildAndSignUserOperationForPaymentRequest, BuildAndSignUserOperationResponse, CreateWalletRequest, ExportWalletResponse, GetTokenBalanceResponse, HyperwalletMessage, - HyperwalletRequest, HyperwalletResponse, ImportWalletRequest, ListWalletsResponse, + HyperwalletRequest, ImportWalletRequest, ListWalletsResponse, PaymasterConfig, RenameWalletRequest, SendEthRequest, SendTokenRequest, SessionId, - SubmitUserOperationResponse, TxReceipt, UnlockWalletRequest, UserOperationReceiptResponse, + TxReceipt, UnlockWalletRequest, UserOperationReceiptResponse, Wallet, }; use super::HyperwalletClientError; @@ -15,21 +15,31 @@ pub fn create_wallet( name: Option<&str>, password: Option<&str>, ) -> Result { - let request = build_request( + let message = build_message( session_id, - CreateWalletRequest { + HyperwalletRequest::CreateWallet(CreateWalletRequest { name: name.map(|s| s.to_string()).unwrap_or_default(), password: password.map(|s| s.to_string()), - }, + }), ); - let message = HyperwalletMessage::CreateWallet(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing wallet data in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::CreateWallet(wallet_response)) => { + Ok(types::Wallet { + address: wallet_response.address, + name: Some(wallet_response.name), + chain_id: 8453, // Base mainnet - TODO: get from response + encrypted: password.is_some(), + created_at: None, + last_used: None, + spending_limits: None, + }) + } + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing or invalid wallet data in response"), + )), + } } pub fn import_wallet( @@ -38,22 +48,32 @@ pub fn import_wallet( private_key: &str, password: Option<&str>, ) -> Result { - let request = build_request( + let message = build_message( session_id, - ImportWalletRequest { + HyperwalletRequest::ImportWallet(ImportWalletRequest { name: name.to_string(), private_key: private_key.to_string(), password: password.map(|s| s.to_string()), - }, + }), ); - let message = HyperwalletMessage::ImportWallet(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing wallet data in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::ImportWallet(wallet_response)) => { + Ok(types::Wallet { + address: wallet_response.address, + name: Some(wallet_response.name), + chain_id: 8453, // Base mainnet - TODO: get from response + encrypted: password.is_some(), + created_at: None, + last_used: None, + spending_limits: None, + }) + } + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing or invalid wallet data in response"), + )), + } } pub fn unlock_wallet( @@ -62,68 +82,84 @@ pub fn unlock_wallet( wallet_id: &str, password: &str, ) -> Result<(), HyperwalletClientError> { - let request = build_request( + let message = build_message( session_id, - UnlockWalletRequest { + HyperwalletRequest::UnlockWallet(UnlockWalletRequest { session_id: target_session_id.to_string(), wallet_id: wallet_id.to_string(), password: password.to_string(), - }, + }), ); - let message = HyperwalletMessage::UnlockWallet(request); - let _response: HyperwalletResponse<()> = super::send_message(message)?; - Ok(()) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::UnlockWallet(_)) => Ok(()), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Failed to unlock wallet"), + )), + } } pub fn list_wallets(session_id: &SessionId) -> Result { - let request = build_request(session_id, ()); - - let message = HyperwalletMessage::ListWallets(request); - let response: HyperwalletResponse = super::send_message(message)?; - let list_response = response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing wallet list in response", - )) - })?; - - Ok(list_response) + let message = build_message(session_id, HyperwalletRequest::ListWallets); + + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::ListWallets(list_response)) => Ok(list_response), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing or invalid wallet list in response"), + )), + } } pub fn get_wallet_info( session_id: &SessionId, wallet_id: &str, ) -> Result { - let request = build_request( + let message = build_message( session_id, - types::GetWalletInfoRequest { + HyperwalletRequest::GetWalletInfo(types::GetWalletInfoRequest { wallet_id: wallet_id.to_string(), - }, + }), ); - let message = HyperwalletMessage::GetWalletInfo(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing wallet data in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::GetWalletInfo(info_response)) => { + Ok(types::Wallet { + address: info_response.address, + name: Some(info_response.name), + chain_id: info_response.chain_id, + encrypted: info_response.is_locked, + created_at: None, + last_used: None, + spending_limits: None, + }) + } + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing or invalid wallet data in response"), + )), + } } pub fn delete_wallet( session_id: &SessionId, wallet_id: &str, ) -> Result<(), HyperwalletClientError> { - let request = build_request( + let message = build_message( session_id, - types::DeleteWalletRequest { + HyperwalletRequest::DeleteWallet(types::DeleteWalletRequest { wallet_id: wallet_id.to_string(), - }, + }), ); - let message = HyperwalletMessage::DeleteWallet(request); - let _response: HyperwalletResponse<()> = super::send_message(message)?; - Ok(()) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::DeleteWallet(_)) => Ok(()), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Failed to delete wallet"), + )), + } } pub fn export_wallet( @@ -131,21 +167,21 @@ pub fn export_wallet( wallet_id: &str, password: Option<&str>, ) -> Result { - let request = build_request( + let message = build_message( session_id, - types::ExportWalletRequest { + HyperwalletRequest::ExportWallet(types::ExportWalletRequest { wallet_id: wallet_id.to_string(), password: password.map(|s| s.to_string()), - }, + }), ); - let message = HyperwalletMessage::ExportWallet(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing export data in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::ExportWallet(export_response)) => Ok(export_response), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing export data in response"), + )), + } } pub fn rename_wallet( @@ -153,16 +189,24 @@ pub fn rename_wallet( wallet_id: &str, new_name: &str, ) -> Result<(), HyperwalletClientError> { - let request = build_request( + let message = build_message( session_id, - RenameWalletRequest { + HyperwalletRequest::RenameWallet(RenameWalletRequest { wallet_id: wallet_id.to_string(), new_name: new_name.to_string(), - }, + }), ); - let message = HyperwalletMessage::RenameWallet(request); - let _response: HyperwalletResponse<()> = super::send_message(message)?; - Ok(()) + let response = super::send_message(message)?; + // RenameWallet doesn't have a response variant in the enum, so we just check for success + if response.error.is_none() { + Ok(()) + } else { + Err(HyperwalletClientError::ServerError( + response.error.unwrap_or_else(|| { + types::OperationError::internal_error("Failed to rename wallet") + }), + )) + } } // === TRANSACTIONS === @@ -173,22 +217,30 @@ pub fn send_eth( to_address: &str, amount_eth: &str, ) -> Result { - let request = build_request( + let message = build_message( session_id, - SendEthRequest { + HyperwalletRequest::SendEth(SendEthRequest { wallet_id: wallet_id.to_string(), to: to_address.to_string(), amount: amount_eth.to_string(), - }, + }), ); - let message = HyperwalletMessage::SendEth(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing transaction receipt in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::SendEth(send_response)) => Ok(TxReceipt { + hash: send_response.tx_hash, + details: serde_json::json!({ + "from": send_response.from_address, + "to": send_response.to_address, + "amount": send_response.amount, + "chain_id": send_response.chain_id, + }), + }), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing transaction receipt in response"), + )), + } } pub fn send_token( @@ -198,23 +250,32 @@ pub fn send_token( to_address: &str, amount: &str, ) -> Result { - let request = build_request( + let message = build_message( session_id, - SendTokenRequest { + HyperwalletRequest::SendToken(SendTokenRequest { wallet_id: wallet_id.to_string(), token_address: token_address.to_string(), to: to_address.to_string(), amount: amount.to_string(), - }, + }), ); - let message = HyperwalletMessage::SendToken(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing transaction receipt in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::SendToken(send_response)) => Ok(TxReceipt { + hash: send_response.tx_hash, + details: serde_json::json!({ + "from": send_response.from_address, + "to": send_response.to_address, + "token_address": send_response.token_address, + "amount": send_response.amount, + "chain_id": send_response.chain_id, + }), + }), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing transaction receipt in response"), + )), + } } // === QUERIES === @@ -223,20 +284,20 @@ pub fn get_balance( session_id: &SessionId, wallet_id: &str, ) -> Result { - let request = build_request( + let message = build_message( session_id, - types::GetBalanceRequest { + HyperwalletRequest::GetBalance(types::GetBalanceRequest { wallet_id: wallet_id.to_string(), - }, + }), ); - let message = HyperwalletMessage::GetBalance(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing balance data in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::GetBalance(balance_response)) => Ok(balance_response.balance), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing balance data in response"), + )), + } } pub fn get_token_balance( @@ -244,21 +305,21 @@ pub fn get_token_balance( wallet_id: &str, token_address: &str, ) -> Result { - let request = build_request( + let message = build_message( session_id, - types::GetTokenBalanceRequest { + HyperwalletRequest::GetTokenBalance(types::GetTokenBalanceRequest { wallet_id: wallet_id.to_string(), token_address: token_address.to_string(), - }, + }), ); - let message = HyperwalletMessage::GetTokenBalance(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing token balance data in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::GetTokenBalance(balance_response)) => Ok(balance_response), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing token balance data in response"), + )), + } } // === ACCOUNT ABSTRACTION === @@ -273,9 +334,9 @@ pub fn build_and_sign_user_operation_for_payment( paymaster_config: Option, password: Option<&str>, ) -> Result { - let request = build_request( + let message = build_message( session_id, - BuildAndSignUserOperationForPaymentRequest { + HyperwalletRequest::BuildAndSignUserOperationForPayment(BuildAndSignUserOperationForPaymentRequest { eoa_wallet_id: eoa_wallet_id.to_string(), tba_address: tba_address.to_string(), target: target.to_string(), @@ -283,17 +344,16 @@ pub fn build_and_sign_user_operation_for_payment( use_paymaster, paymaster_config, password: password.map(|s| s.to_string()), - }, + }), ); - let message = HyperwalletMessage::BuildAndSignUserOperationForPayment(request); - let response: HyperwalletResponse = - super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing UserOperation build response data", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::BuildAndSignUserOperationForPayment(build_response)) => Ok(build_response), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing UserOperation build response data"), + )), + } } pub fn submit_user_operation( @@ -302,45 +362,44 @@ pub fn submit_user_operation( entry_point: &str, bundler_url: Option<&str>, ) -> Result { - let request = build_request( + let message = build_message( session_id, - types::SubmitUserOperationRequest { + HyperwalletRequest::SubmitUserOperation(types::SubmitUserOperationRequest { signed_user_operation, entry_point: entry_point.to_string(), bundler_url: bundler_url.map(|s| s.to_string()), - }, + }), ); - let message = HyperwalletMessage::SubmitUserOperation(request); - let response: HyperwalletResponse = super::send_message(message)?; - let data = response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing UserOperation response data", - )) - })?; - - // Direct field access - no manual JSON parsing needed! - Ok(data.user_op_hash) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::SubmitUserOperation(submit_response)) => { + Ok(submit_response.user_op_hash) + } + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing UserOperation response data"), + )), + } } pub fn get_user_operation_receipt( session_id: &SessionId, user_op_hash: &str, ) -> Result { - let request = build_request( + let message = build_message( session_id, - types::GetUserOperationReceiptRequest { + HyperwalletRequest::GetUserOperationReceipt(types::GetUserOperationReceiptRequest { user_op_hash: user_op_hash.to_string(), - }, + }), ); - let message = HyperwalletMessage::GetUserOperationReceipt(request); - let response: HyperwalletResponse = super::send_message(message)?; - response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing UserOperation receipt data in response", - )) - }) + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::GetUserOperationReceipt(receipt_response)) => Ok(receipt_response), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing UserOperation receipt data in response"), + )), + } } // === CONVENIENCE FUNCTIONS === @@ -425,9 +484,9 @@ pub fn create_tba_payment_calldata( // === INTERNAL HELPERS === -fn build_request(session_id: &SessionId, operation_data: T) -> HyperwalletRequest { - HyperwalletRequest { - data: operation_data, +fn build_message(session_id: &SessionId, request: HyperwalletRequest) -> HyperwalletMessage { + HyperwalletMessage { + request, session_id: session_id.clone(), } } diff --git a/src/hyperwallet_client/mod.rs b/src/hyperwallet_client/mod.rs index 8547aec..6d8ec8f 100644 --- a/src/hyperwallet_client/mod.rs +++ b/src/hyperwallet_client/mod.rs @@ -9,11 +9,11 @@ pub use types::{ CreateWalletResponse, DeleteWalletRequest, DeleteWalletResponse, ErrorCode, ExecuteViaTbaResponse, ExportWalletRequest, ExportWalletResponse, GetBalanceRequest, GetBalanceResponse, GetTokenBalanceRequest, GetTokenBalanceResponse, GetWalletInfoRequest, - GetWalletInfoResponse, HandshakeConfig, HandshakeRequest, HandshakeStep, HyperwalletMessage, - HyperwalletRequest, HyperwalletResponse, HyperwalletResponseData, ImportWalletRequest, - ImportWalletResponse, ListWalletsResponse, Operation, OperationCategory, OperationError, - PaymasterConfig, ProcessAddress, ProcessPermissions, RenameWalletRequest, SendEthRequest, - SendEthResponse, SendTokenRequest, SendTokenResponse, SessionId, SessionInfo, SpendingLimits, + GetWalletInfoResponse, HandshakeConfig, HandshakeStep, HyperwalletMessage, HyperwalletRequest, + HyperwalletResponse, HyperwalletResponseData, ImportWalletRequest, ImportWalletResponse, + ListWalletsResponse, Operation, OperationCategory, OperationError, PaymasterConfig, + ProcessAddress, ProcessPermissions, RenameWalletRequest, SendEthRequest, SendEthResponse, + SendTokenRequest, SendTokenResponse, SessionId, SessionInfo, SpendingLimits, SubmitUserOperationResponse, TxReceipt, UnlockWalletResponse, UpdatableSetting, UserOperationHash, UserOperationReceiptResponse, WalletAddress, }; @@ -49,17 +49,23 @@ pub fn initialize(config: HandshakeConfig) -> Result = - send_message(hello_message)?; + let welcome_response = send_message(hello_message)?; - let welcome_step = welcome_response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Missing handshake step in ServerWelcome response", - )) - })?; + let welcome_step = match welcome_response.data { + Some(types::HyperwalletResponseData::Handshake(step)) => step, + _ => { + return Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error( + "Missing or invalid handshake step in ServerWelcome response", + ), + )) + } + }; let supported_operations = match welcome_step { types::HandshakeStep::ServerWelcome { @@ -93,18 +99,23 @@ pub fn initialize(config: HandshakeConfig) -> Result = - send_message(register_message)?; + let complete_response = send_message(register_message)?; - let complete_step = complete_response.data.ok_or_else(|| { - HyperwalletClientError::ServerError(types::OperationError::internal_error( - "Complete response contained no data", - )) - })?; + let complete_step = match complete_response.data { + Some(types::HyperwalletResponseData::Handshake(step)) => step, + _ => { + return Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error( + "Complete response contained no data or invalid data type", + ), + )) + } + }; // Extract SessionInfo using pattern matching match complete_step { @@ -129,12 +140,9 @@ pub fn initialize(config: HandshakeConfig) -> Result( +pub(crate) fn send_message( message: types::HyperwalletMessage, -) -> Result, HyperwalletClientError> -where - T: for<'de> serde::Deserialize<'de>, -{ +) -> Result { // Use local address pattern like HTTP client - hyperwallet is always local let response = Request::to(("our", "hyperwallet", "hyperwallet", "hallman.hypr")) .body(serde_json::to_vec(&message).map_err(HyperwalletClientError::Serialization)?) @@ -142,7 +150,7 @@ where .map_err(|e| HyperwalletClientError::Communication(e.into()))? .map_err(|e| HyperwalletClientError::Communication(e.into()))?; - let hyperwallet_response: types::HyperwalletResponse = + let hyperwallet_response: types::HyperwalletResponse = serde_json::from_slice(response.body()).map_err(HyperwalletClientError::Deserialization)?; if !hyperwallet_response.success { diff --git a/src/hyperwallet_client/types.rs b/src/hyperwallet_client/types.rs index f18925c..8833d88 100644 --- a/src/hyperwallet_client/types.rs +++ b/src/hyperwallet_client/types.rs @@ -270,153 +270,146 @@ pub enum HandshakeStep { } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct HyperwalletRequest { - pub data: T, +pub struct HyperwalletMessage { + pub request: HyperwalletRequest, pub session_id: SessionId, } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct HandshakeRequest { - pub step: T, -} - /// Typed message enum for type-safe communication #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(tag = "operation")] -pub enum HyperwalletMessage { +pub enum HyperwalletRequest { // Session Management (Unauthenticated) - Handshake(HandshakeRequest), + Handshake(HandshakeStep), // Session Management (Authenticated) - UnlockWallet(HyperwalletRequest), + UnlockWallet(UnlockWalletRequest), // Wallet Lifecycle Management - CreateWallet(HyperwalletRequest), - ImportWallet(HyperwalletRequest), - DeleteWallet(HyperwalletRequest), - RenameWallet(HyperwalletRequest), - ExportWallet(HyperwalletRequest), - ListWallets(HyperwalletRequest<()>), // No parameters needed - GetWalletInfo(HyperwalletRequest), + CreateWallet(CreateWalletRequest), + ImportWallet(ImportWalletRequest), + DeleteWallet(DeleteWalletRequest), + RenameWallet(RenameWalletRequest), + ExportWallet(ExportWalletRequest), + ListWallets, + GetWalletInfo(GetWalletInfoRequest), // Ethereum Operations - SendEth(HyperwalletRequest), - SendToken(HyperwalletRequest), - ApproveToken(HyperwalletRequest), - GetBalance(HyperwalletRequest), - GetTokenBalance(HyperwalletRequest), - CallContract(HyperwalletRequest), - SignTransaction(HyperwalletRequest), - SignMessage(HyperwalletRequest), - GetTransactionHistory(HyperwalletRequest), - EstimateGas(HyperwalletRequest), - GetGasPrice(HyperwalletRequest<()>), // No parameters needed - GetTransactionReceipt(HyperwalletRequest), + SendEth(SendEthRequest), + SendToken(SendTokenRequest), + ApproveToken(ApproveTokenRequest), + GetBalance(GetBalanceRequest), + GetTokenBalance(GetTokenBalanceRequest), + CallContract(CallContractRequest), + SignTransaction(SignTransactionRequest), + SignMessage(SignMessageRequest), + GetTransactionHistory(GetTransactionHistoryRequest), + EstimateGas(EstimateGasRequest), + GetGasPrice, + GetTransactionReceipt(GetTransactionReceiptRequest), // Token Bound Account Operations - ExecuteViaTba(HyperwalletRequest), - CheckTbaOwnership(HyperwalletRequest), - SetupTbaDelegation(HyperwalletRequest), + ExecuteViaTba(ExecuteViaTbaRequest), + CheckTbaOwnership(CheckTbaOwnershipRequest), + SetupTbaDelegation(SetupTbaDelegationRequest), // Account Abstraction (ERC-4337) - BuildAndSignUserOperationForPayment( - HyperwalletRequest, - ), - SubmitUserOperation(HyperwalletRequest), - GetUserOperationReceipt(HyperwalletRequest), - BuildUserOperation(HyperwalletRequest), - SignUserOperation(HyperwalletRequest), - BuildAndSignUserOperation(HyperwalletRequest), - EstimateUserOperationGas(HyperwalletRequest), - ConfigurePaymaster(HyperwalletRequest), + BuildAndSignUserOperationForPayment(BuildAndSignUserOperationForPaymentRequest), + SubmitUserOperation(SubmitUserOperationRequest), + GetUserOperationReceipt(GetUserOperationReceiptRequest), + BuildUserOperation(BuildUserOperationRequest), + SignUserOperation(SignUserOperationRequest), + BuildAndSignUserOperation(BuildAndSignUserOperationRequest), + EstimateUserOperationGas(EstimateUserOperationGasRequest), + ConfigurePaymaster(ConfigurePaymasterRequest), // Hypermap Operations - ResolveIdentity(HyperwalletRequest), - CreateNote(HyperwalletRequest), - ReadNote(HyperwalletRequest), - SetupDelegation(HyperwalletRequest), - VerifyDelegation(HyperwalletRequest), - MintEntry(HyperwalletRequest), + ResolveIdentity(ResolveIdentityRequest), + CreateNote(CreateNoteRequest), + ReadNote(ReadNoteRequest), + SetupDelegation(SetupDelegationRequest), + VerifyDelegation(VerifyDelegationRequest), + MintEntry(MintEntryRequest), // Process Management (Legacy) - UpdateSpendingLimits(HyperwalletRequest), + UpdateSpendingLimits(UpdateSpendingLimitsRequest), } impl HyperwalletMessage { /// Get the operation type for this message - used for permission checking and routing pub fn operation_type(&self) -> Operation { - match self { + match self.request { // Session Management - HyperwalletMessage::Handshake(_) => Operation::Handshake, - HyperwalletMessage::UnlockWallet(_) => Operation::UnlockWallet, + HyperwalletRequest::Handshake(_) => Operation::Handshake, + HyperwalletRequest::UnlockWallet(_) => Operation::UnlockWallet, // Wallet Lifecycle Management - HyperwalletMessage::CreateWallet(_) => Operation::CreateWallet, - HyperwalletMessage::ImportWallet(_) => Operation::ImportWallet, - HyperwalletMessage::DeleteWallet(_) => Operation::DeleteWallet, - HyperwalletMessage::RenameWallet(_) => Operation::RenameWallet, - HyperwalletMessage::ExportWallet(_) => Operation::ExportWallet, - HyperwalletMessage::ListWallets(_) => Operation::ListWallets, - HyperwalletMessage::GetWalletInfo(_) => Operation::GetWalletInfo, + HyperwalletRequest::CreateWallet(_) => Operation::CreateWallet, + HyperwalletRequest::ImportWallet(_) => Operation::ImportWallet, + HyperwalletRequest::DeleteWallet(_) => Operation::DeleteWallet, + HyperwalletRequest::RenameWallet(_) => Operation::RenameWallet, + HyperwalletRequest::ExportWallet(_) => Operation::ExportWallet, + HyperwalletRequest::ListWallets => Operation::ListWallets, + HyperwalletRequest::GetWalletInfo(_) => Operation::GetWalletInfo, // Ethereum Operations - HyperwalletMessage::SendEth(_) => Operation::SendEth, - HyperwalletMessage::SendToken(_) => Operation::SendToken, - HyperwalletMessage::ApproveToken(_) => Operation::ApproveToken, - HyperwalletMessage::GetBalance(_) => Operation::GetBalance, - HyperwalletMessage::GetTokenBalance(_) => Operation::GetTokenBalance, - HyperwalletMessage::CallContract(_) => Operation::CallContract, - HyperwalletMessage::SignTransaction(_) => Operation::SignTransaction, - HyperwalletMessage::SignMessage(_) => Operation::SignMessage, - HyperwalletMessage::GetTransactionHistory(_) => Operation::GetTransactionHistory, - HyperwalletMessage::EstimateGas(_) => Operation::EstimateGas, - HyperwalletMessage::GetGasPrice(_) => Operation::GetGasPrice, - HyperwalletMessage::GetTransactionReceipt(_) => Operation::GetTransactionReceipt, + HyperwalletRequest::SendEth(_) => Operation::SendEth, + HyperwalletRequest::SendToken(_) => Operation::SendToken, + HyperwalletRequest::ApproveToken(_) => Operation::ApproveToken, + HyperwalletRequest::GetBalance(_) => Operation::GetBalance, + HyperwalletRequest::GetTokenBalance(_) => Operation::GetTokenBalance, + HyperwalletRequest::CallContract(_) => Operation::CallContract, + HyperwalletRequest::SignTransaction(_) => Operation::SignTransaction, + HyperwalletRequest::SignMessage(_) => Operation::SignMessage, + HyperwalletRequest::GetTransactionHistory(_) => Operation::GetTransactionHistory, + HyperwalletRequest::EstimateGas(_) => Operation::EstimateGas, + HyperwalletRequest::GetGasPrice => Operation::GetGasPrice, + HyperwalletRequest::GetTransactionReceipt(_) => Operation::GetTransactionReceipt, // Token Bound Account Operations - HyperwalletMessage::ExecuteViaTba(_) => Operation::ExecuteViaTba, - HyperwalletMessage::CheckTbaOwnership(_) => Operation::CheckTbaOwnership, - HyperwalletMessage::SetupTbaDelegation(_) => Operation::SetupTbaDelegation, + HyperwalletRequest::ExecuteViaTba(_) => Operation::ExecuteViaTba, + HyperwalletRequest::CheckTbaOwnership(_) => Operation::CheckTbaOwnership, + HyperwalletRequest::SetupTbaDelegation(_) => Operation::SetupTbaDelegation, // Account Abstraction (ERC-4337) - HyperwalletMessage::BuildAndSignUserOperationForPayment(_) => { + HyperwalletRequest::BuildAndSignUserOperationForPayment(_) => { Operation::BuildAndSignUserOperationForPayment } - HyperwalletMessage::SubmitUserOperation(_) => Operation::SubmitUserOperation, - HyperwalletMessage::GetUserOperationReceipt(_) => Operation::GetUserOperationReceipt, - HyperwalletMessage::BuildUserOperation(_) => Operation::BuildUserOperation, - HyperwalletMessage::SignUserOperation(_) => Operation::SignUserOperation, - HyperwalletMessage::BuildAndSignUserOperation(_) => { + HyperwalletRequest::SubmitUserOperation(_) => Operation::SubmitUserOperation, + HyperwalletRequest::GetUserOperationReceipt(_) => Operation::GetUserOperationReceipt, + HyperwalletRequest::BuildUserOperation(_) => Operation::BuildUserOperation, + HyperwalletRequest::SignUserOperation(_) => Operation::SignUserOperation, + HyperwalletRequest::BuildAndSignUserOperation(_) => { Operation::BuildAndSignUserOperation } - HyperwalletMessage::EstimateUserOperationGas(_) => Operation::EstimateUserOperationGas, - HyperwalletMessage::ConfigurePaymaster(_) => Operation::ConfigurePaymaster, + HyperwalletRequest::EstimateUserOperationGas(_) => Operation::EstimateUserOperationGas, + HyperwalletRequest::ConfigurePaymaster(_) => Operation::ConfigurePaymaster, // Hypermap Operations - HyperwalletMessage::ResolveIdentity(_) => Operation::ResolveIdentity, - HyperwalletMessage::CreateNote(_) => Operation::CreateNote, - HyperwalletMessage::ReadNote(_) => Operation::ReadNote, - HyperwalletMessage::SetupDelegation(_) => Operation::SetupDelegation, - HyperwalletMessage::VerifyDelegation(_) => Operation::VerifyDelegation, - HyperwalletMessage::MintEntry(_) => Operation::MintEntry, + HyperwalletRequest::ResolveIdentity(_) => Operation::ResolveIdentity, + HyperwalletRequest::CreateNote(_) => Operation::CreateNote, + HyperwalletRequest::ReadNote(_) => Operation::ReadNote, + HyperwalletRequest::SetupDelegation(_) => Operation::SetupDelegation, + HyperwalletRequest::VerifyDelegation(_) => Operation::VerifyDelegation, + HyperwalletRequest::MintEntry(_) => Operation::MintEntry, // Process Management (Legacy) - HyperwalletMessage::UpdateSpendingLimits(_) => Operation::UpdateSpendingLimits, + HyperwalletRequest::UpdateSpendingLimits(_) => Operation::UpdateSpendingLimits, } } } /// Unified response type #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct HyperwalletResponse { +pub struct HyperwalletResponse { pub success: bool, - pub data: Option, + pub data: Option, pub error: Option, pub request_id: Option, } -impl HyperwalletResponse { - pub fn success(data: T) -> Self { +impl HyperwalletResponse { + pub fn success(data: HyperwalletResponseData) -> Self { Self { success: true, data: Some(data), @@ -433,18 +426,6 @@ impl HyperwalletResponse { request_id: None, } } - - pub fn map(self, f: F) -> HyperwalletResponse - where - F: FnOnce(T) -> U, - { - HyperwalletResponse { - success: self.success, - data: self.data.map(f), - error: self.error, - request_id: self.request_id, - } - } } #[derive(Debug, Clone, Serialize, Deserialize)] From 3243620a972fb2d56207b41812987c7f5697a8ba Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 5 Aug 2025 15:54:19 -0700 Subject: [PATCH 2/9] hyperwallet: wit-ify --- hyperware-wit/hyperwallet.wit | 631 ++++++++ hyperware-wit/process-lib.wit | 1 + src/hyperwallet_client/api.rs | 77 +- src/hyperwallet_client/mod.rs | 27 +- src/hyperwallet_client/serde_impls.rs | 1348 +++++++++++++++++ .../serde_request_response_impls.rs | 130 ++ src/hyperwallet_client/serde_variant_impls.rs | 427 ++++++ src/hyperwallet_client/types.rs | 1182 ++++----------- src/signer.rs | 1 + src/wallet.rs | 28 +- 10 files changed, 2864 insertions(+), 988 deletions(-) create mode 100644 hyperware-wit/hyperwallet.wit create mode 100644 src/hyperwallet_client/serde_impls.rs create mode 100644 src/hyperwallet_client/serde_request_response_impls.rs create mode 100644 src/hyperwallet_client/serde_variant_impls.rs diff --git a/hyperware-wit/hyperwallet.wit b/hyperware-wit/hyperwallet.wit new file mode 100644 index 0000000..1e67bc3 --- /dev/null +++ b/hyperware-wit/hyperwallet.wit @@ -0,0 +1,631 @@ +interface hyperwallet { + use standard.{address, process-id, node-id}; + + /// JSON is passed over Wasm boundary as a string + type json = string; + + /// Wallet address (Ethereum address) + type wallet-address = string; + + /// Chain ID for blockchain networks + type chain-id = u64; + + /// Session identifier + type session-id = string; + + /// User operation hash + type user-operation-hash = string; + + /// Cryptographic signature as bytes + type signature = list; + + /// Available operations in the Hyperwallet protocol + enum operation { + handshake, + unlock-wallet, + register-process, + update-spending-limits, + create-wallet, + import-wallet, + delete-wallet, + rename-wallet, + export-wallet, + encrypt-wallet, + decrypt-wallet, + get-wallet-info, + list-wallets, + set-wallet-limits, + send-eth, + send-token, + approve-token, + call-contract, + sign-transaction, + sign-message, + execute-via-tba, + check-tba-ownership, + setup-tba-delegation, + build-and-sign-user-operation-for-payment, + submit-user-operation, + build-user-operation, + sign-user-operation, + build-and-sign-user-operation, + estimate-user-operation-gas, + get-user-operation-receipt, + configure-paymaster, + resolve-identity, + create-note, + read-note, + setup-delegation, + verify-delegation, + mint-entry, + get-balance, + get-token-balance, + get-transaction-history, + estimate-gas, + get-gas-price, + get-transaction-receipt, + batch-operations, + schedule-operation, + cancel-operation, + } + + /// Categories of operations + enum operation-category { + system, + process-management, + wallet-management, + ethereum, + token-bound-account, + erc4337, + hypermap, + query, + advanced, + } + + /// Spending limits configuration + record spending-limits { + per-tx-eth: option, + daily-eth: option, + per-tx-usdc: option, + daily-usdc: option, + daily-reset-at: u64, + spent-today-eth: string, + spent-today-usdc: string, + } + + /// Process permissions + record process-permissions { + address: address, + allowed-operations: list, + spending-limits: option, + updatable-settings: list, + registered-at: u64, + } + + /// Settings that can be updated + enum updatable-setting { + spending-limits, + } + + /// Session information + record session-info { + server-version: string, + session-id: session-id, + registered-permissions: process-permissions, + initial-chain-id: chain-id, + } + + /// Handshake protocol steps + variant handshake-step { + client-hello(client-hello), + server-welcome(server-welcome), + register(register-request), + complete(complete-handshake), + } + + record client-hello { + client-version: string, + client-name: string, + } + + record server-welcome { + server-version: string, + supported-operations: list, + supported-chains: list, + features: list, + } + + record register-request { + required-operations: list, + spending-limits: option, + } + + record complete-handshake { + registered-permissions: process-permissions, + session-id: string, + } + + /// Main message structure + record hyperwallet-message { + request: hyperwallet-request, + session-id: session-id, + } + + /// All possible request types + variant hyperwallet-request { + // Session Management + handshake(handshake-step), + unlock-wallet(unlock-wallet-request), + + // Wallet Lifecycle Management + create-wallet(create-wallet-request), + import-wallet(import-wallet-request), + delete-wallet(delete-wallet-request), + rename-wallet(rename-wallet-request), + export-wallet(export-wallet-request), + list-wallets, + get-wallet-info(get-wallet-info-request), + + // Ethereum Operations + send-eth(send-eth-request), + send-token(send-token-request), + approve-token(approve-token-request), + get-balance(get-balance-request), + get-token-balance(get-token-balance-request), + call-contract(call-contract-request), + sign-transaction(sign-transaction-request), + sign-message(sign-message-request), + get-transaction-history(get-transaction-history-request), + estimate-gas(estimate-gas-request), + get-gas-price, + get-transaction-receipt(get-transaction-receipt-request), + + // Token Bound Account Operations + execute-via-tba(execute-via-tba-request), + check-tba-ownership(check-tba-ownership-request), + setup-tba-delegation(setup-tba-delegation-request), + + // Account Abstraction (ERC-4337) + build-and-sign-user-operation-for-payment(build-and-sign-user-operation-for-payment-request), + submit-user-operation(submit-user-operation-request), + get-user-operation-receipt(get-user-operation-receipt-request), + build-user-operation(build-user-operation-request), + sign-user-operation(sign-user-operation-request), + build-and-sign-user-operation(build-and-sign-user-operation-request), + estimate-user-operation-gas(estimate-user-operation-gas-request), + configure-paymaster(configure-paymaster-request), + + // Hypermap Operations + resolve-identity(resolve-identity-request), + create-note(create-note-request), + read-note(read-note-request), + setup-delegation(setup-delegation-request), + verify-delegation(verify-delegation-request), + mint-entry(mint-entry-request), + + // Process Management + update-spending-limits(update-spending-limits-request), + } + + /// Response structure + record hyperwallet-response { + success: bool, + data: option, + error: option, + request-id: option, + } + + /// Error information + record operation-error { + code: error-code, + message: string, + details: option, + } + + /// Error codes + enum error-code { + permission-denied, + wallet-not-found, + insufficient-funds, + invalid-operation, + invalid-params, + spending-limit-exceeded, + chain-not-allowed, + blockchain-error, + internal-error, + authentication-failed, + wallet-locked, + operation-not-supported, + version-mismatch, + } + + /// Response data variants + variant hyperwallet-response-data { + // Session Management + handshake(handshake-step), + unlock-wallet(unlock-wallet-response), + + // Wallet Lifecycle + create-wallet(create-wallet-response), + import-wallet(import-wallet-response), + delete-wallet(delete-wallet-response), + export-wallet(export-wallet-response), + + // Wallet Queries + list-wallets(list-wallets-response), + get-wallet-info(get-wallet-info-response), + get-balance(get-balance-response), + get-token-balance(get-token-balance-response), + + // Transactions + send-eth(send-eth-response), + send-token(send-token-response), + + // ERC4337 Account Abstraction + build-and-sign-user-operation-for-payment(build-and-sign-user-operation-response), + submit-user-operation(submit-user-operation-response), + get-user-operation-receipt(user-operation-receipt-response), + + // Hypermap + create-note(create-note-response), + + // Token Bound Accounts + execute-via-tba(execute-via-tba-response), + check-tba-ownership(check-tba-ownership-response), + } + + // Request types + + record unlock-wallet-request { + session-id: session-id, + wallet-id: string, + password: string, + } + + record create-wallet-request { + name: string, + password: option, + } + + record import-wallet-request { + name: string, + private-key: string, + password: option, + } + + record delete-wallet-request { + wallet-id: string, + } + + record rename-wallet-request { + wallet-id: string, + new-name: string, + } + + record export-wallet-request { + wallet-id: string, + password: option, + } + + record get-wallet-info-request { + wallet-id: string, + } + + record get-balance-request { + wallet-id: string, + } + + record send-eth-request { + wallet-id: string, + to: string, + amount: string, + } + + record send-token-request { + wallet-id: string, + token-address: string, + to: string, + amount: string, + } + + record approve-token-request { + token-address: string, + spender: string, + amount: string, + } + + record get-token-balance-request { + wallet-id: string, + token-address: string, + } + + record call-contract-request { + to: string, + data: string, + value: option, + } + + record sign-transaction-request { + to: string, + value: string, + data: option, + gas-limit: option, + gas-price: option, + nonce: option, + } + + record sign-message-request { + message: string, + message-type: message-type, + } + + variant message-type { + plain-text, + eip191, + eip712(eip712-data), + } + + record eip712-data { + domain: json, + types: json, + } + + record get-transaction-history-request { + limit: option, + offset: option, + from-block: option, + to-block: option, + } + + record estimate-gas-request { + to: string, + data: option, + value: option, + } + + record get-transaction-receipt-request { + tx-hash: string, + } + + record execute-via-tba-request { + tba-address: string, + target: string, + call-data: string, + value: option, + } + + record check-tba-ownership-request { + tba-address: string, + signer-address: string, + } + + record setup-tba-delegation-request { + tba-address: string, + delegate-address: string, + permissions: list, + } + + record build-and-sign-user-operation-for-payment-request { + eoa-wallet-id: string, + tba-address: string, + target: string, + call-data: string, + use-paymaster: bool, + paymaster-config: option, + password: option, + } + + record paymaster-config { + is-circle-paymaster: bool, + paymaster-address: string, + paymaster-verification-gas: string, + paymaster-post-op-gas: string, + } + + record submit-user-operation-request { + signed-user-operation: json, + entry-point: string, + bundler-url: option, + } + + record get-user-operation-receipt-request { + user-op-hash: string, + } + + record build-user-operation-request { + target: string, + call-data: string, + value: option, + } + + record sign-user-operation-request { + unsigned-user-operation: json, + entry-point: string, + } + + record build-and-sign-user-operation-request { + target: string, + call-data: string, + value: option, + entry-point: string, + } + + record estimate-user-operation-gas-request { + user-operation: json, + entry-point: string, + } + + record configure-paymaster-request { + paymaster-address: string, + paymaster-data: option, + verification-gas-limit: string, + post-op-gas-limit: string, + } + + record resolve-identity-request { + entry-name: string, + } + + record create-note-request { + note-data: json, + metadata: option, + } + + record read-note-request { + note-id: string, + } + + record setup-delegation-request { + delegate-address: string, + permissions: list, + expiry: option, + } + + record verify-delegation-request { + delegate-address: string, + signature: string, + message: string, + } + + record mint-entry-request { + entry-name: string, + metadata: json, + } + + record update-spending-limits-request { + new-limits: spending-limits, + } + + // Response types + + record unlock-wallet-response { + success: bool, + wallet-id: string, + message: string, + } + + record create-wallet-response { + wallet-id: string, + address: string, + name: string, + } + + record import-wallet-response { + wallet-id: string, + address: string, + name: string, + } + + record delete-wallet-response { + success: bool, + wallet-id: string, + message: string, + } + + record export-wallet-response { + address: string, + private-key: string, + } + + record get-wallet-info-response { + wallet-id: string, + address: string, + name: string, + chain-id: chain-id, + is-locked: bool, + } + + record list-wallets-response { + process: string, + wallets: list, + total: u64, + } + + record wallet { + address: wallet-address, + name: option, + chain-id: chain-id, + encrypted: bool, + created-at: option, + last-used: option, + spending-limits: option, + } + + record wallet-spending-limits { + max-per-call: option, + max-total: option, + currency: string, + total-spent: string, + set-at: option, + updated-at: option, + } + + record get-balance-response { + balance: balance, + wallet-id: string, + chain-id: chain-id, + } + + record balance { + formatted: string, + raw: string, + } + + record get-token-balance-response { + balance: string, + formatted: option, + decimals: option, + } + + record send-eth-response { + tx-hash: string, + from-address: string, + to-address: string, + amount: string, + chain-id: chain-id, + } + + record send-token-response { + tx-hash: string, + from-address: string, + to-address: string, + token-address: string, + amount: string, + chain-id: chain-id, + } + + record build-and-sign-user-operation-response { + signed-user-operation: json, + entry-point: string, + ready-to-submit: bool, + } + + record submit-user-operation-response { + user-op-hash: string, + } + + record user-operation-receipt-response { + receipt: option, + user-op-hash: string, + status: string, + } + + record create-note-response { + note-id: string, + content-hash: string, + created-at: u64, + } + + record execute-via-tba-response { + tx-hash: string, + tba-address: string, + target-address: string, + success: bool, + } + + record check-tba-ownership-response { + tba-address: string, + owner-address: string, + is-owned: bool, + } +} diff --git a/hyperware-wit/process-lib.wit b/hyperware-wit/process-lib.wit index 834f96b..c85f693 100644 --- a/hyperware-wit/process-lib.wit +++ b/hyperware-wit/process-lib.wit @@ -1,5 +1,6 @@ world process-lib { import sign; import hypermap-cacher; + import hyperwallet; include lib; } diff --git a/src/hyperwallet_client/api.rs b/src/hyperwallet_client/api.rs index 03fa821..d92e6e4 100644 --- a/src/hyperwallet_client/api.rs +++ b/src/hyperwallet_client/api.rs @@ -1,10 +1,9 @@ use super::types::{ self, Balance, BuildAndSignUserOperationForPaymentRequest, BuildAndSignUserOperationResponse, CreateWalletRequest, ExportWalletResponse, GetTokenBalanceResponse, HyperwalletMessage, - HyperwalletRequest, ImportWalletRequest, ListWalletsResponse, - PaymasterConfig, RenameWalletRequest, SendEthRequest, SendTokenRequest, SessionId, - TxReceipt, UnlockWalletRequest, UserOperationReceiptResponse, - Wallet, + HyperwalletRequest, ImportWalletRequest, ListWalletsResponse, PaymasterConfig, + RenameWalletRequest, SendEthRequest, SendTokenRequest, SessionId, TxReceipt, + UnlockWalletRequest, UserOperationReceiptResponse, Wallet, }; use super::HyperwalletClientError; use crate::wallet; @@ -125,17 +124,15 @@ pub fn get_wallet_info( let response = super::send_message(message)?; match response.data { - Some(types::HyperwalletResponseData::GetWalletInfo(info_response)) => { - Ok(types::Wallet { - address: info_response.address, - name: Some(info_response.name), - chain_id: info_response.chain_id, - encrypted: info_response.is_locked, - created_at: None, - last_used: None, - spending_limits: None, - }) - } + Some(types::HyperwalletResponseData::GetWalletInfo(info_response)) => Ok(types::Wallet { + address: info_response.address, + name: Some(info_response.name), + chain_id: info_response.chain_id, + encrypted: info_response.is_locked, + created_at: None, + last_used: None, + spending_limits: None, + }), _ => Err(HyperwalletClientError::ServerError( types::OperationError::internal_error("Missing or invalid wallet data in response"), )), @@ -293,7 +290,9 @@ pub fn get_balance( let response = super::send_message(message)?; match response.data { - Some(types::HyperwalletResponseData::GetBalance(balance_response)) => Ok(balance_response.balance), + Some(types::HyperwalletResponseData::GetBalance(balance_response)) => { + Ok(balance_response.balance) + } _ => Err(HyperwalletClientError::ServerError( types::OperationError::internal_error("Missing balance data in response"), )), @@ -315,7 +314,9 @@ pub fn get_token_balance( let response = super::send_message(message)?; match response.data { - Some(types::HyperwalletResponseData::GetTokenBalance(balance_response)) => Ok(balance_response), + Some(types::HyperwalletResponseData::GetTokenBalance(balance_response)) => { + Ok(balance_response) + } _ => Err(HyperwalletClientError::ServerError( types::OperationError::internal_error("Missing token balance data in response"), )), @@ -336,20 +337,24 @@ pub fn build_and_sign_user_operation_for_payment( ) -> Result { let message = build_message( session_id, - HyperwalletRequest::BuildAndSignUserOperationForPayment(BuildAndSignUserOperationForPaymentRequest { - eoa_wallet_id: eoa_wallet_id.to_string(), - tba_address: tba_address.to_string(), - target: target.to_string(), - call_data: call_data.to_string(), - use_paymaster, - paymaster_config, - password: password.map(|s| s.to_string()), - }), + HyperwalletRequest::BuildAndSignUserOperationForPayment( + BuildAndSignUserOperationForPaymentRequest { + eoa_wallet_id: eoa_wallet_id.to_string(), + tba_address: tba_address.to_string(), + target: target.to_string(), + call_data: call_data.to_string(), + use_paymaster, + paymaster_config, + password: password.map(|s| s.to_string()), + }, + ), ); let response = super::send_message(message)?; match response.data { - Some(types::HyperwalletResponseData::BuildAndSignUserOperationForPayment(build_response)) => Ok(build_response), + Some(types::HyperwalletResponseData::BuildAndSignUserOperationForPayment( + build_response, + )) => Ok(build_response), _ => Err(HyperwalletClientError::ServerError( types::OperationError::internal_error("Missing UserOperation build response data"), )), @@ -365,7 +370,8 @@ pub fn submit_user_operation( let message = build_message( session_id, HyperwalletRequest::SubmitUserOperation(types::SubmitUserOperationRequest { - signed_user_operation, + signed_user_operation: serde_json::to_string(&signed_user_operation) + .map_err(HyperwalletClientError::Serialization)?, entry_point: entry_point.to_string(), bundler_url: bundler_url.map(|s| s.to_string()), }), @@ -395,7 +401,9 @@ pub fn get_user_operation_receipt( let response = super::send_message(message)?; match response.data { - Some(types::HyperwalletResponseData::GetUserOperationReceipt(receipt_response)) => Ok(receipt_response), + Some(types::HyperwalletResponseData::GetUserOperationReceipt(receipt_response)) => { + Ok(receipt_response) + } _ => Err(HyperwalletClientError::ServerError( types::OperationError::internal_error("Missing UserOperation receipt data in response"), )), @@ -428,7 +436,8 @@ pub fn execute_gasless_payment( let user_op_hash = submit_user_operation( session_id, - build_response.signed_user_operation, + serde_json::from_str(&build_response.signed_user_operation) + .map_err(HyperwalletClientError::Deserialization)?, &build_response.entry_point, None, // bundler_url )?; @@ -445,10 +454,10 @@ pub fn execute_gasless_payment( let tx_hash = receipt_response .receipt .as_ref() - .and_then(|r| r.get("transactionHash")) - .and_then(|h| h.as_str()) - .unwrap_or(&user_op_hash) // Fallback to user op hash - .to_string(); + .and_then(|r| serde_json::from_str::(r).ok()) + .and_then(|v| v.get("transactionHash").cloned()) + .and_then(|h| h.as_str().map(|s| s.to_string())) + .unwrap_or_else(|| user_op_hash.clone()); Ok(tx_hash) } diff --git a/src/hyperwallet_client/mod.rs b/src/hyperwallet_client/mod.rs index 6d8ec8f..43a3ff2 100644 --- a/src/hyperwallet_client/mod.rs +++ b/src/hyperwallet_client/mod.rs @@ -2,6 +2,9 @@ use crate::Request; use thiserror::Error; pub mod api; +pub mod serde_impls; +mod serde_request_response_impls; +mod serde_variant_impls; pub mod types; pub use types::{ Balance, BuildAndSignUserOperationForPaymentRequest, BuildAndSignUserOperationResponse, @@ -45,10 +48,10 @@ pub enum HyperwalletClientError { pub fn initialize(config: HandshakeConfig) -> Result { let client_name = config.client_name.expect("Client name is required"); - let hello_step = types::HandshakeStep::ClientHello { + let hello_step = types::HandshakeStep::ClientHello(types::ClientHello { client_version: "0.1.0".to_string(), client_name, - }; + }); let hello_message = types::HyperwalletMessage { request: types::HyperwalletRequest::Handshake(hello_step), session_id: String::new(), @@ -68,10 +71,7 @@ pub fn initialize(config: HandshakeConfig) -> Result supported_operations, + types::HandshakeStep::ServerWelcome(server_welcome) => server_welcome.supported_operations, _ => { return Err(HyperwalletClientError::ServerError( types::OperationError::internal_error( @@ -94,10 +94,10 @@ pub fn initialize(config: HandshakeConfig) -> Result Result { - Ok(SessionInfo { + types::HandshakeStep::Complete(complete_handshake) => { + Ok(types::SessionInfo { server_version: "0.1.0".to_string(), //lol, server should send it's version - session_id, - registered_permissions, + session_id: complete_handshake.session_id, + registered_permissions: complete_handshake.registered_permissions, initial_chain_id: config.initial_chain_id, }) } diff --git a/src/hyperwallet_client/serde_impls.rs b/src/hyperwallet_client/serde_impls.rs new file mode 100644 index 0000000..c56e71a --- /dev/null +++ b/src/hyperwallet_client/serde_impls.rs @@ -0,0 +1,1348 @@ +use crate::hyperware::process::hyperwallet as wit; +use serde::de::{self, MapAccess, Visitor}; +use serde::ser::{Serialize, SerializeStruct}; +use serde::Deserialize; + +// ============================================================================ +// HyperwalletMessage +// ============================================================================ + +impl Serialize for wit::HyperwalletMessage { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("HyperwalletMessage", 2)?; + state.serialize_field("request", &self.request)?; + state.serialize_field("session_id", &self.session_id)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::HyperwalletMessage { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + Request, + SessionId, + } + + struct HyperwalletMessageVisitor; + + impl<'de> Visitor<'de> for HyperwalletMessageVisitor { + type Value = wit::HyperwalletMessage; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct HyperwalletMessage") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut request = None; + let mut session_id = None; + + while let Some(key) = map.next_key()? { + match key { + Field::Request => { + if request.is_some() { + return Err(de::Error::duplicate_field("request")); + } + request = Some(map.next_value()?); + } + Field::SessionId => { + if session_id.is_some() { + return Err(de::Error::duplicate_field("session_id")); + } + session_id = Some(map.next_value()?); + } + } + } + + let request = request.ok_or_else(|| de::Error::missing_field("request"))?; + let session_id = + session_id.ok_or_else(|| de::Error::missing_field("session_id"))?; + + Ok(wit::HyperwalletMessage { + request, + session_id, + }) + } + } + + const FIELDS: &[&str] = &["request", "session_id"]; + deserializer.deserialize_struct("HyperwalletMessage", FIELDS, HyperwalletMessageVisitor) + } +} + +// ============================================================================ +// HyperwalletResponse +// ============================================================================ + +impl Serialize for wit::HyperwalletResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("HyperwalletResponse", 4)?; + state.serialize_field("success", &self.success)?; + state.serialize_field("data", &self.data)?; + state.serialize_field("error", &self.error)?; + state.serialize_field("request_id", &self.request_id)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::HyperwalletResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + Success, + Data, + Error, + RequestId, + } + + struct HyperwalletResponseVisitor; + + impl<'de> Visitor<'de> for HyperwalletResponseVisitor { + type Value = wit::HyperwalletResponse; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct HyperwalletResponse") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut success = None; + let mut data = None; + let mut error = None; + let mut request_id = None; + + while let Some(key) = map.next_key()? { + match key { + Field::Success => { + if success.is_some() { + return Err(de::Error::duplicate_field("success")); + } + success = Some(map.next_value()?); + } + Field::Data => { + if data.is_some() { + return Err(de::Error::duplicate_field("data")); + } + data = Some(map.next_value()?); + } + Field::Error => { + if error.is_some() { + return Err(de::Error::duplicate_field("error")); + } + error = Some(map.next_value()?); + } + Field::RequestId => { + if request_id.is_some() { + return Err(de::Error::duplicate_field("request_id")); + } + request_id = Some(map.next_value()?); + } + } + } + + let success = success.ok_or_else(|| de::Error::missing_field("success"))?; + + Ok(wit::HyperwalletResponse { + success, + data, + error, + request_id, + }) + } + } + + const FIELDS: &[&str] = &["success", "data", "error", "request_id"]; + deserializer.deserialize_struct("HyperwalletResponse", FIELDS, HyperwalletResponseVisitor) + } +} + +// ============================================================================ +// OperationError +// ============================================================================ + +impl Serialize for wit::OperationError { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("OperationError", 3)?; + state.serialize_field("code", &self.code)?; + state.serialize_field("message", &self.message)?; + state.serialize_field("details", &self.details)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::OperationError { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + Code, + Message, + Details, + } + + struct OperationErrorVisitor; + + impl<'de> Visitor<'de> for OperationErrorVisitor { + type Value = wit::OperationError; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct OperationError") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut code = None; + let mut message = None; + let mut details = None; + + while let Some(key) = map.next_key()? { + match key { + Field::Code => { + if code.is_some() { + return Err(de::Error::duplicate_field("code")); + } + code = Some(map.next_value()?); + } + Field::Message => { + if message.is_some() { + return Err(de::Error::duplicate_field("message")); + } + message = Some(map.next_value()?); + } + Field::Details => { + if details.is_some() { + return Err(de::Error::duplicate_field("details")); + } + details = Some(map.next_value()?); + } + } + } + + let code = code.ok_or_else(|| de::Error::missing_field("code"))?; + let message = message.ok_or_else(|| de::Error::missing_field("message"))?; + + Ok(wit::OperationError { + code, + message, + details, + }) + } + } + + const FIELDS: &[&str] = &["code", "message", "details"]; + deserializer.deserialize_struct("OperationError", FIELDS, OperationErrorVisitor) + } +} + +// ============================================================================ +// ErrorCode enum +// ============================================================================ + +impl Serialize for wit::ErrorCode { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.serialize_str(match self { + wit::ErrorCode::InternalError => "InternalError", + wit::ErrorCode::InvalidParams => "InvalidParams", + wit::ErrorCode::InvalidOperation => "InvalidOperation", + wit::ErrorCode::PermissionDenied => "PermissionDenied", + wit::ErrorCode::WalletNotFound => "WalletNotFound", + wit::ErrorCode::WalletLocked => "WalletLocked", + wit::ErrorCode::AuthenticationFailed => "AuthenticationFailed", + wit::ErrorCode::InsufficientFunds => "InsufficientFunds", + wit::ErrorCode::SpendingLimitExceeded => "SpendingLimitExceeded", + wit::ErrorCode::BlockchainError => "BlockchainError", + wit::ErrorCode::ChainNotAllowed => "ChainNotAllowed", + wit::ErrorCode::OperationNotSupported => "OperationNotSupported", + wit::ErrorCode::VersionMismatch => "VersionMismatch", + }) + } +} + +impl<'a> Deserialize<'a> for wit::ErrorCode { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + let s = String::deserialize(deserializer)?; + match s.as_str() { + "InternalError" => Ok(wit::ErrorCode::InternalError), + "InvalidParams" => Ok(wit::ErrorCode::InvalidParams), + "InvalidOperation" => Ok(wit::ErrorCode::InvalidOperation), + "PermissionDenied" => Ok(wit::ErrorCode::PermissionDenied), + "WalletNotFound" => Ok(wit::ErrorCode::WalletNotFound), + "WalletLocked" => Ok(wit::ErrorCode::WalletLocked), + "AuthenticationFailed" => Ok(wit::ErrorCode::AuthenticationFailed), + "InsufficientFunds" => Ok(wit::ErrorCode::InsufficientFunds), + "SpendingLimitExceeded" => Ok(wit::ErrorCode::SpendingLimitExceeded), + "BlockchainError" => Ok(wit::ErrorCode::BlockchainError), + "ChainNotAllowed" => Ok(wit::ErrorCode::ChainNotAllowed), + "OperationNotSupported" => Ok(wit::ErrorCode::OperationNotSupported), + "VersionMismatch" => Ok(wit::ErrorCode::VersionMismatch), + _ => Err(de::Error::unknown_variant( + &s, + &[ + "InternalError", + "InvalidParams", + "InvalidOperation", + "PermissionDenied", + "WalletNotFound", + "WalletLocked", + "AuthenticationFailed", + "InsufficientFunds", + "SpendingLimitExceeded", + "BlockchainError", + "ChainNotAllowed", + "OperationNotSupported", + "VersionMismatch", + ], + )), + } + } +} // ============================================================================ + // Request Types (Records) + // ============================================================================ + +// CreateWalletRequest +impl Serialize for wit::CreateWalletRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("CreateWalletRequest", 2)?; + state.serialize_field("name", &self.name)?; + state.serialize_field("password", &self.password)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::CreateWalletRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + Name, + Password, + } + + struct CreateWalletRequestVisitor; + + impl<'de> Visitor<'de> for CreateWalletRequestVisitor { + type Value = wit::CreateWalletRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct CreateWalletRequest") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut name = None; + let mut password = None; + + while let Some(key) = map.next_key()? { + match key { + Field::Name => { + if name.is_some() { + return Err(de::Error::duplicate_field("name")); + } + name = Some(map.next_value()?); + } + Field::Password => { + if password.is_some() { + return Err(de::Error::duplicate_field("password")); + } + password = Some(map.next_value()?); + } + } + } + + let name = name.ok_or_else(|| de::Error::missing_field("name"))?; + + Ok(wit::CreateWalletRequest { name, password }) + } + } + + const FIELDS: &[&str] = &["name", "password"]; + deserializer.deserialize_struct("CreateWalletRequest", FIELDS, CreateWalletRequestVisitor) + } +} + +// UnlockWalletRequest +impl Serialize for wit::UnlockWalletRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("UnlockWalletRequest", 3)?; + state.serialize_field("session_id", &self.session_id)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("password", &self.password)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::UnlockWalletRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + SessionId, + WalletId, + Password, + } + + struct UnlockWalletRequestVisitor; + + impl<'de> Visitor<'de> for UnlockWalletRequestVisitor { + type Value = wit::UnlockWalletRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct UnlockWalletRequest") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut session_id = None; + let mut wallet_id = None; + let mut password = None; + + while let Some(key) = map.next_key()? { + match key { + Field::SessionId => { + if session_id.is_some() { + return Err(de::Error::duplicate_field("session_id")); + } + session_id = Some(map.next_value()?); + } + Field::WalletId => { + if wallet_id.is_some() { + return Err(de::Error::duplicate_field("wallet_id")); + } + wallet_id = Some(map.next_value()?); + } + Field::Password => { + if password.is_some() { + return Err(de::Error::duplicate_field("password")); + } + password = Some(map.next_value()?); + } + } + } + + let session_id = + session_id.ok_or_else(|| de::Error::missing_field("session_id"))?; + let wallet_id = wallet_id.ok_or_else(|| de::Error::missing_field("wallet_id"))?; + let password = password.ok_or_else(|| de::Error::missing_field("password"))?; + + Ok(wit::UnlockWalletRequest { + session_id, + wallet_id, + password, + }) + } + } + + const FIELDS: &[&str] = &["session_id", "wallet_id", "password"]; + deserializer.deserialize_struct("UnlockWalletRequest", FIELDS, UnlockWalletRequestVisitor) + } +} + +// ============================================================================ +// Operation enum +// ============================================================================ + +impl Serialize for wit::Operation { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + use wit::Operation::*; + serializer.serialize_str(match self { + Handshake => "Handshake", + UnlockWallet => "UnlockWallet", + RegisterProcess => "RegisterProcess", + UpdateSpendingLimits => "UpdateSpendingLimits", + CreateWallet => "CreateWallet", + ImportWallet => "ImportWallet", + DeleteWallet => "DeleteWallet", + RenameWallet => "RenameWallet", + ExportWallet => "ExportWallet", + EncryptWallet => "EncryptWallet", + DecryptWallet => "DecryptWallet", + GetWalletInfo => "GetWalletInfo", + ListWallets => "ListWallets", + SetWalletLimits => "SetWalletLimits", + SendEth => "SendEth", + SendToken => "SendToken", + ApproveToken => "ApproveToken", + CallContract => "CallContract", + SignTransaction => "SignTransaction", + SignMessage => "SignMessage", + ExecuteViaTba => "ExecuteViaTba", + CheckTbaOwnership => "CheckTbaOwnership", + SetupTbaDelegation => "SetupTbaDelegation", + BuildAndSignUserOperationForPayment => "BuildAndSignUserOperationForPayment", + SubmitUserOperation => "SubmitUserOperation", + BuildUserOperation => "BuildUserOperation", + SignUserOperation => "SignUserOperation", + BuildAndSignUserOperation => "BuildAndSignUserOperation", + EstimateUserOperationGas => "EstimateUserOperationGas", + GetUserOperationReceipt => "GetUserOperationReceipt", + ConfigurePaymaster => "ConfigurePaymaster", + ResolveIdentity => "ResolveIdentity", + CreateNote => "CreateNote", + ReadNote => "ReadNote", + SetupDelegation => "SetupDelegation", + VerifyDelegation => "VerifyDelegation", + MintEntry => "MintEntry", + GetBalance => "GetBalance", + GetTokenBalance => "GetTokenBalance", + GetTransactionHistory => "GetTransactionHistory", + EstimateGas => "EstimateGas", + GetGasPrice => "GetGasPrice", + GetTransactionReceipt => "GetTransactionReceipt", + BatchOperations => "BatchOperations", + ScheduleOperation => "ScheduleOperation", + CancelOperation => "CancelOperation", + }) + } +} + +impl<'a> Deserialize<'a> for wit::Operation { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + let s = String::deserialize(deserializer)?; + use wit::Operation::*; + match s.as_str() { + "Handshake" => Ok(Handshake), + "UnlockWallet" => Ok(UnlockWallet), + "RegisterProcess" => Ok(RegisterProcess), + "UpdateSpendingLimits" => Ok(UpdateSpendingLimits), + "CreateWallet" => Ok(CreateWallet), + "ImportWallet" => Ok(ImportWallet), + "DeleteWallet" => Ok(DeleteWallet), + "RenameWallet" => Ok(RenameWallet), + "ExportWallet" => Ok(ExportWallet), + "EncryptWallet" => Ok(EncryptWallet), + "DecryptWallet" => Ok(DecryptWallet), + "GetWalletInfo" => Ok(GetWalletInfo), + "ListWallets" => Ok(ListWallets), + "SetWalletLimits" => Ok(SetWalletLimits), + "SendEth" => Ok(SendEth), + "SendToken" => Ok(SendToken), + "ApproveToken" => Ok(ApproveToken), + "CallContract" => Ok(CallContract), + "SignTransaction" => Ok(SignTransaction), + "SignMessage" => Ok(SignMessage), + "ExecuteViaTba" => Ok(ExecuteViaTba), + "CheckTbaOwnership" => Ok(CheckTbaOwnership), + "SetupTbaDelegation" => Ok(SetupTbaDelegation), + "BuildAndSignUserOperationForPayment" => Ok(BuildAndSignUserOperationForPayment), + "SubmitUserOperation" => Ok(SubmitUserOperation), + "BuildUserOperation" => Ok(BuildUserOperation), + "SignUserOperation" => Ok(SignUserOperation), + "BuildAndSignUserOperation" => Ok(BuildAndSignUserOperation), + "EstimateUserOperationGas" => Ok(EstimateUserOperationGas), + "GetUserOperationReceipt" => Ok(GetUserOperationReceipt), + "ConfigurePaymaster" => Ok(ConfigurePaymaster), + "ResolveIdentity" => Ok(ResolveIdentity), + "CreateNote" => Ok(CreateNote), + "ReadNote" => Ok(ReadNote), + "SetupDelegation" => Ok(SetupDelegation), + "VerifyDelegation" => Ok(VerifyDelegation), + "MintEntry" => Ok(MintEntry), + "GetBalance" => Ok(GetBalance), + "GetTokenBalance" => Ok(GetTokenBalance), + "GetTransactionHistory" => Ok(GetTransactionHistory), + "EstimateGas" => Ok(EstimateGas), + "GetGasPrice" => Ok(GetGasPrice), + "GetTransactionReceipt" => Ok(GetTransactionReceipt), + "BatchOperations" => Ok(BatchOperations), + "ScheduleOperation" => Ok(ScheduleOperation), + "CancelOperation" => Ok(CancelOperation), + _ => Err(de::Error::unknown_variant(&s, &[])), + } + } +} + +// ============================================================================ +// ProcessPermissions +// ============================================================================ + +impl Serialize for wit::ProcessPermissions { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("ProcessPermissions", 5)?; + state.serialize_field("address", &self.address)?; + state.serialize_field("allowed_operations", &self.allowed_operations)?; + state.serialize_field("spending_limits", &self.spending_limits)?; + state.serialize_field("updatable_settings", &self.updatable_settings)?; + state.serialize_field("registered_at", &self.registered_at)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::ProcessPermissions { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + Address, + AllowedOperations, + SpendingLimits, + UpdatableSettings, + RegisteredAt, + } + + struct ProcessPermissionsVisitor; + + impl<'de> Visitor<'de> for ProcessPermissionsVisitor { + type Value = wit::ProcessPermissions; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct ProcessPermissions") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut address = None; + let mut allowed_operations = None; + let mut spending_limits = None; + let mut updatable_settings = None; + let mut registered_at = None; + + while let Some(key) = map.next_key()? { + match key { + Field::Address => { + if address.is_some() { + return Err(de::Error::duplicate_field("address")); + } + address = Some(map.next_value()?); + } + Field::AllowedOperations => { + if allowed_operations.is_some() { + return Err(de::Error::duplicate_field("allowed_operations")); + } + allowed_operations = Some(map.next_value()?); + } + Field::SpendingLimits => { + if spending_limits.is_some() { + return Err(de::Error::duplicate_field("spending_limits")); + } + spending_limits = Some(map.next_value()?); + } + Field::UpdatableSettings => { + if updatable_settings.is_some() { + return Err(de::Error::duplicate_field("updatable_settings")); + } + updatable_settings = Some(map.next_value()?); + } + Field::RegisteredAt => { + if registered_at.is_some() { + return Err(de::Error::duplicate_field("registered_at")); + } + registered_at = Some(map.next_value()?); + } + } + } + + let address = address.ok_or_else(|| de::Error::missing_field("address"))?; + let allowed_operations = allowed_operations + .ok_or_else(|| de::Error::missing_field("allowed_operations"))?; + let registered_at = + registered_at.ok_or_else(|| de::Error::missing_field("registered_at"))?; + + Ok(wit::ProcessPermissions { + address, + allowed_operations, + spending_limits, + updatable_settings: updatable_settings.unwrap_or_default(), + registered_at, + }) + } + } + + const FIELDS: &[&str] = &[ + "address", + "allowed_operations", + "spending_limits", + "updatable_settings", + "registered_at", + ]; + deserializer.deserialize_struct("ProcessPermissions", FIELDS, ProcessPermissionsVisitor) + } +} + +// ============================================================================ +// SpendingLimits +// ============================================================================ + +impl Serialize for wit::SpendingLimits { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("SpendingLimits", 7)?; + state.serialize_field("per_tx_eth", &self.per_tx_eth)?; + state.serialize_field("daily_eth", &self.daily_eth)?; + state.serialize_field("per_tx_usdc", &self.per_tx_usdc)?; + state.serialize_field("daily_usdc", &self.daily_usdc)?; + state.serialize_field("daily_reset_at", &self.daily_reset_at)?; + state.serialize_field("spent_today_eth", &self.spent_today_eth)?; + state.serialize_field("spent_today_usdc", &self.spent_today_usdc)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::SpendingLimits { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + PerTxEth, + DailyEth, + PerTxUsdc, + DailyUsdc, + DailyResetAt, + SpentTodayEth, + SpentTodayUsdc, + } + + struct SpendingLimitsVisitor; + + impl<'de> Visitor<'de> for SpendingLimitsVisitor { + type Value = wit::SpendingLimits; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct SpendingLimits") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut per_tx_eth = None; + let mut daily_eth = None; + let mut per_tx_usdc = None; + let mut daily_usdc = None; + let mut daily_reset_at = None; + let mut spent_today_eth = None; + let mut spent_today_usdc = None; + + while let Some(key) = map.next_key()? { + match key { + Field::PerTxEth => { + if per_tx_eth.is_some() { + return Err(de::Error::duplicate_field("per_tx_eth")); + } + per_tx_eth = Some(map.next_value()?); + } + Field::DailyEth => { + if daily_eth.is_some() { + return Err(de::Error::duplicate_field("daily_eth")); + } + daily_eth = Some(map.next_value()?); + } + Field::PerTxUsdc => { + if per_tx_usdc.is_some() { + return Err(de::Error::duplicate_field("per_tx_usdc")); + } + per_tx_usdc = Some(map.next_value()?); + } + Field::DailyUsdc => { + if daily_usdc.is_some() { + return Err(de::Error::duplicate_field("daily_usdc")); + } + daily_usdc = Some(map.next_value()?); + } + Field::DailyResetAt => { + if daily_reset_at.is_some() { + return Err(de::Error::duplicate_field("daily_reset_at")); + } + daily_reset_at = Some(map.next_value()?); + } + Field::SpentTodayEth => { + if spent_today_eth.is_some() { + return Err(de::Error::duplicate_field("spent_today_eth")); + } + spent_today_eth = Some(map.next_value()?); + } + Field::SpentTodayUsdc => { + if spent_today_usdc.is_some() { + return Err(de::Error::duplicate_field("spent_today_usdc")); + } + spent_today_usdc = Some(map.next_value()?); + } + } + } + + let daily_reset_at = + daily_reset_at.ok_or_else(|| de::Error::missing_field("daily_reset_at"))?; + let spent_today_eth = + spent_today_eth.ok_or_else(|| de::Error::missing_field("spent_today_eth"))?; + let spent_today_usdc = + spent_today_usdc.ok_or_else(|| de::Error::missing_field("spent_today_usdc"))?; + + Ok(wit::SpendingLimits { + per_tx_eth, + daily_eth, + per_tx_usdc, + daily_usdc, + daily_reset_at, + spent_today_eth, + spent_today_usdc, + }) + } + } + + const FIELDS: &[&str] = &[ + "per_tx_eth", + "daily_eth", + "per_tx_usdc", + "daily_usdc", + "daily_reset_at", + "spent_today_eth", + "spent_today_usdc", + ]; + deserializer.deserialize_struct("SpendingLimits", FIELDS, SpendingLimitsVisitor) + } +} + +// ============================================================================ +// UpdatableSetting enum +// ============================================================================ + +impl Serialize for wit::UpdatableSetting { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + use wit::UpdatableSetting::*; + serializer.serialize_str(match self { + SpendingLimits => "SpendingLimits", + }) + } +} + +impl<'a> Deserialize<'a> for wit::UpdatableSetting { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + let s = String::deserialize(deserializer)?; + use wit::UpdatableSetting::*; + match s.as_str() { + "SpendingLimits" => Ok(SpendingLimits), + _ => Err(de::Error::unknown_variant(&s, &["SpendingLimits"])), + } + } +} + +// ============================================================================ +// HandshakeStep variant type +// ============================================================================ + +impl Serialize for wit::HandshakeStep { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + use wit::HandshakeStep::*; + + match self { + ClientHello(data) => { + let mut state = serializer.serialize_struct("HandshakeStep", 2)?; + state.serialize_field("type", "ClientHello")?; + state.serialize_field("data", data)?; + state.end() + } + ServerWelcome(data) => { + let mut state = serializer.serialize_struct("HandshakeStep", 2)?; + state.serialize_field("type", "ServerWelcome")?; + state.serialize_field("data", data)?; + state.end() + } + Register(data) => { + let mut state = serializer.serialize_struct("HandshakeStep", 2)?; + state.serialize_field("type", "Register")?; + state.serialize_field("data", data)?; + state.end() + } + Complete(data) => { + let mut state = serializer.serialize_struct("HandshakeStep", 2)?; + state.serialize_field("type", "Complete")?; + state.serialize_field("data", data)?; + state.end() + } + } + } +} + +impl<'a> Deserialize<'a> for wit::HandshakeStep { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + struct HandshakeStepVisitor; + + impl<'de> Visitor<'de> for HandshakeStepVisitor { + type Value = wit::HandshakeStep; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a HandshakeStep variant") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut variant_type = None; + let mut data = None; + + while let Some(key) = map.next_key::()? { + match key.as_str() { + "type" => { + if variant_type.is_some() { + return Err(de::Error::duplicate_field("type")); + } + variant_type = Some(map.next_value::()?); + } + "data" => { + if data.is_some() { + return Err(de::Error::duplicate_field("data")); + } + data = Some(map.next_value::()?); + } + _ => { + let _ = map.next_value::()?; + } + } + } + + let variant_type = variant_type.ok_or_else(|| de::Error::missing_field("type"))?; + + use wit::HandshakeStep::*; + match variant_type.as_str() { + "ClientHello" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let hello = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!("Failed to deserialize ClientHello: {}", e)) + })?; + Ok(ClientHello(hello)) + } + "ServerWelcome" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let welcome = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!("Failed to deserialize ServerWelcome: {}", e)) + })?; + Ok(ServerWelcome(welcome)) + } + "Register" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let register = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize RegisterRequest: {}", + e + )) + })?; + Ok(Register(register)) + } + "Complete" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let complete = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CompleteHandshake: {}", + e + )) + })?; + Ok(Complete(complete)) + } + _ => Err(de::Error::unknown_variant( + &variant_type, + &["ClientHello", "ServerWelcome", "Register", "Complete"], + )), + } + } + } + + const FIELDS: &[&str] = &["type", "data"]; + deserializer.deserialize_struct("HandshakeStep", FIELDS, HandshakeStepVisitor) + } +} + +// ClientHello +impl Serialize for wit::ClientHello { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("ClientHello", 2)?; + state.serialize_field("client_version", &self.client_version)?; + state.serialize_field("client_name", &self.client_name)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::ClientHello { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + ClientVersion, + ClientName, + } + + struct ClientHelloVisitor; + + impl<'de> Visitor<'de> for ClientHelloVisitor { + type Value = wit::ClientHello; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct ClientHello") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut client_version = None; + let mut client_name = None; + + while let Some(key) = map.next_key()? { + match key { + Field::ClientVersion => { + if client_version.is_some() { + return Err(de::Error::duplicate_field("client_version")); + } + client_version = Some(map.next_value()?); + } + Field::ClientName => { + if client_name.is_some() { + return Err(de::Error::duplicate_field("client_name")); + } + client_name = Some(map.next_value()?); + } + } + } + + let client_version = + client_version.ok_or_else(|| de::Error::missing_field("client_version"))?; + let client_name = + client_name.ok_or_else(|| de::Error::missing_field("client_name"))?; + + Ok(wit::ClientHello { + client_version, + client_name, + }) + } + } + + const FIELDS: &[&str] = &["client_version", "client_name"]; + deserializer.deserialize_struct("ClientHello", FIELDS, ClientHelloVisitor) + } +} + +// ServerWelcome +impl Serialize for wit::ServerWelcome { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("ServerWelcome", 4)?; + state.serialize_field("server_version", &self.server_version)?; + state.serialize_field("supported_operations", &self.supported_operations)?; + state.serialize_field("supported_chains", &self.supported_chains)?; + state.serialize_field("features", &self.features)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::ServerWelcome { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + ServerVersion, + SupportedOperations, + SupportedChains, + Features, + } + + struct ServerWelcomeVisitor; + + impl<'de> Visitor<'de> for ServerWelcomeVisitor { + type Value = wit::ServerWelcome; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct ServerWelcome") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut server_version = None; + let mut supported_operations = None; + let mut supported_chains = None; + let mut features = None; + + while let Some(key) = map.next_key()? { + match key { + Field::ServerVersion => { + if server_version.is_some() { + return Err(de::Error::duplicate_field("server_version")); + } + server_version = Some(map.next_value()?); + } + Field::SupportedOperations => { + if supported_operations.is_some() { + return Err(de::Error::duplicate_field("supported_operations")); + } + supported_operations = Some(map.next_value()?); + } + Field::SupportedChains => { + if supported_chains.is_some() { + return Err(de::Error::duplicate_field("supported_chains")); + } + supported_chains = Some(map.next_value()?); + } + Field::Features => { + if features.is_some() { + return Err(de::Error::duplicate_field("features")); + } + features = Some(map.next_value()?); + } + } + } + + let server_version = + server_version.ok_or_else(|| de::Error::missing_field("server_version"))?; + let supported_operations = supported_operations + .ok_or_else(|| de::Error::missing_field("supported_operations"))?; + let supported_chains = + supported_chains.ok_or_else(|| de::Error::missing_field("supported_chains"))?; + let features = features.ok_or_else(|| de::Error::missing_field("features"))?; + + Ok(wit::ServerWelcome { + server_version, + supported_operations, + supported_chains, + features, + }) + } + } + + const FIELDS: &[&str] = &[ + "server_version", + "supported_operations", + "supported_chains", + "features", + ]; + deserializer.deserialize_struct("ServerWelcome", FIELDS, ServerWelcomeVisitor) + } +} + +// RegisterRequest +impl Serialize for wit::RegisterRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("RegisterRequest", 2)?; + state.serialize_field("required_operations", &self.required_operations)?; + state.serialize_field("spending_limits", &self.spending_limits)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::RegisterRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + RequiredOperations, + SpendingLimits, + } + + struct RegisterRequestVisitor; + + impl<'de> Visitor<'de> for RegisterRequestVisitor { + type Value = wit::RegisterRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct RegisterRequest") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut required_operations = None; + let mut spending_limits = None; + + while let Some(key) = map.next_key()? { + match key { + Field::RequiredOperations => { + if required_operations.is_some() { + return Err(de::Error::duplicate_field("required_operations")); + } + required_operations = Some(map.next_value()?); + } + Field::SpendingLimits => { + if spending_limits.is_some() { + return Err(de::Error::duplicate_field("spending_limits")); + } + spending_limits = Some(map.next_value()?); + } + } + } + + let required_operations = required_operations + .ok_or_else(|| de::Error::missing_field("required_operations"))?; + + Ok(wit::RegisterRequest { + required_operations, + spending_limits, + }) + } + } + + const FIELDS: &[&str] = &["required_operations", "spending_limits"]; + deserializer.deserialize_struct("RegisterRequest", FIELDS, RegisterRequestVisitor) + } +} + +// CompleteHandshake +impl Serialize for wit::CompleteHandshake { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + let mut state = serializer.serialize_struct("CompleteHandshake", 2)?; + state.serialize_field("session_id", &self.session_id)?; + state.serialize_field("registered_permissions", &self.registered_permissions)?; + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::CompleteHandshake { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "snake_case")] + enum Field { + SessionId, + RegisteredPermissions, + } + + struct CompleteHandshakeVisitor; + + impl<'de> Visitor<'de> for CompleteHandshakeVisitor { + type Value = wit::CompleteHandshake; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("struct CompleteHandshake") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut session_id = None; + let mut registered_permissions = None; + + while let Some(key) = map.next_key()? { + match key { + Field::SessionId => { + if session_id.is_some() { + return Err(de::Error::duplicate_field("session_id")); + } + session_id = Some(map.next_value()?); + } + Field::RegisteredPermissions => { + if registered_permissions.is_some() { + return Err(de::Error::duplicate_field("registered_permissions")); + } + registered_permissions = Some(map.next_value()?); + } + } + } + + let session_id = + session_id.ok_or_else(|| de::Error::missing_field("session_id"))?; + let registered_permissions = registered_permissions + .ok_or_else(|| de::Error::missing_field("registered_permissions"))?; + + Ok(wit::CompleteHandshake { + session_id, + registered_permissions, + }) + } + } + + const FIELDS: &[&str] = &["session_id", "registered_permissions"]; + deserializer.deserialize_struct("CompleteHandshake", FIELDS, CompleteHandshakeVisitor) + } +} diff --git a/src/hyperwallet_client/serde_request_response_impls.rs b/src/hyperwallet_client/serde_request_response_impls.rs new file mode 100644 index 0000000..0cb407a --- /dev/null +++ b/src/hyperwallet_client/serde_request_response_impls.rs @@ -0,0 +1,130 @@ +use crate::hyperware::process::hyperwallet as wit; +use serde::de::{self}; +use serde::ser::Serialize; +use serde::Deserialize; + +// Create a macro to generate stub implementations for request/response types +macro_rules! impl_stub_serde { + ($type:ty, $name:literal) => { + impl Serialize for $type { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + // For now, serialize as debug representation + let json_val = serde_json::json!({ + "type": $name, + "data": format!("{:?}", self) + }); + json_val.serialize(serializer) + } + } + + impl<'a> Deserialize<'a> for $type { + fn deserialize(deserializer: D) -> Result<$type, D::Error> + where + D: serde::de::Deserializer<'a>, + { + let _val = serde_json::Value::deserialize(deserializer)?; + Err(de::Error::custom(concat!($name, " deserialization not yet implemented"))) + } + } + }; +} + +// Request types +impl_stub_serde!( + wit::UpdateSpendingLimitsRequest, + "UpdateSpendingLimitsRequest" +); +impl_stub_serde!(wit::ImportWalletRequest, "ImportWalletRequest"); +impl_stub_serde!(wit::DeleteWalletRequest, "DeleteWalletRequest"); +impl_stub_serde!(wit::RenameWalletRequest, "RenameWalletRequest"); +impl_stub_serde!(wit::ExportWalletRequest, "ExportWalletRequest"); +impl_stub_serde!(wit::GetWalletInfoRequest, "GetWalletInfoRequest"); +impl_stub_serde!(wit::SendEthRequest, "SendEthRequest"); +impl_stub_serde!(wit::SendTokenRequest, "SendTokenRequest"); +impl_stub_serde!(wit::ApproveTokenRequest, "ApproveTokenRequest"); +impl_stub_serde!(wit::GetBalanceRequest, "GetBalanceRequest"); +impl_stub_serde!(wit::GetTokenBalanceRequest, "GetTokenBalanceRequest"); +impl_stub_serde!(wit::CallContractRequest, "CallContractRequest"); +impl_stub_serde!(wit::SignTransactionRequest, "SignTransactionRequest"); +impl_stub_serde!(wit::SignMessageRequest, "SignMessageRequest"); +impl_stub_serde!( + wit::BuildAndSignUserOperationForPaymentRequest, + "BuildAndSignUserOperationForPaymentRequest" +); +impl_stub_serde!( + wit::SubmitUserOperationRequest, + "SubmitUserOperationRequest" +); +impl_stub_serde!( + wit::GetUserOperationReceiptRequest, + "GetUserOperationReceiptRequest" +); +impl_stub_serde!( + wit::GetTransactionHistoryRequest, + "GetTransactionHistoryRequest" +); +impl_stub_serde!(wit::EstimateGasRequest, "EstimateGasRequest"); + +// Response types +impl_stub_serde!(wit::UnlockWalletResponse, "UnlockWalletResponse"); +impl_stub_serde!(wit::CreateWalletResponse, "CreateWalletResponse"); +impl_stub_serde!(wit::ImportWalletResponse, "ImportWalletResponse"); +impl_stub_serde!(wit::DeleteWalletResponse, "DeleteWalletResponse"); +impl_stub_serde!(wit::ExportWalletResponse, "ExportWalletResponse"); +impl_stub_serde!(wit::ListWalletsResponse, "ListWalletsResponse"); +impl_stub_serde!(wit::GetWalletInfoResponse, "GetWalletInfoResponse"); +impl_stub_serde!(wit::GetBalanceResponse, "GetBalanceResponse"); +impl_stub_serde!(wit::GetTokenBalanceResponse, "GetTokenBalanceResponse"); +impl_stub_serde!(wit::SendEthResponse, "SendEthResponse"); +impl_stub_serde!(wit::SendTokenResponse, "SendTokenResponse"); +impl_stub_serde!( + wit::BuildAndSignUserOperationResponse, + "BuildAndSignUserOperationResponse" +); +impl_stub_serde!( + wit::SubmitUserOperationResponse, + "SubmitUserOperationResponse" +); +impl_stub_serde!( + wit::UserOperationReceiptResponse, + "UserOperationReceiptResponse" +); + +// Other request types +impl_stub_serde!( + wit::GetTransactionReceiptRequest, + "GetTransactionReceiptRequest" +); +impl_stub_serde!(wit::BuildUserOperationRequest, "BuildUserOperationRequest"); +impl_stub_serde!(wit::SignUserOperationRequest, "SignUserOperationRequest"); +impl_stub_serde!( + wit::BuildAndSignUserOperationRequest, + "BuildAndSignUserOperationRequest" +); +impl_stub_serde!( + wit::EstimateUserOperationGasRequest, + "EstimateUserOperationGasRequest" +); +impl_stub_serde!(wit::ConfigurePaymasterRequest, "ConfigurePaymasterRequest"); +impl_stub_serde!(wit::ExecuteViaTbaRequest, "ExecuteViaTbaRequest"); +impl_stub_serde!(wit::CheckTbaOwnershipRequest, "CheckTbaOwnershipRequest"); +impl_stub_serde!(wit::SetupTbaDelegationRequest, "SetupTbaDelegationRequest"); +impl_stub_serde!(wit::CreateNoteRequest, "CreateNoteRequest"); +impl_stub_serde!(wit::ReadNoteRequest, "ReadNoteRequest"); +impl_stub_serde!(wit::ResolveIdentityRequest, "ResolveIdentityRequest"); +impl_stub_serde!(wit::SetupDelegationRequest, "SetupDelegationRequest"); +impl_stub_serde!(wit::VerifyDelegationRequest, "VerifyDelegationRequest"); +impl_stub_serde!(wit::MintEntryRequest, "MintEntryRequest"); + +// Other response types +impl_stub_serde!(wit::CreateNoteResponse, "CreateNoteResponse"); +impl_stub_serde!(wit::ExecuteViaTbaResponse, "ExecuteViaTbaResponse"); +impl_stub_serde!(wit::CheckTbaOwnershipResponse, "CheckTbaOwnershipResponse"); + +// Other types that may need serde +impl_stub_serde!(wit::Balance, "Balance"); +impl_stub_serde!(wit::Wallet, "Wallet"); +impl_stub_serde!(wit::WalletSpendingLimits, "WalletSpendingLimits"); diff --git a/src/hyperwallet_client/serde_variant_impls.rs b/src/hyperwallet_client/serde_variant_impls.rs new file mode 100644 index 0000000..81f5e4f --- /dev/null +++ b/src/hyperwallet_client/serde_variant_impls.rs @@ -0,0 +1,427 @@ +use crate::hyperware::process::hyperwallet as wit; +use serde::de::{self, MapAccess, Visitor}; +use serde::ser::{Serialize, SerializeStruct}; +use serde::Deserialize; + +// ============================================================================ +// HyperwalletRequest variant type +// ============================================================================ + +impl Serialize for wit::HyperwalletRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + use wit::HyperwalletRequest::*; + + let mut state = serializer.serialize_struct("HyperwalletRequest", 2)?; + + match self { + Handshake(data) => { + state.serialize_field("type", "Handshake")?; + state.serialize_field("data", data)?; + } + UnlockWallet(data) => { + state.serialize_field("type", "UnlockWallet")?; + state.serialize_field("data", data)?; + } + UpdateSpendingLimits(data) => { + state.serialize_field("type", "UpdateSpendingLimits")?; + state.serialize_field("data", data)?; + } + CreateWallet(data) => { + state.serialize_field("type", "CreateWallet")?; + state.serialize_field("data", data)?; + } + ImportWallet(data) => { + state.serialize_field("type", "ImportWallet")?; + state.serialize_field("data", data)?; + } + DeleteWallet(data) => { + state.serialize_field("type", "DeleteWallet")?; + state.serialize_field("data", data)?; + } + RenameWallet(data) => { + state.serialize_field("type", "RenameWallet")?; + state.serialize_field("data", data)?; + } + ExportWallet(data) => { + state.serialize_field("type", "ExportWallet")?; + state.serialize_field("data", data)?; + } + ListWallets => { + state.serialize_field("type", "ListWallets")?; + state.serialize_field("data", &serde_json::Value::Null)?; + } + GetWalletInfo(data) => { + state.serialize_field("type", "GetWalletInfo")?; + state.serialize_field("data", data)?; + } + SendEth(data) => { + state.serialize_field("type", "SendEth")?; + state.serialize_field("data", data)?; + } + SendToken(data) => { + state.serialize_field("type", "SendToken")?; + state.serialize_field("data", data)?; + } + ApproveToken(data) => { + state.serialize_field("type", "ApproveToken")?; + state.serialize_field("data", data)?; + } + GetBalance(data) => { + state.serialize_field("type", "GetBalance")?; + state.serialize_field("data", data)?; + } + GetTokenBalance(data) => { + state.serialize_field("type", "GetTokenBalance")?; + state.serialize_field("data", data)?; + } + CallContract(data) => { + state.serialize_field("type", "CallContract")?; + state.serialize_field("data", data)?; + } + SignTransaction(data) => { + state.serialize_field("type", "SignTransaction")?; + state.serialize_field("data", data)?; + } + SignMessage(data) => { + state.serialize_field("type", "SignMessage")?; + state.serialize_field("data", data)?; + } + BuildAndSignUserOperationForPayment(data) => { + state.serialize_field("type", "BuildAndSignUserOperationForPayment")?; + state.serialize_field("data", data)?; + } + SubmitUserOperation(data) => { + state.serialize_field("type", "SubmitUserOperation")?; + state.serialize_field("data", data)?; + } + GetUserOperationReceipt(data) => { + state.serialize_field("type", "GetUserOperationReceipt")?; + state.serialize_field("data", data)?; + } + GetTransactionHistory(data) => { + state.serialize_field("type", "GetTransactionHistory")?; + state.serialize_field("data", data)?; + } + EstimateGas(data) => { + state.serialize_field("type", "EstimateGas")?; + state.serialize_field("data", data)?; + } + GetGasPrice => { + state.serialize_field("type", "GetGasPrice")?; + state.serialize_field("data", &serde_json::Value::Null)?; + } + GetTransactionReceipt(data) => { + state.serialize_field("type", "GetTransactionReceipt")?; + state.serialize_field("data", data)?; + } + BuildUserOperation(data) => { + state.serialize_field("type", "BuildUserOperation")?; + state.serialize_field("data", data)?; + } + SignUserOperation(data) => { + state.serialize_field("type", "SignUserOperation")?; + state.serialize_field("data", data)?; + } + BuildAndSignUserOperation(data) => { + state.serialize_field("type", "BuildAndSignUserOperation")?; + state.serialize_field("data", data)?; + } + EstimateUserOperationGas(data) => { + state.serialize_field("type", "EstimateUserOperationGas")?; + state.serialize_field("data", data)?; + } + ConfigurePaymaster(data) => { + state.serialize_field("type", "ConfigurePaymaster")?; + state.serialize_field("data", data)?; + } + ExecuteViaTba(data) => { + state.serialize_field("type", "ExecuteViaTba")?; + state.serialize_field("data", data)?; + } + CheckTbaOwnership(data) => { + state.serialize_field("type", "CheckTbaOwnership")?; + state.serialize_field("data", data)?; + } + SetupTbaDelegation(data) => { + state.serialize_field("type", "SetupTbaDelegation")?; + state.serialize_field("data", data)?; + } + CreateNote(data) => { + state.serialize_field("type", "CreateNote")?; + state.serialize_field("data", data)?; + } + ReadNote(data) => { + state.serialize_field("type", "ReadNote")?; + state.serialize_field("data", data)?; + } + ResolveIdentity(data) => { + state.serialize_field("type", "ResolveIdentity")?; + state.serialize_field("data", data)?; + } + SetupDelegation(data) => { + state.serialize_field("type", "SetupDelegation")?; + state.serialize_field("data", data)?; + } + VerifyDelegation(data) => { + state.serialize_field("type", "VerifyDelegation")?; + state.serialize_field("data", data)?; + } + MintEntry(data) => { + state.serialize_field("type", "MintEntry")?; + state.serialize_field("data", data)?; + } + } + + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::HyperwalletRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + struct HyperwalletRequestVisitor; + + impl<'de> Visitor<'de> for HyperwalletRequestVisitor { + type Value = wit::HyperwalletRequest; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a HyperwalletRequest variant") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut variant_type = None; + let mut data = None; + + while let Some(key) = map.next_key::()? { + match key.as_str() { + "type" => { + if variant_type.is_some() { + return Err(de::Error::duplicate_field("type")); + } + variant_type = Some(map.next_value::()?); + } + "data" => { + if data.is_some() { + return Err(de::Error::duplicate_field("data")); + } + data = Some(map.next_value::()?); + } + _ => { + let _ = map.next_value::()?; + } + } + } + + let variant_type = variant_type.ok_or_else(|| de::Error::missing_field("type"))?; + + use wit::HyperwalletRequest::*; + match variant_type.as_str() { + "Handshake" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let step = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!("Failed to deserialize HandshakeStep: {}", e)) + })?; + Ok(Handshake(step)) + } + "UnlockWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize UnlockWalletRequest: {}", + e + )) + })?; + Ok(UnlockWallet(req)) + } + "CreateWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CreateWalletRequest: {}", + e + )) + })?; + Ok(CreateWallet(req)) + } + "ListWallets" => Ok(ListWallets), + _ => { + // For unimplemented variants, return an error + Err(de::Error::unknown_variant(&variant_type, &[])) + } + } + } + } + + const FIELDS: &[&str] = &["type", "data"]; + deserializer.deserialize_struct("HyperwalletRequest", FIELDS, HyperwalletRequestVisitor) + } +} + +// ============================================================================ +// HyperwalletResponseData variant type +// ============================================================================ + +impl Serialize for wit::HyperwalletResponseData { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + use wit::HyperwalletResponseData::*; + + let mut state = serializer.serialize_struct("HyperwalletResponseData", 2)?; + + match self { + Handshake(data) => { + state.serialize_field("type", "Handshake")?; + state.serialize_field("data", data)?; + } + UnlockWallet(data) => { + state.serialize_field("type", "UnlockWallet")?; + state.serialize_field("data", data)?; + } + CreateWallet(data) => { + state.serialize_field("type", "CreateWallet")?; + state.serialize_field("data", data)?; + } + ImportWallet(data) => { + state.serialize_field("type", "ImportWallet")?; + state.serialize_field("data", data)?; + } + DeleteWallet(data) => { + state.serialize_field("type", "DeleteWallet")?; + state.serialize_field("data", data)?; + } + ExportWallet(data) => { + state.serialize_field("type", "ExportWallet")?; + state.serialize_field("data", data)?; + } + ListWallets(data) => { + state.serialize_field("type", "ListWallets")?; + state.serialize_field("data", data)?; + } + GetWalletInfo(data) => { + state.serialize_field("type", "GetWalletInfo")?; + state.serialize_field("data", data)?; + } + GetBalance(data) => { + state.serialize_field("type", "GetBalance")?; + state.serialize_field("data", data)?; + } + GetTokenBalance(data) => { + state.serialize_field("type", "GetTokenBalance")?; + state.serialize_field("data", data)?; + } + SendEth(data) => { + state.serialize_field("type", "SendEth")?; + state.serialize_field("data", data)?; + } + SendToken(data) => { + state.serialize_field("type", "SendToken")?; + state.serialize_field("data", data)?; + } + BuildAndSignUserOperationForPayment(data) => { + state.serialize_field("type", "BuildAndSignUserOperationForPayment")?; + state.serialize_field("data", data)?; + } + SubmitUserOperation(data) => { + state.serialize_field("type", "SubmitUserOperation")?; + state.serialize_field("data", data)?; + } + GetUserOperationReceipt(data) => { + state.serialize_field("type", "GetUserOperationReceipt")?; + state.serialize_field("data", data)?; + } + CreateNote(data) => { + state.serialize_field("type", "CreateNote")?; + state.serialize_field("data", data)?; + } + ExecuteViaTba(data) => { + state.serialize_field("type", "ExecuteViaTba")?; + state.serialize_field("data", data)?; + } + CheckTbaOwnership(data) => { + state.serialize_field("type", "CheckTbaOwnership")?; + state.serialize_field("data", data)?; + } + } + + state.end() + } +} + +impl<'a> Deserialize<'a> for wit::HyperwalletResponseData { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'a>, + { + struct HyperwalletResponseDataVisitor; + + impl<'de> Visitor<'de> for HyperwalletResponseDataVisitor { + type Value = wit::HyperwalletResponseData; + + fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result { + formatter.write_str("a HyperwalletResponseData variant") + } + + fn visit_map(self, mut map: V) -> Result + where + V: MapAccess<'de>, + { + let mut variant_type = None; + let mut data = None; + + while let Some(key) = map.next_key::()? { + match key.as_str() { + "type" => { + if variant_type.is_some() { + return Err(de::Error::duplicate_field("type")); + } + variant_type = Some(map.next_value::()?); + } + "data" => { + if data.is_some() { + return Err(de::Error::duplicate_field("data")); + } + data = Some(map.next_value::()?); + } + _ => { + let _ = map.next_value::()?; + } + } + } + + let variant_type = variant_type.ok_or_else(|| de::Error::missing_field("type"))?; + + use wit::HyperwalletResponseData::*; + match variant_type.as_str() { + "Handshake" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let step = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!("Failed to deserialize HandshakeStep: {}", e)) + })?; + Ok(Handshake(step)) + } + _ => { + // For unimplemented variants, return an error + Err(de::Error::unknown_variant(&variant_type, &[])) + } + } + } + } + + const FIELDS: &[&str] = &["type", "data"]; + deserializer.deserialize_struct( + "HyperwalletResponseData", + FIELDS, + HyperwalletResponseDataVisitor, + ) + } +} diff --git a/src/hyperwallet_client/types.rs b/src/hyperwallet_client/types.rs index 8833d88..d2aeb2e 100644 --- a/src/hyperwallet_client/types.rs +++ b/src/hyperwallet_client/types.rs @@ -1,192 +1,76 @@ -//! Shared types for the Hyperwallet protocol, used by both the client and the server. - -use serde::{Deserialize, Serialize}; -use std::collections::HashSet; - -pub type ProcessAddress = crate::Address; -pub type WalletAddress = String; -pub type ChainId = u64; -pub type SessionId = String; -pub type UserOperationHash = String; -pub type Signature = Vec; - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)] -pub enum Operation { - Handshake, - UnlockWallet, - RegisterProcess, // Deprecated - UpdateSpendingLimits, - CreateWallet, - ImportWallet, - DeleteWallet, - RenameWallet, - ExportWallet, - EncryptWallet, - DecryptWallet, - GetWalletInfo, - ListWallets, - SetWalletLimits, - SendEth, - SendToken, - ApproveToken, - CallContract, - SignTransaction, - SignMessage, - ExecuteViaTba, - CheckTbaOwnership, - SetupTbaDelegation, - BuildAndSignUserOperationForPayment, - SubmitUserOperation, - BuildUserOperation, - SignUserOperation, - BuildAndSignUserOperation, - EstimateUserOperationGas, - GetUserOperationReceipt, - ConfigurePaymaster, - ResolveIdentity, - CreateNote, - ReadNote, - SetupDelegation, - VerifyDelegation, - MintEntry, - GetBalance, - GetTokenBalance, - GetTransactionHistory, - EstimateGas, - GetGasPrice, - GetTransactionReceipt, - BatchOperations, - ScheduleOperation, - CancelOperation, -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub enum OperationCategory { - System, - ProcessManagement, - WalletManagement, - Ethereum, - TokenBoundAccount, - ERC4337, - Hypermap, - Query, - Advanced, -} - -impl Operation { - pub fn all() -> Vec { - vec![ - Operation::Handshake, - Operation::UnlockWallet, - Operation::RegisterProcess, - Operation::UpdateSpendingLimits, - Operation::CreateWallet, - Operation::ImportWallet, - Operation::DeleteWallet, - Operation::RenameWallet, - Operation::ExportWallet, - Operation::EncryptWallet, - Operation::DecryptWallet, - Operation::GetWalletInfo, - Operation::ListWallets, - Operation::SetWalletLimits, - Operation::SendEth, - Operation::SendToken, - Operation::ApproveToken, - Operation::CallContract, - Operation::SignTransaction, - Operation::SignMessage, - Operation::ExecuteViaTba, - Operation::CheckTbaOwnership, - Operation::SetupTbaDelegation, - Operation::BuildAndSignUserOperationForPayment, - Operation::SubmitUserOperation, - Operation::BuildUserOperation, - Operation::SignUserOperation, - Operation::BuildAndSignUserOperation, - Operation::EstimateUserOperationGas, - Operation::GetUserOperationReceipt, - Operation::ConfigurePaymaster, - Operation::ResolveIdentity, - Operation::CreateNote, - Operation::ReadNote, - Operation::SetupDelegation, - Operation::VerifyDelegation, - Operation::MintEntry, - Operation::GetBalance, - Operation::GetTokenBalance, - Operation::GetTransactionHistory, - Operation::EstimateGas, - Operation::GetGasPrice, - Operation::GetTransactionReceipt, - Operation::BatchOperations, - Operation::ScheduleOperation, - Operation::CancelOperation, - ] +//! Hyperwallet types exposed via WIT interface +//! This module re-exports the WIT-generated types and provides conversion utilities + +use crate::hyperware::process::hyperwallet as wit; + +// Re-export WIT types with original names for backwards compatibility +pub use wit::{ + Balance, ChainId, ClientHello, CompleteHandshake, CreateNoteResponse, CreateWalletRequest, + CreateWalletResponse, DeleteWalletRequest, DeleteWalletResponse, ErrorCode, + ExecuteViaTbaResponse, ExportWalletRequest, ExportWalletResponse, GetBalanceRequest, + GetBalanceResponse, GetTokenBalanceRequest, GetTokenBalanceResponse, GetWalletInfoRequest, + GetWalletInfoResponse, ImportWalletRequest, ImportWalletResponse, ListWalletsResponse, + OperationError, PaymasterConfig, RegisterRequest, RenameWalletRequest, SendEthRequest, + SendEthResponse, SendTokenRequest, SendTokenResponse, ServerWelcome, SessionId, Signature, + SpendingLimits, UnlockWalletRequest, UnlockWalletResponse, UpdatableSetting, UserOperationHash, + UserOperationReceiptResponse, Wallet, WalletAddress, WalletSpendingLimits, +}; + +// Re-export enum variants +pub use wit::{ + HandshakeStep, HyperwalletRequest, HyperwalletResponse, HyperwalletResponseData, MessageType, + Operation, OperationCategory, +}; + +// Implement Default for PaymasterConfig +impl Default for wit::PaymasterConfig { + fn default() -> Self { + Self { + is_circle_paymaster: true, + paymaster_address: "0x0578cFB241215b77442a541325d6A4E6dFE700Ec".to_string(), + paymaster_verification_gas: "0x7a120".to_string(), + paymaster_post_op_gas: "0x493e0".to_string(), + } } +} - pub fn category(&self) -> OperationCategory { - match self { - Operation::Handshake | Operation::UnlockWallet => OperationCategory::System, - - Operation::RegisterProcess | Operation::UpdateSpendingLimits => { - OperationCategory::ProcessManagement - } - - Operation::CreateWallet - | Operation::ImportWallet - | Operation::DeleteWallet - | Operation::RenameWallet - | Operation::ExportWallet - | Operation::EncryptWallet - | Operation::DecryptWallet - | Operation::GetWalletInfo - | Operation::ListWallets - | Operation::SetWalletLimits => OperationCategory::WalletManagement, - - Operation::SendEth - | Operation::SendToken - | Operation::ApproveToken - | Operation::CallContract - | Operation::SignTransaction - | Operation::SignMessage - | Operation::GetBalance - | Operation::GetTokenBalance - | Operation::GetTransactionHistory - | Operation::EstimateGas - | Operation::GetGasPrice - | Operation::GetTransactionReceipt => OperationCategory::Ethereum, - - Operation::ExecuteViaTba - | Operation::CheckTbaOwnership - | Operation::SetupTbaDelegation => OperationCategory::TokenBoundAccount, - - Operation::BuildAndSignUserOperationForPayment - | Operation::SubmitUserOperation - | Operation::BuildUserOperation - | Operation::SignUserOperation - | Operation::BuildAndSignUserOperation - | Operation::EstimateUserOperationGas - | Operation::GetUserOperationReceipt - | Operation::ConfigurePaymaster => OperationCategory::ERC4337, +// Re-export request types +pub use wit::{ + ApproveTokenRequest, BuildAndSignUserOperationForPaymentRequest, + BuildAndSignUserOperationRequest, BuildUserOperationRequest, CallContractRequest, + CheckTbaOwnershipRequest, ConfigurePaymasterRequest, CreateNoteRequest, EstimateGasRequest, + EstimateUserOperationGasRequest, ExecuteViaTbaRequest, GetTransactionHistoryRequest, + GetTransactionReceiptRequest, GetUserOperationReceiptRequest, MintEntryRequest, + ReadNoteRequest, ResolveIdentityRequest, SetupDelegationRequest, SetupTbaDelegationRequest, + SignMessageRequest, SignTransactionRequest, SignUserOperationRequest, + SubmitUserOperationRequest, UpdateSpendingLimitsRequest, VerifyDelegationRequest, +}; + +// Re-export response types +pub use wit::{ + BuildAndSignUserOperationResponse, CheckTbaOwnershipResponse, SubmitUserOperationResponse, +}; + +// Type aliases for compatibility +pub type ProcessAddress = crate::Address; - Operation::ResolveIdentity - | Operation::CreateNote - | Operation::ReadNote - | Operation::SetupDelegation - | Operation::VerifyDelegation - | Operation::MintEntry => OperationCategory::Hypermap, +// Additional types that need conversion or special handling +pub use wit::HyperwalletMessage; +pub use wit::ProcessPermissions; - Operation::BatchOperations - | Operation::ScheduleOperation - | Operation::CancelOperation => OperationCategory::Advanced, - } - } +/// Session information combining handshake completion with metadata +#[derive(Debug, Clone)] +pub struct SessionInfo { + pub server_version: String, + pub session_id: SessionId, + pub registered_permissions: ProcessPermissions, + pub initial_chain_id: ChainId, } +/// Configuration for the handshake process #[derive(Debug)] pub struct HandshakeConfig { - pub(crate) required_operations: HashSet, + pub(crate) required_operations: Vec, pub(crate) spending_limits: Option, pub(crate) client_name: Option, pub(crate) initial_chain_id: ChainId, @@ -195,7 +79,7 @@ pub struct HandshakeConfig { impl Default for HandshakeConfig { fn default() -> Self { Self { - required_operations: HashSet::new(), + required_operations: Vec::new(), spending_limits: None, client_name: None, initial_chain_id: 8453, // Default to Base mainnet @@ -209,16 +93,24 @@ impl HandshakeConfig { } pub fn with_operations(mut self, operations: &[Operation]) -> Self { - self.required_operations.extend(operations.iter().cloned()); + for op in operations { + if !self.required_operations.iter().any(|o| o == op) { + self.required_operations.push(op.clone()); + } + } self } pub fn require_category(mut self, category: OperationCategory) -> Self { - self.required_operations.extend( - Operation::all() - .into_iter() - .filter(|op| op.category() == category), - ); + // Convert operations matching the category + let all_ops = all_operations(); + for op in all_ops { + if operation_category(&op) == category + && !self.required_operations.iter().any(|o| o == &op) + { + self.required_operations.push(op); + } + } self } @@ -238,177 +130,179 @@ impl HandshakeConfig { } } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SessionInfo { - pub server_version: String, - pub session_id: SessionId, - pub registered_permissions: ProcessPermissions, - pub initial_chain_id: ChainId, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "step")] -pub enum HandshakeStep { - ClientHello { - client_version: String, - client_name: String, - }, - ServerWelcome { - server_version: String, - supported_operations: Vec, - supported_chains: Vec, - features: Vec, - }, - Register { - required_operations: Vec, - spending_limits: Option, - }, - Complete { - registered_permissions: ProcessPermissions, - session_id: String, - }, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct HyperwalletMessage { - pub request: HyperwalletRequest, - pub session_id: SessionId, -} - -/// Typed message enum for type-safe communication -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "operation")] -pub enum HyperwalletRequest { - // Session Management (Unauthenticated) - Handshake(HandshakeStep), - - // Session Management (Authenticated) - UnlockWallet(UnlockWalletRequest), - - // Wallet Lifecycle Management - CreateWallet(CreateWalletRequest), - ImportWallet(ImportWalletRequest), - DeleteWallet(DeleteWalletRequest), - RenameWallet(RenameWalletRequest), - ExportWallet(ExportWalletRequest), - ListWallets, - GetWalletInfo(GetWalletInfoRequest), - - // Ethereum Operations - SendEth(SendEthRequest), - SendToken(SendTokenRequest), - ApproveToken(ApproveTokenRequest), - GetBalance(GetBalanceRequest), - GetTokenBalance(GetTokenBalanceRequest), - CallContract(CallContractRequest), - SignTransaction(SignTransactionRequest), - SignMessage(SignMessageRequest), - GetTransactionHistory(GetTransactionHistoryRequest), - EstimateGas(EstimateGasRequest), - GetGasPrice, - GetTransactionReceipt(GetTransactionReceiptRequest), - - // Token Bound Account Operations - ExecuteViaTba(ExecuteViaTbaRequest), - CheckTbaOwnership(CheckTbaOwnershipRequest), - SetupTbaDelegation(SetupTbaDelegationRequest), - - // Account Abstraction (ERC-4337) - BuildAndSignUserOperationForPayment(BuildAndSignUserOperationForPaymentRequest), - SubmitUserOperation(SubmitUserOperationRequest), - GetUserOperationReceipt(GetUserOperationReceiptRequest), - BuildUserOperation(BuildUserOperationRequest), - SignUserOperation(SignUserOperationRequest), - BuildAndSignUserOperation(BuildAndSignUserOperationRequest), - EstimateUserOperationGas(EstimateUserOperationGasRequest), - ConfigurePaymaster(ConfigurePaymasterRequest), - - // Hypermap Operations - ResolveIdentity(ResolveIdentityRequest), - CreateNote(CreateNoteRequest), - ReadNote(ReadNoteRequest), - SetupDelegation(SetupDelegationRequest), - VerifyDelegation(VerifyDelegationRequest), - MintEntry(MintEntryRequest), - - // Process Management (Legacy) - UpdateSpendingLimits(UpdateSpendingLimitsRequest), -} - -impl HyperwalletMessage { - /// Get the operation type for this message - used for permission checking and routing - pub fn operation_type(&self) -> Operation { - match self.request { - // Session Management - HyperwalletRequest::Handshake(_) => Operation::Handshake, - HyperwalletRequest::UnlockWallet(_) => Operation::UnlockWallet, - - // Wallet Lifecycle Management - HyperwalletRequest::CreateWallet(_) => Operation::CreateWallet, - HyperwalletRequest::ImportWallet(_) => Operation::ImportWallet, - HyperwalletRequest::DeleteWallet(_) => Operation::DeleteWallet, - HyperwalletRequest::RenameWallet(_) => Operation::RenameWallet, - HyperwalletRequest::ExportWallet(_) => Operation::ExportWallet, - HyperwalletRequest::ListWallets => Operation::ListWallets, - HyperwalletRequest::GetWalletInfo(_) => Operation::GetWalletInfo, - - // Ethereum Operations - HyperwalletRequest::SendEth(_) => Operation::SendEth, - HyperwalletRequest::SendToken(_) => Operation::SendToken, - HyperwalletRequest::ApproveToken(_) => Operation::ApproveToken, - HyperwalletRequest::GetBalance(_) => Operation::GetBalance, - HyperwalletRequest::GetTokenBalance(_) => Operation::GetTokenBalance, - HyperwalletRequest::CallContract(_) => Operation::CallContract, - HyperwalletRequest::SignTransaction(_) => Operation::SignTransaction, - HyperwalletRequest::SignMessage(_) => Operation::SignMessage, - HyperwalletRequest::GetTransactionHistory(_) => Operation::GetTransactionHistory, - HyperwalletRequest::EstimateGas(_) => Operation::EstimateGas, - HyperwalletRequest::GetGasPrice => Operation::GetGasPrice, - HyperwalletRequest::GetTransactionReceipt(_) => Operation::GetTransactionReceipt, - - // Token Bound Account Operations - HyperwalletRequest::ExecuteViaTba(_) => Operation::ExecuteViaTba, - HyperwalletRequest::CheckTbaOwnership(_) => Operation::CheckTbaOwnership, - HyperwalletRequest::SetupTbaDelegation(_) => Operation::SetupTbaDelegation, - - // Account Abstraction (ERC-4337) - HyperwalletRequest::BuildAndSignUserOperationForPayment(_) => { - Operation::BuildAndSignUserOperationForPayment - } - HyperwalletRequest::SubmitUserOperation(_) => Operation::SubmitUserOperation, - HyperwalletRequest::GetUserOperationReceipt(_) => Operation::GetUserOperationReceipt, - HyperwalletRequest::BuildUserOperation(_) => Operation::BuildUserOperation, - HyperwalletRequest::SignUserOperation(_) => Operation::SignUserOperation, - HyperwalletRequest::BuildAndSignUserOperation(_) => { - Operation::BuildAndSignUserOperation - } - HyperwalletRequest::EstimateUserOperationGas(_) => Operation::EstimateUserOperationGas, - HyperwalletRequest::ConfigurePaymaster(_) => Operation::ConfigurePaymaster, +/// Get all available operations +pub fn all_operations() -> Vec { + vec![ + Operation::Handshake, + Operation::UnlockWallet, + Operation::RegisterProcess, + Operation::UpdateSpendingLimits, + Operation::CreateWallet, + Operation::ImportWallet, + Operation::DeleteWallet, + Operation::RenameWallet, + Operation::ExportWallet, + Operation::EncryptWallet, + Operation::DecryptWallet, + Operation::GetWalletInfo, + Operation::ListWallets, + Operation::SetWalletLimits, + Operation::SendEth, + Operation::SendToken, + Operation::ApproveToken, + Operation::CallContract, + Operation::SignTransaction, + Operation::SignMessage, + Operation::ExecuteViaTba, + Operation::CheckTbaOwnership, + Operation::SetupTbaDelegation, + Operation::BuildAndSignUserOperationForPayment, + Operation::SubmitUserOperation, + Operation::BuildUserOperation, + Operation::SignUserOperation, + Operation::BuildAndSignUserOperation, + Operation::EstimateUserOperationGas, + Operation::GetUserOperationReceipt, + Operation::ConfigurePaymaster, + Operation::ResolveIdentity, + Operation::CreateNote, + Operation::ReadNote, + Operation::SetupDelegation, + Operation::VerifyDelegation, + Operation::MintEntry, + Operation::GetBalance, + Operation::GetTokenBalance, + Operation::GetTransactionHistory, + Operation::EstimateGas, + Operation::GetGasPrice, + Operation::GetTransactionReceipt, + Operation::BatchOperations, + Operation::ScheduleOperation, + Operation::CancelOperation, + ] +} + +/// Get the category for an operation +pub fn operation_category(op: &Operation) -> OperationCategory { + match op { + Operation::Handshake | Operation::UnlockWallet => OperationCategory::System, + + Operation::RegisterProcess | Operation::UpdateSpendingLimits => { + OperationCategory::ProcessManagement + } - // Hypermap Operations - HyperwalletRequest::ResolveIdentity(_) => Operation::ResolveIdentity, - HyperwalletRequest::CreateNote(_) => Operation::CreateNote, - HyperwalletRequest::ReadNote(_) => Operation::ReadNote, - HyperwalletRequest::SetupDelegation(_) => Operation::SetupDelegation, - HyperwalletRequest::VerifyDelegation(_) => Operation::VerifyDelegation, - HyperwalletRequest::MintEntry(_) => Operation::MintEntry, + Operation::CreateWallet + | Operation::ImportWallet + | Operation::DeleteWallet + | Operation::RenameWallet + | Operation::ExportWallet + | Operation::EncryptWallet + | Operation::DecryptWallet + | Operation::GetWalletInfo + | Operation::ListWallets + | Operation::SetWalletLimits => OperationCategory::WalletManagement, + + Operation::SendEth + | Operation::SendToken + | Operation::ApproveToken + | Operation::CallContract + | Operation::SignTransaction + | Operation::SignMessage + | Operation::GetBalance + | Operation::GetTokenBalance + | Operation::GetTransactionHistory + | Operation::EstimateGas + | Operation::GetGasPrice + | Operation::GetTransactionReceipt => OperationCategory::Ethereum, + + Operation::ExecuteViaTba | Operation::CheckTbaOwnership | Operation::SetupTbaDelegation => { + OperationCategory::TokenBoundAccount + } - // Process Management (Legacy) - HyperwalletRequest::UpdateSpendingLimits(_) => Operation::UpdateSpendingLimits, + Operation::BuildAndSignUserOperationForPayment + | Operation::SubmitUserOperation + | Operation::BuildUserOperation + | Operation::SignUserOperation + | Operation::BuildAndSignUserOperation + | Operation::EstimateUserOperationGas + | Operation::GetUserOperationReceipt + | Operation::ConfigurePaymaster => OperationCategory::Erc4337, + + Operation::ResolveIdentity + | Operation::CreateNote + | Operation::ReadNote + | Operation::SetupDelegation + | Operation::VerifyDelegation + | Operation::MintEntry => OperationCategory::Hypermap, + + Operation::BatchOperations | Operation::ScheduleOperation | Operation::CancelOperation => { + OperationCategory::Advanced } } } -/// Unified response type -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct HyperwalletResponse { - pub success: bool, - pub data: Option, - pub error: Option, - pub request_id: Option, +/// Get the operation type for a HyperwalletRequest +pub fn operation_type(request: &HyperwalletRequest) -> Operation { + match request { + // Session Management + HyperwalletRequest::Handshake(_) => Operation::Handshake, + HyperwalletRequest::UnlockWallet(_) => Operation::UnlockWallet, + + // Wallet Lifecycle Management + HyperwalletRequest::CreateWallet(_) => Operation::CreateWallet, + HyperwalletRequest::ImportWallet(_) => Operation::ImportWallet, + HyperwalletRequest::DeleteWallet(_) => Operation::DeleteWallet, + HyperwalletRequest::RenameWallet(_) => Operation::RenameWallet, + HyperwalletRequest::ExportWallet(_) => Operation::ExportWallet, + HyperwalletRequest::ListWallets => Operation::ListWallets, + HyperwalletRequest::GetWalletInfo(_) => Operation::GetWalletInfo, + + // Ethereum Operations + HyperwalletRequest::SendEth(_) => Operation::SendEth, + HyperwalletRequest::SendToken(_) => Operation::SendToken, + HyperwalletRequest::ApproveToken(_) => Operation::ApproveToken, + HyperwalletRequest::GetBalance(_) => Operation::GetBalance, + HyperwalletRequest::GetTokenBalance(_) => Operation::GetTokenBalance, + HyperwalletRequest::CallContract(_) => Operation::CallContract, + HyperwalletRequest::SignTransaction(_) => Operation::SignTransaction, + HyperwalletRequest::SignMessage(_) => Operation::SignMessage, + HyperwalletRequest::GetTransactionHistory(_) => Operation::GetTransactionHistory, + HyperwalletRequest::EstimateGas(_) => Operation::EstimateGas, + HyperwalletRequest::GetGasPrice => Operation::GetGasPrice, + HyperwalletRequest::GetTransactionReceipt(_) => Operation::GetTransactionReceipt, + + // Token Bound Account Operations + HyperwalletRequest::ExecuteViaTba(_) => Operation::ExecuteViaTba, + HyperwalletRequest::CheckTbaOwnership(_) => Operation::CheckTbaOwnership, + HyperwalletRequest::SetupTbaDelegation(_) => Operation::SetupTbaDelegation, + + // Account Abstraction (ERC-4337) + HyperwalletRequest::BuildAndSignUserOperationForPayment(_) => { + Operation::BuildAndSignUserOperationForPayment + } + HyperwalletRequest::SubmitUserOperation(_) => Operation::SubmitUserOperation, + HyperwalletRequest::GetUserOperationReceipt(_) => Operation::GetUserOperationReceipt, + HyperwalletRequest::BuildUserOperation(_) => Operation::BuildUserOperation, + HyperwalletRequest::SignUserOperation(_) => Operation::SignUserOperation, + HyperwalletRequest::BuildAndSignUserOperation(_) => Operation::BuildAndSignUserOperation, + HyperwalletRequest::EstimateUserOperationGas(_) => Operation::EstimateUserOperationGas, + HyperwalletRequest::ConfigurePaymaster(_) => Operation::ConfigurePaymaster, + + // Hypermap Operations + HyperwalletRequest::ResolveIdentity(_) => Operation::ResolveIdentity, + HyperwalletRequest::CreateNote(_) => Operation::CreateNote, + HyperwalletRequest::ReadNote(_) => Operation::ReadNote, + HyperwalletRequest::SetupDelegation(_) => Operation::SetupDelegation, + HyperwalletRequest::VerifyDelegation(_) => Operation::VerifyDelegation, + HyperwalletRequest::MintEntry(_) => Operation::MintEntry, + + // Process Management (Legacy) + HyperwalletRequest::UpdateSpendingLimits(_) => Operation::UpdateSpendingLimits, + } } -impl HyperwalletResponse { +// Helper functions for HyperwalletResponse +impl wit::HyperwalletResponse { pub fn success(data: HyperwalletResponseData) -> Self { Self { success: true, @@ -428,286 +322,8 @@ impl HyperwalletResponse { } } -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BuildAndSignUserOperationForPaymentRequest { - pub eoa_wallet_id: String, - pub tba_address: String, - pub target: String, - pub call_data: String, - pub use_paymaster: bool, - pub paymaster_config: Option, - pub password: Option, -} - -/// Configuration for Circle paymaster (gasless transactions) -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PaymasterConfig { - pub is_circle_paymaster: bool, - pub paymaster_address: String, - pub paymaster_verification_gas: String, - pub paymaster_post_op_gas: String, -} - -impl Default for PaymasterConfig { - fn default() -> Self { - Self { - is_circle_paymaster: true, - paymaster_address: "0x0578cFB241215b77442a541325d6A4E6dFE700Ec".to_string(), // Base Circle paymaster - paymaster_verification_gas: "0x7a120".to_string(), // 500000 - paymaster_post_op_gas: "0x493e0".to_string(), // 300000 - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CreateWalletRequest { - pub name: String, - pub password: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UnlockWalletRequest { - pub session_id: SessionId, - pub wallet_id: String, - pub password: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ImportWalletRequest { - pub name: String, - pub private_key: String, - pub password: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct RenameWalletRequest { - pub wallet_id: String, - pub new_name: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ExportWalletRequest { - pub wallet_id: String, - pub password: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SendEthRequest { - pub wallet_id: String, - pub to: String, - pub amount: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SendTokenRequest { - pub wallet_id: String, - pub token_address: String, - pub to: String, - pub amount: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ApproveTokenRequest { - pub token_address: String, - pub spender: String, - pub amount: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetTokenBalanceRequest { - pub wallet_id: String, - pub token_address: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ExecuteViaTbaRequest { - pub tba_address: String, - pub target: String, - pub call_data: String, - pub value: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CheckTbaOwnershipRequest { - pub tba_address: String, - pub signer_address: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SubmitUserOperationRequest { - pub signed_user_operation: serde_json::Value, - pub entry_point: String, - pub bundler_url: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetUserOperationReceiptRequest { - pub user_op_hash: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ResolveIdentityRequest { - pub entry_name: String, -} - -// === NEW PROPERLY TYPED REQUEST STRUCTS === - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CallContractRequest { - pub to: String, - pub data: String, - pub value: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SignTransactionRequest { - pub to: String, - pub value: String, - pub data: Option, - pub gas_limit: Option, - pub gas_price: Option, - pub nonce: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SignMessageRequest { - pub message: String, - pub message_type: MessageType, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub enum MessageType { - PlainText, - Eip191, - Eip712 { - domain: serde_json::Value, - types: serde_json::Value, - }, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetTransactionHistoryRequest { - pub limit: Option, - pub offset: Option, - pub from_block: Option, - pub to_block: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EstimateGasRequest { - pub to: String, - pub data: Option, - pub value: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetTransactionReceiptRequest { - pub tx_hash: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SetupTbaDelegationRequest { - pub tba_address: String, - pub delegate_address: String, - pub permissions: Vec, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BuildUserOperationRequest { - pub target: String, - pub call_data: String, - pub value: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SignUserOperationRequest { - pub unsigned_user_operation: serde_json::Value, - pub entry_point: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BuildAndSignUserOperationRequest { - pub target: String, - pub call_data: String, - pub value: Option, - pub entry_point: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct EstimateUserOperationGasRequest { - pub user_operation: serde_json::Value, - pub entry_point: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ConfigurePaymasterRequest { - pub paymaster_address: String, - pub paymaster_data: Option, - pub verification_gas_limit: String, - pub post_op_gas_limit: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ReadNoteRequest { - pub note_id: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SetupDelegationRequest { - pub delegate_address: String, - pub permissions: Vec, - pub expiry: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct VerifyDelegationRequest { - pub delegate_address: String, - pub signature: String, - pub message: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct MintEntryRequest { - pub entry_name: String, - pub metadata: serde_json::Value, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UpdateSpendingLimitsRequest { - pub new_limits: SpendingLimits, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CreateNoteRequest { - pub note_data: serde_json::Value, - pub metadata: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DeleteWalletRequest { - pub wallet_id: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetWalletInfoRequest { - pub wallet_id: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetBalanceRequest { - pub wallet_id: String, -} - -// === ESSENTIAL TYPES (NOT LEGACY) === - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct OperationError { - pub code: ErrorCode, - pub message: String, - pub details: Option, -} - -impl OperationError { +// Helper functions for OperationError +impl wit::OperationError { pub fn internal_error(message: &str) -> Self { Self { code: ErrorCode::InternalError, @@ -800,54 +416,19 @@ impl OperationError { } } -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub enum ErrorCode { - PermissionDenied, - WalletNotFound, - InsufficientFunds, - InvalidOperation, - InvalidParams, - SpendingLimitExceeded, - ChainNotAllowed, - BlockchainError, - InternalError, - AuthenticationFailed, - WalletLocked, - OperationNotSupported, - VersionMismatch, -} - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct SpendingLimits { - pub per_tx_eth: Option, - pub daily_eth: Option, - pub per_tx_usdc: Option, - pub daily_usdc: Option, - pub daily_reset_at: u64, - pub spent_today_eth: String, - pub spent_today_usdc: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] -pub enum UpdatableSetting { - SpendingLimits, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ProcessPermissions { - pub address: ProcessAddress, - pub allowed_operations: HashSet, - pub spending_limits: Option, - pub updatable_settings: Vec, - pub registered_at: u64, +// Add operation_type method to HyperwalletMessage +impl wit::HyperwalletMessage { + pub fn operation_type(&self) -> Operation { + operation_type(&self.request) + } } -impl ProcessPermissions { - /// Create new ProcessPermissions for a process during handshake registration +// Conversion function for ProcessPermissions +impl wit::ProcessPermissions { pub fn new(address: crate::Address, required_operations: Vec) -> Self { Self { address, - allowed_operations: required_operations.into_iter().collect(), + allowed_operations: required_operations, spending_limits: None, updatable_settings: vec![], registered_at: std::time::SystemTime::now() @@ -858,258 +439,9 @@ impl ProcessPermissions { } } -// API Result Structs - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UnlockWalletResponse { - pub success: bool, - pub wallet_id: String, - pub message: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CreateWalletResponse { - pub wallet_id: String, - pub address: String, - pub name: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ImportWalletResponse { - pub wallet_id: String, - pub address: String, - pub name: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct DeleteWalletResponse { - pub success: bool, - pub wallet_id: String, - pub message: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetWalletInfoResponse { - pub wallet_id: String, - pub address: String, - pub name: String, - pub chain_id: ChainId, - pub is_locked: bool, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetBalanceResponse { - pub balance: Balance, - pub wallet_id: String, - pub chain_id: ChainId, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SendEthResponse { - pub tx_hash: String, - pub from_address: String, - pub to_address: String, - pub amount: String, - pub chain_id: ChainId, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SendTokenResponse { - pub tx_hash: String, - pub from_address: String, - pub to_address: String, - pub token_address: String, - pub amount: String, - pub chain_id: ChainId, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CreateNoteResponse { - pub note_id: String, - pub content_hash: String, - pub created_at: u64, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ExecuteViaTbaResponse { - pub tx_hash: String, - pub tba_address: String, - pub target_address: String, - pub success: bool, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CheckTbaOwnershipResponse { - pub tba_address: String, - pub owner_address: String, - pub is_owned: bool, -} - -/// Unified response type that preserves type safety for all hyperwallet operations -/// This replaces serde_json::Value in the message dispatcher -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(tag = "operation_type")] -pub enum HyperwalletResponseData { - // Session Management - Handshake(HandshakeStep), - UnlockWallet(UnlockWalletResponse), - - // Wallet Lifecycle - CreateWallet(CreateWalletResponse), - ImportWallet(ImportWalletResponse), - DeleteWallet(DeleteWalletResponse), - ExportWallet(ExportWalletResponse), - - // Wallet Queries - ListWallets(ListWalletsResponse), - GetWalletInfo(GetWalletInfoResponse), - GetBalance(GetBalanceResponse), - GetTokenBalance(GetTokenBalanceResponse), - - // Transactions - SendEth(SendEthResponse), - SendToken(SendTokenResponse), - - // ERC4337 Account Abstraction - BuildAndSignUserOperationForPayment(BuildAndSignUserOperationResponse), - SubmitUserOperation(SubmitUserOperationResponse), - GetUserOperationReceipt(UserOperationReceiptResponse), - - // Hypermap - CreateNote(CreateNoteResponse), - - // Token Bound Accounts - ExecuteViaTba(ExecuteViaTbaResponse), - CheckTbaOwnership(CheckTbaOwnershipResponse), -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Wallet { - pub address: WalletAddress, - pub name: Option, - pub chain_id: ChainId, - pub encrypted: bool, - pub created_at: Option, - pub last_used: Option, - pub spending_limits: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct WalletSpendingLimits { - pub max_per_call: Option, - pub max_total: Option, - pub currency: String, - pub total_spent: String, - pub set_at: Option, - pub updated_at: Option, -} - -#[derive(Debug, Serialize, Deserialize)] +// Legacy type that doesn't exist in WIT - kept for compatibility +#[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct TxReceipt { pub hash: String, pub details: serde_json::Value, } - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct Balance { - pub formatted: String, - pub raw: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct BuildAndSignUserOperationResponse { - pub signed_user_operation: serde_json::Value, - pub entry_point: String, - pub ready_to_submit: bool, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct SubmitUserOperationResponse { - pub user_op_hash: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ExportWalletResponse { - pub address: String, - pub private_key: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct ListWalletsResponse { - pub process: String, - pub wallets: Vec, - pub total: usize, -} - -// === NEW RESPONSE STRUCTS FOR TYPE SAFETY === - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct GetTokenBalanceResponse { - pub balance: String, - pub formatted: Option, - pub decimals: Option, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct UserOperationReceiptResponse { - pub receipt: Option, - pub user_op_hash: String, - pub status: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct CallContractResponse { - pub result: String, - pub gas_used: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SignTransactionResponse { - pub signed_transaction: String, - pub transaction_hash: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct SignMessageResponse { - pub signature: String, - pub message_hash: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct EstimateGasResponse { - pub gas_estimate: String, - pub gas_price: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct GetGasPriceResponse { - pub gas_price: String, - pub fast_gas_price: Option, - pub standard_gas_price: Option, - pub safe_gas_price: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TransactionHistoryResponse { - pub transactions: Vec, - pub total: usize, - pub page: Option, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct TransactionHistoryItem { - pub hash: String, - pub from: String, - pub to: String, - pub value: String, - pub gas_used: Option, - pub timestamp: u64, - pub status: String, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct ResolveIdentityResponse { - pub address: Option, - pub entry_name: String, - pub found: bool, -} diff --git a/src/signer.rs b/src/signer.rs index 3af90f4..21895d5 100644 --- a/src/signer.rs +++ b/src/signer.rs @@ -143,6 +143,7 @@ impl<'de> Deserialize<'de> for LocalSigner { { #[derive(Deserialize)] struct LocalSignerData { + #[allow(dead_code)] address: EthAddress, chain_id: u64, private_key_hex: String, diff --git a/src/wallet.rs b/src/wallet.rs index ddeb181..0f7e6ad 100644 --- a/src/wallet.rs +++ b/src/wallet.rs @@ -2345,7 +2345,7 @@ impl UserOperationBuilder { } /// Calculate the UserOp hash according to ERC-4337 spec - fn get_user_op_hash( + fn _get_user_op_hash( &self, user_op: &UserOperation, entry_point: EthAddress, @@ -2354,7 +2354,7 @@ impl UserOperationBuilder { use sha3::{Digest, Keccak256}; // Pack the UserOp for hashing (without signature) - let packed = self.pack_user_op_for_hash(user_op); + let packed = self._pack_user_op_for_hash(user_op); let user_op_hash = Keccak256::digest(&packed); // Create the final hash with entry point and chain ID @@ -2389,7 +2389,7 @@ impl UserOperationBuilder { } /// Pack UserOp fields for hashing (ERC-4337 specification) - fn pack_user_op_for_hash(&self, user_op: &UserOperation) -> Vec { + fn _pack_user_op_for_hash(&self, user_op: &UserOperation) -> Vec { use sha3::{Digest, Keccak256}; let mut packed = Vec::new(); @@ -2473,11 +2473,11 @@ impl UserOperationBuilder { pub fn paymaster_with_permit( &mut self, paymaster: EthAddress, - token_address: EthAddress, - max_cost: U256, - tba_address: EthAddress, - signer: &S, - provider: &Provider, + _token_address: EthAddress, + _max_cost: U256, + _tba_address: EthAddress, + _signer: &S, + _provider: &Provider, ) -> Result<(), WalletError> { // Use simple Circle format - no permit signature needed // The TBA has already approved the paymaster to spend USDC @@ -2741,8 +2741,8 @@ pub fn encode_usdc_paymaster_data_with_signer( /// This version uses a dummy signature and will fail with AA33 pub fn encode_usdc_paymaster_data( paymaster: EthAddress, - token_address: EthAddress, - max_cost: U256, + _token_address: EthAddress, + _max_cost: U256, ) -> Vec { // Use the new Circle format with default gas limits encode_circle_paymaster_data(paymaster, 500_000, 300_000) @@ -2826,13 +2826,13 @@ pub fn create_erc20_permit_calldata( /// Creates a multicall calldata that combines permit + another operation /// This is useful for TBAs to approve and use tokens in a single transaction pub fn create_multicall_permit_and_execute( - token_address: EthAddress, + _token_address: EthAddress, permit_spender: EthAddress, permit_amount: U256, permit_deadline: U256, - execute_target: EthAddress, - execute_calldata: Vec, - execute_value: U256, + _execute_target: EthAddress, + _execute_calldata: Vec, + _execute_value: U256, ) -> Vec { // Create permit calldata let permit_calldata = create_erc20_permit_calldata( From ac4d308855aa73cdb2eb4fdc98230fb97b81863f Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 5 Aug 2025 16:02:15 -0700 Subject: [PATCH 3/9] hyperwallet: gate behind a feature flag --- Cargo.toml | 9 +++++---- src/lib.rs | 3 +++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 628bd81..c91d63c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ license = "Apache-2.0" [features] logging = ["dep:color-eyre", "dep:tracing", "dep:tracing-error", "dep:tracing-subscriber"] +hyperwallet = [] simulation-mode = [] [dependencies] @@ -25,19 +26,19 @@ alloy = { version = "0.8.1", features = [ "consensus", "network", ] } -hex = "0.4.3" -sha3 = "0.10.8" anyhow = "1.0" base64 = "0.22.1" bincode = "1.3.3" color-eyre = { version = "0.6", features = ["capture-spantrace"], optional = true } +hex = "0.4.3" http = "1.0.0" mime_guess = "2.0" -serde = { version = "1.0", features = ["derive"] } -serde_json = "1.0.120" rand = "0.8" regex = "1.11.1" rmp-serde = "1.1.2" +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0.120" +sha3 = "0.10.8" thiserror = "1.0" tracing = { version = "0.1", optional = true } tracing-error = { version = "0.2", optional = true } diff --git a/src/lib.rs b/src/lib.rs index be83181..baca934 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -56,6 +56,7 @@ pub mod logging; pub mod net; pub mod sign; /// Low-level Ethereum signing operations and key management. +#[cfg(feature = "hyperwallet")] pub mod signer; /// Interact with the sqlite module /// @@ -72,11 +73,13 @@ pub mod timer; /// `vfs:distro:sys` to use this module. pub mod vfs; /// Ethereum wallet management with transaction preparation and submission. +#[cfg(feature = "hyperwallet")] pub mod wallet; /// A set of types and macros for writing "script" processes. pub mod scripting; +#[cfg(feature = "hyperwallet")] pub mod hyperwallet_client; mod types; From 4764ce3dd090d3e7de7a43cd479001c26f450cd4 Mon Sep 17 00:00:00 2001 From: hosted-fornet Date: Tue, 5 Aug 2025 16:35:01 -0700 Subject: [PATCH 4/9] hyperwallet: consolidate wit file --- hyperware-wit/{hyperwallet.wit => hyperwallet:sys-v0.wit} | 5 +++++ 1 file changed, 5 insertions(+) rename hyperware-wit/{hyperwallet.wit => hyperwallet:sys-v0.wit} (99%) diff --git a/hyperware-wit/hyperwallet.wit b/hyperware-wit/hyperwallet:sys-v0.wit similarity index 99% rename from hyperware-wit/hyperwallet.wit rename to hyperware-wit/hyperwallet:sys-v0.wit index 1e67bc3..a65942e 100644 --- a/hyperware-wit/hyperwallet.wit +++ b/hyperware-wit/hyperwallet:sys-v0.wit @@ -629,3 +629,8 @@ interface hyperwallet { is-owned: bool, } } + +world hyperwallet-sys-v0 { + import hyperwallet; + include process-v1; +} From 1b26075977d16bbe8561d7ce8fba3af4e9efed74 Mon Sep 17 00:00:00 2001 From: Hallmane Date: Thu, 7 Aug 2025 00:19:06 +0200 Subject: [PATCH 5/9] :zyzz --- src/hyperwallet_client/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hyperwallet_client/mod.rs b/src/hyperwallet_client/mod.rs index 43a3ff2..9374ae0 100644 --- a/src/hyperwallet_client/mod.rs +++ b/src/hyperwallet_client/mod.rs @@ -141,7 +141,7 @@ pub(crate) fn send_message( message: types::HyperwalletMessage, ) -> Result { // Use local address pattern like HTTP client - hyperwallet is always local - let response = Request::to(("our", "hyperwallet", "hyperwallet", "hallman.hypr")) + let response = Request::to(("our", "hyperwallet", "hyperwallet", "sys")) .body(serde_json::to_vec(&message).map_err(HyperwalletClientError::Serialization)?) .send_and_await_response(5) // 5s timeout .map_err(|e| HyperwalletClientError::Communication(e.into()))? From fb37552af48d5708602171733ddd9ec74b12c215 Mon Sep 17 00:00:00 2001 From: Hallmane Date: Fri, 8 Aug 2025 00:49:44 +0200 Subject: [PATCH 6/9] fixed request/response serde (without diff.diff) --- src/hyperwallet_client/mod.rs | 5 +- src/hyperwallet_client/serde_impls.rs | 14 +- .../serde_request_response_impls.rs | 130 -- .../serde_response_impls.rs | 1959 +++++++++++++++++ src/hyperwallet_client/serde_variant_impls.rs | 186 +- 5 files changed, 2154 insertions(+), 140 deletions(-) delete mode 100644 src/hyperwallet_client/serde_request_response_impls.rs create mode 100644 src/hyperwallet_client/serde_response_impls.rs diff --git a/src/hyperwallet_client/mod.rs b/src/hyperwallet_client/mod.rs index 9374ae0..04a2223 100644 --- a/src/hyperwallet_client/mod.rs +++ b/src/hyperwallet_client/mod.rs @@ -1,9 +1,10 @@ +use crate::println as kiprintln; use crate::Request; use thiserror::Error; pub mod api; pub mod serde_impls; -mod serde_request_response_impls; +mod serde_response_impls; // Proper implementations replacing broken stubs mod serde_variant_impls; pub mod types; pub use types::{ @@ -147,6 +148,8 @@ pub(crate) fn send_message( .map_err(|e| HyperwalletClientError::Communication(e.into()))? .map_err(|e| HyperwalletClientError::Communication(e.into()))?; + kiprintln!("Response: {:?}", response); + let hyperwallet_response: types::HyperwalletResponse = serde_json::from_slice(response.body()).map_err(HyperwalletClientError::Deserialization)?; diff --git a/src/hyperwallet_client/serde_impls.rs b/src/hyperwallet_client/serde_impls.rs index c56e71a..c140b6d 100644 --- a/src/hyperwallet_client/serde_impls.rs +++ b/src/hyperwallet_client/serde_impls.rs @@ -142,19 +142,19 @@ impl<'a> Deserialize<'a> for wit::HyperwalletResponse { if data.is_some() { return Err(de::Error::duplicate_field("data")); } - data = Some(map.next_value()?); + data = map.next_value()?; } Field::Error => { if error.is_some() { return Err(de::Error::duplicate_field("error")); } - error = Some(map.next_value()?); + error = map.next_value()?; } Field::RequestId => { if request_id.is_some() { return Err(de::Error::duplicate_field("request_id")); } - request_id = Some(map.next_value()?); + request_id = map.next_value()?; } } } @@ -338,9 +338,13 @@ impl Serialize for wit::CreateWalletRequest { where S: serde::ser::Serializer, { - let mut state = serializer.serialize_struct("CreateWalletRequest", 2)?; + // Only include password when present to avoid sending null + let field_count = if self.password.is_some() { 2 } else { 1 }; + let mut state = serializer.serialize_struct("CreateWalletRequest", field_count)?; state.serialize_field("name", &self.name)?; - state.serialize_field("password", &self.password)?; + if let Some(ref pwd) = self.password { + state.serialize_field("password", pwd)?; + } state.end() } } diff --git a/src/hyperwallet_client/serde_request_response_impls.rs b/src/hyperwallet_client/serde_request_response_impls.rs deleted file mode 100644 index 0cb407a..0000000 --- a/src/hyperwallet_client/serde_request_response_impls.rs +++ /dev/null @@ -1,130 +0,0 @@ -use crate::hyperware::process::hyperwallet as wit; -use serde::de::{self}; -use serde::ser::Serialize; -use serde::Deserialize; - -// Create a macro to generate stub implementations for request/response types -macro_rules! impl_stub_serde { - ($type:ty, $name:literal) => { - impl Serialize for $type { - fn serialize(&self, serializer: S) -> Result - where - S: serde::ser::Serializer, - { - // For now, serialize as debug representation - let json_val = serde_json::json!({ - "type": $name, - "data": format!("{:?}", self) - }); - json_val.serialize(serializer) - } - } - - impl<'a> Deserialize<'a> for $type { - fn deserialize(deserializer: D) -> Result<$type, D::Error> - where - D: serde::de::Deserializer<'a>, - { - let _val = serde_json::Value::deserialize(deserializer)?; - Err(de::Error::custom(concat!($name, " deserialization not yet implemented"))) - } - } - }; -} - -// Request types -impl_stub_serde!( - wit::UpdateSpendingLimitsRequest, - "UpdateSpendingLimitsRequest" -); -impl_stub_serde!(wit::ImportWalletRequest, "ImportWalletRequest"); -impl_stub_serde!(wit::DeleteWalletRequest, "DeleteWalletRequest"); -impl_stub_serde!(wit::RenameWalletRequest, "RenameWalletRequest"); -impl_stub_serde!(wit::ExportWalletRequest, "ExportWalletRequest"); -impl_stub_serde!(wit::GetWalletInfoRequest, "GetWalletInfoRequest"); -impl_stub_serde!(wit::SendEthRequest, "SendEthRequest"); -impl_stub_serde!(wit::SendTokenRequest, "SendTokenRequest"); -impl_stub_serde!(wit::ApproveTokenRequest, "ApproveTokenRequest"); -impl_stub_serde!(wit::GetBalanceRequest, "GetBalanceRequest"); -impl_stub_serde!(wit::GetTokenBalanceRequest, "GetTokenBalanceRequest"); -impl_stub_serde!(wit::CallContractRequest, "CallContractRequest"); -impl_stub_serde!(wit::SignTransactionRequest, "SignTransactionRequest"); -impl_stub_serde!(wit::SignMessageRequest, "SignMessageRequest"); -impl_stub_serde!( - wit::BuildAndSignUserOperationForPaymentRequest, - "BuildAndSignUserOperationForPaymentRequest" -); -impl_stub_serde!( - wit::SubmitUserOperationRequest, - "SubmitUserOperationRequest" -); -impl_stub_serde!( - wit::GetUserOperationReceiptRequest, - "GetUserOperationReceiptRequest" -); -impl_stub_serde!( - wit::GetTransactionHistoryRequest, - "GetTransactionHistoryRequest" -); -impl_stub_serde!(wit::EstimateGasRequest, "EstimateGasRequest"); - -// Response types -impl_stub_serde!(wit::UnlockWalletResponse, "UnlockWalletResponse"); -impl_stub_serde!(wit::CreateWalletResponse, "CreateWalletResponse"); -impl_stub_serde!(wit::ImportWalletResponse, "ImportWalletResponse"); -impl_stub_serde!(wit::DeleteWalletResponse, "DeleteWalletResponse"); -impl_stub_serde!(wit::ExportWalletResponse, "ExportWalletResponse"); -impl_stub_serde!(wit::ListWalletsResponse, "ListWalletsResponse"); -impl_stub_serde!(wit::GetWalletInfoResponse, "GetWalletInfoResponse"); -impl_stub_serde!(wit::GetBalanceResponse, "GetBalanceResponse"); -impl_stub_serde!(wit::GetTokenBalanceResponse, "GetTokenBalanceResponse"); -impl_stub_serde!(wit::SendEthResponse, "SendEthResponse"); -impl_stub_serde!(wit::SendTokenResponse, "SendTokenResponse"); -impl_stub_serde!( - wit::BuildAndSignUserOperationResponse, - "BuildAndSignUserOperationResponse" -); -impl_stub_serde!( - wit::SubmitUserOperationResponse, - "SubmitUserOperationResponse" -); -impl_stub_serde!( - wit::UserOperationReceiptResponse, - "UserOperationReceiptResponse" -); - -// Other request types -impl_stub_serde!( - wit::GetTransactionReceiptRequest, - "GetTransactionReceiptRequest" -); -impl_stub_serde!(wit::BuildUserOperationRequest, "BuildUserOperationRequest"); -impl_stub_serde!(wit::SignUserOperationRequest, "SignUserOperationRequest"); -impl_stub_serde!( - wit::BuildAndSignUserOperationRequest, - "BuildAndSignUserOperationRequest" -); -impl_stub_serde!( - wit::EstimateUserOperationGasRequest, - "EstimateUserOperationGasRequest" -); -impl_stub_serde!(wit::ConfigurePaymasterRequest, "ConfigurePaymasterRequest"); -impl_stub_serde!(wit::ExecuteViaTbaRequest, "ExecuteViaTbaRequest"); -impl_stub_serde!(wit::CheckTbaOwnershipRequest, "CheckTbaOwnershipRequest"); -impl_stub_serde!(wit::SetupTbaDelegationRequest, "SetupTbaDelegationRequest"); -impl_stub_serde!(wit::CreateNoteRequest, "CreateNoteRequest"); -impl_stub_serde!(wit::ReadNoteRequest, "ReadNoteRequest"); -impl_stub_serde!(wit::ResolveIdentityRequest, "ResolveIdentityRequest"); -impl_stub_serde!(wit::SetupDelegationRequest, "SetupDelegationRequest"); -impl_stub_serde!(wit::VerifyDelegationRequest, "VerifyDelegationRequest"); -impl_stub_serde!(wit::MintEntryRequest, "MintEntryRequest"); - -// Other response types -impl_stub_serde!(wit::CreateNoteResponse, "CreateNoteResponse"); -impl_stub_serde!(wit::ExecuteViaTbaResponse, "ExecuteViaTbaResponse"); -impl_stub_serde!(wit::CheckTbaOwnershipResponse, "CheckTbaOwnershipResponse"); - -// Other types that may need serde -impl_stub_serde!(wit::Balance, "Balance"); -impl_stub_serde!(wit::Wallet, "Wallet"); -impl_stub_serde!(wit::WalletSpendingLimits, "WalletSpendingLimits"); diff --git a/src/hyperwallet_client/serde_response_impls.rs b/src/hyperwallet_client/serde_response_impls.rs new file mode 100644 index 0000000..8eddf26 --- /dev/null +++ b/src/hyperwallet_client/serde_response_impls.rs @@ -0,0 +1,1959 @@ +// Proper serde implementations for request/response types + +use crate::hyperware::process::hyperwallet as wit; +use serde::de::{self, MapAccess, Visitor}; +use serde::ser::SerializeStruct; +use serde::{Deserialize, Serialize}; + +// ============== REQUEST TYPES ============== + +// ImportWalletRequest +impl Serialize for wit::ImportWalletRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ImportWalletRequest", 3)?; + state.serialize_field("name", &self.name)?; + state.serialize_field("private_key", &self.private_key)?; + state.serialize_field("password", &self.password)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ImportWalletRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + name: String, + private_key: String, + password: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ImportWalletRequest { + name: h.name, + private_key: h.private_key, + password: h.password, + }) + } +} + +// DeleteWalletRequest +impl Serialize for wit::DeleteWalletRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("DeleteWalletRequest", 1)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::DeleteWalletRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::DeleteWalletRequest { + wallet_id: h.wallet_id, + }) + } +} + +// RenameWalletRequest +impl Serialize for wit::RenameWalletRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("RenameWalletRequest", 2)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("new_name", &self.new_name)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::RenameWalletRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + new_name: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::RenameWalletRequest { + wallet_id: h.wallet_id, + new_name: h.new_name, + }) + } +} + +// ExportWalletRequest +impl Serialize for wit::ExportWalletRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ExportWalletRequest", 2)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("password", &self.password)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ExportWalletRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + password: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ExportWalletRequest { + wallet_id: h.wallet_id, + password: h.password, + }) + } +} + +// GetWalletInfoRequest +impl Serialize for wit::GetWalletInfoRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetWalletInfoRequest", 1)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetWalletInfoRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetWalletInfoRequest { + wallet_id: h.wallet_id, + }) + } +} + +// SendEthRequest +impl Serialize for wit::SendEthRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SendEthRequest", 3)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("to", &self.to)?; + state.serialize_field("amount", &self.amount)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SendEthRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + to: String, + amount: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SendEthRequest { + wallet_id: h.wallet_id, + to: h.to, + amount: h.amount, + }) + } +} + +// SendTokenRequest +impl Serialize for wit::SendTokenRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SendTokenRequest", 4)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("token_address", &self.token_address)?; + state.serialize_field("to", &self.to)?; + state.serialize_field("amount", &self.amount)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SendTokenRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + token_address: String, + to: String, + amount: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SendTokenRequest { + wallet_id: h.wallet_id, + token_address: h.token_address, + to: h.to, + amount: h.amount, + }) + } +} + +// GetBalanceRequest +impl Serialize for wit::GetBalanceRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetBalanceRequest", 1)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetBalanceRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetBalanceRequest { + wallet_id: h.wallet_id, + }) + } +} + +// GetTokenBalanceRequest +impl Serialize for wit::GetTokenBalanceRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetTokenBalanceRequest", 2)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("token_address", &self.token_address)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetTokenBalanceRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + token_address: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetTokenBalanceRequest { + wallet_id: h.wallet_id, + token_address: h.token_address, + }) + } +} + +// BuildAndSignUserOperationForPaymentRequest +impl Serialize for wit::BuildAndSignUserOperationForPaymentRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = + serializer.serialize_struct("BuildAndSignUserOperationForPaymentRequest", 7)?; + state.serialize_field("eoa_wallet_id", &self.eoa_wallet_id)?; + state.serialize_field("tba_address", &self.tba_address)?; + state.serialize_field("target", &self.target)?; + state.serialize_field("call_data", &self.call_data)?; + state.serialize_field("use_paymaster", &self.use_paymaster)?; + state.serialize_field("paymaster_config", &self.paymaster_config)?; + state.serialize_field("password", &self.password)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::BuildAndSignUserOperationForPaymentRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + eoa_wallet_id: String, + tba_address: String, + target: String, + call_data: String, + use_paymaster: bool, + paymaster_config: Option, + password: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::BuildAndSignUserOperationForPaymentRequest { + eoa_wallet_id: h.eoa_wallet_id, + tba_address: h.tba_address, + target: h.target, + call_data: h.call_data, + use_paymaster: h.use_paymaster, + paymaster_config: h.paymaster_config, + password: h.password, + }) + } +} + +// SubmitUserOperationRequest +impl Serialize for wit::SubmitUserOperationRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SubmitUserOperationRequest", 3)?; + state.serialize_field("signed_user_operation", &self.signed_user_operation)?; + state.serialize_field("entry_point", &self.entry_point)?; + state.serialize_field("bundler_url", &self.bundler_url)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SubmitUserOperationRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + signed_user_operation: String, + entry_point: String, + bundler_url: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SubmitUserOperationRequest { + signed_user_operation: h.signed_user_operation, + entry_point: h.entry_point, + bundler_url: h.bundler_url, + }) + } +} + +// GetUserOperationReceiptRequest +impl Serialize for wit::GetUserOperationReceiptRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetUserOperationReceiptRequest", 1)?; + state.serialize_field("user_op_hash", &self.user_op_hash)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetUserOperationReceiptRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + user_op_hash: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetUserOperationReceiptRequest { + user_op_hash: h.user_op_hash, + }) + } +} + +// ============== RESPONSE TYPES ============== + +// CreateWalletResponse +impl Serialize for wit::CreateWalletResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("CreateWalletResponse", 3)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("address", &self.address)?; + state.serialize_field("name", &self.name)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::CreateWalletResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + address: String, + name: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::CreateWalletResponse { + wallet_id: h.wallet_id, + address: h.address, + name: h.name, + }) + } +} + +// ImportWalletResponse +impl Serialize for wit::ImportWalletResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ImportWalletResponse", 3)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("address", &self.address)?; + state.serialize_field("name", &self.name)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ImportWalletResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + address: String, + name: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ImportWalletResponse { + wallet_id: h.wallet_id, + address: h.address, + name: h.name, + }) + } +} + +// DeleteWalletResponse +impl Serialize for wit::DeleteWalletResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("DeleteWalletResponse", 3)?; + state.serialize_field("success", &self.success)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("message", &self.message)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::DeleteWalletResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + success: bool, + wallet_id: String, + message: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::DeleteWalletResponse { + success: h.success, + wallet_id: h.wallet_id, + message: h.message, + }) + } +} + +// ExportWalletResponse +impl Serialize for wit::ExportWalletResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ExportWalletResponse", 2)?; + state.serialize_field("address", &self.address)?; + state.serialize_field("private_key", &self.private_key)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ExportWalletResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + address: String, + private_key: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ExportWalletResponse { + address: h.address, + private_key: h.private_key, + }) + } +} + +// ListWalletsResponse +impl Serialize for wit::ListWalletsResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ListWalletsResponse", 3)?; + state.serialize_field("process", &self.process)?; + state.serialize_field("wallets", &self.wallets)?; + state.serialize_field("total", &self.total)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ListWalletsResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + process: String, + wallets: Vec, + total: u64, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ListWalletsResponse { + process: h.process, + wallets: h.wallets, + total: h.total, + }) + } +} + +// GetWalletInfoResponse +impl Serialize for wit::GetWalletInfoResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetWalletInfoResponse", 5)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("address", &self.address)?; + state.serialize_field("name", &self.name)?; + state.serialize_field("chain_id", &self.chain_id)?; + state.serialize_field("is_locked", &self.is_locked)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetWalletInfoResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + address: String, + name: String, + chain_id: u64, + is_locked: bool, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetWalletInfoResponse { + wallet_id: h.wallet_id, + address: h.address, + name: h.name, + chain_id: h.chain_id, + is_locked: h.is_locked, + }) + } +} + +// GetBalanceResponse +impl Serialize for wit::GetBalanceResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetBalanceResponse", 3)?; + state.serialize_field("balance", &self.balance)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("chain_id", &self.chain_id)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetBalanceResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + balance: wit::Balance, + wallet_id: String, + chain_id: u64, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetBalanceResponse { + balance: h.balance, + wallet_id: h.wallet_id, + chain_id: h.chain_id, + }) + } +} + +// GetTokenBalanceResponse +impl Serialize for wit::GetTokenBalanceResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetTokenBalanceResponse", 3)?; + state.serialize_field("balance", &self.balance)?; + state.serialize_field("formatted", &self.formatted)?; + state.serialize_field("decimals", &self.decimals)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetTokenBalanceResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + balance: String, + formatted: Option, + decimals: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetTokenBalanceResponse { + balance: h.balance, + formatted: h.formatted, + decimals: h.decimals, + }) + } +} + +// SendEthResponse +impl Serialize for wit::SendEthResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SendEthResponse", 5)?; + state.serialize_field("tx_hash", &self.tx_hash)?; + state.serialize_field("from_address", &self.from_address)?; + state.serialize_field("to_address", &self.to_address)?; + state.serialize_field("amount", &self.amount)?; + state.serialize_field("chain_id", &self.chain_id)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SendEthResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tx_hash: String, + from_address: String, + to_address: String, + amount: String, + chain_id: u64, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SendEthResponse { + tx_hash: h.tx_hash, + from_address: h.from_address, + to_address: h.to_address, + amount: h.amount, + chain_id: h.chain_id, + }) + } +} + +// SendTokenResponse +impl Serialize for wit::SendTokenResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SendTokenResponse", 6)?; + state.serialize_field("tx_hash", &self.tx_hash)?; + state.serialize_field("from_address", &self.from_address)?; + state.serialize_field("to_address", &self.to_address)?; + state.serialize_field("token_address", &self.token_address)?; + state.serialize_field("amount", &self.amount)?; + state.serialize_field("chain_id", &self.chain_id)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SendTokenResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tx_hash: String, + from_address: String, + to_address: String, + token_address: String, + amount: String, + chain_id: u64, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SendTokenResponse { + tx_hash: h.tx_hash, + from_address: h.from_address, + to_address: h.to_address, + token_address: h.token_address, + amount: h.amount, + chain_id: h.chain_id, + }) + } +} + +// UnlockWalletResponse +impl Serialize for wit::UnlockWalletResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("UnlockWalletResponse", 3)?; + state.serialize_field("success", &self.success)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("message", &self.message)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::UnlockWalletResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + success: bool, + wallet_id: String, + message: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::UnlockWalletResponse { + success: h.success, + wallet_id: h.wallet_id, + message: h.message, + }) + } +} + +// BuildAndSignUserOperationResponse +impl Serialize for wit::BuildAndSignUserOperationResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("BuildAndSignUserOperationResponse", 3)?; + state.serialize_field("signed_user_operation", &self.signed_user_operation)?; + state.serialize_field("entry_point", &self.entry_point)?; + state.serialize_field("ready_to_submit", &self.ready_to_submit)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::BuildAndSignUserOperationResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + signed_user_operation: String, + entry_point: String, + ready_to_submit: bool, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::BuildAndSignUserOperationResponse { + signed_user_operation: h.signed_user_operation, + entry_point: h.entry_point, + ready_to_submit: h.ready_to_submit, + }) + } +} + +// SubmitUserOperationResponse +impl Serialize for wit::SubmitUserOperationResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SubmitUserOperationResponse", 1)?; + state.serialize_field("user_op_hash", &self.user_op_hash)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SubmitUserOperationResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + user_op_hash: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SubmitUserOperationResponse { + user_op_hash: h.user_op_hash, + }) + } +} + +// UserOperationReceiptResponse +impl Serialize for wit::UserOperationReceiptResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("UserOperationReceiptResponse", 3)?; + state.serialize_field("receipt", &self.receipt)?; + state.serialize_field("user_op_hash", &self.user_op_hash)?; + state.serialize_field("status", &self.status)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::UserOperationReceiptResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + receipt: Option, + user_op_hash: String, + status: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::UserOperationReceiptResponse { + receipt: h.receipt, + user_op_hash: h.user_op_hash, + status: h.status, + }) + } +} + +// ============== SUPPORTING TYPES ============== + +// Balance +impl Serialize for wit::Balance { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("Balance", 2)?; + state.serialize_field("formatted", &self.formatted)?; + state.serialize_field("raw", &self.raw)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::Balance { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + formatted: String, + raw: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::Balance { + formatted: h.formatted, + raw: h.raw, + }) + } +} + +// Wallet +impl Serialize for wit::Wallet { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("Wallet", 7)?; + state.serialize_field("address", &self.address)?; + state.serialize_field("name", &self.name)?; + state.serialize_field("chain_id", &self.chain_id)?; + state.serialize_field("encrypted", &self.encrypted)?; + state.serialize_field("created_at", &self.created_at)?; + state.serialize_field("last_used", &self.last_used)?; + state.serialize_field("spending_limits", &self.spending_limits)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::Wallet { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + address: String, + name: Option, + chain_id: u64, + encrypted: bool, + created_at: Option, + last_used: Option, + spending_limits: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::Wallet { + address: h.address, + name: h.name, + chain_id: h.chain_id, + encrypted: h.encrypted, + created_at: h.created_at, + last_used: h.last_used, + spending_limits: h.spending_limits, + }) + } +} + +// WalletSpendingLimits +impl Serialize for wit::WalletSpendingLimits { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("WalletSpendingLimits", 6)?; + state.serialize_field("max_per_call", &self.max_per_call)?; + state.serialize_field("max_total", &self.max_total)?; + state.serialize_field("currency", &self.currency)?; + state.serialize_field("total_spent", &self.total_spent)?; + state.serialize_field("set_at", &self.set_at)?; + state.serialize_field("updated_at", &self.updated_at)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::WalletSpendingLimits { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + max_per_call: Option, + max_total: Option, + currency: String, + total_spent: String, + set_at: Option, + updated_at: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::WalletSpendingLimits { + max_per_call: h.max_per_call, + max_total: h.max_total, + currency: h.currency, + total_spent: h.total_spent, + set_at: h.set_at, + updated_at: h.updated_at, + }) + } +} + +// ============== MISSING REQUEST TYPES ============== + +// UpdateSpendingLimitsRequest +impl Serialize for wit::UpdateSpendingLimitsRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("UpdateSpendingLimitsRequest", 1)?; + state.serialize_field("new_limits", &self.new_limits)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::UpdateSpendingLimitsRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + new_limits: wit::SpendingLimits, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::UpdateSpendingLimitsRequest { + new_limits: h.new_limits, + }) + } +} + +// ApproveTokenRequest +impl Serialize for wit::ApproveTokenRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ApproveTokenRequest", 3)?; + state.serialize_field("token_address", &self.token_address)?; + state.serialize_field("spender", &self.spender)?; + state.serialize_field("amount", &self.amount)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ApproveTokenRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + token_address: String, + spender: String, + amount: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ApproveTokenRequest { + token_address: h.token_address, + spender: h.spender, + amount: h.amount, + }) + } +} + +// CallContractRequest +impl Serialize for wit::CallContractRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("CallContractRequest", 3)?; + state.serialize_field("to", &self.to)?; + state.serialize_field("data", &self.data)?; + state.serialize_field("value", &self.value)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::CallContractRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + to: String, + data: String, + value: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::CallContractRequest { + to: h.to, + data: h.data, + value: h.value, + }) + } +} + +// SignTransactionRequest +impl Serialize for wit::SignTransactionRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SignTransactionRequest", 6)?; + state.serialize_field("to", &self.to)?; + state.serialize_field("value", &self.value)?; + state.serialize_field("data", &self.data)?; + state.serialize_field("gas_limit", &self.gas_limit)?; + state.serialize_field("gas_price", &self.gas_price)?; + state.serialize_field("nonce", &self.nonce)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SignTransactionRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + to: String, + value: String, + data: Option, + gas_limit: Option, + gas_price: Option, + nonce: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SignTransactionRequest { + to: h.to, + value: h.value, + data: h.data, + gas_limit: h.gas_limit, + gas_price: h.gas_price, + nonce: h.nonce, + }) + } +} + +// MessageType enum (needed for SignMessageRequest) +impl Serialize for wit::MessageType { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + match self { + wit::MessageType::PlainText => { + serializer.serialize_unit_variant("MessageType", 0, "plain_text") + } + wit::MessageType::Eip191 => { + serializer.serialize_unit_variant("MessageType", 1, "eip191") + } + wit::MessageType::Eip712(data) => { + use serde::ser::SerializeStructVariant; + let mut state = + serializer.serialize_struct_variant("MessageType", 2, "eip712", 1)?; + state.serialize_field("data", data)?; + state.end() + } + } + } +} + +impl<'de> Deserialize<'de> for wit::MessageType { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(rename_all = "snake_case")] + enum MessageTypeHelper { + PlainText, + Eip191, + Eip712 { data: wit::Eip712Data }, + } + + match MessageTypeHelper::deserialize(deserializer)? { + MessageTypeHelper::PlainText => Ok(wit::MessageType::PlainText), + MessageTypeHelper::Eip191 => Ok(wit::MessageType::Eip191), + MessageTypeHelper::Eip712 { data } => Ok(wit::MessageType::Eip712(data)), + } + } +} + +// Eip712Data struct (needed for MessageType::Eip712) +impl Serialize for wit::Eip712Data { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("Eip712Data", 2)?; + state.serialize_field("domain", &self.domain)?; + state.serialize_field("types", &self.types)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::Eip712Data { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + domain: String, + types: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::Eip712Data { + domain: h.domain, + types: h.types, + }) + } +} + +// SignMessageRequest +impl Serialize for wit::SignMessageRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SignMessageRequest", 2)?; + state.serialize_field("message", &self.message)?; + state.serialize_field("message_type", &self.message_type)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SignMessageRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + message: String, + message_type: wit::MessageType, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SignMessageRequest { + message: h.message, + message_type: h.message_type, + }) + } +} + +// GetTransactionHistoryRequest +impl Serialize for wit::GetTransactionHistoryRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetTransactionHistoryRequest", 4)?; + state.serialize_field("limit", &self.limit)?; + state.serialize_field("offset", &self.offset)?; + state.serialize_field("from_block", &self.from_block)?; + state.serialize_field("to_block", &self.to_block)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetTransactionHistoryRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + limit: Option, + offset: Option, + from_block: Option, + to_block: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetTransactionHistoryRequest { + limit: h.limit, + offset: h.offset, + from_block: h.from_block, + to_block: h.to_block, + }) + } +} + +// EstimateGasRequest +impl Serialize for wit::EstimateGasRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("EstimateGasRequest", 3)?; + state.serialize_field("to", &self.to)?; + state.serialize_field("data", &self.data)?; + state.serialize_field("value", &self.value)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::EstimateGasRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + to: String, + data: Option, + value: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::EstimateGasRequest { + to: h.to, + data: h.data, + value: h.value, + }) + } +} + +// GetTransactionReceiptRequest +impl Serialize for wit::GetTransactionReceiptRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("GetTransactionReceiptRequest", 1)?; + state.serialize_field("tx_hash", &self.tx_hash)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::GetTransactionReceiptRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tx_hash: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::GetTransactionReceiptRequest { tx_hash: h.tx_hash }) + } +} + +// BuildUserOperationRequest +impl Serialize for wit::BuildUserOperationRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("BuildUserOperationRequest", 3)?; + state.serialize_field("target", &self.target)?; + state.serialize_field("call_data", &self.call_data)?; + state.serialize_field("value", &self.value)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::BuildUserOperationRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + target: String, + call_data: String, + value: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::BuildUserOperationRequest { + target: h.target, + call_data: h.call_data, + value: h.value, + }) + } +} + +// SignUserOperationRequest +impl Serialize for wit::SignUserOperationRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SignUserOperationRequest", 2)?; + state.serialize_field("unsigned_user_operation", &self.unsigned_user_operation)?; + state.serialize_field("entry_point", &self.entry_point)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SignUserOperationRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + unsigned_user_operation: String, + entry_point: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SignUserOperationRequest { + unsigned_user_operation: h.unsigned_user_operation, + entry_point: h.entry_point, + }) + } +} + +// BuildAndSignUserOperationRequest +impl Serialize for wit::BuildAndSignUserOperationRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("BuildAndSignUserOperationRequest", 4)?; + state.serialize_field("target", &self.target)?; + state.serialize_field("call_data", &self.call_data)?; + state.serialize_field("value", &self.value)?; + state.serialize_field("entry_point", &self.entry_point)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::BuildAndSignUserOperationRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + target: String, + call_data: String, + value: Option, + entry_point: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::BuildAndSignUserOperationRequest { + target: h.target, + call_data: h.call_data, + value: h.value, + entry_point: h.entry_point, + }) + } +} + +// EstimateUserOperationGasRequest +impl Serialize for wit::EstimateUserOperationGasRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("EstimateUserOperationGasRequest", 2)?; + state.serialize_field("user_operation", &self.user_operation)?; + state.serialize_field("entry_point", &self.entry_point)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::EstimateUserOperationGasRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + user_operation: String, + entry_point: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::EstimateUserOperationGasRequest { + user_operation: h.user_operation, + entry_point: h.entry_point, + }) + } +} + +// ConfigurePaymasterRequest +impl Serialize for wit::ConfigurePaymasterRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ConfigurePaymasterRequest", 4)?; + state.serialize_field("paymaster_address", &self.paymaster_address)?; + state.serialize_field("paymaster_data", &self.paymaster_data)?; + state.serialize_field("verification_gas_limit", &self.verification_gas_limit)?; + state.serialize_field("post_op_gas_limit", &self.post_op_gas_limit)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ConfigurePaymasterRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + paymaster_address: String, + paymaster_data: Option, + verification_gas_limit: String, + post_op_gas_limit: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ConfigurePaymasterRequest { + paymaster_address: h.paymaster_address, + paymaster_data: h.paymaster_data, + verification_gas_limit: h.verification_gas_limit, + post_op_gas_limit: h.post_op_gas_limit, + }) + } +} + +// ExecuteViaTbaRequest +impl Serialize for wit::ExecuteViaTbaRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ExecuteViaTbaRequest", 4)?; + state.serialize_field("tba_address", &self.tba_address)?; + state.serialize_field("target", &self.target)?; + state.serialize_field("call_data", &self.call_data)?; + state.serialize_field("value", &self.value)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ExecuteViaTbaRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tba_address: String, + target: String, + call_data: String, + value: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ExecuteViaTbaRequest { + tba_address: h.tba_address, + target: h.target, + call_data: h.call_data, + value: h.value, + }) + } +} + +// CheckTbaOwnershipRequest +impl Serialize for wit::CheckTbaOwnershipRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("CheckTbaOwnershipRequest", 2)?; + state.serialize_field("tba_address", &self.tba_address)?; + state.serialize_field("signer_address", &self.signer_address)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::CheckTbaOwnershipRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tba_address: String, + signer_address: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::CheckTbaOwnershipRequest { + tba_address: h.tba_address, + signer_address: h.signer_address, + }) + } +} + +// SetupTbaDelegationRequest +impl Serialize for wit::SetupTbaDelegationRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SetupTbaDelegationRequest", 3)?; + state.serialize_field("tba_address", &self.tba_address)?; + state.serialize_field("delegate_address", &self.delegate_address)?; + state.serialize_field("permissions", &self.permissions)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SetupTbaDelegationRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tba_address: String, + delegate_address: String, + permissions: Vec, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SetupTbaDelegationRequest { + tba_address: h.tba_address, + delegate_address: h.delegate_address, + permissions: h.permissions, + }) + } +} + +// CreateNoteRequest +impl Serialize for wit::CreateNoteRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("CreateNoteRequest", 2)?; + state.serialize_field("note_data", &self.note_data)?; + state.serialize_field("metadata", &self.metadata)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::CreateNoteRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + note_data: String, + metadata: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::CreateNoteRequest { + note_data: h.note_data, + metadata: h.metadata, + }) + } +} + +// ReadNoteRequest +impl Serialize for wit::ReadNoteRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ReadNoteRequest", 1)?; + state.serialize_field("note_id", &self.note_id)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ReadNoteRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + note_id: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ReadNoteRequest { note_id: h.note_id }) + } +} + +// ResolveIdentityRequest +impl Serialize for wit::ResolveIdentityRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ResolveIdentityRequest", 1)?; + state.serialize_field("entry_name", &self.entry_name)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ResolveIdentityRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + entry_name: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ResolveIdentityRequest { + entry_name: h.entry_name, + }) + } +} + +// SetupDelegationRequest +impl Serialize for wit::SetupDelegationRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SetupDelegationRequest", 3)?; + state.serialize_field("delegate_address", &self.delegate_address)?; + state.serialize_field("permissions", &self.permissions)?; + state.serialize_field("expiry", &self.expiry)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SetupDelegationRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + delegate_address: String, + permissions: Vec, + expiry: Option, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SetupDelegationRequest { + delegate_address: h.delegate_address, + permissions: h.permissions, + expiry: h.expiry, + }) + } +} + +// VerifyDelegationRequest +impl Serialize for wit::VerifyDelegationRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("VerifyDelegationRequest", 3)?; + state.serialize_field("delegate_address", &self.delegate_address)?; + state.serialize_field("signature", &self.signature)?; + state.serialize_field("message", &self.message)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::VerifyDelegationRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + delegate_address: String, + signature: String, + message: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::VerifyDelegationRequest { + delegate_address: h.delegate_address, + signature: h.signature, + message: h.message, + }) + } +} + +// MintEntryRequest +impl Serialize for wit::MintEntryRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("MintEntryRequest", 2)?; + state.serialize_field("entry_name", &self.entry_name)?; + state.serialize_field("metadata", &self.metadata)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::MintEntryRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + entry_name: String, + metadata: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::MintEntryRequest { + entry_name: h.entry_name, + metadata: h.metadata, + }) + } +} + +// ============== MISSING RESPONSE TYPES ============== + +// CreateNoteResponse +impl Serialize for wit::CreateNoteResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("CreateNoteResponse", 3)?; + state.serialize_field("note_id", &self.note_id)?; + state.serialize_field("content_hash", &self.content_hash)?; + state.serialize_field("created_at", &self.created_at)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::CreateNoteResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + note_id: String, + content_hash: String, + created_at: u64, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::CreateNoteResponse { + note_id: h.note_id, + content_hash: h.content_hash, + created_at: h.created_at, + }) + } +} + +// ExecuteViaTbaResponse +impl Serialize for wit::ExecuteViaTbaResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("ExecuteViaTbaResponse", 4)?; + state.serialize_field("tx_hash", &self.tx_hash)?; + state.serialize_field("tba_address", &self.tba_address)?; + state.serialize_field("target_address", &self.target_address)?; + state.serialize_field("success", &self.success)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::ExecuteViaTbaResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tx_hash: String, + tba_address: String, + target_address: String, + success: bool, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::ExecuteViaTbaResponse { + tx_hash: h.tx_hash, + tba_address: h.tba_address, + target_address: h.target_address, + success: h.success, + }) + } +} + +// CheckTbaOwnershipResponse +impl Serialize for wit::CheckTbaOwnershipResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("CheckTbaOwnershipResponse", 3)?; + state.serialize_field("tba_address", &self.tba_address)?; + state.serialize_field("owner_address", &self.owner_address)?; + state.serialize_field("is_owned", &self.is_owned)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::CheckTbaOwnershipResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + tba_address: String, + owner_address: String, + is_owned: bool, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::CheckTbaOwnershipResponse { + tba_address: h.tba_address, + owner_address: h.owner_address, + is_owned: h.is_owned, + }) + } +} + +// PaymasterConfig +impl Serialize for wit::PaymasterConfig { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("PaymasterConfig", 4)?; + state.serialize_field("is_circle_paymaster", &self.is_circle_paymaster)?; + state.serialize_field("paymaster_address", &self.paymaster_address)?; + state.serialize_field( + "paymaster_verification_gas", + &self.paymaster_verification_gas, + )?; + state.serialize_field("paymaster_post_op_gas", &self.paymaster_post_op_gas)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::PaymasterConfig { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + is_circle_paymaster: bool, + paymaster_address: String, + paymaster_verification_gas: String, + paymaster_post_op_gas: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::PaymasterConfig { + is_circle_paymaster: h.is_circle_paymaster, + paymaster_address: h.paymaster_address, + paymaster_verification_gas: h.paymaster_verification_gas, + paymaster_post_op_gas: h.paymaster_post_op_gas, + }) + } +} diff --git a/src/hyperwallet_client/serde_variant_impls.rs b/src/hyperwallet_client/serde_variant_impls.rs index 81f5e4f..e68852c 100644 --- a/src/hyperwallet_client/serde_variant_impls.rs +++ b/src/hyperwallet_client/serde_variant_impls.rs @@ -252,9 +252,83 @@ impl<'a> Deserialize<'a> for wit::HyperwalletRequest { Ok(CreateWallet(req)) } "ListWallets" => Ok(ListWallets), + "GetWalletInfo" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetWalletInfoRequest: {}", + e + )) + })?; + Ok(GetWalletInfo(req)) + } + "GetBalance" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetBalanceRequest: {}", + e + )) + })?; + Ok(GetBalance(req)) + } + "GetTokenBalance" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetTokenBalanceRequest: {}", + e + )) + })?; + Ok(GetTokenBalance(req)) + } + "BuildAndSignUserOperationForPayment" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize BuildAndSignUserOperationForPaymentRequest: {}", + e + )) + })?; + Ok(BuildAndSignUserOperationForPayment(req)) + } + "SubmitUserOperation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SubmitUserOperationRequest: {}", + e + )) + })?; + Ok(SubmitUserOperation(req)) + } + "GetUserOperationReceipt" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetUserOperationReceiptRequest: {}", + e + )) + })?; + Ok(GetUserOperationReceipt(req)) + } _ => { - // For unimplemented variants, return an error - Err(de::Error::unknown_variant(&variant_type, &[])) + // For unimplemented variants, return an error with helpful message + Err(de::Error::unknown_variant( + &variant_type, + &[ + "Handshake", + "UnlockWallet", + "CreateWallet", + "ListWallets", + "GetWalletInfo", + "GetBalance", + "GetTokenBalance", + "BuildAndSignUserOperationForPayment", + "SubmitUserOperation", + "GetUserOperationReceipt", + ], + )) } } } @@ -409,9 +483,113 @@ impl<'a> Deserialize<'a> for wit::HyperwalletResponseData { })?; Ok(Handshake(step)) } + "ListWallets" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ListWalletsResponse: {}", + e + )) + })?; + Ok(ListWallets(response)) + } + "GetWalletInfo" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetWalletInfoResponse: {}", + e + )) + })?; + Ok(GetWalletInfo(response)) + } + "CreateWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CreateWalletResponse: {}", + e + )) + })?; + Ok(CreateWallet(response)) + } + "UnlockWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize UnlockWalletResponse: {}", + e + )) + })?; + Ok(UnlockWallet(response)) + } + "BuildAndSignUserOperationForPayment" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize BuildAndSignUserOperationResponse: {}", + e + )) + })?; + Ok(BuildAndSignUserOperationForPayment(response)) + } + "SubmitUserOperation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SubmitUserOperationResponse: {}", + e + )) + })?; + Ok(SubmitUserOperation(response)) + } + "GetUserOperationReceipt" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize UserOperationReceiptResponse: {}", + e + )) + })?; + Ok(GetUserOperationReceipt(response)) + } + "GetBalance" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetBalanceResponse: {}", + e + )) + })?; + Ok(GetBalance(response)) + } + "GetTokenBalance" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetTokenBalanceResponse: {}", + e + )) + })?; + Ok(GetTokenBalance(response)) + } _ => { - // For unimplemented variants, return an error - Err(de::Error::unknown_variant(&variant_type, &[])) + // For unimplemented variants, return an error with helpful message + Err(de::Error::unknown_variant( + &variant_type, + &[ + "Handshake", + "ListWallets", + "GetWalletInfo", + "CreateWallet", + "UnlockWallet", + "BuildAndSignUserOperationForPayment", + "SubmitUserOperation", + "GetUserOperationReceipt", + "GetBalance", + "GetTokenBalance", + ], + )) } } } From a75f550c64ebca42426ee215558f4c9ab052d852 Mon Sep 17 00:00:00 2001 From: Hallmane Date: Fri, 8 Aug 2025 16:20:27 +0200 Subject: [PATCH 7/9] fixed a bunch of ser-and-deserialization errors in requests and responses --- src/hyperwallet_client/mod.rs | 45 +- src/hyperwallet_client/serde_impls.rs | 3 +- .../serde_response_impls.rs | 16 +- src/hyperwallet_client/serde_variant_impls.rs | 387 ++++++++++++++++++ src/hyperwallet_client/types.rs | 18 + 5 files changed, 448 insertions(+), 21 deletions(-) diff --git a/src/hyperwallet_client/mod.rs b/src/hyperwallet_client/mod.rs index 04a2223..a577686 100644 --- a/src/hyperwallet_client/mod.rs +++ b/src/hyperwallet_client/mod.rs @@ -10,14 +10,14 @@ pub mod types; pub use types::{ Balance, BuildAndSignUserOperationForPaymentRequest, BuildAndSignUserOperationResponse, ChainId, CheckTbaOwnershipResponse, CreateNoteResponse, CreateWalletRequest, - CreateWalletResponse, DeleteWalletRequest, DeleteWalletResponse, ErrorCode, + CreateWalletResponse, DeleteWalletRequest, DeleteWalletResponse, Eip712Data, ErrorCode, ExecuteViaTbaResponse, ExportWalletRequest, ExportWalletResponse, GetBalanceRequest, GetBalanceResponse, GetTokenBalanceRequest, GetTokenBalanceResponse, GetWalletInfoRequest, GetWalletInfoResponse, HandshakeConfig, HandshakeStep, HyperwalletMessage, HyperwalletRequest, HyperwalletResponse, HyperwalletResponseData, ImportWalletRequest, ImportWalletResponse, - ListWalletsResponse, Operation, OperationCategory, OperationError, PaymasterConfig, - ProcessAddress, ProcessPermissions, RenameWalletRequest, SendEthRequest, SendEthResponse, - SendTokenRequest, SendTokenResponse, SessionId, SessionInfo, SpendingLimits, + ListWalletsResponse, MessageType, Operation, OperationCategory, OperationError, + PaymasterConfig, ProcessAddress, ProcessPermissions, RenameWalletRequest, SendEthRequest, + SendEthResponse, SendTokenRequest, SendTokenResponse, SessionId, SessionInfo, SpendingLimits, SubmitUserOperationResponse, TxReceipt, UnlockWalletResponse, UpdatableSetting, UserOperationHash, UserOperationReceiptResponse, WalletAddress, }; @@ -47,10 +47,11 @@ pub enum HyperwalletClientError { /// Performs the full handshake and registration protocol with the Hyperwallet service. pub fn initialize(config: HandshakeConfig) -> Result { + const CLIENT_PROTOCOL_VERSION: &str = "0.1.0"; let client_name = config.client_name.expect("Client name is required"); let hello_step = types::HandshakeStep::ClientHello(types::ClientHello { - client_version: "0.1.0".to_string(), + client_version: CLIENT_PROTOCOL_VERSION.to_string(), client_name, }); let hello_message = types::HyperwalletMessage { @@ -71,8 +72,11 @@ pub fn initialize(config: HandshakeConfig) -> Result server_welcome.supported_operations, + let (server_version, supported_operations) = match welcome_step { + types::HandshakeStep::ServerWelcome(server_welcome) => ( + server_welcome.server_version, + server_welcome.supported_operations, + ), _ => { return Err(HyperwalletClientError::ServerError( types::OperationError::internal_error( @@ -82,6 +86,19 @@ pub fn initialize(config: HandshakeConfig) -> Result Result { - Ok(types::SessionInfo { - server_version: "0.1.0".to_string(), //lol, server should send it's version - session_id: complete_handshake.session_id, - registered_permissions: complete_handshake.registered_permissions, - initial_chain_id: config.initial_chain_id, - }) - } + types::HandshakeStep::Complete(complete_handshake) => Ok(types::SessionInfo { + server_version, + session_id: complete_handshake.session_id, + registered_permissions: complete_handshake.registered_permissions, + initial_chain_id: config.initial_chain_id, + }), _ => Err(HyperwalletClientError::ServerError( types::OperationError::internal_error( "Expected Complete handshake step, received different step", diff --git a/src/hyperwallet_client/serde_impls.rs b/src/hyperwallet_client/serde_impls.rs index c140b6d..83b4111 100644 --- a/src/hyperwallet_client/serde_impls.rs +++ b/src/hyperwallet_client/serde_impls.rs @@ -240,7 +240,8 @@ impl<'a> Deserialize<'a> for wit::OperationError { if details.is_some() { return Err(de::Error::duplicate_field("details")); } - details = Some(map.next_value()?); + // Accept Option: null -> None + details = map.next_value()?; } } } diff --git a/src/hyperwallet_client/serde_response_impls.rs b/src/hyperwallet_client/serde_response_impls.rs index 8eddf26..08dbb69 100644 --- a/src/hyperwallet_client/serde_response_impls.rs +++ b/src/hyperwallet_client/serde_response_impls.rs @@ -1,7 +1,7 @@ // Proper serde implementations for request/response types use crate::hyperware::process::hyperwallet as wit; -use serde::de::{self, MapAccess, Visitor}; +// no direct use of serde::de; rely on derives and serde_json where necessary use serde::ser::SerializeStruct; use serde::{Deserialize, Serialize}; @@ -13,10 +13,13 @@ impl Serialize for wit::ImportWalletRequest { where S: serde::Serializer, { - let mut state = serializer.serialize_struct("ImportWalletRequest", 3)?; + let field_count = if self.password.is_some() { 3 } else { 2 }; + let mut state = serializer.serialize_struct("ImportWalletRequest", field_count)?; state.serialize_field("name", &self.name)?; state.serialize_field("private_key", &self.private_key)?; - state.serialize_field("password", &self.password)?; + if let Some(ref pwd) = self.password { + state.serialize_field("password", pwd)?; + } state.end() } } @@ -106,9 +109,12 @@ impl Serialize for wit::ExportWalletRequest { where S: serde::Serializer, { - let mut state = serializer.serialize_struct("ExportWalletRequest", 2)?; + let field_count = if self.password.is_some() { 2 } else { 1 }; + let mut state = serializer.serialize_struct("ExportWalletRequest", field_count)?; state.serialize_field("wallet_id", &self.wallet_id)?; - state.serialize_field("password", &self.password)?; + if let Some(ref pwd) = self.password { + state.serialize_field("password", pwd)?; + } state.end() } } diff --git a/src/hyperwallet_client/serde_variant_impls.rs b/src/hyperwallet_client/serde_variant_impls.rs index e68852c..de1a8fa 100644 --- a/src/hyperwallet_client/serde_variant_impls.rs +++ b/src/hyperwallet_client/serde_variant_impls.rs @@ -231,6 +231,46 @@ impl<'a> Deserialize<'a> for wit::HyperwalletRequest { })?; Ok(Handshake(step)) } + "ImportWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ImportWalletRequest: {}", + e + )) + })?; + Ok(ImportWallet(req)) + } + "DeleteWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize DeleteWalletRequest: {}", + e + )) + })?; + Ok(DeleteWallet(req)) + } + "RenameWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize RenameWalletRequest: {}", + e + )) + })?; + Ok(RenameWallet(req)) + } + "ExportWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ExportWalletRequest: {}", + e + )) + })?; + Ok(ExportWallet(req)) + } "UnlockWallet" => { let data = data.ok_or_else(|| de::Error::missing_field("data"))?; let req = serde_json::from_value(data).map_err(|e| { @@ -262,6 +302,36 @@ impl<'a> Deserialize<'a> for wit::HyperwalletRequest { })?; Ok(GetWalletInfo(req)) } + "SendEth" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SendEthRequest: {}", + e + )) + })?; + Ok(SendEth(req)) + } + "SendToken" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SendTokenRequest: {}", + e + )) + })?; + Ok(SendToken(req)) + } + "ApproveToken" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ApproveTokenRequest: {}", + e + )) + })?; + Ok(ApproveToken(req)) + } "GetBalance" => { let data = data.ok_or_else(|| de::Error::missing_field("data"))?; let req = serde_json::from_value(data).map_err(|e| { @@ -282,6 +352,67 @@ impl<'a> Deserialize<'a> for wit::HyperwalletRequest { })?; Ok(GetTokenBalance(req)) } + "CallContract" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CallContractRequest: {}", + e + )) + })?; + Ok(CallContract(req)) + } + "SignTransaction" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SignTransactionRequest: {}", + e + )) + })?; + Ok(SignTransaction(req)) + } + "SignMessage" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SignMessageRequest: {}", + e + )) + })?; + Ok(SignMessage(req)) + } + "GetTransactionHistory" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetTransactionHistoryRequest: {}", + e + )) + })?; + Ok(GetTransactionHistory(req)) + } + "EstimateGas" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize EstimateGasRequest: {}", + e + )) + })?; + Ok(EstimateGas(req)) + } + "GetGasPrice" => Ok(GetGasPrice), + "GetTransactionReceipt" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize GetTransactionReceiptRequest: {}", + e + )) + })?; + Ok(GetTransactionReceipt(req)) + } "BuildAndSignUserOperationForPayment" => { let data = data.ok_or_else(|| de::Error::missing_field("data"))?; let req = serde_json::from_value(data).map_err(|e| { @@ -312,21 +443,189 @@ impl<'a> Deserialize<'a> for wit::HyperwalletRequest { })?; Ok(GetUserOperationReceipt(req)) } + "BuildUserOperation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize BuildUserOperationRequest: {}", + e + )) + })?; + Ok(BuildUserOperation(req)) + } + "SignUserOperation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SignUserOperationRequest: {}", + e + )) + })?; + Ok(SignUserOperation(req)) + } + "BuildAndSignUserOperation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize BuildAndSignUserOperationRequest: {}", + e + )) + })?; + Ok(BuildAndSignUserOperation(req)) + } + "EstimateUserOperationGas" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize EstimateUserOperationGasRequest: {}", + e + )) + })?; + Ok(EstimateUserOperationGas(req)) + } + "ConfigurePaymaster" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ConfigurePaymasterRequest: {}", + e + )) + })?; + Ok(ConfigurePaymaster(req)) + } + "ExecuteViaTba" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ExecuteViaTbaRequest: {}", + e + )) + })?; + Ok(ExecuteViaTba(req)) + } + "CheckTbaOwnership" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CheckTbaOwnershipRequest: {}", + e + )) + })?; + Ok(CheckTbaOwnership(req)) + } + "SetupTbaDelegation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SetupTbaDelegationRequest: {}", + e + )) + })?; + Ok(SetupTbaDelegation(req)) + } + "CreateNote" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CreateNoteRequest: {}", + e + )) + })?; + Ok(CreateNote(req)) + } + "ReadNote" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ReadNoteRequest: {}", + e + )) + })?; + Ok(ReadNote(req)) + } + "ResolveIdentity" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ResolveIdentityRequest: {}", + e + )) + })?; + Ok(ResolveIdentity(req)) + } + "SetupDelegation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SetupDelegationRequest: {}", + e + )) + })?; + Ok(SetupDelegation(req)) + } + "VerifyDelegation" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize VerifyDelegationRequest: {}", + e + )) + })?; + Ok(VerifyDelegation(req)) + } + "MintEntry" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize MintEntryRequest: {}", + e + )) + })?; + Ok(MintEntry(req)) + } _ => { // For unimplemented variants, return an error with helpful message Err(de::Error::unknown_variant( &variant_type, &[ "Handshake", + "ImportWallet", + "DeleteWallet", + "RenameWallet", + "ExportWallet", "UnlockWallet", "CreateWallet", "ListWallets", "GetWalletInfo", + "SendEth", + "SendToken", + "ApproveToken", "GetBalance", "GetTokenBalance", + "CallContract", + "SignTransaction", + "SignMessage", + "GetTransactionHistory", + "EstimateGas", + "GetGasPrice", + "GetTransactionReceipt", "BuildAndSignUserOperationForPayment", "SubmitUserOperation", "GetUserOperationReceipt", + "BuildUserOperation", + "SignUserOperation", + "BuildAndSignUserOperation", + "EstimateUserOperationGas", + "ConfigurePaymaster", + "ExecuteViaTba", + "CheckTbaOwnership", + "SetupTbaDelegation", + "CreateNote", + "ReadNote", + "ResolveIdentity", + "SetupDelegation", + "VerifyDelegation", + "MintEntry", ], )) } @@ -483,6 +782,36 @@ impl<'a> Deserialize<'a> for wit::HyperwalletResponseData { })?; Ok(Handshake(step)) } + "ImportWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ImportWalletResponse: {}", + e + )) + })?; + Ok(ImportWallet(response)) + } + "DeleteWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize DeleteWalletResponse: {}", + e + )) + })?; + Ok(DeleteWallet(response)) + } + "ExportWallet" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ExportWalletResponse: {}", + e + )) + })?; + Ok(ExportWallet(response)) + } "ListWallets" => { let data = data.ok_or_else(|| de::Error::missing_field("data"))?; let response = serde_json::from_value(data).map_err(|e| { @@ -523,6 +852,26 @@ impl<'a> Deserialize<'a> for wit::HyperwalletResponseData { })?; Ok(UnlockWallet(response)) } + "SendEth" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SendEthResponse: {}", + e + )) + })?; + Ok(SendEth(response)) + } + "SendToken" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SendTokenResponse: {}", + e + )) + })?; + Ok(SendToken(response)) + } "BuildAndSignUserOperationForPayment" => { let data = data.ok_or_else(|| de::Error::missing_field("data"))?; let response = serde_json::from_value(data).map_err(|e| { @@ -573,21 +922,59 @@ impl<'a> Deserialize<'a> for wit::HyperwalletResponseData { })?; Ok(GetTokenBalance(response)) } + "CreateNote" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CreateNoteResponse: {}", + e + )) + })?; + Ok(CreateNote(response)) + } + "ExecuteViaTba" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize ExecuteViaTbaResponse: {}", + e + )) + })?; + Ok(ExecuteViaTba(response)) + } + "CheckTbaOwnership" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize CheckTbaOwnershipResponse: {}", + e + )) + })?; + Ok(CheckTbaOwnership(response)) + } _ => { // For unimplemented variants, return an error with helpful message Err(de::Error::unknown_variant( &variant_type, &[ "Handshake", + "ImportWallet", + "DeleteWallet", + "ExportWallet", "ListWallets", "GetWalletInfo", "CreateWallet", "UnlockWallet", + "SendEth", + "SendToken", "BuildAndSignUserOperationForPayment", "SubmitUserOperation", "GetUserOperationReceipt", "GetBalance", "GetTokenBalance", + "CreateNote", + "ExecuteViaTba", + "CheckTbaOwnership", ], )) } diff --git a/src/hyperwallet_client/types.rs b/src/hyperwallet_client/types.rs index d2aeb2e..7d4dc04 100644 --- a/src/hyperwallet_client/types.rs +++ b/src/hyperwallet_client/types.rs @@ -22,6 +22,9 @@ pub use wit::{ Operation, OperationCategory, }; +// Additional WIT types needed by clients +pub use wit::Eip712Data; + // Implement Default for PaymasterConfig impl Default for wit::PaymasterConfig { fn default() -> Self { @@ -67,6 +70,21 @@ pub struct SessionInfo { pub initial_chain_id: ChainId, } +impl SessionInfo { + /// Returns true when the server registered this operation for the session + pub fn supports(&self, operation: &Operation) -> bool { + self.registered_permissions + .allowed_operations + .iter() + .any(|op| op == operation) + } + + /// Returns the list of operations the server registered for the session + pub fn allowed_operations(&self) -> &Vec { + &self.registered_permissions.allowed_operations + } +} + /// Configuration for the handshake process #[derive(Debug)] pub struct HandshakeConfig { From eaa9799bd9bed2de4dc49fe6188cb2f2e12dde3d Mon Sep 17 00:00:00 2001 From: Hallmane Date: Sat, 9 Aug 2025 05:28:01 +0200 Subject: [PATCH 8/9] spending limits added to wit --- hyperware-wit/hyperwallet:sys-v0.wit | 15 +++ src/hyperwallet_client/api.rs | 26 +++- .../serde_request_response_impls.rs | 127 ++++++++++++++++++ .../serde_response_impls.rs | 63 +++++++++ src/hyperwallet_client/serde_variant_impls.rs | 28 ++++ src/hyperwallet_client/types.rs | 14 +- 6 files changed, 267 insertions(+), 6 deletions(-) create mode 100644 src/hyperwallet_client/serde_request_response_impls.rs diff --git a/hyperware-wit/hyperwallet:sys-v0.wit b/hyperware-wit/hyperwallet:sys-v0.wit index a65942e..e5f5048 100644 --- a/hyperware-wit/hyperwallet:sys-v0.wit +++ b/hyperware-wit/hyperwallet:sys-v0.wit @@ -165,6 +165,7 @@ interface hyperwallet { export-wallet(export-wallet-request), list-wallets, get-wallet-info(get-wallet-info-request), + set-wallet-limits(set-wallet-limits-request), // Ethereum Operations send-eth(send-eth-request), @@ -256,6 +257,7 @@ interface hyperwallet { get-wallet-info(get-wallet-info-response), get-balance(get-balance-response), get-token-balance(get-token-balance-response), + set-wallet-limits(set-wallet-limits-response), // Transactions send-eth(send-eth-response), @@ -311,6 +313,12 @@ interface hyperwallet { wallet-id: string, } + /// Set wallet-level spending limits + record set-wallet-limits-request { + wallet-id: string, + limits: wallet-spending-limits, + } + record get-balance-request { wallet-id: string, } @@ -541,6 +549,13 @@ interface hyperwallet { total: u64, } + /// Response for setting wallet limits + record set-wallet-limits-response { + success: bool, + wallet-id: string, + message: string, + } + record wallet { address: wallet-address, name: option, diff --git a/src/hyperwallet_client/api.rs b/src/hyperwallet_client/api.rs index d92e6e4..0496921 100644 --- a/src/hyperwallet_client/api.rs +++ b/src/hyperwallet_client/api.rs @@ -2,8 +2,8 @@ use super::types::{ self, Balance, BuildAndSignUserOperationForPaymentRequest, BuildAndSignUserOperationResponse, CreateWalletRequest, ExportWalletResponse, GetTokenBalanceResponse, HyperwalletMessage, HyperwalletRequest, ImportWalletRequest, ListWalletsResponse, PaymasterConfig, - RenameWalletRequest, SendEthRequest, SendTokenRequest, SessionId, TxReceipt, - UnlockWalletRequest, UserOperationReceiptResponse, Wallet, + RenameWalletRequest, SendEthRequest, SendTokenRequest, SessionId, SetWalletLimitsRequest, + SetWalletLimitsResponse, TxReceipt, UnlockWalletRequest, UserOperationReceiptResponse, Wallet, }; use super::HyperwalletClientError; use crate::wallet; @@ -206,6 +206,28 @@ pub fn rename_wallet( } } +pub fn set_wallet_limits( + session_id: &SessionId, + wallet_id: &str, + limits: types::WalletSpendingLimits, +) -> Result { + let message = build_message( + session_id, + HyperwalletRequest::SetWalletLimits(SetWalletLimitsRequest { + wallet_id: wallet_id.to_string(), + limits, + }), + ); + + let response = super::send_message(message)?; + match response.data { + Some(types::HyperwalletResponseData::SetWalletLimits(resp)) => Ok(resp), + _ => Err(HyperwalletClientError::ServerError( + types::OperationError::internal_error("Missing SetWalletLimits response data"), + )), + } +} + // === TRANSACTIONS === pub fn send_eth( diff --git a/src/hyperwallet_client/serde_request_response_impls.rs b/src/hyperwallet_client/serde_request_response_impls.rs new file mode 100644 index 0000000..88bc9d4 --- /dev/null +++ b/src/hyperwallet_client/serde_request_response_impls.rs @@ -0,0 +1,127 @@ +use crate::hyperware::process::hyperwallet as wit; +use serde::de::{self}; +use serde::ser::Serialize; +use serde::Deserialize; + +// Create a macro to generate stub implementations for request/response types +macro_rules! impl_stub_serde { + ($type:ty, $name:literal) => { + impl Serialize for $type { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + // For now, serialize as debug representation + let json_val = serde_json::json!({ + "type": $name, + "data": format!("{:?}", self) + }); + json_val.serialize(serializer) + } + } + + impl<'a> Deserialize<'a> for $type { + fn deserialize(deserializer: D) -> Result<$type, D::Error> + where + D: serde::de::Deserializer<'a>, + { + // The hyperwallet service is sending the response wrapped in a debug format + // We need to deserialize the actual JSON payload + let val = serde_json::Value::deserialize(deserializer)?; + + // Try normal JSON deserialization first + match serde_json::from_value(val.clone()) { + Ok(result) => Ok(result), + Err(_) => { + // If that fails, it might be wrapped in the debug format + // For now, we can't parse debug format strings back to structs + // This is a fundamental issue with the hyperwallet service + Err(de::Error::custom(format!( + "{} cannot be deserialized from debug format. The hyperwallet service needs to be fixed to return proper JSON.", + $name + ))) + } + } + } + } + }; +} + +// Request types +impl_stub_serde!( + wit::UpdateSpendingLimitsRequest, + "UpdateSpendingLimitsRequest" +); +impl_stub_serde!(wit::ImportWalletRequest, "ImportWalletRequest"); +impl_stub_serde!(wit::DeleteWalletRequest, "DeleteWalletRequest"); +impl_stub_serde!(wit::RenameWalletRequest, "RenameWalletRequest"); +impl_stub_serde!(wit::ExportWalletRequest, "ExportWalletRequest"); +impl_stub_serde!(wit::GetWalletInfoRequest, "GetWalletInfoRequest"); +impl_stub_serde!(wit::SendEthRequest, "SendEthRequest"); +impl_stub_serde!(wit::SendTokenRequest, "SendTokenRequest"); +impl_stub_serde!(wit::ApproveTokenRequest, "ApproveTokenRequest"); +impl_stub_serde!(wit::GetBalanceRequest, "GetBalanceRequest"); +impl_stub_serde!(wit::GetTokenBalanceRequest, "GetTokenBalanceRequest"); +impl_stub_serde!(wit::CallContractRequest, "CallContractRequest"); +impl_stub_serde!(wit::SignTransactionRequest, "SignTransactionRequest"); +impl_stub_serde!(wit::SignMessageRequest, "SignMessageRequest"); +impl_stub_serde!( + wit::BuildAndSignUserOperationForPaymentRequest, + "BuildAndSignUserOperationForPaymentRequest" +); +impl_stub_serde!( + wit::SubmitUserOperationRequest, + "SubmitUserOperationRequest" +); +impl_stub_serde!( + wit::GetUserOperationReceiptRequest, + "GetUserOperationReceiptRequest" +); +impl_stub_serde!( + wit::GetTransactionHistoryRequest, + "GetTransactionHistoryRequest" +); +impl_stub_serde!(wit::EstimateGasRequest, "EstimateGasRequest"); + +// Response types +impl_stub_serde!(wit::UnlockWalletResponse, "UnlockWalletResponse"); +impl_stub_serde!(wit::CreateWalletResponse, "CreateWalletResponse"); +impl_stub_serde!(wit::ImportWalletResponse, "ImportWalletResponse"); +impl_stub_serde!(wit::DeleteWalletResponse, "DeleteWalletResponse"); +impl_stub_serde!(wit::ExportWalletResponse, "ExportWalletResponse"); +impl_stub_serde!(wit::ListWalletsResponse, "ListWalletsResponse"); +impl_stub_serde!(wit::GetWalletInfoResponse, "GetWalletInfoResponse"); +impl_stub_serde!(wit::GetBalanceResponse, "GetBalanceResponse"); +impl_stub_serde!(wit::GetTokenBalanceResponse, "GetTokenBalanceResponse"); +impl_stub_serde!(wit::SendEthResponse, "SendEthResponse"); +impl_stub_serde!(wit::SendTokenResponse, "SendTokenResponse"); +impl_stub_serde!(wit::BuildAndSignUserOperationResponse,"BuildAndSignUserOperationResponse"); +impl_stub_serde!(wit::SubmitUserOperationResponse,"SubmitUserOperationResponse"); +impl_stub_serde!(wit::UserOperationReceiptResponse,"UserOperationReceiptResponse"); + +// Other request types +impl_stub_serde!(wit::GetTransactionReceiptRequest,"GetTransactionReceiptRequest"); +impl_stub_serde!(wit::BuildUserOperationRequest, "BuildUserOperationRequest"); +impl_stub_serde!(wit::SignUserOperationRequest, "SignUserOperationRequest"); +impl_stub_serde!(wit::BuildAndSignUserOperationRequest,"BuildAndSignUserOperationRequest"); +impl_stub_serde!(wit::EstimateUserOperationGasRequest,"EstimateUserOperationGasRequest"); +impl_stub_serde!(wit::ConfigurePaymasterRequest, "ConfigurePaymasterRequest"); +impl_stub_serde!(wit::ExecuteViaTbaRequest, "ExecuteViaTbaRequest"); +impl_stub_serde!(wit::CheckTbaOwnershipRequest, "CheckTbaOwnershipRequest"); +impl_stub_serde!(wit::SetupTbaDelegationRequest, "SetupTbaDelegationRequest"); +impl_stub_serde!(wit::CreateNoteRequest, "CreateNoteRequest"); +impl_stub_serde!(wit::ReadNoteRequest, "ReadNoteRequest"); +impl_stub_serde!(wit::ResolveIdentityRequest, "ResolveIdentityRequest"); +impl_stub_serde!(wit::SetupDelegationRequest, "SetupDelegationRequest"); +impl_stub_serde!(wit::VerifyDelegationRequest, "VerifyDelegationRequest"); +impl_stub_serde!(wit::MintEntryRequest, "MintEntryRequest"); + +// Other response types +impl_stub_serde!(wit::CreateNoteResponse, "CreateNoteResponse"); +impl_stub_serde!(wit::ExecuteViaTbaResponse, "ExecuteViaTbaResponse"); +impl_stub_serde!(wit::CheckTbaOwnershipResponse, "CheckTbaOwnershipResponse"); + +// Other types that may need serde +impl_stub_serde!(wit::Balance, "Balance"); +impl_stub_serde!(wit::Wallet, "Wallet"); +impl_stub_serde!(wit::WalletSpendingLimits, "WalletSpendingLimits"); diff --git a/src/hyperwallet_client/serde_response_impls.rs b/src/hyperwallet_client/serde_response_impls.rs index 08dbb69..2d4e764 100644 --- a/src/hyperwallet_client/serde_response_impls.rs +++ b/src/hyperwallet_client/serde_response_impls.rs @@ -6,6 +6,36 @@ use serde::ser::SerializeStruct; use serde::{Deserialize, Serialize}; // ============== REQUEST TYPES ============== +// SetWalletLimitsRequest +impl Serialize for wit::SetWalletLimitsRequest { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SetWalletLimitsRequest", 2)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("limits", &self.limits)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SetWalletLimitsRequest { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + wallet_id: String, + limits: wit::WalletSpendingLimits, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SetWalletLimitsRequest { + wallet_id: h.wallet_id, + limits: h.limits, + }) + } +} // ImportWalletRequest impl Serialize for wit::ImportWalletRequest { @@ -405,6 +435,39 @@ impl<'de> Deserialize<'de> for wit::GetUserOperationReceiptRequest { } // ============== RESPONSE TYPES ============== +// SetWalletLimitsResponse +impl Serialize for wit::SetWalletLimitsResponse { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + let mut state = serializer.serialize_struct("SetWalletLimitsResponse", 3)?; + state.serialize_field("success", &self.success)?; + state.serialize_field("wallet_id", &self.wallet_id)?; + state.serialize_field("message", &self.message)?; + state.end() + } +} + +impl<'de> Deserialize<'de> for wit::SetWalletLimitsResponse { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + #[derive(Deserialize)] + struct Helper { + success: bool, + wallet_id: String, + message: String, + } + let h = Helper::deserialize(deserializer)?; + Ok(wit::SetWalletLimitsResponse { + success: h.success, + wallet_id: h.wallet_id, + message: h.message, + }) + } +} // CreateWalletResponse impl Serialize for wit::CreateWalletResponse { diff --git a/src/hyperwallet_client/serde_variant_impls.rs b/src/hyperwallet_client/serde_variant_impls.rs index de1a8fa..cca4380 100644 --- a/src/hyperwallet_client/serde_variant_impls.rs +++ b/src/hyperwallet_client/serde_variant_impls.rs @@ -173,6 +173,10 @@ impl Serialize for wit::HyperwalletRequest { state.serialize_field("type", "MintEntry")?; state.serialize_field("data", data)?; } + SetWalletLimits(data) => { + state.serialize_field("type", "SetWalletLimits")?; + state.serialize_field("data", data)?; + } } state.end() @@ -443,6 +447,16 @@ impl<'a> Deserialize<'a> for wit::HyperwalletRequest { })?; Ok(GetUserOperationReceipt(req)) } + "SetWalletLimits" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let req = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SetWalletLimitsRequest: {}", + e + )) + })?; + Ok(SetWalletLimits(req)) + } "BuildUserOperation" => { let data = data.ok_or_else(|| de::Error::missing_field("data"))?; let req = serde_json::from_value(data).map_err(|e| { @@ -724,6 +738,10 @@ impl Serialize for wit::HyperwalletResponseData { state.serialize_field("type", "CheckTbaOwnership")?; state.serialize_field("data", data)?; } + SetWalletLimits(data) => { + state.serialize_field("type", "SetWalletLimits")?; + state.serialize_field("data", data)?; + } } state.end() @@ -922,6 +940,16 @@ impl<'a> Deserialize<'a> for wit::HyperwalletResponseData { })?; Ok(GetTokenBalance(response)) } + "SetWalletLimits" => { + let data = data.ok_or_else(|| de::Error::missing_field("data"))?; + let response = serde_json::from_value(data).map_err(|e| { + de::Error::custom(format!( + "Failed to deserialize SetWalletLimitsResponse: {}", + e + )) + })?; + Ok(SetWalletLimits(response)) + } "CreateNote" => { let data = data.ok_or_else(|| de::Error::missing_field("data"))?; let response = serde_json::from_value(data).map_err(|e| { diff --git a/src/hyperwallet_client/types.rs b/src/hyperwallet_client/types.rs index 7d4dc04..b2f4119 100644 --- a/src/hyperwallet_client/types.rs +++ b/src/hyperwallet_client/types.rs @@ -44,14 +44,19 @@ pub use wit::{ CheckTbaOwnershipRequest, ConfigurePaymasterRequest, CreateNoteRequest, EstimateGasRequest, EstimateUserOperationGasRequest, ExecuteViaTbaRequest, GetTransactionHistoryRequest, GetTransactionReceiptRequest, GetUserOperationReceiptRequest, MintEntryRequest, - ReadNoteRequest, ResolveIdentityRequest, SetupDelegationRequest, SetupTbaDelegationRequest, - SignMessageRequest, SignTransactionRequest, SignUserOperationRequest, - SubmitUserOperationRequest, UpdateSpendingLimitsRequest, VerifyDelegationRequest, + ReadNoteRequest, ResolveIdentityRequest, SetWalletLimitsRequest, SetupDelegationRequest, + SetupTbaDelegationRequest, SignMessageRequest, SignTransactionRequest, + SignUserOperationRequest, SubmitUserOperationRequest, UpdateSpendingLimitsRequest, + VerifyDelegationRequest, }; +// SetWalletLimits request/response types (wallet-level limits) +// Not available in current WIT; requires WIT update to add request/response and variants. + // Re-export response types pub use wit::{ - BuildAndSignUserOperationResponse, CheckTbaOwnershipResponse, SubmitUserOperationResponse, + BuildAndSignUserOperationResponse, CheckTbaOwnershipResponse, SetWalletLimitsResponse, + SubmitUserOperationResponse, }; // Type aliases for compatibility @@ -305,6 +310,7 @@ pub fn operation_type(request: &HyperwalletRequest) -> Operation { HyperwalletRequest::BuildAndSignUserOperation(_) => Operation::BuildAndSignUserOperation, HyperwalletRequest::EstimateUserOperationGas(_) => Operation::EstimateUserOperationGas, HyperwalletRequest::ConfigurePaymaster(_) => Operation::ConfigurePaymaster, + HyperwalletRequest::SetWalletLimits(_) => Operation::SetWalletLimits, // Hypermap Operations HyperwalletRequest::ResolveIdentity(_) => Operation::ResolveIdentity, From 9a546cf1a7d1b5fdb3b0713b41c2f137f4d96d8b Mon Sep 17 00:00:00 2001 From: Hallmane Date: Tue, 12 Aug 2025 01:56:47 +0200 Subject: [PATCH 9/9] no --- src/hyperwallet_client/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hyperwallet_client/mod.rs b/src/hyperwallet_client/mod.rs index a577686..adad227 100644 --- a/src/hyperwallet_client/mod.rs +++ b/src/hyperwallet_client/mod.rs @@ -163,8 +163,6 @@ pub(crate) fn send_message( .map_err(|e| HyperwalletClientError::Communication(e.into()))? .map_err(|e| HyperwalletClientError::Communication(e.into()))?; - kiprintln!("Response: {:?}", response); - let hyperwallet_response: types::HyperwalletResponse = serde_json::from_slice(response.body()).map_err(HyperwalletClientError::Deserialization)?;