diff --git a/Dockerfile.metis b/Dockerfile.metis index 66ec7f7697..4054a1252a 100644 --- a/Dockerfile.metis +++ b/Dockerfile.metis @@ -54,10 +54,10 @@ RUN curl -fsSL https://downloads.1password.com/linux/keys/1password.asc \ && rm -rf /var/lib/apt/lists/* RUN op --version -# Install metis CLI binary (always pulls the current release) -RUN curl -fsSL https://github.com/dourolabs/metis-releases/releases/download/latest/metis-x86_64-unknown-linux-gnu \ - -o /usr/local/bin/metis \ - && chmod +x /usr/local/bin/metis +# Install hydra CLI binary +RUN curl -fsSL https://github.com/dourolabs/metis-releases/releases/download/v0.9.0/hydra-x86_64-unknown-linux-gnu \ + -o /usr/local/bin/hydra \ + && chmod +x /usr/local/bin/hydra # Create non-root worker user RUN useradd -m -s /bin/bash -u 1000 worker diff --git a/lazer/contracts/stellar/.gitignore b/lazer/contracts/stellar/.gitignore new file mode 100644 index 0000000000..e0012bda91 --- /dev/null +++ b/lazer/contracts/stellar/.gitignore @@ -0,0 +1,5 @@ +target/ +*.wasm +.soroban/ +test_snapshots/ +.stellar/ diff --git a/lazer/contracts/stellar/Cargo.lock b/lazer/contracts/stellar/Cargo.lock new file mode 100644 index 0000000000..472bda45fc --- /dev/null +++ b/lazer/contracts/stellar/Cargo.lock @@ -0,0 +1,1734 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +dependencies = [ + "derive_arbitrary", +] + +[[package]] +name = "ark-bls12-381" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c775f0d12169cba7aae4caeb547bb6a50781c7449a8aa53793827c9ec4abf488" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "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", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[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.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-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[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 = "bumpalo" +version = "3.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" + +[[package]] +name = "bytes-lit" +version = "0.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0adabf37211a5276e46335feabcbb1530c95eb3fdf85f324c7db942770aa025d" +dependencies = [ + "num-bigint", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "cc" +version = "1.2.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[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 = "crate-git-revision" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c521bf1f43d31ed2f73441775ed31935d77901cb3451e44b38a1c1612fcbaf98" +dependencies = [ + "serde", + "serde_derive", + "serde_json", +] + +[[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", + "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 = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.117", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core 0.20.11", + "darling_macro 0.20.11", +] + +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core 0.23.0", + "darling_macro 0.23.0", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core 0.20.11", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core 0.23.0", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "data-encoding" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" + +[[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 = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[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_arbitrary" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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 = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[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", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "escape-bytes" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfcf67fea2815c2fc3b90873fae90957be12ff417335dfadc7f52927feb03b2" + +[[package]] +name = "ethnum" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca81e6b4777c89fd810c25a4be2b1bd93ea034fbe58e6a75216a34c6b82c539b" + +[[package]] +name = "ff" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "generic-array" +version = "0.14.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" +dependencies = [ + "serde", +] + +[[package]] +name = "hex-literal" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "indexmap-nostd" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e04e2fd2b8188ea827b32ef11de88377086d690286ab35747ef7f9bf3ccb590" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4c90f45aa2e6eacbe8645f77fdea542ac97a494bcd117a67df9ff4d611f995" +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", + "signature", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.183" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" + +[[package]] +name = "libm" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "memchr" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" + +[[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-conv" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[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", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "pyth-lazer-stellar" +version = "0.1.0" +dependencies = [ + "hex-literal", + "soroban-sdk", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[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", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[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 = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_with" +version = "3.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.13.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" +dependencies = [ + "darling 0.23.0", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[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", + "rand_core", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "soroban-builtin-sdk-macros" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf2e42bf80fcdefb3aae6ff3c7101a62cf942e95320ed5b518a1705bc11c6b2f" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "soroban-env-common" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "027cd856171bfd6ad2c0ffb3b7dfe55ad7080fb3050c36ad20970f80da634472" +dependencies = [ + "arbitrary", + "crate-git-revision", + "ethnum", + "num-derive", + "num-traits", + "serde", + "soroban-env-macros", + "soroban-wasmi", + "static_assertions", + "stellar-xdr", + "wasmparser", +] + +[[package]] +name = "soroban-env-guest" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a07dda1ae5220d975979b19ad4fd56bc86ec7ec1b4b25bc1c5d403f934e592e" +dependencies = [ + "soroban-env-common", + "static_assertions", +] + +[[package]] +name = "soroban-env-host" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66e8b03a4191d485eab03f066336112b2a50541a7553179553dc838b986b94dd" +dependencies = [ + "ark-bls12-381", + "ark-ec", + "ark-ff", + "ark-serialize", + "curve25519-dalek", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "generic-array", + "getrandom", + "hex-literal", + "hmac", + "k256", + "num-derive", + "num-integer", + "num-traits", + "p256", + "rand", + "rand_chacha", + "sec1", + "sha2", + "sha3", + "soroban-builtin-sdk-macros", + "soroban-env-common", + "soroban-wasmi", + "static_assertions", + "stellar-strkey", + "wasmparser", +] + +[[package]] +name = "soroban-env-macros" +version = "22.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00eff744764ade3bc480e4909e3a581a240091f3d262acdce80b41f7069b2bd9" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "serde", + "serde_json", + "stellar-xdr", + "syn 2.0.117", +] + +[[package]] +name = "soroban-ledger-snapshot" +version = "22.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c30035cf1e8f02f65de3e594b6da113ecdaf1cd134d8480961d62568bb15adaf" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "soroban-env-common", + "soroban-env-host", + "thiserror", +] + +[[package]] +name = "soroban-sdk" +version = "22.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff18e8d7ca6d5340a211605ca2c86383bd4dfacc4f8253d72a1573974ffffe69" +dependencies = [ + "arbitrary", + "bytes-lit", + "ctor", + "derive_arbitrary", + "ed25519-dalek", + "rand", + "rustc_version", + "serde", + "serde_json", + "soroban-env-guest", + "soroban-env-host", + "soroban-ledger-snapshot", + "soroban-sdk-macros", + "stellar-strkey", +] + +[[package]] +name = "soroban-sdk-macros" +version = "22.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42b205cd86b34d530db87667bd287fbb194166d79b368227fd842110a914fde8" +dependencies = [ + "crate-git-revision", + "darling 0.20.11", + "itertools", + "proc-macro2", + "quote", + "rustc_version", + "sha2", + "soroban-env-common", + "soroban-spec", + "soroban-spec-rust", + "stellar-xdr", + "syn 2.0.117", +] + +[[package]] +name = "soroban-spec" +version = "22.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb6a16f2de28852c759f4da5f28cda54ec0d8dfa4c0e6e8cb3495234a72b0cea" +dependencies = [ + "base64 0.13.1", + "stellar-xdr", + "thiserror", + "wasmparser", +] + +[[package]] +name = "soroban-spec-rust" +version = "22.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdc6db5902ab21290dddf63fec4ee95703fe59891a947646e7b8607536f043fc" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "sha2", + "soroban-spec", + "stellar-xdr", + "syn 2.0.117", + "thiserror", +] + +[[package]] +name = "soroban-wasmi" +version = "0.31.1-soroban.20.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "710403de32d0e0c35375518cb995d4fc056d0d48966f2e56ea471b8cb8fc9719" +dependencies = [ + "smallvec", + "spin", + "wasmi_arena", + "wasmi_core", + "wasmparser-nostd", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stellar-integration-tests" +version = "0.1.0" +dependencies = [ + "hex-literal", + "k256", + "pyth-lazer-stellar", + "soroban-sdk", + "tiny-keccak", + "wormhole-executor-stellar", +] + +[[package]] +name = "stellar-strkey" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e3aa3ed00e70082cb43febc1c2afa5056b9bb3e348bbb43d0cd0aa88a611144" +dependencies = [ + "crate-git-revision", + "data-encoding", + "thiserror", +] + +[[package]] +name = "stellar-xdr" +version = "22.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ce69db907e64d1e70a3dce8d4824655d154749426a6132b25395c49136013e4" +dependencies = [ + "arbitrary", + "base64 0.13.1", + "crate-git-revision", + "escape-bytes", + "hex", + "serde", + "serde_with", + "stellar-strkey", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[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.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[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.117", +] + +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6523d69017b7633e396a89c5efab138161ed5aafcbc8d3e5c5a42ae38f50495a" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e3a6c758eb2f701ed3d052ff5737f5bfe6614326ea7f3bbac7156192dc32e67" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921de2737904886b52bcbb237301552d05969a6f9c40d261eb0533c8b055fedf" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.117", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.115" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a93e946af942b58934c604527337bad9ae33ba1d5c6900bbb41c2c07c2364a93" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasmi_arena" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "104a7f73be44570cac297b3035d76b169d6599637631cf37a1703326a0727073" + +[[package]] +name = "wasmi_core" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcf1a7db34bff95b85c261002720c00c3a6168256dcb93041d3fa2054d19856a" +dependencies = [ + "downcast-rs", + "libm", + "num-traits", + "paste", +] + +[[package]] +name = "wasmparser" +version = "0.116.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a58e28b80dd8340cb07b8242ae654756161f6fc8d0038123d679b7b99964fa50" +dependencies = [ + "indexmap 2.13.0", + "semver", +] + +[[package]] +name = "wasmparser-nostd" +version = "0.100.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5a015fe95f3504a94bb1462c717aae75253e39b9dd6c3fb1062c934535c64aa" +dependencies = [ + "indexmap-nostd", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wormhole-executor-stellar" +version = "0.1.0" +dependencies = [ + "k256", + "soroban-sdk", + "tiny-keccak", +] + +[[package]] +name = "zerocopy" +version = "0.8.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/lazer/contracts/stellar/Cargo.toml b/lazer/contracts/stellar/Cargo.toml new file mode 100644 index 0000000000..2b1e762550 --- /dev/null +++ b/lazer/contracts/stellar/Cargo.toml @@ -0,0 +1,10 @@ +[workspace] +resolver = "2" +members = [ + "contracts/wormhole-executor-stellar", + "contracts/pyth-lazer-stellar", + "contracts/integration-tests", +] + +[workspace.dependencies] +soroban-sdk = "22.0.5" diff --git a/lazer/contracts/stellar/DESIGN.md b/lazer/contracts/stellar/DESIGN.md new file mode 100644 index 0000000000..465da465f3 --- /dev/null +++ b/lazer/contracts/stellar/DESIGN.md @@ -0,0 +1,455 @@ +# Pyth Lazer Stellar (Soroban) Verification Contract - Design Document + +## Problem Statement + +Pyth Lazer is a low-latency price oracle system that distributes signed price feed data to consumers across multiple blockchain ecosystems. On-chain verification contracts exist for EVM (Solidity), Solana (Anchor/Rust), Sui (Move), and Aptos (Move), but not for Stellar's Soroban smart contract platform. To serve the Stellar DeFi ecosystem, we need: + +1. A **Pyth Lazer verification contract** that verifies Pyth Lazer LE-ECDSA signed price updates and exposes verified payload for on-chain consumption. +2. A **Wormhole governance executor contract** that verifies Wormhole VAAs and dispatches governance actions (updating trusted signers, upgrading contracts), following the same pattern used by the EVM Executor and Solana remote-executor contracts. + +## Goals + +1. Implement a Soroban smart contract that verifies Pyth Lazer LE-ECDSA signed price updates using secp256k1 key recovery and keccak256 hashing. +2. Implement a Wormhole executor/governance contract for Stellar that can verify Wormhole VAAs and execute arbitrary governance actions via cross-contract calls. +3. Maintain a set of trusted signers (compressed secp256k1 public keys) with expiry timestamps, managed via Wormhole governance. +4. Parse verified payloads into structured price feed data (timestamp, channel, feeds with properties). +5. Follow the same architectural patterns as existing Lazer contracts (especially the Sui contract for verification, and the EVM Executor / Solana remote-executor for Wormhole governance). +6. Support contract upgradeability. +7. Provide a companion SDK crate for off-chain integration. +8. Manage Soroban state rent proactively to prevent archival of critical contract data. + +## Non-Goals + +- Ed25519 signature support (the Sui and EVM contracts only support ECDSA; ed25519 is Solana-specific). +- Full Wormhole core bridge port (we only need VAA verification, not message publishing). + +## Background: Existing Contract Architecture + +### Wire Format (LE-ECDSA Message) + +The Pyth Lazer protocol defines an `LeEcdsaMessage` envelope (used by Sui and Solana ECDSA paths): + +``` +[4 bytes] magic (LE u32) = 0x4D475044 (LE_ECDSA_FORMAT_MAGIC = 1296547300) +[64 bytes] ECDSA signature (r: 32 bytes, s: 32 bytes) +[1 byte] recovery_id +[2 bytes] payload_length (LE u16) +[N bytes] payload +``` + +The payload is signed with secp256k1 ECDSA over `keccak256(payload)`. The signer's public key is recovered from the signature and checked against the trusted signers list. + +### Payload Format + +``` +[4 bytes] payload_magic (LE u32) = 0x93DFF3F5 (PAYLOAD_MAGIC = 2479346549) +[8 bytes] timestamp (LE u64, microseconds since epoch) +[1 byte] channel (enum: 0=Invalid, 1=RealTime, 2=FixedRate50, etc.) +[1 byte] num_feeds +For each feed: + [4 bytes] feed_id (LE u32) + [1 byte] num_properties + For each property: + [1 byte] property_id (enum) + [variable] value (depends on property type) +``` + +### Common Contract Components + +All existing Lazer contracts share these components: +1. **Storage/State**: Trusted signers list (pubkey + expiry), admin/authority +2. **Admin functions**: initialize, update_trusted_signer (add/update/remove by setting expiry=0) +3. **Verification function**: Accepts raw update bytes, verifies signature against trusted signers, returns verified payload + +### Wormhole Governance Pattern Across Ecosystems + +The Pyth ecosystem uses Wormhole VAAs to deliver governance instructions across chains. The pattern varies by ecosystem: + +**EVM (Executor.sol)**: A standalone `Executor` contract verifies Wormhole VAAs via the Wormhole core bridge (`IWormhole.parseAndVerifyVM`). The VAA payload contains a serialized `GovernanceInstruction` with the PTGM (Pyth Governance Message) format: magic `0x5054474d` ("PTGM"), module, action, target chain, executor address, call address, value, and calldata. The executor dispatches an arbitrary EVM call to the target contract. This enables any governance action (updating signers, upgrading contracts, etc.) without modifying the executor itself. + +**Solana (remote-executor)**: Similarly, a standalone `remote_executor` program processes posted Wormhole VAAs. The VAA payload contains an `ExecutorPayload` with a list of instructions (program ID, accounts, data). The executor invokes each instruction via CPI, signing with a PDA derived from the emitter address. This enables arbitrary Solana program calls governed by Wormhole. + +**Sui (governance.move + actions.move)**: Wormhole governance is integrated directly into the Lazer contract. The `governance` module validates incoming VAAs (emitter chain, emitter address, sequence number) and parses the PTGM header. The `actions` module implements specific governance actions: `upgrade` (contract upgrade via UpgradeCap) and `update_trusted_signer`. The Sui Wormhole SDK is vendored and provides `vaa::VAA` for VAA parsing. + +### Common PTGM Format + +All governance messages use the PTGM (Pyth Governance Message) header: +``` +[4 bytes] magic = "PTGM" (0x5054474d) +[1 byte] module (3 = Lazer) +[1 byte] action (0 = upgrade contract, 1 = update trusted signer) +[2 bytes] target_chain_id (BE u16) +[variable] action-specific payload +``` + +For `update_trusted_signer` (action=1): +``` +[33 bytes] compressed secp256k1 public key +[8 bytes] expires_at (BE u64, 0 = remove) +``` + +For `upgrade_contract` (action=0): +``` +[8 bytes] version (BE u64) +[32 bytes] wasm digest/hash +``` + +## Proposed Approach + +### Technology Choice + +- **Language**: Rust (compiled to WASM via Soroban SDK) +- **SDK**: `soroban-sdk` (the official Stellar smart contract SDK) +- **Crypto**: Soroban native host functions: + - `env.crypto().keccak256()` for hashing (both Lazer payloads and VAA body hashing) + - `env.crypto().secp256k1_recover()` for recovering public keys (both Lazer signer verification and Wormhole guardian signature verification) +- **Testing**: Soroban SDK's built-in local testing mode (`soroban-sdk` with `testutils` feature) +- **Deployment tool**: `stellar` CLI + +### Architecture Overview + +The system consists of two Soroban contracts: + +1. **Pyth Lazer contract** (`pyth-lazer-stellar`): Verifies Lazer price update signatures and manages trusted signers. Admin functions are callable by the governance executor. +2. **Wormhole executor contract** (`wormhole-executor-stellar`): Verifies Wormhole VAAs, parses PTGM governance payloads, and dispatches calls to the Lazer contract (or any other target contract). This is the Stellar equivalent of the EVM `Executor.sol` and Solana `remote-executor`. + +The governance flow: +``` +Wormhole VAA (from guardians) + → Wormhole Executor contract (verify VAA, parse PTGM) + → Cross-contract call to Lazer contract (update_trusted_signer, upgrade, etc.) +``` + +### Contract 1: Wormhole Executor + +#### 1a. VAA Verification + +Since there is no existing Wormhole core bridge deployed on Stellar, the executor contract must verify Wormhole VAAs directly. This involves: + +1. Parsing the VAA binary format (version, guardian set index, signatures, body) +2. Computing `keccak256(keccak256(body))` (the Wormhole double-hash) +3. For each guardian signature, using `secp256k1_recover` to recover the signer's public key +4. Checking recovered keys against the stored guardian set +5. Verifying quorum (2/3 + 1 of guardians signed) + +The guardian set (list of guardian public keys) is stored in the contract and updated via guardian set upgrade VAAs (a self-referential governance mechanism built into Wormhole). + +#### 1b. Wormhole VAA Format + +``` +[1 byte] version (must be 1) +[4 bytes] guardian_set_index (BE u32) +[1 byte] num_signatures +For each signature: + [1 byte] guardian_index + [64 bytes] ECDSA signature (r: 32, s: 32) + [1 byte] recovery_id +Body: + [4 bytes] timestamp (BE u32) + [4 bytes] nonce (BE u32) + [2 bytes] emitter_chain (BE u16) + [32 bytes] emitter_address + [8 bytes] sequence (BE u64) + [1 byte] consistency_level + [N bytes] payload +``` + +#### 1c. Executor State + +``` +Storage (persistent): + - owner_emitter_chain_id: u16 // authorized governance emitter chain + - owner_emitter_address: BytesN<32> // authorized governance emitter address + - last_executed_sequence: u64 // replay protection + - chain_id: u16 // this chain's Wormhole chain ID + - guardian_set: Vec> // current guardian set (ethereum addresses) + - guardian_set_index: u32 // current guardian set index +``` + +#### 1d. Executor Functions + +- `initialize(env, wormhole_chain_id, owner_emitter_chain_id, owner_emitter_address, initial_guardian_set, guardian_set_index)` - One-time setup +- `execute_governance_action(env, vaa_bytes: Bytes)` - Verify VAA, parse PTGM, dispatch cross-contract call +- `update_guardian_set(env, vaa_bytes: Bytes)` - Process guardian set upgrade VAA (self-governance) + +The execution flow: +1. Parse and verify the Wormhole VAA (guardian signatures, quorum) +2. Check emitter chain/address matches the authorized governance source +3. Check sequence > last_executed_sequence (replay protection) +4. Parse the PTGM header from the VAA payload +5. Based on the PTGM module and action, dispatch a cross-contract call to the appropriate target (e.g., Lazer contract's `update_trusted_signer` or `upgrade`) + +#### 1e. Dispatch Model + +Following the EVM Executor pattern, the PTGM payload includes the target contract address and action-specific calldata. The executor makes a cross-contract `env.invoke_contract()` call to the target. The target contract must check that the caller is the authorized executor address. + +### Contract 2: Pyth Lazer Verification + +#### 2a. State Management + +``` +Storage (persistent): + - executor: Address // authorized Wormhole executor contract address + - trusted_signers: Map, u64> // compressed secp256k1 pubkey -> expires_at (unix seconds) +``` + +Note: The `admin` field from the original design is replaced by `executor` - the Wormhole executor contract is the authority for governance operations. For initial setup, an `initialize` function with a one-time admin is still needed. Fee collection has been removed as Pyth is moving away from on-chain fees. + +#### 2b. Contract Functions + +**Governance functions** (require `executor` authorization): + +- `update_trusted_signer(env, pubkey: BytesN<33>, expires_at: u64)` - Add/update/remove signer (expires_at=0 removes) +- `upgrade(env, new_wasm_hash: BytesN<32>)` - Upgrade the contract WASM + +**Setup function** (one-time): + +- `initialize(env, executor: Address)` - One-time setup, stores initial config + +**Verification function** (public): + +- `verify_update(env, update: Bytes) -> Bytes` - Verifies the LE-ECDSA envelope signature, checks signer is trusted and not expired, returns the raw payload bytes + +The verification flow: +1. Parse the LE-ECDSA envelope: magic, signature (64 bytes), recovery_id (1 byte), payload_length, payload +2. Compute `hash = keccak256(payload)` +3. Recover public key: `recovered_pubkey = secp256k1_recover(hash, signature, recovery_id)` +4. Look up the recovered compressed public key in trusted signers storage +5. Check `current_timestamp < expires_at` for the matched signer +6. Return the verified payload bytes + +#### 2c. Upgradeability + +Soroban contracts are upgradeable by default. The governance executor can trigger an upgrade by calling `upgrade(new_wasm_hash)` which invokes `env.deployer().update_current_contract_wasm(new_wasm_hash)`. + +### Project Structure + +``` +lazer/contracts/stellar/ + Cargo.toml # workspace root + contracts/ + pyth-lazer-stellar/ + Cargo.toml + src/ + lib.rs # contract entry point, public functions + state.rs # storage keys, read/write helpers + verify.rs # signature verification logic + error.rs # custom error enum + test.rs # unit tests + wormhole-executor-stellar/ + Cargo.toml + src/ + lib.rs # executor contract entry, dispatch logic + vaa.rs # Wormhole VAA parsing and verification + guardian.rs # guardian set management + governance.rs # PTGM header parsing + error.rs # custom error enum + test.rs # unit tests + Makefile # build, test, deploy scripts + README.md +``` + +### Key Design Decisions + +**1. LE-ECDSA format (not EVM format)** + +The Sui contract uses the LE-ECDSA format (`LeEcdsaMessage` with magic `0x4D475044`). We will use the same format for Stellar since: +- LE encoding is natural for WASM/Rust +- The Sui contract is the closest reference implementation +- keccak256 + secp256k1 are natively supported as Soroban host functions + +**2. Compressed public keys (33 bytes)** + +Following the Sui contract convention, trusted signers are stored as compressed secp256k1 public keys (33 bytes). Soroban's `secp256k1_recover` returns uncompressed 65-byte keys, so the contract applies SEC-1 point compression (parity byte + x-coordinate) before comparison. This is a trivial operation (~few hundred instructions) documented in the "secp256k1_recover: Output Format and Key Conversion" section above. + +**3. Wormhole governance via executor contract** + +Following the EVM and Solana patterns, we implement a standalone Wormhole executor contract that verifies VAAs and dispatches governance calls. This is preferred over the simpler admin authority approach because: +- It matches the production governance model used by EVM and Solana deployments +- It enables trustless governance from the Pyth governance multisig via Wormhole +- The executor is reusable for other Pyth contracts deployed on Stellar in the future +- The Lazer contract doesn't need to know about Wormhole internals + +**4. Inline VAA verification (no core bridge dependency)** + +Since there is no existing Wormhole core bridge on Stellar, the executor contract verifies Wormhole VAAs directly using Soroban's native `secp256k1_recover` and `keccak256`. This is similar to how the Sui Lazer contract vendors the Wormhole SDK. The tradeoff is more code in the executor, but no external dependency. If a Wormhole core bridge is later deployed on Stellar, the executor could be updated to delegate verification to it. + +**5. No on-chain fee collection** + +Pyth is moving away from on-chain verification fees. The Stellar contract will not charge per-verification fees, simplifying the contract interface and removing the need for treasury management and token transfer logic. + +**6. Return raw payload bytes** + +The `verify_update` function returns the raw verified payload bytes. A separate SDK/library (either on-chain or off-chain) can parse the payload into structured data. This follows the EVM contract pattern where `verifyUpdate` returns `(bytes payload, address signer)`. + +### Soroban State Rent Model + +Soroban uses a **rent-based state model** to prevent unbounded ledger growth. Every piece of stored data has a TTL (time-to-live) measured in ledgers (~5 seconds per ledger). Understanding and managing rent is critical for these contracts. + +#### How Rent Works + +Each ledger entry (contract data, contract code) has a `liveUntilLedger` field. When the current ledger exceeds this value, the entry's fate depends on its storage type: + +| Storage Type | On Expiry | Restoration | Use Case | +|---|---|---|---| +| **Persistent** | Archived (moved off-chain), NOT deleted | Restorable via `RestoreFootprintOp` or auto-restore (Protocol 23+) | Financially meaningful data: trusted signers, guardian sets | +| **Instance** | Archived with contract instance | Same as persistent | Contract configuration, executor settings | +| **Temporary** | Permanently deleted | Cannot be restored | Ephemeral data (not used by these contracts) | + +**Key TTL limits (current mainnet):** + +| Parameter | Value | Approximate Time | +|---|---|---| +| `maxEntryTTL` | 6,312,000 ledgers | ~1 year | +| `min_persistent_entry_ttl` | 4,096 ledgers | ~5.7 hours | +| Ledger close time | ~5 seconds | — | + +**Rent cost** is dynamic, computed as: `size_bytes × ledgers × write_fee_per_1kb / (1024 × rentRateDenominator)`. The `write_fee_per_1kb` scales with total ledger size, and the `persistentRentRateDenominator` is currently 2,103. In practice, average Soroban transaction fees (including rent) are ~0.02 XLM (~$0.003). + +#### Rent Strategy for Pyth Contracts + +**Contract instance and code TTL:** +- Both contracts must extend their own instance and code TTLs proactively on every user-facing call (`verify_update`, `execute_governance_action`). +- Use threshold-based extension: `env.storage().instance().extend_ttl(THRESHOLD, EXTEND_TO)` where `THRESHOLD` = ~100,000 ledgers (~6 days) and `EXTEND_TO` = ~500,000 ledgers (~29 days). This way the TTL is refreshed only when it drops below the threshold, amortizing the rent cost across many transactions. + +**Persistent data (trusted signers, guardian set):** +- Extend TTL on each write (governance updates) and each read (`verify_update` extends signer entry TTL, `execute_governance_action` extends guardian set TTL). +- Use the same threshold pattern: `env.storage().persistent().extend_ttl(&key, THRESHOLD, EXTEND_TO)`. + +**Fallback for inactive periods:** +- If the contracts go unused for extended periods, entries may approach expiry. An external cron job or admin script using `stellar contract extend --id --ledgers-to-extend ` can extend TTLs without calling contract functions. +- Protocol 23 auto-restoration means that even if entries are archived, the next transaction that touches them will automatically restore them (the caller pays the restoration fee). This is a safety net, not the primary strategy. + +**Cost estimation:** +- Guardian set (~19 × 20-byte addresses + overhead ≈ ~500 bytes): extending for 500,000 ledgers costs a few hundred stroops (~negligible). +- Trusted signers (each 33-byte key + 8-byte expiry ≈ ~50 bytes per signer): similarly negligible per extension. +- Use `simulateTransaction` RPC to get precise rent costs before deployment. + +### Resource Limits and Gas Analysis for VAA Verification + +Wormhole VAA verification requires 13+ `secp256k1_recover` calls (2/3 + 1 of the 19 mainnet guardians). This section analyzes whether this fits within Soroban's per-transaction resource limits. + +#### Per-Transaction Resource Limits (Current Mainnet) + +| Resource | Limit | +|---|---| +| CPU Instructions | 100,000,000 (100M) | +| Memory (RAM) | 40 MB | +| Transaction Size | 132,096 bytes (~129 KB) | +| Read Entries (footprint) | 100 entries | +| Write Entries | 50 entries | +| Read Bytes | 200,000 bytes | +| Write Bytes | 132,096 bytes | + +#### Cost Breakdown for VAA Verification (13 Signatures) + +| Operation | Per-Call Cost | Count | Total | +|---|---|---|---| +| `secp256k1_recover` | ~2,312,848 instructions | 13 | ~30,067,024 | +| `keccak256` (body hashing) | ~few thousand | 2-14 | ~100,000 | +| WASM execution (parsing, loops) | — | — | ~5M-15M (est.) | +| VM instantiation overhead | — | 1 | ~10M-30M (est.) | +| **Estimated total** | | | **~45M-75M instructions** | + +**Conclusion: VAA verification fits within the 100M instruction budget.** The 13 `secp256k1_recover` calls alone consume ~30M instructions (30% of budget), leaving ample room for parsing, WASM overhead, and cross-contract calls. Protocol 23 improvements (WASM module caching via CAP-0054/0055/0056) further reduce VM instantiation overhead. + +**Note:** SLP-0004 proposes increasing the per-transaction limit to 400M instructions, which would provide even more headroom. However, the current 100M limit is sufficient. + +**Risk mitigation:** +- Use `simulateTransaction` on testnet with a prototype to get exact resource consumption. +- If a specific edge case exceeds 100M (e.g., very large VAA + complex dispatch), the contract could accept pre-parsed guardian signatures, but this is unlikely to be necessary. + +### secp256k1_recover: Output Format and Key Conversion + +Soroban's `secp256k1_recover` returns a **65-byte uncompressed SEC-1 public key** (`BytesN<65>`), formatted as `0x04 || x (32 bytes) || y (32 bytes)`. The function signature is: + +```rust +pub fn secp256k1_recover( + &self, + message_digest: &Hash<32>, // must be output of a hash function + signature: &BytesN<64>, // r (32 bytes) || s (32 bytes) + recovery_id: u32, // valid range: 0-3 +) -> BytesN<65> +``` + +The Soroban SDK does **not** provide a built-in compressed/uncompressed key conversion. This differs from Sui's `secp256k1_ecrecover`, which returns compressed (33-byte) keys directly. + +**Solution for Lazer signer verification (compressed key comparison):** + +Since trusted signers are stored as 33-byte compressed keys (matching the governance PTGM format and other Pyth contracts), the contract must compress the recovered key before lookup. Point compression is straightforward and cheap: + +```rust +fn compress_pubkey(uncompressed: &BytesN<65>) -> BytesN<33> { + // uncompressed format: 0x04 || x (32 bytes) || y (32 bytes) + let mut compressed = [0u8; 33]; + // Parity prefix: 0x02 if y is even, 0x03 if y is odd + compressed[0] = if uncompressed.get(64) & 1 == 0 { 0x02 } else { 0x03 }; + // Copy x-coordinate (bytes 1..33 of the uncompressed key) + compressed[1..33].copy_from_slice(&uncompressed[1..33]); + BytesN::from_array(env, &compressed) +} +``` + +This adds negligible cost (a few hundred instructions) compared to the `secp256k1_recover` call itself (~2.3M instructions). + +**Solution for Wormhole guardian verification (Ethereum address derivation):** + +Wormhole guardians are identified by 20-byte Ethereum addresses, derived from the uncompressed public key as: `keccak256(x || y)[12..32]` (last 20 bytes of the keccak256 hash of the 64-byte x,y coordinates, excluding the `0x04` prefix). This is the standard Ethereum address derivation: + +```rust +fn eth_address_from_pubkey(env: &Env, uncompressed: &BytesN<65>) -> BytesN<20> { + // Hash the 64-byte raw key (skip the 0x04 prefix) + let raw_key: Bytes = uncompressed.slice(1..65); + let hash = env.crypto().keccak256(&raw_key); + // Ethereum address = last 20 bytes of keccak256 hash + BytesN::from_array(env, &hash.to_array()[12..32]) +} +``` + +Both Soroban host functions (`keccak256` and `secp256k1_recover`) are available natively, so no external crates are needed for cryptographic operations. + +**Note on the `Hash<32>` type:** The public `Crypto::secp256k1_recover` wraps the digest in `Hash<32>` (not raw `BytesN<32>`) to provide type-level assurance that the input has been hashed. The contract must pass the output of `env.crypto().keccak256()` directly, which already returns the correct type. + +### Remaining Risks and Open Questions + +1. **Contract size limit**: Soroban contracts have a 64KB WASM size limit. The executor contract includes VAA verification logic which adds code size. Need to verify both contracts fit within limits after compilation with optimizations. + +2. **Wormhole chain ID for Stellar**: Need to determine the correct Wormhole chain ID for Stellar. This may require coordination with the Wormhole team if Stellar is not yet registered. + +3. **Guardian set bootstrap**: The initial guardian set must be hardcoded or provided at initialization time. Need to obtain the current Wormhole mainnet guardian set for deployment. + +4. **Cross-contract call authorization**: The Lazer contract must verify that governance calls come from the authorized executor. In Soroban, this is done via `env.require_auth()` where the executor's contract address is the authorized caller. + +## Key Files and Directories + +- **New directory**: `lazer/contracts/stellar/` in pyth-crosschain repo +- **Reference implementations**: + - `lazer/contracts/sui/` (closest reference for Lazer verification - LE-ECDSA, secp256k1, includes Wormhole governance) + - `lazer/contracts/evm/` (EVM format reference, includes payload parsing) + - `target_chains/ethereum/contracts/contracts/executor/Executor.sol` (EVM Wormhole executor - governance dispatch pattern) + - `governance/remote_executor/programs/remote-executor/` (Solana Wormhole executor - CPI dispatch pattern) + - `pyth-lazer/contracts/solana/` (Solana Lazer format reference) +- **Protocol definitions**: `pyth-lazer/sdk/rust/protocol/src/message.rs` (wire formats), `pyth-lazer/sdk/rust/protocol/src/payload.rs` (payload format) +- **Target branch**: `stellar` branch of pyth-crosschain + +## Implementation Plan + +### Task 1: Wormhole executor - VAA verification and guardian set management + +Set up the `wormhole-executor-stellar` project under `lazer/contracts/stellar/contracts/`. Implement Wormhole VAA binary parsing, guardian signature verification using `secp256k1_recover` + `keccak256`, quorum checking, and guardian set storage/updates. Include unit tests with real VAA test vectors. + +### Task 2: Wormhole executor - PTGM parsing and governance dispatch + +Add PTGM header parsing (magic, module, action, chain ID), emitter validation, sequence-based replay protection, and cross-contract call dispatch to target contracts. Include unit tests for governance message parsing and dispatch. + +### Task 3: Pyth Lazer contract - scaffolding, admin, and signature verification + +Set up the `pyth-lazer-stellar` project. Implement initialization, trusted signer management (with executor authorization), and the core `verify_update` function (LE-ECDSA envelope parsing, keccak256 hashing, secp256k1 key recovery, signer lookup). Include proactive rent management (TTL extension on reads/writes). Include unit tests for all functions. + +### Task 4: Payload parsing + +Implement payload parsing functions that decode the verified payload bytes into structured data (timestamp, channel, feeds with their properties). This mirrors PythLazerLib.sol and the Sui update.move/feed.move modules. Include typed return structs and accessor functions. + +### Task 5: Integration tests and documentation + +Write integration tests using the Soroban test framework that test the full governance flow: deploy both contracts, initialize, deliver a Wormhole VAA to add a trusted signer via the executor, then verify a Lazer price update. Create a README with build/test/deploy instructions and add CI configuration. diff --git a/lazer/contracts/stellar/Makefile b/lazer/contracts/stellar/Makefile new file mode 100644 index 0000000000..51776b1905 --- /dev/null +++ b/lazer/contracts/stellar/Makefile @@ -0,0 +1,31 @@ +.PHONY: build optimize test clean fmt fmt-check clippy check deploy-testnet + +WASM_DIR = $(CURDIR)/target/wasm32-unknown-unknown/release + +build: + cd $(CURDIR) && cargo build --release --target wasm32-unknown-unknown + +optimize: build + wasm-opt -Oz --disable-reference-types \ + $(WASM_DIR)/wormhole_executor_stellar.wasm \ + -o $(WASM_DIR)/wormhole_executor_stellar.optimized.wasm + wasm-opt -Oz --disable-reference-types \ + $(WASM_DIR)/pyth_lazer_stellar.wasm \ + -o $(WASM_DIR)/pyth_lazer_stellar.optimized.wasm + +test: + cd $(CURDIR) && cargo test + +clean: + cd $(CURDIR) && cargo clean + +fmt: + cd $(CURDIR) && cargo fmt --all + +fmt-check: + cd $(CURDIR) && cargo fmt --all -- --check + +clippy: + cd $(CURDIR) && cargo clippy --all-targets -- -D warnings + +check: fmt-check clippy test diff --git a/lazer/contracts/stellar/README.md b/lazer/contracts/stellar/README.md new file mode 100644 index 0000000000..010f515199 --- /dev/null +++ b/lazer/contracts/stellar/README.md @@ -0,0 +1,201 @@ +# Pyth Lazer Stellar Contracts + +Soroban smart contracts for verifying [Pyth Lazer](https://docs.pyth.network/lazer) price feed updates on the [Stellar](https://stellar.org) network. + +## Architecture + +``` + Wormhole Guardians + | + sign VAAs + | + v +┌──────────────────────────────────────────┐ +│ wormhole-executor-stellar │ +│ │ +│ - Verifies Wormhole VAA signatures │ +│ - Manages guardian sets │ +│ - Parses PTGM governance payloads │ +│ - Dispatches governance to target │ +└────────────────┬─────────────────────────┘ + │ cross-contract call + │ (update_trusted_signer / upgrade) + v +┌──────────────────────────────────────────┐ +│ pyth-lazer-stellar │ +│ │ +│ - Verifies LE-ECDSA signed updates │ +│ - Manages trusted signers (via executor)│ +│ - Parses structured price feed payloads │ +│ - Returns verified payload to caller │ +└──────────────────────────────────────────┘ + ^ + │ verify_update(data) + │ + Consumer dApp +``` + +**Flow:** +1. Wormhole governance VAAs add/remove trusted Lazer signers via the executor +2. Lazer publishes LE-ECDSA signed price updates off-chain +3. Consumer dApps submit updates to `pyth-lazer-stellar.verify_update()` to get verified price data + +## Prerequisites + +- [Rust](https://rustup.rs/) (stable) +- Soroban target: `rustup target add wasm32-unknown-unknown` +- [Stellar CLI](https://developers.stellar.org/docs/tools/developer-tools/cli/install-cli) (for deployment) + +## Build + +```bash +make build +``` + +This compiles both contracts to WASM targeting `wasm32-unknown-unknown`. + +## Test + +```bash +make test +``` + +Runs all unit tests and integration tests. The integration test suite (`contracts/integration-tests`) exercises: + +- Full governance flow: VAA -> executor -> Lazer contract (add/update/remove signers) +- Full verification flow: signed Lazer update -> verify -> parse payload (BTC, ETH, SOL feeds) +- Upgrade governance dispatch +- Guardian set upgrades followed by governance actions +- Negative cases: expired signers, wrong emitter, replayed VAAs, unauthorized calls, invalid PTGM + +## End-to-End Test + +Run the E2E test against the testnet deployment: + +```bash +cd scripts/e2e +PYTH_LAZER_TOKEN= npx tsx src/test_real_update.ts \ + --contract-id CCE62RN3NUTNMD2SQ2EGWRJ6XHL7RUYQBNCEK7LVGFRLPCW7U7FGACM5 +``` + +This fetches a real signed price update from the Pyth Lazer service and verifies it on-chain. + +## Code Quality + +```bash +make fmt # Format code +make fmt-check # Check formatting (CI) +make clippy # Run clippy lints +make check # fmt-check + clippy + test +``` + +## Project Structure + +``` +lazer/contracts/stellar/ +├── Cargo.toml # Workspace root +├── Makefile +├── README.md +├── contracts/ +│ ├── pyth-lazer-stellar/ # Lazer verification contract +│ │ └── src/ +│ │ ├── lib.rs # Contract entry points +│ │ ├── verify.rs # LE-ECDSA signature verification +│ │ ├── payload.rs # Price feed payload parsing +│ │ ├── state.rs # Storage management +│ │ └── error.rs # Error types +│ ├── wormhole-executor-stellar/ # Wormhole governance executor +│ │ └── src/ +│ │ ├── lib.rs # Contract entry points +│ │ ├── vaa.rs # VAA parsing & verification +│ │ ├── governance.rs # PTGM parsing +│ │ ├── guardian.rs # Guardian set management +│ │ └── error.rs # Error types +│ └── integration-tests/ # Cross-contract integration tests +│ └── src/ +│ └── test.rs +``` + +## Testnet Deployment + +| Contract | Address | +|----------|---------| +| Pyth Lazer | `CCE62RN3NUTNMD2SQ2EGWRJ6XHL7RUYQBNCEK7LVGFRLPCW7U7FGACM5` | + +The testnet contract is initialized with the Pyth Lazer trusted signer and ready for use. + +## Deployment + +### Testnet + +1. Configure Stellar CLI for testnet: + +```bash +stellar keys generate deployer --network testnet +``` + +2. Build the WASM binaries: + +```bash +make build +``` + +3. Deploy the Wormhole executor contract: + +```bash +stellar contract deploy \ + --wasm target/wasm32-unknown-unknown/release/wormhole_executor_stellar.wasm \ + --network testnet \ + --source deployer +``` + +4. Initialize the executor with the Wormhole guardian set: + +```bash +stellar contract invoke \ + --id \ + --network testnet \ + --source deployer \ + -- initialize \ + --chain_id 30 \ + --owner_emitter_chain 1 \ + --owner_emitter_address \ + --initial_guardian_set '["", ...]' \ + --guardian_set_index +``` + +5. Deploy the Pyth Lazer contract: + +```bash +stellar contract deploy \ + --wasm target/wasm32-unknown-unknown/release/pyth_lazer_stellar.wasm \ + --network testnet \ + --source deployer +``` + +6. Initialize the Lazer contract with the executor address: + +```bash +stellar contract invoke \ + --id \ + --network testnet \ + --source deployer \ + -- initialize \ + --executor +``` + +### Mainnet + +Follow the same steps as testnet, replacing `--network testnet` with `--network mainnet` and using production guardian set values. + +## Configuration + +| Parameter | Description | +|-----------|-------------| +| `chain_id` | Wormhole chain ID for Stellar (30) | +| `owner_emitter_chain` | Wormhole chain ID of the governance emitter (1 = Solana) | +| `owner_emitter_address` | 32-byte Wormhole emitter address for governance | +| `initial_guardian_set` | List of 20-byte Ethereum addresses of Wormhole guardians | +| `guardian_set_index` | Current guardian set index from Wormhole | + +See [Wormhole contract addresses](https://wormhole.com/docs/products/reference/contract-addresses) and [chain IDs](https://wormhole.com/docs/products/reference/chain-ids) for reference values. diff --git a/lazer/contracts/stellar/contracts/integration-tests/Cargo.toml b/lazer/contracts/stellar/contracts/integration-tests/Cargo.toml new file mode 100644 index 0000000000..ff0939da95 --- /dev/null +++ b/lazer/contracts/stellar/contracts/integration-tests/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "stellar-integration-tests" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } +pyth-lazer-stellar = { path = "../pyth-lazer-stellar" } +wormhole-executor-stellar = { path = "../wormhole-executor-stellar" } +k256 = { version = "0.13", features = ["ecdsa"] } +tiny-keccak = { version = "2.0", features = ["keccak"] } +hex-literal = "0.4" diff --git a/lazer/contracts/stellar/contracts/integration-tests/src/lib.rs b/lazer/contracts/stellar/contracts/integration-tests/src/lib.rs new file mode 100644 index 0000000000..d0435bce86 --- /dev/null +++ b/lazer/contracts/stellar/contracts/integration-tests/src/lib.rs @@ -0,0 +1,2 @@ +#[cfg(test)] +mod test; diff --git a/lazer/contracts/stellar/contracts/integration-tests/src/test.rs b/lazer/contracts/stellar/contracts/integration-tests/src/test.rs new file mode 100644 index 0000000000..b5fa67056f --- /dev/null +++ b/lazer/contracts/stellar/contracts/integration-tests/src/test.rs @@ -0,0 +1,920 @@ +extern crate alloc; +extern crate std; + +use k256::ecdsa::SigningKey; +use soroban_sdk::{testutils::Address as _, testutils::Ledger, Address, Bytes, BytesN, Env, Vec}; +use tiny_keccak::{Hasher, Keccak}; + +use pyth_lazer_stellar::{payload, ContractError as LazerError, PythLazerContract, PythLazerContractClient}; +use wormhole_executor_stellar::{WormholeExecutor, WormholeExecutorClient}; + +// ────────────────────────────────────────────────────────────────────── +// Crypto helpers (shared with wormhole-executor-stellar unit tests) +// ────────────────────────────────────────────────────────────────────── + +fn test_secret(index: u8) -> [u8; 32] { + let mut secret = [0u8; 32]; + secret[31] = index + 1; + secret +} + +fn eth_address_from_secret(secret: &[u8; 32]) -> [u8; 20] { + let signing_key = SigningKey::from_bytes(secret.into()).expect("valid key"); + let verifying_key = signing_key.verifying_key(); + let uncompressed = verifying_key.to_encoded_point(false); + let pubkey_bytes = &uncompressed.as_bytes()[1..]; + + let mut hasher = Keccak::v256(); + let mut hash = [0u8; 32]; + hasher.update(pubkey_bytes); + hasher.finalize(&mut hash); + + let mut addr = [0u8; 20]; + addr.copy_from_slice(&hash[12..32]); + addr +} + +fn keccak256(data: &[u8]) -> [u8; 32] { + let mut hasher = Keccak::v256(); + let mut out = [0u8; 32]; + hasher.update(data); + hasher.finalize(&mut out); + out +} + +fn sign_hash(secret: &[u8; 32], hash: &[u8; 32]) -> ([u8; 64], u32) { + let signing_key = SigningKey::from_bytes(secret.into()).expect("valid key"); + let (signature, recovery_id) = signing_key + .sign_prehash_recoverable(hash) + .expect("signing failed"); + let sig_bytes: [u8; 64] = signature.to_bytes().into(); + (sig_bytes, recovery_id.to_byte() as u32) +} + +// ────────────────────────────────────────────────────────────────────── +// VAA construction helpers +// ────────────────────────────────────────────────────────────────────── + +fn build_body( + timestamp: u32, + nonce: u32, + emitter_chain: u16, + emitter_address: &[u8; 32], + sequence: u64, + consistency_level: u8, + payload: &[u8], +) -> alloc::vec::Vec { + let mut body = alloc::vec::Vec::new(); + body.extend_from_slice(×tamp.to_be_bytes()); + body.extend_from_slice(&nonce.to_be_bytes()); + body.extend_from_slice(&emitter_chain.to_be_bytes()); + body.extend_from_slice(emitter_address); + body.extend_from_slice(&sequence.to_be_bytes()); + body.push(consistency_level); + body.extend_from_slice(payload); + body +} + +fn build_signed_vaa( + guardian_set_index: u32, + signers: &[(u8, [u8; 32])], + body: &[u8], +) -> alloc::vec::Vec { + let body_hash = keccak256(body); + let double_hash = keccak256(&body_hash); + + let mut vaa = alloc::vec::Vec::new(); + vaa.push(1u8); // version + vaa.extend_from_slice(&guardian_set_index.to_be_bytes()); + vaa.push(signers.len() as u8); + + for (guardian_index, secret) in signers { + let (sig, recovery_id) = sign_hash(secret, &double_hash); + vaa.push(*guardian_index); + vaa.extend_from_slice(&sig); + vaa.push(recovery_id as u8); + } + + vaa.extend_from_slice(body); + vaa +} + +// ────────────────────────────────────────────────────────────────────── +// PTGM construction helpers +// ────────────────────────────────────────────────────────────────────── + +const PTGM_MAGIC: [u8; 4] = [0x50, 0x54, 0x47, 0x4d]; // "PTGM" + +fn build_ptgm_update_signer( + chain_id: u16, + executor_contract: &Address, + target_contract: &Address, + pubkey: &[u8; 33], + expires_at: u64, +) -> alloc::vec::Vec { + let mut data = alloc::vec::Vec::new(); + data.extend_from_slice(&PTGM_MAGIC); + data.push(3); // module = Lazer + data.push(1); // action = update_trusted_signer + data.extend_from_slice(&chain_id.to_be_bytes()); + let executor = address_to_payload_bytes(executor_contract); + data.push(executor.len() as u8); + data.extend_from_slice(&executor); + let target = address_to_payload_bytes(target_contract); + data.push(target.len() as u8); + data.extend_from_slice(&target); + data.extend_from_slice(pubkey); + data.extend_from_slice(&expires_at.to_be_bytes()); + data +} + +fn build_ptgm_upgrade( + chain_id: u16, + executor_contract: &Address, + target_contract: &Address, + version: u64, + wasm_digest: &[u8; 32], +) -> alloc::vec::Vec { + let mut data = alloc::vec::Vec::new(); + data.extend_from_slice(&PTGM_MAGIC); + data.push(3); // module = Lazer + data.push(0); // action = upgrade + data.extend_from_slice(&chain_id.to_be_bytes()); + let executor = address_to_payload_bytes(executor_contract); + data.push(executor.len() as u8); + data.extend_from_slice(&executor); + let target = address_to_payload_bytes(target_contract); + data.push(target.len() as u8); + data.extend_from_slice(&target); + data.extend_from_slice(&version.to_be_bytes()); + data.extend_from_slice(wasm_digest); + data +} + +fn address_to_payload_bytes(address: &Address) -> alloc::vec::Vec { + let strkey = address.to_string(); + let mut out = alloc::vec![0u8; strkey.len() as usize]; + strkey.copy_into_slice(&mut out); + out +} + +fn build_guardian_set_upgrade_payload( + target_chain: u16, + new_index: u32, + new_guardians: &[[u8; 20]], +) -> alloc::vec::Vec { + let mut payload = alloc::vec::Vec::new(); + payload.extend_from_slice(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Core"); + payload.push(2); // action: guardian set upgrade + payload.extend_from_slice(&target_chain.to_be_bytes()); + payload.extend_from_slice(&new_index.to_be_bytes()); + payload.push(new_guardians.len() as u8); + for addr in new_guardians { + payload.extend_from_slice(addr); + } + payload +} + +// ────────────────────────────────────────────────────────────────────── +// Test environment setup +// ────────────────────────────────────────────────────────────────────── + +const CHAIN_ID: u32 = 30; +const OWNER_EMITTER_CHAIN: u32 = 1; // Solana + +/// Shared test vector: trusted signer compressed public key (from Sui test suite). +fn test_trusted_signer_pubkey() -> [u8; 33] { + hex_literal::hex!("03a4380f01136eb2640f90c17e1e319e02bbafbeef2e6e67dc48af53f9827e155b") +} + +/// Shared test vector: signed Lazer update bytes. +fn test_lazer_update_bytes(env: &Env) -> Bytes { + Bytes::from_slice( + env, + &hex_literal::hex!( + "e4bd474d73a7e70a8e2b8de236b55dcc6a771b4a8a1533fe" + "492f424fae162369fa14103e04c1c93302cef8a052110a95" + "0da031f9dc5eade9e6099e95668aff2592ec1f7900fe0075" + "d3c7934067e9c7f14a06000303010000000b00e1637ad535" + "060000015a2507d335060000027f8bfdf53506000004f8ff" + "0600070008000900000a601299cd3e0600000bc07595c73e" + "0600000c014067e9c7f14a0600020000000b00971b209c2d" + "0000000144056b9b2d0000000298fb6b9c2d00000004f8ff" + "0600070008000900000a284444f92d0000000b480c07f92d" + "0000000c014067e9c7f14a0600700000000b0020d85dd2d7" + "8df30001000000000000000002000000000000000004f4ff" + "060130f80bfeffffffff0701b8ab7057ec4a060008010020" + "9db4060000000900000a00000000000000000b0000000000" + "0000000c014067e9c7f14a0600" + ), + ) +} + +struct TestEnv<'a> { + env: Env, + executor_client: WormholeExecutorClient<'a>, + lazer_client: PythLazerContractClient<'a>, + guardian_secrets: alloc::vec::Vec<[u8; 32]>, + owner_emitter_address: [u8; 32], +} + +/// Deploy both contracts with constructor args and a shared guardian set. +fn setup(num_guardians: u8) -> TestEnv<'static> { + let env = Env::default(); + + // Build guardian set. + let mut secrets = alloc::vec::Vec::new(); + let mut guardian_addrs: Vec> = Vec::new(&env); + for i in 0..num_guardians { + let secret = test_secret(i); + let addr = eth_address_from_secret(&secret); + secrets.push(secret); + guardian_addrs.push_back(BytesN::from_array(&env, &addr)); + } + + let owner_emitter_address = [0x42u8; 32]; + + // Deploy executor contract. + let executor_id = env.register( + WormholeExecutor, + ( + CHAIN_ID, + OWNER_EMITTER_CHAIN, + BytesN::from_array(&env, &owner_emitter_address), + guardian_addrs, + 0u32, + ), + ); + let executor_client = WormholeExecutorClient::new(&env, &executor_id); + + // Deploy Lazer contract, initialized with executor as its governance authority. + let lazer_id = env.register(PythLazerContract, (executor_id.clone(), None::>, None::)); + let lazer_client = PythLazerContractClient::new(&env, &lazer_id); + + TestEnv { + env, + executor_client, + lazer_client, + guardian_secrets: secrets, + owner_emitter_address, + } +} + +/// Build a governance VAA signed by the test guardian set. +fn build_governance_vaa( + te: &TestEnv, + sequence: u64, + ptgm_payload: &[u8], +) -> alloc::vec::Vec { + let body = build_body( + 1000, + 0, + OWNER_EMITTER_CHAIN as u16, + &te.owner_emitter_address, + sequence, + 0, + ptgm_payload, + ); + let signers: alloc::vec::Vec<(u8, [u8; 32])> = te + .guardian_secrets + .iter() + .enumerate() + .map(|(i, s)| (i as u8, *s)) + .collect(); + build_signed_vaa(0, &signers, &body) +} + +// ══════════════════════════════════════════════════════════════════════ +// Integration tests +// ══════════════════════════════════════════════════════════════════════ + +// ────────────────────────────────────────────────────────────────────── +// Full governance flow: VAA -> executor -> Lazer contract +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_full_governance_add_trusted_signer() { + let te = setup(1); + + let pubkey = test_trusted_signer_pubkey(); + let expires_at = 2_000_000_000u64; + let update = test_lazer_update_bytes(&te.env); + + // Before governance, signer is not trusted and verification must fail. + let pre_result = te.lazer_client.try_verify_update(&update); + assert_eq!(pre_result.err().unwrap(), Ok(LazerError::SignerNotTrusted)); + + // Build PTGM to add a trusted signer. + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + expires_at, + ); + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + let vaa_bytes = Bytes::from_slice(&te.env, &vaa_raw); + + // Execute governance action: executor verifies VAA and dispatches to Lazer. + te.executor_client + .execute_governance_action(&vaa_bytes); + + // Verify the signer was added by submitting a signed Lazer update. + let payload = te.lazer_client.verify_update(&update); + assert!(payload.len() > 0); +} + +#[test] +fn test_full_governance_update_signer_expiry() { + let te = setup(1); + + let pubkey = test_trusted_signer_pubkey(); + + // Add signer with short expiry. + let ptgm1 = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 1_000, + ); + let vaa1 = build_governance_vaa(&te, 1, &ptgm1); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa1), + ); + + // Update signer with longer expiry via a second governance action. + let ptgm2 = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + let vaa2 = build_governance_vaa(&te, 2, &ptgm2); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa2), + ); + + // Set ledger past the old expiry but before the new one. + te.env.ledger().with_mut(|li| { + li.timestamp = 5_000; + }); + + // Verification should succeed with the updated expiry. + let update = test_lazer_update_bytes(&te.env); + let payload = te.lazer_client.verify_update(&update); + assert!(payload.len() > 0); +} + +#[test] +fn test_full_governance_remove_signer() { + let te = setup(1); + + let pubkey = test_trusted_signer_pubkey(); + + // Add signer. + let ptgm1 = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + let vaa1 = build_governance_vaa(&te, 1, &ptgm1); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa1), + ); + + // Verify signer works. + let update = test_lazer_update_bytes(&te.env); + assert!(te.lazer_client.verify_update(&update).len() > 0); + + // Remove signer via governance (expires_at = 0). + let ptgm2 = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 0, + ); + let vaa2 = build_governance_vaa(&te, 2, &ptgm2); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa2), + ); + + // Verification should now fail. + let result = te.lazer_client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(LazerError::SignerNotTrusted)); +} + +// ────────────────────────────────────────────────────────────────────── +// Full verification flow: governance -> verify -> parse payload +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_full_verification_and_payload_parsing() { + let te = setup(1); + + let pubkey = test_trusted_signer_pubkey(); + + // Add trusted signer via governance. + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa_raw), + ); + + // Submit a signed Lazer update and get verified payload. + let update = test_lazer_update_bytes(&te.env); + let verified_payload = te.lazer_client.verify_update(&update); + + // Parse the verified payload off-chain. + let parsed = payload::parse_payload(&verified_payload).unwrap(); + + assert_eq!(parsed.timestamp, 1_771_252_161_800_000); + assert_eq!(parsed.channel, payload::Channel::FixedRate200ms); + assert_eq!(parsed.feeds.len(), 3); + + // Feed 1: BTC/USD + let btc = &parsed.feeds[0]; + assert_eq!(btc.feed_id, 1); + assert_eq!(btc.price, Some(6_828_284_601_313)); + assert_eq!(btc.exponent, Some(-8)); + assert_eq!(btc.market_session, Some(payload::MarketSession::Regular)); + + // Feed 2: ETH/USD + let eth = &parsed.feeds[1]; + assert_eq!(eth.feed_id, 2); + assert_eq!(eth.price, Some(195_892_878_231)); + assert_eq!(eth.exponent, Some(-8)); + + // Feed 3: SOL/USD (with funding rate) + let sol = &parsed.feeds[2]; + assert_eq!(sol.feed_id, 112); + assert_eq!(sol.price, Some(68_554_377_427_540_000)); + assert_eq!(sol.exponent, Some(-12)); + assert_eq!(sol.funding_rate, Some(-32_770_000)); + assert_eq!(sol.funding_timestamp, Some(1_771_228_800_003_000)); +} + +// ────────────────────────────────────────────────────────────────────── +// Upgrade governance flow +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_governance_upgrade_dispatched_to_lazer() { + let te = setup(1); + + // Upload a real wasm blob so the dispatched upgrade can succeed. + let wasm_hash = te.env.deployer().upload_contract_wasm(Bytes::new(&te.env)); + let wasm_digest: [u8; 32] = wasm_hash.into(); + let ptgm = build_ptgm_upgrade( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + 1, + &wasm_digest, + ); + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + let vaa_bytes = Bytes::from_slice(&te.env, &vaa_raw); + + let result = te + .executor_client + .try_execute_governance_action(&vaa_bytes); + assert!(result.is_ok()); +} + +// ────────────────────────────────────────────────────────────────────── +// Guardian set upgrade flow +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_guardian_set_upgrade_then_governance() { + let te = setup(1); + + // Upgrade guardian set from index 0 to index 1 with new guardians. + let new_secret = test_secret(10); + let new_addr = eth_address_from_secret(&new_secret); + let upgrade_payload = build_guardian_set_upgrade_payload(0, 1, &[new_addr]); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &upgrade_payload); + let vaa_raw = build_signed_vaa(0, &[(0u8, te.guardian_secrets[0])], &body); + te.executor_client + .update_guardian_set(&Bytes::from_slice(&te.env, &vaa_raw)); + + // Now use the new guardian set to execute a governance action. + let pubkey = test_trusted_signer_pubkey(); + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + let gov_body = build_body( + 2000, + 0, + OWNER_EMITTER_CHAIN as u16, + &te.owner_emitter_address, + 2, + 0, + &ptgm, + ); + let gov_vaa = build_signed_vaa(1, &[(0u8, new_secret)], &gov_body); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &gov_vaa), + ); + + // Verify the signer was added. + let update = test_lazer_update_bytes(&te.env); + let payload = te.lazer_client.verify_update(&update); + assert!(payload.len() > 0); +} + +#[test] +fn test_sequential_guardian_upgrades_then_governance() { + let te = setup(1); + + // Upgrade 0 -> 1 + let secret_1 = test_secret(10); + let addr_1 = eth_address_from_secret(&secret_1); + let up1 = build_guardian_set_upgrade_payload(0, 1, &[addr_1]); + let body1 = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &up1); + let vaa1 = build_signed_vaa(0, &[(0u8, te.guardian_secrets[0])], &body1); + te.executor_client + .update_guardian_set(&Bytes::from_slice(&te.env, &vaa1)); + + // Upgrade 1 -> 2 + let secret_2a = test_secret(20); + let secret_2b = test_secret(21); + let addr_2a = eth_address_from_secret(&secret_2a); + let addr_2b = eth_address_from_secret(&secret_2b); + let up2 = build_guardian_set_upgrade_payload(0, 2, &[addr_2a, addr_2b]); + let body2 = build_body(2000, 0, 1, &[0u8; 32], 2, 0, &up2); + let vaa2 = build_signed_vaa(1, &[(0u8, secret_1)], &body2); + te.executor_client + .update_guardian_set(&Bytes::from_slice(&te.env, &vaa2)); + + // Execute governance with the new 2-guardian set. + let pubkey = test_trusted_signer_pubkey(); + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + let gov_body = build_body( + 3000, + 0, + OWNER_EMITTER_CHAIN as u16, + &te.owner_emitter_address, + 3, + 0, + &ptgm, + ); + let gov_vaa = build_signed_vaa(2, &[(0u8, secret_2a), (1u8, secret_2b)], &gov_body); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &gov_vaa), + ); + + // Verify signer was added. + let update = test_lazer_update_bytes(&te.env); + assert!(te.lazer_client.verify_update(&update).len() > 0); +} + +// ────────────────────────────────────────────────────────────────────── +// Negative tests: expired signer +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_expired_signer_after_governance() { + let te = setup(1); + + let pubkey = test_trusted_signer_pubkey(); + + // Add signer with short expiry via governance. + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 1_000, + ); + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa_raw), + ); + + // Set ledger past expiry. + te.env.ledger().with_mut(|li| { + li.timestamp = 1_000; + }); + + let update = test_lazer_update_bytes(&te.env); + let result = te.lazer_client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(LazerError::SignerExpired)); +} + +// ────────────────────────────────────────────────────────────────────── +// Negative tests: wrong emitter +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_governance_wrong_emitter_chain() { + let te = setup(1); + + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &[0xAA; 33], + 1000, + ); + // Use emitter_chain = 2 instead of 1. + let body = build_body(1000, 0, 2, &te.owner_emitter_address, 1, 0, &ptgm); + let vaa_raw = build_signed_vaa(0, &[(0u8, te.guardian_secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&te.env, &vaa_raw); + + let result = te + .executor_client + .try_execute_governance_action(&vaa_bytes); + assert!(result.is_err()); +} + +#[test] +fn test_governance_wrong_emitter_address() { + let te = setup(1); + + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &[0xAA; 33], + 1000, + ); + let wrong_address = [0x99u8; 32]; + let body = build_body( + 1000, + 0, + OWNER_EMITTER_CHAIN as u16, + &wrong_address, + 1, + 0, + &ptgm, + ); + let vaa_raw = build_signed_vaa(0, &[(0u8, te.guardian_secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&te.env, &vaa_raw); + + let result = te + .executor_client + .try_execute_governance_action(&vaa_bytes); + assert!(result.is_err()); +} + +#[test] +fn test_governance_wrong_executor_address_in_payload() { + let te = setup(1); + + let wrong_executor = Address::generate(&te.env); + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &wrong_executor, + &te.lazer_client.address, + &[0xAA; 33], + 1000, + ); + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + let vaa_bytes = Bytes::from_slice(&te.env, &vaa_raw); + + let result = te + .executor_client + .try_execute_governance_action(&vaa_bytes); + assert!(result.is_err()); +} + +// ────────────────────────────────────────────────────────────────────── +// Negative tests: replayed VAA +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_governance_replayed_vaa() { + let te = setup(1); + + let pubkey = test_trusted_signer_pubkey(); + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + let vaa_bytes = Bytes::from_slice(&te.env, &vaa_raw); + + // First execution succeeds. + te.executor_client + .execute_governance_action(&vaa_bytes); + + // Replay with the same sequence should fail. + let result = te + .executor_client + .try_execute_governance_action(&vaa_bytes); + assert!(result.is_err()); + + // Earlier sequence (never executed, but now below last_executed) should fail. + let ptgm_earlier = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 3_000_000_000, + ); + let vaa_earlier = build_governance_vaa(&te, 0, &ptgm_earlier); + let result = te.executor_client.try_execute_governance_action( + &Bytes::from_slice(&te.env, &vaa_earlier), + ); + assert!(result.is_err()); + + // Next sequence succeeds. + let ptgm_next = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 3_000_000_000, + ); + let vaa_next = build_governance_vaa(&te, 2, &ptgm_next); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa_next), + ); +} + +#[test] +fn test_governance_stale_sequence() { + let te = setup(1); + + let pubkey = test_trusted_signer_pubkey(); + + // Execute sequence 5. + let ptgm1 = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + let vaa1 = build_governance_vaa(&te, 5, &ptgm1); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa1), + ); + + // Try sequence 3 (stale). + let ptgm2 = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 3_000_000_000, + ); + let vaa2 = build_governance_vaa(&te, 3, &ptgm2); + let result = te.executor_client.try_execute_governance_action( + &Bytes::from_slice(&te.env, &vaa2), + ); + assert!(result.is_err()); +} + +// ────────────────────────────────────────────────────────────────────── +// Negative tests: unauthorized governance call +// ────────────────────────────────────────────────────────────────────── + +#[test] +#[should_panic(expected = "HostError: Error(Auth")] +fn test_unauthorized_direct_signer_update() { + let env = Env::default(); + + let owner_emitter_address = BytesN::from_array(&env, &[0x42u8; 32]); + let guardian_addrs: Vec> = Vec::new(&env); + let executor_id = env.register( + WormholeExecutor, + (CHAIN_ID, OWNER_EMITTER_CHAIN, owner_emitter_address, guardian_addrs, 0u32), + ); + let lazer_id = env.register(PythLazerContract, (executor_id.clone(), None::>, None::)); + let lazer_client = PythLazerContractClient::new(&env, &lazer_id); + + let pubkey = BytesN::from_array(&env, &test_trusted_signer_pubkey()); + + // Direct invocation without executor authorization must fail. + lazer_client.update_trusted_signer(&pubkey, &2_000_000_000u64); +} + +#[test] +#[should_panic(expected = "HostError: Error(Auth")] +fn test_unauthorized_direct_upgrade() { + let env = Env::default(); + + let owner_emitter_address = BytesN::from_array(&env, &[0x42u8; 32]); + let guardian_addrs: Vec> = Vec::new(&env); + let executor_id = env.register( + WormholeExecutor, + (CHAIN_ID, OWNER_EMITTER_CHAIN, owner_emitter_address, guardian_addrs, 0u32), + ); + let lazer_id = env.register(PythLazerContract, (executor_id.clone(), None::>, None::)); + let lazer_client = PythLazerContractClient::new(&env, &lazer_id); + + let fake_hash = BytesN::from_array(&env, &[0u8; 32]); + + // Direct invocation without executor authorization must fail. + lazer_client.upgrade(&fake_hash); +} + +// ────────────────────────────────────────────────────────────────────── +// Negative tests: invalid PTGM in governance VAA +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_governance_invalid_ptgm_magic() { + let te = setup(1); + + let mut ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &[0xAA; 33], + 1000, + ); + ptgm[0] = 0xFF; // corrupt PTGM magic + + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + let result = te.executor_client.try_execute_governance_action( + &Bytes::from_slice(&te.env, &vaa_raw), + ); + assert!(result.is_err()); +} + +#[test] +fn test_governance_wrong_target_chain() { + let te = setup(1); + + // PTGM targets chain 99, but executor is on chain 30. + let ptgm = build_ptgm_update_signer( + 99, + &te.executor_client.address, + &te.lazer_client.address, + &[0xAA; 33], + 1000, + ); + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + let result = te.executor_client.try_execute_governance_action( + &Bytes::from_slice(&te.env, &vaa_raw), + ); + assert!(result.is_err()); +} + +// ────────────────────────────────────────────────────────────────────── +// Multi-guardian quorum test +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_governance_with_quorum() { + // 3 guardians, quorum = 3. + let te = setup(3); + + let pubkey = test_trusted_signer_pubkey(); + let ptgm = build_ptgm_update_signer( + CHAIN_ID as u16, + &te.executor_client.address, + &te.lazer_client.address, + &pubkey, + 2_000_000_000, + ); + + // All 3 guardians sign. + let vaa_raw = build_governance_vaa(&te, 1, &ptgm); + te.executor_client.execute_governance_action( + &Bytes::from_slice(&te.env, &vaa_raw), + ); + + let update = test_lazer_update_bytes(&te.env); + assert!(te.lazer_client.verify_update(&update).len() > 0); +} + +// ────────────────────────────────────────────────────────────────────── +// Verify update without any trusted signer +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_verify_update_no_signers_configured() { + let te = setup(1); + + // No governance action to add signers — verify should fail. + let update = test_lazer_update_bytes(&te.env); + let result = te.lazer_client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(LazerError::SignerNotTrusted)); +} diff --git a/lazer/contracts/stellar/contracts/pyth-lazer-stellar/Cargo.toml b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/Cargo.toml new file mode 100644 index 0000000000..fc314bf70f --- /dev/null +++ b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "pyth-lazer-stellar" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +soroban-sdk = { workspace = true, features = ["alloc"] } + +[dev-dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } +hex-literal = "0.4" diff --git a/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/error.rs b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/error.rs new file mode 100644 index 0000000000..d482192817 --- /dev/null +++ b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/error.rs @@ -0,0 +1,19 @@ +use soroban_sdk::contracterror; + +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[repr(u32)] +pub enum ContractError { + AlreadyInitialized = 1, + NotInitialized = 2, + InvalidMagic = 3, + TruncatedData = 4, + InvalidPayloadLength = 5, + SignerNotTrusted = 6, + SignerExpired = 7, + Unauthorized = 8, + InvalidPayloadMagic = 9, + InvalidChannel = 10, + InvalidProperty = 11, + InvalidMarketSession = 12, +} diff --git a/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/lib.rs b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/lib.rs new file mode 100644 index 0000000000..aa9323d31e --- /dev/null +++ b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/lib.rs @@ -0,0 +1,73 @@ +#![no_std] + +use soroban_sdk::{contract, contractimpl, Address, Bytes, BytesN, Env}; + +mod bytes; +mod error; +pub mod payload; +mod state; +mod verify; + +#[cfg(test)] +mod test; + +pub use error::ContractError; + +#[contract] +pub struct PythLazerContract; + +#[contractimpl] +impl PythLazerContract { + /// Constructor. Stores the executor address (the Wormhole executor + /// contract authorized for governance operations). + /// + /// Optionally accepts an initial trusted signer and expiry. This avoids + /// needing a governance VAA for the very first signer during deployment. + pub fn __constructor( + env: Env, + executor: Address, + initial_signer: Option>, + initial_signer_expires_at: Option, + ) -> Result<(), ContractError> { + if state::has_executor(&env) { + return Err(ContractError::AlreadyInitialized); + } + state::set_executor(&env, &executor); + if let (Some(pubkey), Some(expires_at)) = (initial_signer, initial_signer_expires_at) { + state::set_trusted_signer(&env, &pubkey, expires_at); + } + state::extend_instance_ttl(&env); + Ok(()) + } + + /// Verify an LE-ECDSA signed Pyth Lazer update. + /// + /// Parses the envelope, recovers the signer's public key, checks it against + /// trusted signers, validates expiry, and returns the verified payload bytes. + pub fn verify_update(env: Env, data: Bytes) -> Result { + state::extend_instance_ttl(&env); + verify::verify_update(&env, &data) + } + + /// Add, update, or remove a trusted signer. Callable only by the executor. + /// Setting `expires_at` to 0 removes the signer. + pub fn update_trusted_signer( + env: Env, + pubkey: BytesN<33>, + expires_at: u64, + ) -> Result<(), ContractError> { + let executor = state::get_executor(&env)?; + executor.require_auth(); + state::set_trusted_signer(&env, &pubkey, expires_at); + state::extend_instance_ttl(&env); + Ok(()) + } + + /// Upgrade the contract WASM. Callable only by the executor. + pub fn upgrade(env: Env, new_wasm_hash: BytesN<32>) -> Result<(), ContractError> { + let executor = state::get_executor(&env)?; + executor.require_auth(); + env.deployer().update_current_contract_wasm(new_wasm_hash); + Ok(()) + } +} diff --git a/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/payload.rs b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/payload.rs new file mode 100644 index 0000000000..6f3cbe963d --- /dev/null +++ b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/payload.rs @@ -0,0 +1,521 @@ +extern crate alloc; + +use alloc::vec::Vec; +use soroban_sdk::Bytes; + +use crate::bytes::get_byte; +use crate::error::ContractError; + +// TODO: this payload parsing code needs to be a library or something that users can integrate +// in their contract. + +/// Payload magic number (LE u32 = 0x93C7D375 = 2479346549). +const PAYLOAD_MAGIC: u32 = 2_479_346_549; + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Channel { + RealTime, + FixedRate50ms, + FixedRate200ms, + FixedRate1000ms, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum MarketSession { + Regular, + PreMarket, + PostMarket, + OverNight, + Closed, +} + +/// Parsed price feed data. +/// +/// Each field is `Option` where `None` means the property was either not +/// present in the payload or had an absent/zero value. For properties with an +/// explicit "exists" flag on the wire (funding_rate, funding_timestamp, +/// funding_rate_interval, feed_update_timestamp), `None` means the flag was +/// false or the property was not included. +/// +/// Signed integer fields (price, best_bid_price, best_ask_price, confidence, +/// funding_rate, ema_price) are decoded from LE two's complement u64 on the wire. +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Feed { + pub feed_id: u32, + pub price: Option, + pub best_bid_price: Option, + pub best_ask_price: Option, + pub publisher_count: Option, + pub exponent: Option, + pub confidence: Option, + pub funding_rate: Option, + pub funding_timestamp: Option, + pub funding_rate_interval: Option, + pub market_session: Option, + pub ema_price: Option, + pub ema_confidence: Option, + pub feed_update_timestamp: Option, +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Update { + pub timestamp: u64, + pub channel: Channel, + pub feeds: Vec, +} + +/// Cursor for reading little-endian values from Soroban Bytes. +struct Reader<'a> { + data: &'a Bytes, + offset: u32, +} + +impl<'a> Reader<'a> { + fn new(data: &'a Bytes) -> Self { + Self { data, offset: 0 } + } + + fn remaining(&self) -> u32 { + self.data.len().saturating_sub(self.offset) + } + + fn read_u8(&mut self) -> Result { + if self.offset >= self.data.len() { + return Err(ContractError::TruncatedData); + } + let val = get_byte(self.data, self.offset)?; + self.offset += 1; + Ok(val) + } + + fn read_bool(&mut self) -> Result { + Ok(self.read_u8()? != 0) + } + + fn read_le_u16(&mut self) -> Result { + if self.remaining() < 2 { + return Err(ContractError::TruncatedData); + } + let b0 = get_byte(self.data, self.offset)? as u16; + let b1 = get_byte(self.data, self.offset + 1)? as u16; + self.offset += 2; + Ok(b0 | (b1 << 8)) + } + + fn read_le_u32(&mut self) -> Result { + if self.remaining() < 4 { + return Err(ContractError::TruncatedData); + } + let b0 = get_byte(self.data, self.offset)? as u32; + let b1 = get_byte(self.data, self.offset + 1)? as u32; + let b2 = get_byte(self.data, self.offset + 2)? as u32; + let b3 = get_byte(self.data, self.offset + 3)? as u32; + self.offset += 4; + Ok(b0 | (b1 << 8) | (b2 << 16) | (b3 << 24)) + } + + fn read_le_u64(&mut self) -> Result { + if self.remaining() < 8 { + return Err(ContractError::TruncatedData); + } + let mut val = 0u64; + for i in 0..8u32 { + val |= (get_byte(self.data, self.offset + i)? as u64) << (i * 8); + } + self.offset += 8; + Ok(val) + } +} + +fn parse_channel(value: u8) -> Result { + match value { + 1 => Ok(Channel::RealTime), + 2 => Ok(Channel::FixedRate50ms), + 3 => Ok(Channel::FixedRate200ms), + 4 => Ok(Channel::FixedRate1000ms), + _ => Err(ContractError::InvalidChannel), + } +} + +fn parse_market_session(value: u16) -> Result { + match value { + 0 => Ok(MarketSession::Regular), + 1 => Ok(MarketSession::PreMarket), + 2 => Ok(MarketSession::PostMarket), + 3 => Ok(MarketSession::OverNight), + 4 => Ok(MarketSession::Closed), + _ => Err(ContractError::InvalidMarketSession), + } +} + +/// Read a u64 from the wire and reinterpret as i64 (two's complement). +/// Returns None if the raw value is 0 (convention for absent values). +fn read_optional_i64(reader: &mut Reader) -> Result, ContractError> { + let raw = reader.read_le_u64()?; + if raw == 0 { + Ok(None) + } else { + Ok(Some(raw as i64)) + } +} + +fn parse_feed(reader: &mut Reader) -> Result { + let feed_id = reader.read_le_u32()?; + let num_properties = reader.read_u8()?; + + let mut feed = Feed { + feed_id, + price: None, + best_bid_price: None, + best_ask_price: None, + publisher_count: None, + exponent: None, + confidence: None, + funding_rate: None, + funding_timestamp: None, + funding_rate_interval: None, + market_session: None, + ema_price: None, + ema_confidence: None, + feed_update_timestamp: None, + }; + + for _ in 0..num_properties { + let property_id = reader.read_u8()?; + match property_id { + 0 => { + // Price: u64 on wire, reinterpret as i64; 0 = absent + feed.price = read_optional_i64(reader)?; + } + 1 => { + // BestBidPrice + feed.best_bid_price = read_optional_i64(reader)?; + } + 2 => { + // BestAskPrice + feed.best_ask_price = read_optional_i64(reader)?; + } + 3 => { + // PublisherCount: u16 + feed.publisher_count = Some(reader.read_le_u16()?); + } + 4 => { + // Exponent: u16 on wire, reinterpret as i16 (two's complement) + let raw = reader.read_le_u16()?; + feed.exponent = Some(raw as i16); + } + 5 => { + // Confidence: u64 on wire, reinterpret as i64; 0 = absent + feed.confidence = read_optional_i64(reader)?; + } + 6 => { + // FundingRate: bool exists flag + u64 + if reader.read_bool()? { + let raw = reader.read_le_u64()?; + feed.funding_rate = Some(raw as i64); + } + } + 7 => { + // FundingTimestamp: bool exists flag + u64 + if reader.read_bool()? { + feed.funding_timestamp = Some(reader.read_le_u64()?); + } + } + 8 => { + // FundingRateInterval: bool exists flag + u64 + if reader.read_bool()? { + feed.funding_rate_interval = Some(reader.read_le_u64()?); + } + } + 9 => { + // MarketSession: u16 + let raw = reader.read_le_u16()?; + feed.market_session = Some(parse_market_session(raw)?); + } + 10 => { + // EmaPrice: u64 on wire, reinterpret as i64; 0 = absent + feed.ema_price = read_optional_i64(reader)?; + } + 11 => { + // EmaConfidence: u64; 0 = absent + let raw = reader.read_le_u64()?; + feed.ema_confidence = if raw == 0 { None } else { Some(raw) }; + } + 12 => { + // FeedUpdateTimestamp: bool exists flag + u64 + if reader.read_bool()? { + feed.feed_update_timestamp = Some(reader.read_le_u64()?); + } + } + _ => { + return Err(ContractError::InvalidProperty); + } + } + } + + Ok(feed) +} + +/// Parse verified payload bytes into a structured Update. +/// +/// The payload format (all integers little-endian): +/// - 4 bytes: magic (0x93C7D375) +/// - 8 bytes: timestamp (u64, microseconds) +/// - 1 byte: channel +/// - 1 byte: number of feeds +/// - For each feed: +/// - 4 bytes: feed_id (u32) +/// - 1 byte: number of properties +/// - For each property: 1 byte property_id, then type-specific value bytes +pub fn parse_payload(payload: &Bytes) -> Result { + let mut reader = Reader::new(payload); + + let magic = reader.read_le_u32()?; + if magic != PAYLOAD_MAGIC { + return Err(ContractError::InvalidPayloadMagic); + } + + let timestamp = reader.read_le_u64()?; + + let channel_value = reader.read_u8()?; + let channel = parse_channel(channel_value)?; + + let num_feeds = reader.read_u8()?; + let mut feeds = Vec::with_capacity(num_feeds as usize); + + for _ in 0..num_feeds { + feeds.push(parse_feed(&mut reader)?); + } + + if reader.remaining() != 0 { + return Err(ContractError::InvalidPayloadLength); + } + + Ok(Update { + timestamp, + channel, + feeds, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use soroban_sdk::Env; + + /// Payload extracted from the shared Sui/Stellar test vector (TEST_LAZER_UPDATE bytes 71+). + /// Contains 3 feeds (BTC/USD id=1, ETH/USD id=2, SOL/USD id=112) with 11 properties each. + fn test_payload_bytes(env: &Env) -> Bytes { + Bytes::from_slice( + env, + &hex_literal::hex!( + "75d3c7934067e9c7f14a06000303010000000b00e1637ad5" + "35060000015a2507d335060000027f8bfdf53506000004f8" + "ff0600070008000900000a601299cd3e0600000bc07595c7" + "3e0600000c014067e9c7f14a0600020000000b00971b209c" + "2d0000000144056b9b2d0000000298fb6b9c2d00000004f8" + "ff0600070008000900000a284444f92d0000000b480c07f9" + "2d0000000c014067e9c7f14a0600700000000b0020d85dd2" + "d78df30001000000000000000002000000000000000004f4" + "ff060130f80bfeffffffff0701b8ab7057ec4a0600080100" + "209db4060000000900000a00000000000000000b00000000" + "000000000c014067e9c7f14a0600" + ), + ) + } + + #[test] + fn test_parse_payload_success() { + let env = Env::default(); + let payload = test_payload_bytes(&env); + let update = parse_payload(&payload).unwrap(); + + assert_eq!(update.timestamp, 1_771_252_161_800_000); + assert_eq!(update.channel, Channel::FixedRate200ms); + assert_eq!(update.feeds.len(), 3); + } + + #[test] + fn test_parse_feed_1_btc() { + let env = Env::default(); + let payload = test_payload_bytes(&env); + let update = parse_payload(&payload).unwrap(); + let feed = &update.feeds[0]; + + assert_eq!(feed.feed_id, 1); + assert_eq!(feed.price, Some(6_828_284_601_313)); + assert_eq!(feed.best_bid_price, Some(6_828_243_494_234)); + assert_eq!(feed.best_ask_price, Some(6_828_830_067_583)); + assert_eq!(feed.exponent, Some(-8)); + assert_eq!(feed.publisher_count, None); // not in payload + assert_eq!(feed.confidence, None); // not in payload + assert_eq!(feed.funding_rate, None); // exists=false + assert_eq!(feed.funding_timestamp, None); // exists=false + assert_eq!(feed.funding_rate_interval, None); // exists=false + assert_eq!(feed.market_session, Some(MarketSession::Regular)); + assert_eq!(feed.ema_price, Some(6_866_807_100_000)); + assert_eq!(feed.ema_confidence, Some(6_866_706_200_000)); + assert_eq!(feed.feed_update_timestamp, Some(1_771_252_161_800_000)); + } + + #[test] + fn test_parse_feed_2_eth() { + let env = Env::default(); + let payload = test_payload_bytes(&env); + let update = parse_payload(&payload).unwrap(); + let feed = &update.feeds[1]; + + assert_eq!(feed.feed_id, 2); + assert_eq!(feed.price, Some(195_892_878_231)); + assert_eq!(feed.best_bid_price, Some(195_881_010_500)); + assert_eq!(feed.best_ask_price, Some(195_897_850_776)); + assert_eq!(feed.exponent, Some(-8)); + assert_eq!(feed.funding_rate, None); + assert_eq!(feed.funding_timestamp, None); + assert_eq!(feed.funding_rate_interval, None); + assert_eq!(feed.market_session, Some(MarketSession::Regular)); + assert_eq!(feed.ema_price, Some(197_455_529_000)); + assert_eq!(feed.ema_confidence, Some(197_451_517_000)); + assert_eq!(feed.feed_update_timestamp, Some(1_771_252_161_800_000)); + } + + #[test] + fn test_parse_feed_3_with_funding() { + let env = Env::default(); + let payload = test_payload_bytes(&env); + let update = parse_payload(&payload).unwrap(); + let feed = &update.feeds[2]; + + assert_eq!(feed.feed_id, 112); + assert_eq!(feed.price, Some(68_554_377_427_540_000)); + // best_bid/ask are 0 on wire → None + assert_eq!(feed.best_bid_price, None); + assert_eq!(feed.best_ask_price, None); + assert_eq!(feed.exponent, Some(-12)); + assert_eq!(feed.funding_rate, Some(-32_770_000)); + assert_eq!(feed.funding_timestamp, Some(1_771_228_800_003_000)); + assert_eq!(feed.funding_rate_interval, Some(28_800_000_000)); + assert_eq!(feed.market_session, Some(MarketSession::Regular)); + // ema_price and ema_confidence are 0 on wire → None + assert_eq!(feed.ema_price, None); + assert_eq!(feed.ema_confidence, None); + assert_eq!(feed.feed_update_timestamp, Some(1_771_252_161_800_000)); + } + + #[test] + fn test_parse_payload_invalid_magic() { + let env = Env::default(); + let mut raw = hex_literal::hex!( + "75d3c7934067e9c7f14a06000303010000000b00e1637ad5" + "35060000015a2507d335060000027f8bfdf53506000004f8" + "ff0600070008000900000a601299cd3e0600000bc07595c7" + "3e0600000c014067e9c7f14a0600020000000b00971b209c" + "2d0000000144056b9b2d0000000298fb6b9c2d00000004f8" + "ff0600070008000900000a284444f92d0000000b480c07f9" + "2d0000000c014067e9c7f14a0600700000000b0020d85dd2" + "d78df30001000000000000000002000000000000000004f4" + "ff060130f80bfeffffffff0701b8ab7057ec4a0600080100" + "209db4060000000900000a00000000000000000b00000000" + "000000000c014067e9c7f14a0600" + ) + .to_vec(); + raw[0] = 0xFF; // corrupt magic + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_payload(&payload), + Err(ContractError::InvalidPayloadMagic) + ); + } + + #[test] + fn test_parse_payload_truncated() { + let env = Env::default(); + // Only 10 bytes — not enough for magic + timestamp + let payload = Bytes::from_slice(&env, &[0x75, 0xd3, 0xc7, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]); + + assert_eq!(parse_payload(&payload), Err(ContractError::TruncatedData)); + } + + #[test] + fn test_parse_payload_unknown_property() { + let env = Env::default(); + // Valid header + 1 feed with 1 unknown property (id=99) + let payload = Bytes::from_slice( + &env, + &hex_literal::hex!( + "75d3c793" // magic + "4067e9c7f14a0600" // timestamp + "01" // channel = RealTime + "01" // 1 feed + "01000000" // feed_id = 1 + "01" // 1 property + "63" // property_id = 99 (unknown) + "0000000000000000" // 8 bytes of data (won't be parsed) + ), + ); + + assert_eq!( + parse_payload(&payload), + Err(ContractError::InvalidProperty) + ); + } + + #[test] + fn test_parse_payload_invalid_channel() { + let env = Env::default(); + let payload = Bytes::from_slice( + &env, + &hex_literal::hex!( + "75d3c793" // magic + "4067e9c7f14a0600" // timestamp + "FF" // channel = 255 (invalid) + "00" // 0 feeds + ), + ); + + assert_eq!( + parse_payload(&payload), + Err(ContractError::InvalidChannel) + ); + } + + #[test] + fn test_parse_payload_trailing_bytes() { + let env = Env::default(); + let payload = Bytes::from_slice( + &env, + &hex_literal::hex!( + "75d3c793" // magic + "4067e9c7f14a0600" // timestamp + "01" // channel = RealTime + "00" // 0 feeds + "FF" // unexpected trailing byte + ), + ); + + assert_eq!( + parse_payload(&payload), + Err(ContractError::InvalidPayloadLength) + ); + } + + #[test] + fn test_parse_payload_empty_feeds() { + let env = Env::default(); + let payload = Bytes::from_slice( + &env, + &hex_literal::hex!( + "75d3c793" // magic + "4067e9c7f14a0600" // timestamp + "01" // channel = RealTime + "00" // 0 feeds + ), + ); + + let update = parse_payload(&payload).unwrap(); + assert_eq!(update.timestamp, 1_771_252_161_800_000); + assert_eq!(update.channel, Channel::RealTime); + assert_eq!(update.feeds.len(), 0); + } +} diff --git a/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/state.rs b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/state.rs new file mode 100644 index 0000000000..f83f7aee36 --- /dev/null +++ b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/state.rs @@ -0,0 +1,68 @@ +use soroban_sdk::{contracttype, Address, BytesN, Env}; + +use crate::error::ContractError; + +/// TTL threshold: extend when TTL drops below this (approx 6 days at 5s/ledger). +pub const TTL_THRESHOLD: u32 = 100_000; +/// TTL extension target (approx 29 days at 5s/ledger). +pub const TTL_EXTEND_TO: u32 = 500_000; + +#[derive(Clone)] +#[contracttype] +pub enum DataKey { + /// The executor address authorized for governance operations. + Executor, + /// Trusted signer entry: maps compressed secp256k1 pubkey to expiry timestamp. + TrustedSigner(BytesN<33>), +} + +/// Store the executor address (one-time initialization). +pub fn set_executor(env: &Env, executor: &Address) { + env.storage().instance().set(&DataKey::Executor, executor); +} + +/// Read the executor address. Panics if not initialized. +pub fn get_executor(env: &Env) -> Result { + env.storage() + .instance() + .get(&DataKey::Executor) + .ok_or(ContractError::NotInitialized) +} + +/// Check whether the contract has been initialized. +pub fn has_executor(env: &Env) -> bool { + env.storage().instance().has(&DataKey::Executor) +} + +/// Store or update a trusted signer's expiry timestamp (unix seconds). +/// If `expires_at` is 0, removes the signer. +pub fn set_trusted_signer(env: &Env, pubkey: &BytesN<33>, expires_at: u64) { + let key = DataKey::TrustedSigner(pubkey.clone()); + if expires_at == 0 { + env.storage().persistent().remove(&key); + } else { + env.storage().persistent().set(&key, &expires_at); + env.storage() + .persistent() + .extend_ttl(&key, TTL_THRESHOLD, TTL_EXTEND_TO); + } +} + +/// Get a trusted signer's expiry timestamp. Returns None if not found. +pub fn get_trusted_signer_expiry(env: &Env, pubkey: &BytesN<33>) -> Option { + let key = DataKey::TrustedSigner(pubkey.clone()); + let result: Option = env.storage().persistent().get(&key); + if result.is_some() { + env.storage() + .persistent() + .extend_ttl(&key, TTL_THRESHOLD, TTL_EXTEND_TO); + } + result +} + +/// Extend TTL on instance storage (call on every user-facing invocation). +pub fn extend_instance_ttl(env: &Env) { + env.storage() + .instance() + .extend_ttl(TTL_THRESHOLD, TTL_EXTEND_TO); +} diff --git a/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/test.rs b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/test.rs new file mode 100644 index 0000000000..9c4dd5c11d --- /dev/null +++ b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/test.rs @@ -0,0 +1,375 @@ +extern crate alloc; + +use soroban_sdk::{testutils::Address as _, testutils::Ledger, Address, Bytes, BytesN, Env, IntoVal}; + +use crate::{error::ContractError, PythLazerContract, PythLazerContractClient}; + +fn test_lazer_update_bytes(env: &Env) -> Bytes { + Bytes::from_slice( + env, + &hex_literal::hex!( + "e4bd474d73a7e70a8e2b8de236b55dcc6a771b4a8a1533fe" + "492f424fae162369fa14103e04c1c93302cef8a052110a95" + "0da031f9dc5eade9e6099e95668aff2592ec1f7900fe0075" + "d3c7934067e9c7f14a06000303010000000b00e1637ad535" + "060000015a2507d335060000027f8bfdf53506000004f8ff" + "0600070008000900000a601299cd3e0600000bc07595c73e" + "0600000c014067e9c7f14a0600020000000b00971b209c2d" + "0000000144056b9b2d0000000298fb6b9c2d00000004f8ff" + "0600070008000900000a284444f92d0000000b480c07f92d" + "0000000c014067e9c7f14a0600700000000b0020d85dd2d7" + "8df30001000000000000000002000000000000000004f4ff" + "060130f80bfeffffffff0701b8ab7057ec4a060008010020" + "9db4060000000900000a00000000000000000b0000000000" + "0000000c014067e9c7f14a0600" + ), + ) +} + +/// Trusted signer compressed public key from the Sui test suite. +fn test_trusted_signer_pubkey(env: &Env) -> BytesN<33> { + BytesN::from_array( + env, + &hex_literal::hex!("03a4380f01136eb2640f90c17e1e319e02bbafbeef2e6e67dc48af53f9827e155b"), + ) +} + +/// Deploy the contract with constructor args, returning the client. +fn setup(env: &Env) -> (PythLazerContractClient, Address) { + let executor = Address::generate(env); + let initial_signer: Option> = None; + let initial_signer_expires_at: Option = None; + let contract_id = env.register( + PythLazerContract, + (executor.clone(), initial_signer, initial_signer_expires_at), + ); + let client = PythLazerContractClient::new(env, &contract_id); + (client, executor) +} + +/// Helper to add a trusted signer via the executor. +fn add_trusted_signer( + env: &Env, + client: &PythLazerContractClient, + executor: &Address, + pubkey: &BytesN<33>, + expires_at: u64, +) { + client + .mock_auths(&[soroban_sdk::testutils::MockAuth { + address: executor, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &client.address, + fn_name: "update_trusted_signer", + args: (pubkey.clone(), expires_at).into_val(env), + sub_invokes: &[], + }, + }]) + .update_trusted_signer(pubkey, &expires_at); +} + +#[test] +fn test_verify_update_success() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + let expires_at = 2_000_000_000u64; // Far in the future (unix seconds) + + add_trusted_signer(&env, &client, &executor, &pubkey, expires_at); + + let update = test_lazer_update_bytes(&env); + let payload = client.verify_update(&update); + + // Payload should be non-empty + assert!(payload.len() > 0); +} + +#[test] +fn test_verify_update_invalid_magic() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + add_trusted_signer(&env, &client, &executor, &pubkey, 2_000_000_000); + + // Corrupt the magic bytes + let mut update_raw = test_lazer_update_bytes(&env).to_alloc_vec(); + update_raw[0] = 0xFF; // Corrupt magic + let update = Bytes::from_slice(&env, &update_raw); + + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::InvalidMagic)); +} + +#[test] +fn test_verify_update_truncated_data() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + add_trusted_signer(&env, &client, &executor, &pubkey, 2_000_000_000); + + // Only 50 bytes - too short + let truncated = Bytes::from_slice(&env, &[0u8; 50]); + let result = client.try_verify_update(&truncated); + assert_eq!(result.err().unwrap(), Ok(ContractError::TruncatedData)); +} + +#[test] +fn test_verify_update_unknown_signer() { + let env = Env::default(); + let (client, executor) = setup(&env); + + // Add a different signer that won't match the test data + let wrong_pubkey = BytesN::from_array( + &env, + &hex_literal::hex!("03aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"), + ); + add_trusted_signer(&env, &client, &executor, &wrong_pubkey, 2_000_000_000); + + let update = test_lazer_update_bytes(&env); + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::SignerNotTrusted)); +} + +#[test] +fn test_verify_update_expired_signer() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + let expires_at = 1_000u64; + add_trusted_signer(&env, &client, &executor, &pubkey, expires_at); + + // Set ledger timestamp past expiry + env.ledger().with_mut(|li| { + li.timestamp = 1_000; // >= expires_at + }); + + let update = test_lazer_update_bytes(&env); + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::SignerExpired)); +} + +#[test] +fn test_verify_update_nearly_expired_signer() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + let expires_at = 1_000u64; + add_trusted_signer(&env, &client, &executor, &pubkey, expires_at); + + // Set ledger timestamp just before expiry + env.ledger().with_mut(|li| { + li.timestamp = 999; // < expires_at, should succeed + }); + + let update = test_lazer_update_bytes(&env); + let payload = client.verify_update(&update); + assert!(payload.len() > 0); +} + +#[test] +fn test_verify_update_multiple_signers() { + let env = Env::default(); + let (client, executor) = setup(&env); + + // Add a wrong signer first + let wrong_pubkey = BytesN::from_array( + &env, + &hex_literal::hex!("03bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"), + ); + add_trusted_signer(&env, &client, &executor, &wrong_pubkey, 2_000_000_000); + + // Then add the correct one + let correct_pubkey = test_trusted_signer_pubkey(&env); + add_trusted_signer(&env, &client, &executor, &correct_pubkey, 2_000_000_000); + + let update = test_lazer_update_bytes(&env); + let payload = client.verify_update(&update); + assert!(payload.len() > 0); +} + +#[test] +fn test_verify_update_invalid_payload_length() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + add_trusted_signer(&env, &client, &executor, &pubkey, 2_000_000_000); + + // Take the valid update and corrupt the payload length field (bytes 69-70) + let mut update_raw = test_lazer_update_bytes(&env).to_alloc_vec(); + // Set payload length to 0xFF (wrong) + update_raw[69] = 0xFF; + let update = Bytes::from_slice(&env, &update_raw); + + let result = client.try_verify_update(&update); + assert_eq!( + result.err().unwrap(), + Ok(ContractError::InvalidPayloadLength) + ); +} + +// ── Governance tests ── + +#[test] +fn test_governance_add_new_signer() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + let expires_at = 5_000u64; + let update = test_lazer_update_bytes(&env); + + // Before adding signer, verification should fail as signer is not trusted. + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::SignerNotTrusted)); + + // Add signer and verify the same update now succeeds. + add_trusted_signer(&env, &client, &executor, &pubkey, expires_at); + let payload = client.verify_update(&update); + assert!(payload.len() > 0); +} + +#[test] +fn test_governance_update_signer_expiry() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + let update = test_lazer_update_bytes(&env); + + // Before adding signer, verification should fail. + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::SignerNotTrusted)); + + // Add signer with short expiry. + add_trusted_signer(&env, &client, &executor, &pubkey, 1_000); + + // Before expiry, verification should succeed. + env.ledger().with_mut(|li| { + li.timestamp = 999; + }); + let payload = client.verify_update(&update); + assert!(payload.len() > 0); + + // At expiry, verification should fail. + env.ledger().with_mut(|li| { + li.timestamp = 1_000; + }); + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::SignerExpired)); + + // Update signer with longer expiry. + add_trusted_signer(&env, &client, &executor, &pubkey, 2_000_000_000); + + // Past old expiry but before new expiry should now succeed. + env.ledger().with_mut(|li| { + li.timestamp = 5_000; + }); + let payload = client.verify_update(&update); + assert!(payload.len() > 0); + + // At the updated expiry boundary, verification should fail again. + env.ledger().with_mut(|li| { + li.timestamp = 2_000_000_000; + }); + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::SignerExpired)); +} + +#[test] +fn test_governance_remove_signer() { + let env = Env::default(); + let (client, executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + + // Add signer + add_trusted_signer(&env, &client, &executor, &pubkey, 2_000_000_000); + + // Verify signer works + let update = test_lazer_update_bytes(&env); + let payload = client.verify_update(&update); + assert!(payload.len() > 0); + + // Remove signer (expires_at = 0) + add_trusted_signer(&env, &client, &executor, &pubkey, 0); + + // Verify signer no longer works + let result = client.try_verify_update(&update); + assert_eq!(result.err().unwrap(), Ok(ContractError::SignerNotTrusted)); +} + +#[test] +#[should_panic(expected = "HostError: Error(Auth")] +fn test_governance_unauthorized_update_signer() { + let env = Env::default(); + let (client, _executor) = setup(&env); + + let pubkey = test_trusted_signer_pubkey(&env); + let unauthorized = Address::generate(&env); + + // Try to add a signer with a non-executor address (no mock auth for executor) + client + .mock_auths(&[soroban_sdk::testutils::MockAuth { + address: &unauthorized, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &client.address, + fn_name: "update_trusted_signer", + args: (pubkey.clone(), 2_000_000_000u64).into_val(&env), + sub_invokes: &[], + }, + }]) + .update_trusted_signer(&pubkey, &2_000_000_000u64); +} + +#[test] +#[should_panic(expected = "HostError: Error(Auth")] +fn test_governance_unauthorized_upgrade() { + let env = Env::default(); + let (client, _executor) = setup(&env); + + let unauthorized = Address::generate(&env); + // Upload a real wasm blob so failure can only be due to auth. + let uploaded_hash = env.deployer().upload_contract_wasm(Bytes::new(&env)); + + // Try to upgrade with a non-executor address + client + .mock_auths(&[soroban_sdk::testutils::MockAuth { + address: &unauthorized, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &client.address, + fn_name: "upgrade", + args: (uploaded_hash.clone(),).into_val(&env), + sub_invokes: &[], + }, + }]) + .upgrade(&uploaded_hash); +} + +#[test] +fn test_governance_upgrade_with_executor() { + let env = Env::default(); + let (client, executor) = setup(&env); + + // Upload a real wasm blob so the hash is resolvable by the host. + let uploaded_hash = env.deployer().upload_contract_wasm(Bytes::new(&env)); + + let result = client + .mock_auths(&[soroban_sdk::testutils::MockAuth { + address: &executor, + invoke: &soroban_sdk::testutils::MockAuthInvoke { + contract: &client.address, + fn_name: "upgrade", + args: (uploaded_hash.clone(),).into_val(&env), + sub_invokes: &[], + }, + }]) + .try_upgrade(&uploaded_hash); + + assert!(result.is_ok()); +} diff --git a/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/verify.rs b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/verify.rs new file mode 100644 index 0000000000..55e9e62c85 --- /dev/null +++ b/lazer/contracts/stellar/contracts/pyth-lazer-stellar/src/verify.rs @@ -0,0 +1,111 @@ +use soroban_sdk::{Bytes, BytesN, Env}; + +use crate::bytes::{get_byte, get_byte_n}; +use crate::error::ContractError; +use crate::state; + +/// LE-ECDSA format magic number (LE u32 = 0x4D47BDE4 = 1296547300). +const LE_ECDSA_FORMAT_MAGIC: u32 = 1_296_547_300; + +/// Minimum envelope size: 4 (magic) + 64 (sig) + 1 (recovery_id) + 2 (payload_len) = 71 bytes. +const MIN_ENVELOPE_SIZE: u32 = 71; + +/// Parse and verify an LE-ECDSA signed update message. +/// +/// Wire format: +/// - 4 bytes: magic (LE u32) +/// - 64 bytes: ECDSA signature (r || s) +/// - 1 byte: recovery_id +/// - 2 bytes: payload_length (LE u16) +/// - N bytes: payload +/// +/// Returns the verified payload bytes. +pub fn verify_update(env: &Env, data: &Bytes) -> Result { + let len = data.len(); + if len < MIN_ENVELOPE_SIZE { + return Err(ContractError::TruncatedData); + } + + // Parse magic (LE u32) + let magic = read_le_u32(data, 0)?; + if magic != LE_ECDSA_FORMAT_MAGIC { + return Err(ContractError::InvalidMagic); + } + + // Parse signature (64 bytes at offset 4) + let mut sig_bytes = [0u8; 64]; + for i in 0..64 { + sig_bytes[i] = get_byte(data, 4 + i as u32)?; + } + let signature = BytesN::from_array(env, &sig_bytes); + + // Parse recovery_id (1 byte at offset 68) + let recovery_id = get_byte(data, 68)? as u32; + + // Parse payload_length (LE u16 at offset 69) + let payload_len = read_le_u16(data, 69)? as u32; + + // Validate payload length + let payload_start = 71u32; + let expected_end = payload_start + payload_len; + if expected_end != len { + return Err(ContractError::InvalidPayloadLength); + } + + // Extract payload + let payload = data.slice(payload_start..expected_end); + + // Compute keccak256 hash of payload + let hash = env.crypto().keccak256(&payload); + + // Recover public key from signature + let uncompressed_pubkey = env.crypto().secp256k1_recover(&hash, &signature, recovery_id); + + // Compress the recovered public key + let compressed_pubkey = compress_pubkey(env, &uncompressed_pubkey)?; + + // Look up signer in trusted signers + let expires_at = state::get_trusted_signer_expiry(env, &compressed_pubkey) + .ok_or(ContractError::SignerNotTrusted)?; + + // Check signer is not expired + let current_timestamp = env.ledger().timestamp(); + if current_timestamp >= expires_at { + return Err(ContractError::SignerExpired); + } + + Ok(payload) +} + +/// Compress a 65-byte uncompressed SEC-1 public key to 33-byte compressed format. +/// +/// Input: 0x04 || x (32 bytes) || y (32 bytes) +/// Output: parity_byte || x (32 bytes) +/// where parity_byte = 0x02 if y is even, 0x03 if y is odd +fn compress_pubkey(env: &Env, uncompressed: &BytesN<65>) -> Result, ContractError> { + let mut compressed = [0u8; 33]; + + // Parity prefix: check last byte of y-coordinate for odd/even + let y_last_byte = get_byte_n(uncompressed, 64)?; + compressed[0] = if y_last_byte & 1 == 0 { 0x02 } else { 0x03 }; + + // Copy x-coordinate (bytes 1..33 of uncompressed key) + for i in 0..32 { + compressed[i + 1] = get_byte_n(uncompressed, 1 + i as u32)?; + } + + Ok(BytesN::from_array(env, &compressed)) +} + +/// Read a little-endian u32 from Bytes at the given offset. +fn read_le_u32(data: &Bytes, offset: u32) -> Result { + Ok((get_byte(data, offset)? as u32) + | ((get_byte(data, offset + 1)? as u32) << 8) + | ((get_byte(data, offset + 2)? as u32) << 16) + | ((get_byte(data, offset + 3)? as u32) << 24)) +} + +/// Read a little-endian u16 from Bytes at the given offset. +fn read_le_u16(data: &Bytes, offset: u32) -> Result { + Ok((get_byte(data, offset)? as u16) | ((get_byte(data, offset + 1)? as u16) << 8)) +} diff --git a/lazer/contracts/stellar/contracts/wormhole-executor-stellar/Cargo.toml b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/Cargo.toml new file mode 100644 index 0000000000..ac261732eb --- /dev/null +++ b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "wormhole-executor-stellar" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +soroban-sdk = { workspace = true } + +[dev-dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } +k256 = { version = "0.13", features = ["ecdsa"] } +tiny-keccak = { version = "2.0", features = ["keccak"] } diff --git a/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/error.rs b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/error.rs new file mode 100644 index 0000000000..9a072e2681 --- /dev/null +++ b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/error.rs @@ -0,0 +1,47 @@ +#![allow(dead_code)] + +use soroban_sdk::contracterror; + +#[contracterror] +#[derive(Copy, Clone, Debug, Eq, PartialEq, PartialOrd, Ord)] +#[repr(u32)] +pub enum ContractError { + /// VAA version is not 1. + InvalidVaaVersion = 1, + /// Input data is truncated or too short. + TruncatedData = 2, + /// A guardian index in a signature exceeds the guardian set size. + InvalidGuardianIndex = 3, + /// Not enough guardian signatures to meet quorum. + NoQuorum = 4, + /// A recovered guardian address does not match the stored guardian set. + GuardianSignatureMismatch = 5, + /// The emitter chain ID does not match the expected governance source. + InvalidEmitterChain = 6, + /// The emitter address does not match the expected governance source. + InvalidEmitterAddress = 7, + /// The VAA sequence number has already been processed (replay). + StaleSequence = 8, + /// The contract has already been initialized. + AlreadyInitialized = 9, + /// The contract has not been initialized. + NotInitialized = 10, + /// Duplicate guardian signature index in the VAA. + DuplicateGuardianSignature = 11, + /// The VAA's guardian_set_index does not match the stored index. + InvalidGuardianSetIndex = 12, + /// The new guardian set index is not current + 1. + InvalidGuardianSetUpgrade = 13, + /// The new guardian set is empty. + EmptyGuardianSet = 14, + /// The PTGM magic bytes are not "PTGM" (0x5054474d). + InvalidPtgmMagic = 15, + /// The PTGM module is not Lazer (3). + InvalidPtgmModule = 16, + /// The PTGM target chain ID does not match this chain. + InvalidTargetChain = 17, + /// The PTGM action is not recognized. + InvalidGovernanceAction = 18, + /// The PTGM executor contract does not match this contract. + InvalidExecutorAddress = 19, +} diff --git a/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/governance.rs b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/governance.rs new file mode 100644 index 0000000000..64becf475c --- /dev/null +++ b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/governance.rs @@ -0,0 +1,505 @@ +use soroban_sdk::{Address, Bytes}; + +use crate::bytes::{get_byte, read_be_u16, read_be_u64}; +use crate::error::ContractError; + +/// PTGM magic: "PTGM" = 0x5054474d +const PTGM_MAGIC: [u8; 4] = [0x50, 0x54, 0x47, 0x4d]; + +/// Module 3 = Lazer. +const LAZER_MODULE: u8 = 3; + +/// Governance action: upgrade the target contract. +pub const ACTION_UPGRADE: u8 = 0; + +/// Governance action: update a trusted signer on the target contract. +pub const ACTION_UPDATE_TRUSTED_SIGNER: u8 = 1; + +/// PTGM fixed header size: 4 (magic) + 1 (module) + 1 (action) + 2 (chain_id) = 8 bytes. +const HEADER_SIZE: usize = 8; + +/// Parsed PTGM header. +#[derive(Clone, Debug, PartialEq)] +pub struct PtgmHeader { + pub action: u8, + pub target_chain_id: u16, +} + +/// Parsed update_trusted_signer payload. +#[derive(Clone, Debug, PartialEq)] +pub struct UpdateTrustedSignerPayload { + pub target_contract: Address, + pub pubkey: [u8; 33], + pub expires_at: u64, +} + +/// Parsed upgrade payload. +#[derive(Clone, Debug, PartialEq)] +pub struct UpgradePayload { + pub target_contract: Address, + pub version: u64, + pub wasm_digest: [u8; 32], +} + +/// Parsed governance action from a PTGM. +#[derive(Clone, Debug, PartialEq)] +pub enum GovernanceAction { + Upgrade(UpgradePayload), + UpdateTrustedSigner(UpdateTrustedSignerPayload), +} + +/// Parse a PTGM from a VAA payload. +/// +/// Format: +/// - [4 bytes] magic "PTGM" +/// - [1 byte] module (3 = Lazer) +/// - [1 byte] action (0 = upgrade, 1 = update_trusted_signer) +/// - [2 bytes] target_chain_id (BE u16) +/// - action-specific payload +pub fn parse_ptgm( + payload: &Bytes, + our_chain_id: u32, + expected_executor_contract: &Address, +) -> Result { + let len = payload.len() as usize; + + if len < HEADER_SIZE { + return Err(ContractError::TruncatedData); + } + + // Verify magic. + for i in 0..4 { + if get_byte(payload, i as u32)? != PTGM_MAGIC[i] { + return Err(ContractError::InvalidPtgmMagic); + } + } + + // Verify module. + let module = get_byte(payload, 4)?; + if module != LAZER_MODULE { + return Err(ContractError::InvalidPtgmModule); + } + + // Action. + let action = get_byte(payload, 5)?; + + // Target chain ID (BE u16). + let target_chain_id = read_be_u16(payload, 6)?; + + // Validate target chain: must match our chain (no wildcard 0 for PTGM). + if target_chain_id as u32 != our_chain_id { + return Err(ContractError::InvalidTargetChain); + } + + // Routing metadata encoded in the PTGM payload: + // - [1 byte] executor contract address strkey length + // - [N bytes] executor contract address strkey + // - [1 byte] target contract address strkey length + // - [M bytes] target contract address strkey + // (Note: stellar addresses are variable length, hence the length fields) + let mut offset = HEADER_SIZE; + if len < offset + 2 { + return Err(ContractError::TruncatedData); + } + + let executor_len = get_byte(payload, offset as u32)? as usize; + offset += 1; + if executor_len == 0 || len < offset + executor_len { + return Err(ContractError::TruncatedData); + } + let executor_contract = Address::from_string_bytes( + &payload.slice(offset as u32..(offset + executor_len) as u32), + ); + offset += executor_len; + if &executor_contract != expected_executor_contract { + return Err(ContractError::InvalidExecutorAddress); + } + + if len < offset + 1 { + return Err(ContractError::TruncatedData); + } + let target_len = get_byte(payload, offset as u32)? as usize; + offset += 1; + if target_len == 0 || len < offset + target_len { + return Err(ContractError::TruncatedData); + } + let target_contract = + Address::from_string_bytes(&payload.slice(offset as u32..(offset + target_len) as u32)); + offset += target_len; + + match action { + ACTION_UPDATE_TRUSTED_SIGNER => { + // 33 (pubkey) + 8 (expires_at) = 41 bytes after header. + if len < offset + 41 { + return Err(ContractError::TruncatedData); + } + + let mut pubkey = [0u8; 33]; + for i in 0..33 { + pubkey[i] = get_byte(payload, (offset + i) as u32)?; + } + + let exp_offset = offset + 33; + let expires_at = read_be_u64(payload, exp_offset as u32)?; + + Ok(GovernanceAction::UpdateTrustedSigner( + UpdateTrustedSignerPayload { + target_contract, + pubkey, + expires_at, + }, + )) + } + ACTION_UPGRADE => { + // 8 (version) + 32 (wasm_digest) = 40 bytes after header. + if len < offset + 40 { + return Err(ContractError::TruncatedData); + } + + let ver_offset = offset; + let version = read_be_u64(payload, ver_offset as u32)?; + + let digest_offset = offset + 8; + let mut wasm_digest = [0u8; 32]; + for i in 0..32 { + wasm_digest[i] = get_byte(payload, (digest_offset + i) as u32)?; + } + + Ok(GovernanceAction::Upgrade(UpgradePayload { + target_contract, + version, + wasm_digest, + })) + } + _ => Err(ContractError::InvalidGovernanceAction), + } +} + +#[cfg(test)] +mod tests { + extern crate alloc; + + use super::*; + use soroban_sdk::{testutils::Address as _, Address, Env}; + + const TEST_CHAIN_ID: u32 = 30; + + fn address_to_payload_bytes(address: &Address) -> alloc::vec::Vec { + let strkey = address.to_string(); + let mut out = alloc::vec![0u8; strkey.len() as usize]; + strkey.copy_into_slice(&mut out); + out + } + + fn build_ptgm_header( + module: u8, + action: u8, + chain_id: u16, + executor_contract: &Address, + target_contract: &Address, + ) -> alloc::vec::Vec { + let mut data = alloc::vec::Vec::new(); + data.extend_from_slice(&PTGM_MAGIC); + data.push(module); + data.push(action); + data.extend_from_slice(&chain_id.to_be_bytes()); + let executor = address_to_payload_bytes(executor_contract); + data.push(executor.len() as u8); + data.extend_from_slice(&executor); + let target = address_to_payload_bytes(target_contract); + data.push(target.len() as u8); + data.extend_from_slice(&target); + data + } + + fn build_update_trusted_signer_ptgm( + chain_id: u16, + executor_contract: &Address, + target_contract: &Address, + pubkey: &[u8; 33], + expires_at: u64, + ) -> alloc::vec::Vec { + let mut data = build_ptgm_header( + LAZER_MODULE, + ACTION_UPDATE_TRUSTED_SIGNER, + chain_id, + executor_contract, + target_contract, + ); + data.extend_from_slice(pubkey); + data.extend_from_slice(&expires_at.to_be_bytes()); + data + } + + fn build_upgrade_ptgm( + chain_id: u16, + executor_contract: &Address, + target_contract: &Address, + version: u64, + wasm_digest: &[u8; 32], + ) -> alloc::vec::Vec { + let mut data = build_ptgm_header( + LAZER_MODULE, + ACTION_UPGRADE, + chain_id, + executor_contract, + target_contract, + ); + data.extend_from_slice(&version.to_be_bytes()); + data.extend_from_slice(wasm_digest); + data + } + + #[test] + fn test_parse_update_trusted_signer() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let pubkey = [0xAA; 33]; + let expires_at = 1700000000u64; + + let raw = build_update_trusted_signer_ptgm( + TEST_CHAIN_ID as u16, + &executor, + &target, + &pubkey, + expires_at, + ); + let payload = Bytes::from_slice(&env, &raw); + + let result = parse_ptgm(&payload, TEST_CHAIN_ID, &executor).unwrap(); + match result { + GovernanceAction::UpdateTrustedSigner(p) => { + assert_eq!(p.target_contract, target); + assert_eq!(p.pubkey, pubkey); + assert_eq!(p.expires_at, expires_at); + } + _ => panic!("expected UpdateTrustedSigner"), + } + } + + #[test] + fn test_parse_upgrade() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let version = 42u64; + let wasm_digest = [0xBB; 32]; + + let raw = build_upgrade_ptgm( + TEST_CHAIN_ID as u16, + &executor, + &target, + version, + &wasm_digest, + ); + let payload = Bytes::from_slice(&env, &raw); + + let result = parse_ptgm(&payload, TEST_CHAIN_ID, &executor).unwrap(); + match result { + GovernanceAction::Upgrade(p) => { + assert_eq!(p.target_contract, target); + assert_eq!(p.version, version); + assert_eq!(p.wasm_digest, wasm_digest); + } + _ => panic!("expected Upgrade"), + } + } + + #[test] + fn test_invalid_magic() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let mut raw = build_update_trusted_signer_ptgm( + TEST_CHAIN_ID as u16, + &executor, + &target, + &[0; 33], + 0, + ); + raw[0] = 0xFF; // corrupt magic + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &executor).err(), + Some(ContractError::InvalidPtgmMagic) + ); + } + + #[test] + fn test_invalid_module() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let mut raw = build_ptgm_header( + 99, + ACTION_UPDATE_TRUSTED_SIGNER, + TEST_CHAIN_ID as u16, + &executor, + &target, + ); + // Add enough payload for update_trusted_signer. + raw.extend_from_slice(&[0u8; 41]); + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &executor).err(), + Some(ContractError::InvalidPtgmModule) + ); + } + + #[test] + fn test_invalid_target_chain() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let raw = build_update_trusted_signer_ptgm(99, &executor, &target, &[0; 33], 0); // chain 99 != 30 + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &executor).err(), + Some(ContractError::InvalidTargetChain) + ); + } + + #[test] + fn test_invalid_action() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let mut raw = + build_ptgm_header(LAZER_MODULE, 99, TEST_CHAIN_ID as u16, &executor, &target); + raw.extend_from_slice(&[0u8; 41]); + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &executor).err(), + Some(ContractError::InvalidGovernanceAction) + ); + } + + #[test] + fn test_truncated_header() { + let env = Env::default(); + let payload = Bytes::from_slice(&env, &[0x50, 0x54, 0x47]); // only 3 bytes + let expected_executor = Address::generate(&env); + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &expected_executor).err(), + Some(ContractError::TruncatedData) + ); + } + + #[test] + fn test_truncated_update_trusted_signer_payload() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let mut raw = build_ptgm_header( + LAZER_MODULE, + ACTION_UPDATE_TRUSTED_SIGNER, + TEST_CHAIN_ID as u16, + &executor, + &target, + ); + raw.extend_from_slice(&[0u8; 20]); // not enough for 33 + 8 = 41 bytes + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &executor).err(), + Some(ContractError::TruncatedData) + ); + } + + #[test] + fn test_truncated_upgrade_payload() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let mut raw = build_ptgm_header( + LAZER_MODULE, + ACTION_UPGRADE, + TEST_CHAIN_ID as u16, + &executor, + &target, + ); + raw.extend_from_slice(&[0u8; 10]); // not enough for 8 + 32 = 40 bytes + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &executor).err(), + Some(ContractError::TruncatedData) + ); + } + + #[test] + fn test_parse_max_expires_at() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let raw = build_update_trusted_signer_ptgm( + TEST_CHAIN_ID as u16, + &executor, + &target, + &[0xFF; 33], + u64::MAX, + ); + let payload = Bytes::from_slice(&env, &raw); + + let result = parse_ptgm(&payload, TEST_CHAIN_ID, &executor).unwrap(); + match result { + GovernanceAction::UpdateTrustedSigner(p) => { + assert_eq!(p.target_contract, target); + assert_eq!(p.expires_at, u64::MAX); + assert_eq!(p.pubkey, [0xFF; 33]); + } + _ => panic!("expected UpdateTrustedSigner"), + } + } + + #[test] + fn test_parse_max_version() { + let env = Env::default(); + let executor = Address::generate(&env); + let target = Address::generate(&env); + let raw = build_upgrade_ptgm( + TEST_CHAIN_ID as u16, + &executor, + &target, + u64::MAX, + &[0xFF; 32], + ); + let payload = Bytes::from_slice(&env, &raw); + + let result = parse_ptgm(&payload, TEST_CHAIN_ID, &executor).unwrap(); + match result { + GovernanceAction::Upgrade(p) => { + assert_eq!(p.target_contract, target); + assert_eq!(p.version, u64::MAX); + assert_eq!(p.wasm_digest, [0xFF; 32]); + } + _ => panic!("expected Upgrade"), + } + } + + #[test] + fn test_invalid_executor_address() { + let env = Env::default(); + let executor = Address::generate(&env); + let wrong_executor = Address::generate(&env); + let target = Address::generate(&env); + let raw = build_update_trusted_signer_ptgm( + TEST_CHAIN_ID as u16, + &executor, + &target, + &[0xAA; 33], + 1000, + ); + let payload = Bytes::from_slice(&env, &raw); + + assert_eq!( + parse_ptgm(&payload, TEST_CHAIN_ID, &wrong_executor).err(), + Some(ContractError::InvalidExecutorAddress) + ); + } +} diff --git a/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/guardian.rs b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/guardian.rs new file mode 100644 index 0000000000..876babb36f --- /dev/null +++ b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/guardian.rs @@ -0,0 +1,209 @@ +use soroban_sdk::{contracttype, BytesN, Env, Vec}; + +use crate::error::ContractError; + +/// TTL threshold: extend when TTL drops below this (~6 days in ledgers at ~5s/ledger). +const TTL_THRESHOLD: u32 = 100_000; +/// TTL extension target: extend to this value (~29 days in ledgers at ~5s/ledger). +const TTL_EXTEND_TO: u32 = 500_000; + +/// Storage keys for the executor contract. +#[contracttype] +#[derive(Clone, Debug)] +pub enum DataKey { + /// Whether the contract has been initialized. + Initialized, + /// The current guardian set: Vec> (Ethereum addresses). + GuardianSet, + /// The current guardian set index (u32). + GuardianSetIndex, + /// The Wormhole chain ID for this chain (u16 stored as u32). + ChainId, + /// The authorized governance emitter chain ID (u16 stored as u32). + OwnerEmitterChain, + /// The authorized governance emitter address (32 bytes). + OwnerEmitterAddress, + /// The last executed governance sequence number (u64). + LastExecutedSequence, +} + +/// Store the initial contract configuration. +/// +/// This must be called exactly once. It stores the guardian set, owner emitter +/// chain/address, and chain ID. +pub fn initialize( + env: &Env, + chain_id: u32, + owner_emitter_chain: u32, + owner_emitter_address: BytesN<32>, + initial_guardian_set: Vec>, + guardian_set_index: u32, +) -> Result<(), ContractError> { + if env + .storage() + .instance() + .has(&DataKey::Initialized) + { + return Err(ContractError::AlreadyInitialized); + } + + env.storage() + .instance() + .set(&DataKey::Initialized, &true); + env.storage() + .persistent() + .set(&DataKey::GuardianSet, &initial_guardian_set); + env.storage() + .persistent() + .set(&DataKey::GuardianSetIndex, &guardian_set_index); + env.storage() + .instance() + .set(&DataKey::ChainId, &chain_id); + env.storage() + .instance() + .set(&DataKey::OwnerEmitterChain, &owner_emitter_chain); + env.storage() + .instance() + .set(&DataKey::OwnerEmitterAddress, &owner_emitter_address); + env.storage() + .persistent() + .set(&DataKey::LastExecutedSequence, &0u64); + + // Extend TTL for all persistent entries. + extend_guardian_set_ttl(env); + extend_instance_ttl(env); + + Ok(()) +} + +/// Check that the contract has been initialized. +pub fn require_initialized(env: &Env) -> Result<(), ContractError> { + if !env + .storage() + .instance() + .has(&DataKey::Initialized) + { + return Err(ContractError::NotInitialized); + } + Ok(()) +} + +/// Get the current guardian set. +pub fn get_guardian_set(env: &Env) -> Result>, ContractError> { + extend_guardian_set_ttl(env); + env.storage() + .persistent() + .get(&DataKey::GuardianSet) + .ok_or(ContractError::NotInitialized) +} + +/// Get the current guardian set index. +pub fn get_guardian_set_index(env: &Env) -> Result { + env.storage() + .persistent() + .get(&DataKey::GuardianSetIndex) + .ok_or(ContractError::NotInitialized) +} + +/// Get the chain ID. +pub fn get_chain_id(env: &Env) -> Result { + env.storage() + .instance() + .get(&DataKey::ChainId) + .ok_or(ContractError::NotInitialized) +} + +/// Get the owner emitter chain ID. +pub fn get_owner_emitter_chain(env: &Env) -> Result { + env.storage() + .instance() + .get(&DataKey::OwnerEmitterChain) + .ok_or(ContractError::NotInitialized) +} + +/// Get the owner emitter address. +pub fn get_owner_emitter_address(env: &Env) -> Result, ContractError> { + env.storage() + .instance() + .get(&DataKey::OwnerEmitterAddress) + .ok_or(ContractError::NotInitialized) +} + +/// Get the last executed sequence number. +pub fn get_last_executed_sequence(env: &Env) -> u64 { + env.storage() + .persistent() + .get(&DataKey::LastExecutedSequence) + .unwrap_or(0u64) +} + +/// Set the last executed sequence number. +pub fn set_last_executed_sequence(env: &Env, sequence: u64) { + env.storage() + .persistent() + .set(&DataKey::LastExecutedSequence, &sequence); +} + +/// Update the guardian set. Stores the new set and increments the index. +pub fn store_guardian_set( + env: &Env, + new_guardian_set: Vec>, + new_index: u32, +) { + env.storage() + .persistent() + .set(&DataKey::GuardianSet, &new_guardian_set); + env.storage() + .persistent() + .set(&DataKey::GuardianSetIndex, &new_index); + extend_guardian_set_ttl(env); +} + +/// Derive an Ethereum address from an uncompressed secp256k1 public key. +/// +/// The uncompressed key is 65 bytes: `0x04 || x (32) || y (32)`. +/// The Ethereum address is `keccak256(x || y)[12..32]`. +pub fn eth_address_from_pubkey(env: &Env, uncompressed: &BytesN<65>) -> BytesN<20> { + // Get x || y (skip the 0x04 prefix byte). + let raw_key = env.crypto().keccak256( + &soroban_sdk::Bytes::from_slice(env, &uncompressed.to_array()[1..65]), + ); + let hash_array = raw_key.to_array(); + let mut addr = [0u8; 20]; + addr.copy_from_slice(&hash_array[12..32]); + BytesN::from_array(env, &addr) +} + +/// Compute the quorum threshold: 2/3 + 1 of the guardian set size. +/// +/// Uses the same fixed-point formula as the EVM implementation: +/// `(((num_guardians * 10) / 3) * 2) / 10 + 1` +pub fn quorum(num_guardians: u32) -> u32 { + (((num_guardians * 10) / 3) * 2) / 10 + 1 +} + +/// Extend TTL on guardian set persistent storage entries. +fn extend_guardian_set_ttl(env: &Env) { + env.storage().persistent().extend_ttl( + &DataKey::GuardianSet, + TTL_THRESHOLD, + TTL_EXTEND_TO, + ); + env.storage().persistent().extend_ttl( + &DataKey::GuardianSetIndex, + TTL_THRESHOLD, + TTL_EXTEND_TO, + ); + env.storage().persistent().extend_ttl( + &DataKey::LastExecutedSequence, + TTL_THRESHOLD, + TTL_EXTEND_TO, + ); +} + +/// Extend TTL on the contract instance storage. +pub fn extend_instance_ttl(env: &Env) { + env.storage() + .instance() + .extend_ttl(TTL_THRESHOLD, TTL_EXTEND_TO); +} diff --git a/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/lib.rs b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/lib.rs new file mode 100644 index 0000000000..708fe193af --- /dev/null +++ b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/lib.rs @@ -0,0 +1,219 @@ +#![no_std] + +pub mod bytes; +pub mod error; +pub mod governance; +pub mod guardian; +pub mod vaa; + +#[cfg(test)] +mod test; + +use soroban_sdk::{contract, contractimpl, Bytes, BytesN, Env, IntoVal, Symbol, Vec}; + +use crate::bytes::{get_byte, read_be_u16, read_be_u32}; +use crate::error::ContractError; +use crate::governance::{parse_ptgm, GovernanceAction}; +use crate::vaa::{parse_vaa, verify_vaa}; + +/// Wormhole core governance module identifier ("Core" right-aligned in 32 bytes). +const CORE_MODULE: [u8; 32] = *b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Core"; + +/// Guardian set upgrade action ID. +const GUARDIAN_SET_UPGRADE_ACTION: u8 = 2; + +#[contract] +pub struct WormholeExecutor; + +#[contractimpl] +impl WormholeExecutor { + /// Constructor for the executor contract. + /// + /// Runs only during deployment. Sets up the guardian set, chain ID, and + /// governance emitter configuration. + pub fn __constructor( + env: Env, + chain_id: u32, + owner_emitter_chain: u32, + owner_emitter_address: BytesN<32>, + initial_guardian_set: Vec>, + guardian_set_index: u32, + ) -> Result<(), ContractError> { + guardian::initialize( + &env, + chain_id, + owner_emitter_chain, + owner_emitter_address, + initial_guardian_set, + guardian_set_index, + ) + } + + /// Process a guardian set upgrade VAA. + /// + /// This is a self-governance mechanism: the current guardian set signs a VAA + /// that authorizes a new guardian set. The VAA payload follows the Wormhole + /// core governance format: + /// + /// ```text + /// [32 bytes] module ("Core" right-padded) + /// [1 byte] action (2 = guardian set upgrade) + /// [2 bytes] target chain (0 = all chains) + /// [4 bytes] new guardian set index (BE u32) + /// [1 byte] num guardians + /// For each guardian: + /// [20 bytes] Ethereum address + /// ``` + /// + /// FIXME: the handling of the guardian sets here is wrong. It needs to expire the current guardian set + /// and update to the next guardian set, creating the 24h period where both guardian sets are accepted. + /// Look at the ethereum wormhole contract implementation for a guide to how this should work. + pub fn update_guardian_set(env: Env, vaa_bytes: Bytes) -> Result<(), ContractError> { + guardian::require_initialized(&env)?; + guardian::extend_instance_ttl(&env); + + // Parse and verify the VAA with current guardian set. + let vaa = parse_vaa(&env, &vaa_bytes)?; + verify_vaa(&env, &vaa)?; + + let payload = &vaa.body.payload; + let payload_len = payload.len() as usize; + + // Minimum payload size: 32 (module) + 1 (action) + 2 (chain) + 4 (index) + 1 (num) = 40 + if payload_len < 40 { + return Err(ContractError::TruncatedData); + } + + // Verify module is "Core". + let mut module_bytes = [0u8; 32]; + for i in 0..32 { + module_bytes[i] = get_byte(payload, i as u32)?; + } + if module_bytes != CORE_MODULE { + return Err(ContractError::InvalidEmitterAddress); + } + + // Verify action is guardian set upgrade (2). + let action = get_byte(payload, 32)?; + if action != GUARDIAN_SET_UPGRADE_ACTION { + return Err(ContractError::InvalidEmitterChain); + } + + // Target chain (2 bytes BE u16) - 0 means all chains. + let target_chain = read_be_u16(payload, 33)?; + let our_chain = guardian::get_chain_id(&env)?; + if target_chain != 0 && target_chain as u32 != our_chain { + return Err(ContractError::InvalidEmitterChain); + } + + // New guardian set index (4 bytes BE u32). + let new_index = read_be_u32(payload, 35)?; + + // Must increment by exactly 1. + let current_index = guardian::get_guardian_set_index(&env)?; + if new_index != current_index + 1 { + return Err(ContractError::InvalidGuardianSetUpgrade); + } + + // Number of guardians. + let num_guardians = get_byte(payload, 39)? as usize; + if num_guardians == 0 { + return Err(ContractError::EmptyGuardianSet); + } + + // Verify payload has enough data for all guardian addresses. + let required_len = 40 + num_guardians * 20; + if payload_len < required_len { + return Err(ContractError::TruncatedData); + } + + // Parse guardian Ethereum addresses. + let mut new_guardian_set: Vec> = Vec::new(&env); + for i in 0..num_guardians { + let offset = 40 + i * 20; + let mut addr = [0u8; 20]; + for j in 0..20 { + addr[j] = get_byte(payload, (offset + j) as u32)?; + } + new_guardian_set.push_back(BytesN::from_array(&env, &addr)); + } + + // Store the new guardian set. + guardian::store_guardian_set(&env, new_guardian_set, new_index); + + Ok(()) + } + + /// Execute a governance action from a Wormhole VAA containing a PTGM payload. + /// + /// This verifies the VAA, validates the emitter matches the stored owner, + /// enforces replay protection via strictly increasing sequence numbers, + /// parses the PTGM governance instruction, and dispatches a cross-contract + /// call to the target contract. + pub fn execute_governance_action( + env: Env, + vaa_bytes: Bytes, + ) -> Result<(), ContractError> { + guardian::require_initialized(&env)?; + guardian::extend_instance_ttl(&env); + + // Parse and verify the VAA with current guardian set. + let vaa = parse_vaa(&env, &vaa_bytes)?; + verify_vaa(&env, &vaa)?; + + // Validate emitter chain matches stored owner. + let owner_chain = guardian::get_owner_emitter_chain(&env)?; + if vaa.body.emitter_chain as u32 != owner_chain { + return Err(ContractError::InvalidEmitterChain); + } + + // Validate emitter address matches stored owner. + let owner_address = guardian::get_owner_emitter_address(&env)?; + if vaa.body.emitter_address != owner_address { + return Err(ContractError::InvalidEmitterAddress); + } + + // Replay protection: sequence must be strictly increasing. + let last_sequence = guardian::get_last_executed_sequence(&env); + if vaa.body.sequence <= last_sequence { + return Err(ContractError::StaleSequence); + } + + // Update last executed sequence. + guardian::set_last_executed_sequence(&env, vaa.body.sequence); + + // Parse the PTGM governance instruction. + let our_chain = guardian::get_chain_id(&env)?; + // TODO: we should use a more generic encoding of function calls so we're not hardcoding the + // target function names here. The result of parse_ptgm should enable us to call *any* function + // on the contract. I.e., we have something like the string name of the function and a generic + // arg encoding in the payload. + let action = parse_ptgm(&vaa.body.payload, our_chain, &env.current_contract_address())?; + + // Dispatch cross-contract call to the target. + match action { + GovernanceAction::UpdateTrustedSigner(payload) => { + let pubkey = BytesN::from_array(&env, &payload.pubkey); + let args = (pubkey, payload.expires_at).into_val(&env); + env.invoke_contract::<()>( + &payload.target_contract, + &Symbol::new(&env, "update_trusted_signer"), + args, + ); + } + GovernanceAction::Upgrade(payload) => { + let wasm_hash = BytesN::from_array(&env, &payload.wasm_digest); + let args = (wasm_hash,).into_val(&env); + env.invoke_contract::<()>( + &payload.target_contract, + &Symbol::new(&env, "upgrade"), + args, + ); + } + } + + Ok(()) + } + + // TODO: this contract needs upgradability +} diff --git a/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/test.rs b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/test.rs new file mode 100644 index 0000000000..f404ad4708 --- /dev/null +++ b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/test.rs @@ -0,0 +1,539 @@ +extern crate alloc; +extern crate std; + +use alloc::vec; +use k256::ecdsa::SigningKey; +use soroban_sdk::{Address, Bytes, BytesN, Env, Vec}; +use tiny_keccak::{Hasher, Keccak}; + +use crate::error::ContractError; +use crate::guardian; +use crate::vaa::{parse_vaa, verify_vaa}; +use crate::WormholeExecutor; +use crate::WormholeExecutorClient; + +// Tests for the WormholeExecutor contract. +// NOTE: See the integration-tests module for tests of execute_governance_action, +// as these require both contracts to be deployed. + +// ────────────────────────────────────────────────────────────────────── +// Test helpers +// ────────────────────────────────────────────────────────────────────── + +/// Well-known test private keys (32 bytes each). +fn test_secret(index: u8) -> [u8; 32] { + let mut secret = [0u8; 32]; + secret[31] = index + 1; // simple deterministic secrets: 0x01, 0x02, ... + secret +} + +/// Derive the Ethereum address from a private key using off-chain k256. +fn eth_address_from_secret(secret: &[u8; 32]) -> [u8; 20] { + let signing_key = SigningKey::from_bytes(secret.into()).expect("valid key"); + let verifying_key = signing_key.verifying_key(); + let uncompressed = verifying_key.to_encoded_point(false); + let pubkey_bytes = &uncompressed.as_bytes()[1..]; // skip 0x04 prefix + + let mut hasher = Keccak::v256(); + let mut hash = [0u8; 32]; + hasher.update(pubkey_bytes); + hasher.finalize(&mut hash); + + let mut addr = [0u8; 20]; + addr.copy_from_slice(&hash[12..32]); + addr +} + +/// Compute keccak256 off-chain. +fn keccak256(data: &[u8]) -> [u8; 32] { + let mut hasher = Keccak::v256(); + let mut out = [0u8; 32]; + hasher.update(data); + hasher.finalize(&mut out); + out +} + +/// Sign a message hash (already keccak256'd) with a private key, +/// returning (r||s as [u8; 64], recovery_id as u32). +fn sign_hash(secret: &[u8; 32], hash: &[u8; 32]) -> ([u8; 64], u32) { + let signing_key = SigningKey::from_bytes(secret.into()).expect("valid key"); + let (signature, recovery_id) = signing_key + .sign_prehash_recoverable(hash) + .expect("signing failed"); + let sig_bytes: [u8; 64] = signature.to_bytes().into(); + (sig_bytes, recovery_id.to_byte() as u32) +} + +/// Build a raw VAA body (no header/signatures). +fn build_body( + timestamp: u32, + nonce: u32, + emitter_chain: u16, + emitter_address: &[u8; 32], + sequence: u64, + consistency_level: u8, + payload: &[u8], +) -> alloc::vec::Vec { + let mut body = alloc::vec::Vec::new(); + body.extend_from_slice(×tamp.to_be_bytes()); + body.extend_from_slice(&nonce.to_be_bytes()); + body.extend_from_slice(&emitter_chain.to_be_bytes()); + body.extend_from_slice(emitter_address); + body.extend_from_slice(&sequence.to_be_bytes()); + body.push(consistency_level); + body.extend_from_slice(payload); + body +} + +/// Build a complete VAA with real signatures. +/// +/// `signers` is a list of (guardian_index, secret_key) tuples. +fn build_signed_vaa( + guardian_set_index: u32, + signers: &[(u8, [u8; 32])], + body: &[u8], +) -> alloc::vec::Vec { + // Wormhole double-hash: keccak256(keccak256(body)) + let body_hash = keccak256(body); + let double_hash = keccak256(&body_hash); + + let mut vaa = alloc::vec::Vec::new(); + vaa.push(1u8); // version + vaa.extend_from_slice(&guardian_set_index.to_be_bytes()); + vaa.push(signers.len() as u8); + + for (guardian_index, secret) in signers { + let (sig, recovery_id) = sign_hash(secret, &double_hash); + vaa.push(*guardian_index); + vaa.extend_from_slice(&sig); + vaa.push(recovery_id as u8); + } + + vaa.extend_from_slice(body); + vaa +} + +/// Deploy the contract with constructor args and a test guardian set. +/// Returns (client, contract_address, secrets). +fn setup_contract( + env: &Env, + num_guardians: u8, + guardian_set_index: u32, +) -> (WormholeExecutorClient, Address, alloc::vec::Vec<[u8; 32]>) { + let mut secrets = alloc::vec::Vec::new(); + let mut guardian_addrs: Vec> = Vec::new(env); + + for i in 0..num_guardians { + let secret = test_secret(i); + let addr = eth_address_from_secret(&secret); + secrets.push(secret); + guardian_addrs.push_back(BytesN::from_array(env, &addr)); + } + + let owner_emitter_address = BytesN::from_array(env, &[0u8; 32]); + + let contract_id = env.register( + WormholeExecutor, + ( + 30u32, // chain_id (arbitrary for tests) + 1u32, // owner_emitter_chain + owner_emitter_address, + guardian_addrs, + guardian_set_index, + ), + ); + let client = WormholeExecutorClient::new(env, &contract_id); + + (client, contract_id, secrets) +} + +// ────────────────────────────────────────────────────────────────────── +// Tests: quorum calculation +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_quorum_calculation() { + assert_eq!(guardian::quorum(1), 1); + assert_eq!(guardian::quorum(2), 2); + assert_eq!(guardian::quorum(3), 3); + assert_eq!(guardian::quorum(4), 3); + assert_eq!(guardian::quorum(7), 5); + assert_eq!(guardian::quorum(13), 9); + assert_eq!(guardian::quorum(19), 13); +} + +// ────────────────────────────────────────────────────────────────────── +// Tests: eth address derivation +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_eth_address_derivation() { + let env = Env::default(); + let secret = test_secret(0); + let expected_addr = eth_address_from_secret(&secret); + + let signing_key = SigningKey::from_bytes((&secret).into()).expect("valid key"); + let verifying_key = signing_key.verifying_key(); + let uncompressed = verifying_key.to_encoded_point(false); + let uncompressed_bytes: [u8; 65] = uncompressed.as_bytes().try_into().expect("65 bytes"); + + let soroban_uncompressed = BytesN::from_array(&env, &uncompressed_bytes); + let derived_addr = guardian::eth_address_from_pubkey(&env, &soroban_uncompressed); + + assert_eq!(derived_addr, BytesN::from_array(&env, &expected_addr)); +} + +// ────────────────────────────────────────────────────────────────────── +// Tests: constructor deployment +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_constructor_deployment_success() { + let env = Env::default(); + let (_, contract_id, _) = setup_contract(&env, 3, 0); + + // Access storage in contract context. + env.as_contract(&contract_id, || { + let gs = guardian::get_guardian_set(&env); + assert!(gs.is_ok()); + let gs = gs.unwrap_or(Vec::new(&env)); + assert_eq!(gs.len(), 3); + assert_eq!(guardian::get_guardian_set_index(&env), Ok(0)); + assert_eq!(guardian::get_chain_id(&env), Ok(30)); + }); +} + + + +// ────────────────────────────────────────────────────────────────────── +// Tests: VAA signature verification +// ────────────────────────────────────────────────────────────────────── + +#[test] +fn test_verify_vaa_success_single_guardian() { + let env = Env::default(); + let (_, contract_id, secrets) = setup_contract(&env, 1, 0); + + let body = build_body(1000, 42, 1, &[0xABu8; 32], 99, 32, &[0x01, 0x02]); + let vaa_raw = build_signed_vaa(0, &[(0, secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert!(result.is_ok()); + }); +} + +#[test] +fn test_verify_vaa_success_quorum() { + let env = Env::default(); + let (_, contract_id, secrets) = setup_contract(&env, 3, 0); + + let body = build_body(2000, 0, 1, &[0x01u8; 32], 500, 15, &[0xDE, 0xAD]); + let signers: alloc::vec::Vec<(u8, [u8; 32])> = (0..3).map(|i| (i as u8, secrets[i as usize])).collect(); + let vaa_raw = build_signed_vaa(0, &signers, &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert!(result.is_ok()); + }); +} + +#[test] +fn test_verify_vaa_quorum_with_19_guardians() { + let env = Env::default(); + let (_, contract_id, secrets) = setup_contract(&env, 19, 4); + + // Quorum for 19 = 13. Sign with guardians 0..12 (13 signatures). + let body = build_body(1700000000, 12345, 1, &[0x55u8; 32], 9999, 32, &[0xCA, 0xFE]); + let signers: alloc::vec::Vec<(u8, [u8; 32])> = (0..13).map(|i| (i as u8, secrets[i as usize])).collect(); + let vaa_raw = build_signed_vaa(4, &signers, &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert!(result.is_ok()); + }); +} + +#[test] +fn test_verify_vaa_no_quorum() { + let env = Env::default(); + let (_, contract_id, secrets) = setup_contract(&env, 4, 0); + + // Quorum for 4 = 3. Only provide 2 signatures. + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &[]); + let signers = vec![(0u8, secrets[0]), (1u8, secrets[1])]; + let vaa_raw = build_signed_vaa(0, &signers, &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert_eq!(result.err(), Some(ContractError::NoQuorum)); + }); +} + +#[test] +fn test_verify_vaa_wrong_guardian_set_index() { + let env = Env::default(); + let (_, contract_id, secrets) = setup_contract(&env, 1, 0); + + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &[]); + // Sign with guardian_set_index = 1, but stored is 0. + let vaa_raw = build_signed_vaa(1, &[(0u8, secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert_eq!(result.err(), Some(ContractError::InvalidGuardianSetIndex)); + }); +} + +#[test] +fn test_verify_vaa_invalid_signature() { + let env = Env::default(); + let (_, contract_id, _secrets) = setup_contract(&env, 1, 0); + + // Use a different secret to sign (not in guardian set). + let wrong_secret = test_secret(99); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &[]); + let vaa_raw = build_signed_vaa(0, &[(0u8, wrong_secret)], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert_eq!(result.err(), Some(ContractError::GuardianSignatureMismatch)); + }); +} + +#[test] +fn test_verify_vaa_duplicate_guardian_index() { + let env = Env::default(); + let (_, contract_id, secrets) = setup_contract(&env, 3, 0); + + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &[]); + let body_hash = keccak256(&body); + let double_hash = keccak256(&body_hash); + + let (sig0, rec0) = sign_hash(&secrets[0], &double_hash); + let (sig0b, rec0b) = sign_hash(&secrets[0], &double_hash); + + let mut vaa_raw = alloc::vec::Vec::new(); + vaa_raw.push(1u8); // version + vaa_raw.extend_from_slice(&0u32.to_be_bytes()); + vaa_raw.push(3u8); // num_signatures = 3 + + // guardian_index 0 + vaa_raw.push(0u8); + vaa_raw.extend_from_slice(&sig0); + vaa_raw.push(rec0 as u8); + // guardian_index 0 again (duplicate - not ascending) + vaa_raw.push(0u8); + vaa_raw.extend_from_slice(&sig0b); + vaa_raw.push(rec0b as u8); + // guardian_index 1 + let (sig1, rec1) = sign_hash(&secrets[1], &double_hash); + vaa_raw.push(1u8); + vaa_raw.extend_from_slice(&sig1); + vaa_raw.push(rec1 as u8); + + vaa_raw.extend_from_slice(&body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert_eq!(result.err(), Some(ContractError::DuplicateGuardianSignature)); + }); +} + +#[test] +fn test_verify_vaa_guardian_index_out_of_bounds() { + let env = Env::default(); + let (_, contract_id, secrets) = setup_contract(&env, 1, 0); + + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &[]); + let body_hash = keccak256(&body); + let double_hash = keccak256(&body_hash); + let (sig, rec) = sign_hash(&secrets[0], &double_hash); + + let mut vaa_raw = alloc::vec::Vec::new(); + vaa_raw.push(1u8); + vaa_raw.extend_from_slice(&0u32.to_be_bytes()); + vaa_raw.push(1u8); // 1 signature + vaa_raw.push(5u8); // guardian_index = 5 (out of bounds) + vaa_raw.extend_from_slice(&sig); + vaa_raw.push(rec as u8); + vaa_raw.extend_from_slice(&body); + + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + env.as_contract(&contract_id, || { + let result = verify_vaa(&env, &vaa); + assert_eq!(result.err(), Some(ContractError::InvalidGuardianIndex)); + }); +} + +// ────────────────────────────────────────────────────────────────────── +// Tests: guardian set upgrade +// ────────────────────────────────────────────────────────────────────── + +/// Build a guardian set upgrade payload. +fn build_guardian_set_upgrade_payload( + target_chain: u16, + new_index: u32, + new_guardians: &[[u8; 20]], +) -> alloc::vec::Vec { + let mut payload = alloc::vec::Vec::new(); + + // Module: "Core" right-aligned in 32 bytes. + payload.extend_from_slice(b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Core"); + // Action: 2 (guardian set upgrade). + payload.push(2); + // Target chain. + payload.extend_from_slice(&target_chain.to_be_bytes()); + // New guardian set index. + payload.extend_from_slice(&new_index.to_be_bytes()); + // Num guardians. + payload.push(new_guardians.len() as u8); + // Guardian addresses. + for addr in new_guardians { + payload.extend_from_slice(addr); + } + + payload +} + +#[test] +fn test_guardian_set_upgrade() { + let env = Env::default(); + let (client, contract_id, secrets) = setup_contract(&env, 1, 0); + + let new_secret_0 = test_secret(10); + let new_secret_1 = test_secret(11); + let new_addr_0 = eth_address_from_secret(&new_secret_0); + let new_addr_1 = eth_address_from_secret(&new_secret_1); + + let upgrade_payload = build_guardian_set_upgrade_payload(0, 1, &[new_addr_0, new_addr_1]); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &upgrade_payload); + let vaa_raw = build_signed_vaa(0, &[(0u8, secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + client.update_guardian_set(&vaa_bytes); + + env.as_contract(&contract_id, || { + let gs = guardian::get_guardian_set(&env); + assert!(gs.is_ok()); + let gs = gs.unwrap_or(Vec::new(&env)); + assert_eq!(gs.len(), 2); + assert_eq!(gs.get(0).unwrap(), BytesN::from_array(&env, &new_addr_0)); + assert_eq!(gs.get(1).unwrap(), BytesN::from_array(&env, &new_addr_1)); + assert_eq!(guardian::get_guardian_set_index(&env), Ok(1)); + }); +} + +#[test] +fn test_guardian_set_upgrade_wrong_index() { + let env = Env::default(); + let (client, _, secrets) = setup_contract(&env, 1, 0); + + let new_addr = eth_address_from_secret(&test_secret(10)); + + let upgrade_payload = build_guardian_set_upgrade_payload(0, 5, &[new_addr]); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &upgrade_payload); + let vaa_raw = build_signed_vaa(0, &[(0u8, secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let result = client.try_update_guardian_set(&vaa_bytes); + assert!(result.is_err()); +} + +#[test] +fn test_guardian_set_upgrade_empty_set() { + let env = Env::default(); + let (client, _, secrets) = setup_contract(&env, 1, 0); + + let upgrade_payload = build_guardian_set_upgrade_payload(0, 1, &[]); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &upgrade_payload); + let vaa_raw = build_signed_vaa(0, &[(0u8, secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let result = client.try_update_guardian_set(&vaa_bytes); + assert!(result.is_err()); +} + +#[test] +fn test_guardian_set_upgrade_chain_specific() { + let env = Env::default(); + let (client, contract_id, secrets) = setup_contract(&env, 1, 0); + + let new_addr = eth_address_from_secret(&test_secret(10)); + + // target_chain = 30 (our chain) should work. + let upgrade_payload = build_guardian_set_upgrade_payload(30, 1, &[new_addr]); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &upgrade_payload); + let vaa_raw = build_signed_vaa(0, &[(0u8, secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + client.update_guardian_set(&vaa_bytes); + env.as_contract(&contract_id, || { + assert_eq!(guardian::get_guardian_set_index(&env), Ok(1)); + }); +} + +#[test] +fn test_guardian_set_upgrade_wrong_chain() { + let env = Env::default(); + let (client, _, secrets) = setup_contract(&env, 1, 0); + + let new_addr = eth_address_from_secret(&test_secret(10)); + + // target_chain = 5 (not our chain, and not 0). + let upgrade_payload = build_guardian_set_upgrade_payload(5, 1, &[new_addr]); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &upgrade_payload); + let vaa_raw = build_signed_vaa(0, &[(0u8, secrets[0])], &body); + let vaa_bytes = Bytes::from_slice(&env, &vaa_raw); + + let result = client.try_update_guardian_set(&vaa_bytes); + assert!(result.is_err()); +} + +#[test] +fn test_sequential_guardian_set_upgrades() { + let env = Env::default(); + let (client, contract_id, secrets) = setup_contract(&env, 1, 0); + + // Upgrade 0 -> 1 + let new_secret = test_secret(10); + let new_addr = eth_address_from_secret(&new_secret); + let upgrade_payload = build_guardian_set_upgrade_payload(0, 1, &[new_addr]); + let body = build_body(1000, 0, 1, &[0u8; 32], 1, 0, &upgrade_payload); + let vaa_raw = build_signed_vaa(0, &[(0u8, secrets[0])], &body); + client.update_guardian_set(&Bytes::from_slice(&env, &vaa_raw)); + env.as_contract(&contract_id, || { + assert_eq!(guardian::get_guardian_set_index(&env), Ok(1)); + }); + + // Upgrade 1 -> 2 with the new guardian set + let new_secret_2 = test_secret(20); + let new_addr_2 = eth_address_from_secret(&new_secret_2); + let upgrade_payload_2 = build_guardian_set_upgrade_payload(0, 2, &[new_addr_2]); + let body_2 = build_body(2000, 0, 1, &[0u8; 32], 2, 0, &upgrade_payload_2); + let vaa_raw_2 = build_signed_vaa(1, &[(0u8, new_secret)], &body_2); + client.update_guardian_set(&Bytes::from_slice(&env, &vaa_raw_2)); + env.as_contract(&contract_id, || { + assert_eq!(guardian::get_guardian_set_index(&env), Ok(2)); + let gs = guardian::get_guardian_set(&env); + assert!(gs.is_ok()); + let gs = gs.unwrap_or(Vec::new(&env)); + assert_eq!(gs.len(), 1); + }); +} diff --git a/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/vaa.rs b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/vaa.rs new file mode 100644 index 0000000000..41a64d5916 --- /dev/null +++ b/lazer/contracts/stellar/contracts/wormhole-executor-stellar/src/vaa.rs @@ -0,0 +1,721 @@ +use soroban_sdk::{contracttype, Bytes, BytesN, Env, Vec}; + +use crate::bytes::{get_byte, or_truncated, read_be_u16, read_be_u32, read_be_u64}; +use crate::error::ContractError; +use crate::guardian; + +/// Size of a single guardian signature entry in the VAA: +/// 1 (guardian_index) + 64 (signature r||s) + 1 (recovery_id) = 66 bytes +const SIGNATURE_ENTRY_SIZE: usize = 66; + +/// Offset where the VAA body begins, after the fixed header and signatures. +/// 1 (version) + 4 (guardian_set_index) + 1 (num_signatures) +const HEADER_SIZE: usize = 6; + +/// Minimum body size: 4 (timestamp) + 4 (nonce) + 2 (emitter_chain) + +/// 32 (emitter_address) + 8 (sequence) + 1 (consistency_level) = 51 bytes +const MIN_BODY_SIZE: usize = 51; + +/// A parsed Wormhole VAA guardian signature. +#[contracttype] +#[derive(Clone, Debug)] +pub struct GuardianSignature { + pub guardian_index: u32, + pub signature: BytesN<64>, + pub recovery_id: u32, +} + +/// The parsed body of a Wormhole VAA. +#[derive(Clone, Debug)] +pub struct VaaBody { + pub timestamp: u32, + pub nonce: u32, + pub emitter_chain: u16, + pub emitter_address: BytesN<32>, + pub sequence: u64, + pub consistency_level: u8, + pub payload: Bytes, +} + +/// A fully parsed Wormhole VAA. +#[derive(Clone, Debug)] +pub struct Vaa { + pub guardian_set_index: u32, + pub signatures: Vec, + pub body: VaaBody, + /// Raw body bytes for hashing/verification. + pub body_bytes: Bytes, +} + +/// Parse a raw Wormhole VAA from bytes. +/// +/// The VAA binary format: +/// - Version (1 byte, must be 1) +/// - Guardian set index (BE u32) +/// - Number of signatures (1 byte) +/// - For each signature: guardian_index (1 byte), signature (64 bytes r||s), recovery_id (1 byte) +/// - Body: timestamp (BE u32), nonce (BE u32), emitter_chain (BE u16), +/// emitter_address (32 bytes), sequence (BE u64), consistency_level (1 byte), payload (rest) +pub fn parse_vaa(env: &Env, data: &Bytes) -> Result { + let len = data.len() as usize; + + if len < HEADER_SIZE { + return Err(ContractError::TruncatedData); + } + + // Version + let version = get_byte(data, 0)?; + if version != 1 { + return Err(ContractError::InvalidVaaVersion); + } + + // Guardian set index (BE u32) + let guardian_set_index = read_be_u32(data, 1)?; + + // Number of signatures + let num_signatures = get_byte(data, 5)? as usize; + + let body_offset = HEADER_SIZE + num_signatures * SIGNATURE_ENTRY_SIZE; + if len < body_offset + MIN_BODY_SIZE { + return Err(ContractError::TruncatedData); + } + + // Parse signatures + let mut signatures: Vec = Vec::new(env); + for i in 0..num_signatures { + let sig_offset = HEADER_SIZE + i * SIGNATURE_ENTRY_SIZE; + let guardian_index = get_byte(data, sig_offset as u32)? as u32; + + // Extract 64-byte signature (r || s) + let mut sig_bytes: [u8; 64] = [0u8; 64]; + for j in 0..64 { + sig_bytes[j] = get_byte(data, (sig_offset + 1 + j) as u32)?; + } + let signature = BytesN::from_array(env, &sig_bytes); + + let recovery_id = get_byte(data, (sig_offset + 65) as u32)? as u32; + + signatures.push_back(GuardianSignature { + guardian_index, + signature, + recovery_id, + }); + } + + // Extract body bytes (everything from body_offset to end) + let body_bytes = data.slice(body_offset as u32..len as u32); + + // Parse body fields + let timestamp = read_be_u32(data, body_offset as u32)?; + + let nonce = read_be_u32(data, (body_offset + 4) as u32)?; + + let emitter_chain = read_be_u16(data, (body_offset + 8) as u32)?; + + let mut emitter_addr: [u8; 32] = [0u8; 32]; + for j in 0..32 { + emitter_addr[j] = get_byte(data, (body_offset + 10 + j) as u32)?; + } + let emitter_address = BytesN::from_array(env, &emitter_addr); + + let seq_offset = body_offset + 42; + let sequence = read_be_u64(data, seq_offset as u32)?; + + let consistency_level = get_byte(data, (seq_offset + 8) as u32)?; + + let payload_offset = (seq_offset + 9) as u32; + let payload = if payload_offset < len as u32 { + data.slice(payload_offset..len as u32) + } else { + Bytes::new(env) + }; + + Ok(Vaa { + guardian_set_index, + signatures, + body: VaaBody { + timestamp, + nonce, + emitter_chain, + emitter_address, + sequence, + consistency_level, + payload, + }, + body_bytes, + }) +} + +/// Verify a parsed VAA against the stored guardian set. +/// +/// This function: +/// 1. Checks the guardian_set_index matches the stored index. +/// 2. Computes the Wormhole double-hash: `keccak256(keccak256(body))`. +/// 3. For each signature, recovers the signer via `secp256k1_recover`. +/// 4. Derives the Ethereum address from the recovered public key. +/// 5. Checks the address matches the stored guardian at the given index. +/// 6. Verifies quorum (2/3 + 1 of guardians have valid signatures). +/// 7. Checks for duplicate guardian indices. +pub fn verify_vaa(env: &Env, vaa: &Vaa) -> Result<(), ContractError> { + let stored_index = guardian::get_guardian_set_index(env)?; + if vaa.guardian_set_index != stored_index { + return Err(ContractError::InvalidGuardianSetIndex); + } + + let guardian_set = guardian::get_guardian_set(env)?; + let num_guardians = guardian_set.len(); + let required = guardian::quorum(num_guardians); + + let num_sigs = vaa.signatures.len(); + if num_sigs < required { + return Err(ContractError::NoQuorum); + } + + // Wormhole double-hash: keccak256(keccak256(body_bytes)) + let body_hash = env.crypto().keccak256(&vaa.body_bytes); + let digest = env.crypto().keccak256(&Bytes::from_slice(env, &body_hash.to_array())); + + // Track which guardian indices have been seen to detect duplicates. + // Use a simple approach: check ascending order (same as EVM). + let mut last_index: Option = None; + + for i in 0..num_sigs { + let sig = vaa + .signatures + .get(i); + let sig = or_truncated(sig)?; + let gi = sig.guardian_index; + + // Check ascending order (also prevents duplicates). + if let Some(prev) = last_index { + if gi <= prev { + return Err(ContractError::DuplicateGuardianSignature); + } + } + last_index = Some(gi); + + // Check guardian index is in bounds. + if gi >= num_guardians { + return Err(ContractError::InvalidGuardianIndex); + } + + // Recover the public key from the signature. + let recovered_pubkey = env.crypto().secp256k1_recover( + &digest, + &sig.signature, + sig.recovery_id, + ); + + // Derive Ethereum address from the recovered uncompressed public key. + let recovered_addr = guardian::eth_address_from_pubkey(env, &recovered_pubkey); + + // Check against stored guardian address. + let expected_addr = guardian_set + .get(gi) + .ok_or(ContractError::InvalidGuardianIndex)?; + if recovered_addr != expected_addr { + return Err(ContractError::GuardianSignatureMismatch); + } + } + + Ok(()) +} + +/// Parse and verify a VAA in one step. +pub fn parse_and_verify_vaa(env: &Env, data: &Bytes) -> Result { + let vaa = parse_vaa(env, data)?; + verify_vaa(env, &vaa)?; + Ok(vaa) +} + +#[cfg(test)] +mod tests { + extern crate alloc; + + use super::*; + use soroban_sdk::Env; + + fn vec_to_bytes(env: &Env, v: &[u8]) -> Bytes { + Bytes::from_slice(env, v) + } + + fn build_body_vec( + timestamp: u32, + nonce: u32, + emitter_chain: u16, + emitter_address: &[u8; 32], + sequence: u64, + consistency_level: u8, + payload: &[u8], + ) -> alloc::vec::Vec { + let mut body = alloc::vec::Vec::new(); + body.extend_from_slice(×tamp.to_be_bytes()); + body.extend_from_slice(&nonce.to_be_bytes()); + body.extend_from_slice(&emitter_chain.to_be_bytes()); + body.extend_from_slice(emitter_address); + body.extend_from_slice(&sequence.to_be_bytes()); + body.push(consistency_level); + body.extend_from_slice(payload); + body + } + + fn build_full_vaa_vec( + guardian_set_index: u32, + signatures: &[(u8, &[u8; 64], u8)], // (guardian_index, sig, recovery_id) + body: &[u8], + ) -> alloc::vec::Vec { + let mut vaa = alloc::vec::Vec::new(); + vaa.push(1u8); // version + vaa.extend_from_slice(&guardian_set_index.to_be_bytes()); + vaa.push(signatures.len() as u8); + for (guardian_index, sig, recovery_id) in signatures { + vaa.push(*guardian_index); + vaa.extend_from_slice(&sig[..]); + vaa.push(*recovery_id); + } + vaa.extend_from_slice(body); + vaa + } + + #[test] + fn test_parse_minimal_vaa_no_signatures() { + let env = Env::default(); + let emitter_address = [0xABu8; 32]; + let payload = [0x01, 0x02, 0x03, 0x04]; + + let body = build_body_vec(1000, 42, 1, &emitter_address, 99, 32, &payload); + let vaa_raw = build_full_vaa_vec(0, &[], &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_eq!(vaa.guardian_set_index, 0); + assert_eq!(vaa.signatures.len(), 0); + assert_eq!(vaa.body.timestamp, 1000); + assert_eq!(vaa.body.nonce, 42); + assert_eq!(vaa.body.emitter_chain, 1); + assert_eq!( + vaa.body.emitter_address, + BytesN::from_array(&env, &emitter_address) + ); + assert_eq!(vaa.body.sequence, 99); + assert_eq!(vaa.body.consistency_level, 32); + assert_eq!(vaa.body.payload, vec_to_bytes(&env, &payload)); + } + + #[test] + fn test_parse_vaa_with_signatures() { + let env = Env::default(); + let emitter_address = [0x01u8; 32]; + let payload = [0xDE, 0xAD]; + + let sig1 = [0x11u8; 64]; + let sig2 = [0x22u8; 64]; + + let body = build_body_vec(2000, 0, 26, &emitter_address, 500, 15, &payload); + let vaa_raw = build_full_vaa_vec(4, &[(0, &sig1, 0), (1, &sig2, 1)], &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_eq!(vaa.guardian_set_index, 4); + assert_eq!(vaa.signatures.len(), 2); + + let s0 = vaa.signatures.get(0).unwrap(); + assert_eq!(s0.guardian_index, 0); + assert_eq!(s0.signature, BytesN::from_array(&env, &sig1)); + assert_eq!(s0.recovery_id, 0); + + let s1 = vaa.signatures.get(1).unwrap(); + assert_eq!(s1.guardian_index, 1); + assert_eq!(s1.signature, BytesN::from_array(&env, &sig2)); + assert_eq!(s1.recovery_id, 1); + + assert_eq!(vaa.body.timestamp, 2000); + assert_eq!(vaa.body.emitter_chain, 26); + assert_eq!(vaa.body.sequence, 500); + } + + #[test] + fn test_parse_vaa_invalid_version() { + let env = Env::default(); + let emitter_address = [0u8; 32]; + let body = build_body_vec(0, 0, 0, &emitter_address, 0, 0, &[]); + let mut vaa_raw = build_full_vaa_vec(0, &[], &body); + vaa_raw[0] = 2; // invalid version + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let result = parse_vaa(&env, &vaa_bytes); + assert_eq!(result.err(), Some(ContractError::InvalidVaaVersion)); + } + + #[test] + fn test_parse_vaa_truncated_header() { + let env = Env::default(); + let vaa_bytes = vec_to_bytes(&env, &[1, 0, 0]); + + let result = parse_vaa(&env, &vaa_bytes); + assert_eq!(result.err(), Some(ContractError::TruncatedData)); + } + + #[test] + fn test_parse_vaa_truncated_body() { + let env = Env::default(); + let mut raw = alloc::vec::Vec::new(); + raw.push(1u8); // version + raw.extend_from_slice(&0u32.to_be_bytes()); + raw.push(0u8); // num_signatures + raw.extend_from_slice(&[0u8; 10]); // too short body + let vaa_bytes = vec_to_bytes(&env, &raw); + + let result = parse_vaa(&env, &vaa_bytes); + assert_eq!(result.err(), Some(ContractError::TruncatedData)); + } + + #[test] + fn test_parse_vaa_truncated_signatures() { + let env = Env::default(); + let mut raw = alloc::vec::Vec::new(); + raw.push(1u8); // version + raw.extend_from_slice(&0u32.to_be_bytes()); + raw.push(1u8); // num_signatures = 1 but no sig data + raw.extend_from_slice(&[0u8; 51]); // minimal body (but sig space missing) + let vaa_bytes = vec_to_bytes(&env, &raw); + + let result = parse_vaa(&env, &vaa_bytes); + assert_eq!(result.err(), Some(ContractError::TruncatedData)); + } + + #[test] + fn test_parse_vaa_empty_payload() { + let env = Env::default(); + let emitter_address = [0xFFu8; 32]; + + let body = build_body_vec(999, 1, 2, &emitter_address, 42, 200, &[]); + let vaa_raw = build_full_vaa_vec(0, &[], &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_eq!(vaa.body.payload.len(), 0); + assert_eq!(vaa.body.consistency_level, 200); + } + + #[test] + fn test_parse_vaa_large_guardian_set_index() { + let env = Env::default(); + let emitter_address = [0u8; 32]; + + let body = build_body_vec(0, 0, 0, &emitter_address, 0, 0, &[]); + let vaa_raw = build_full_vaa_vec(0xFFFF_FFFF, &[], &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + assert_eq!(vaa.guardian_set_index, 0xFFFF_FFFF); + } + + #[test] + fn test_parse_vaa_large_sequence() { + let env = Env::default(); + let emitter_address = [0u8; 32]; + + let body = build_body_vec(0, 0, 0, &emitter_address, u64::MAX, 0, &[]); + let vaa_raw = build_full_vaa_vec(0, &[], &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + assert_eq!(vaa.body.sequence, u64::MAX); + } + + #[test] + fn test_parse_vaa_body_bytes_match() { + let env = Env::default(); + let emitter_address = [0x42u8; 32]; + let payload = [0x01, 0x02, 0x03]; + + let body = build_body_vec(100, 200, 3, &emitter_address, 300, 1, &payload); + let vaa_raw = build_full_vaa_vec(0, &[], &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + let expected_body_bytes = vec_to_bytes(&env, &body); + assert_eq!(vaa.body_bytes, expected_body_bytes); + } + + /// Test parsing a VAA with a governance-style payload (simulating a + /// Wormhole guardian set upgrade message). + #[test] + fn test_parse_vaa_governance_payload() { + let env = Env::default(); + + // Governance emitter address: 32 bytes with 0x04 at the end + let mut emitter_address = [0u8; 32]; + emitter_address[31] = 0x04; + + // Construct a PTGM-style payload: + // "Core" (0x00000000436f7265) + action 2 (guardian set upgrade) + chain 0 + + // new guardian set index (1) + num guardians (1) + guardian key (20 bytes) + let mut payload = alloc::vec::Vec::new(); + // module "Core" padded to 32 bytes + payload.extend_from_slice(&[0u8; 28]); + payload.extend_from_slice(b"Core"); + // action = 2 (guardian set upgrade) + payload.push(2); + // target chain = 0 (all chains) + payload.extend_from_slice(&0u16.to_be_bytes()); + // new guardian set index + payload.extend_from_slice(&1u32.to_be_bytes()); + // num guardians = 1 + payload.push(1); + // guardian ethereum address (20 bytes) + payload.extend_from_slice(&[0xBEu8; 20]); + + let sig = [0xAAu8; 64]; + let body = build_body_vec(1, 1, 1, &emitter_address, 1, 0, &payload); + let vaa_raw = build_full_vaa_vec(0, &[(0, &sig, 0)], &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_eq!(vaa.guardian_set_index, 0); + assert_eq!(vaa.signatures.len(), 1); + assert_eq!(vaa.body.timestamp, 1); + assert_eq!(vaa.body.nonce, 1); + assert_eq!(vaa.body.emitter_chain, 1); + assert_eq!(vaa.body.sequence, 1); + assert_eq!(vaa.body.consistency_level, 0); + assert_eq!( + vaa.body.emitter_address, + BytesN::from_array(&env, &emitter_address) + ); + assert!(vaa.body.payload.len() > 0); + } + + /// Test parsing a VAA with many signatures (simulating a full guardian quorum). + #[test] + fn test_parse_vaa_13_signatures() { + let env = Env::default(); + let emitter_address = [0x55u8; 32]; + let payload = [0xCA, 0xFE, 0xBA, 0xBE]; + + // Build 13 unique signatures (2/3 + 1 of 19 guardians) + let mut sigs: alloc::vec::Vec<(u8, &[u8; 64], u8)> = alloc::vec::Vec::new(); + let sig_data: alloc::vec::Vec<[u8; 64]> = (0u8..13) + .map(|i| { + let mut s = [0u8; 64]; + s[0] = i; + s[63] = i; + s + }) + .collect(); + for i in 0..13u8 { + sigs.push((i, &sig_data[i as usize], i % 2)); + } + + let body = build_body_vec( + 1700000000, + 12345, + 1, + &emitter_address, + 9999, + 32, + &payload, + ); + let vaa_raw = build_full_vaa_vec(4, &sigs, &body); + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_eq!(vaa.guardian_set_index, 4); + assert_eq!(vaa.signatures.len(), 13); + + for i in 0..13u32 { + let s = vaa.signatures.get(i).unwrap(); + assert_eq!(s.guardian_index, i); + assert_eq!(s.recovery_id, i % 2); + } + + assert_eq!(vaa.body.timestamp, 1700000000); + assert_eq!(vaa.body.sequence, 9999); + assert_eq!(vaa.body.payload, vec_to_bytes(&env, &payload)); + } + + #[test] + fn test_parse_vaa_version_zero() { + let env = Env::default(); + let emitter_address = [0u8; 32]; + let body = build_body_vec(0, 0, 0, &emitter_address, 0, 0, &[]); + let mut vaa_raw = build_full_vaa_vec(0, &[], &body); + vaa_raw[0] = 0; // version 0 + let vaa_bytes = vec_to_bytes(&env, &vaa_raw); + + let result = parse_vaa(&env, &vaa_bytes); + assert_eq!(result.err(), Some(ContractError::InvalidVaaVersion)); + } + + #[test] + fn test_parse_vaa_empty_input() { + let env = Env::default(); + let vaa_bytes = Bytes::new(&env); + + let result = parse_vaa(&env, &vaa_bytes); + assert_eq!(result.err(), Some(ContractError::TruncatedData)); + } + + /// Decode a hex string (without 0x prefix) into a Vec. + fn hex_decode(hex: &str) -> alloc::vec::Vec { + assert!(hex.len() % 2 == 0, "hex string must have even length"); + (0..hex.len()) + .step_by(2) + .map(|i| u8::from_str_radix(&hex[i..i + 2], 16).unwrap()) + .collect() + } + + // Real mainnet guardian set upgrade VAA #0 (guardian_set_index=0, 1 signature). + // Source: target_chains/ton/contracts/tests/utils/wormhole.ts MAINNET_UPGRADE_VAAS[0] + const REAL_VAA_0: &str = "010000000001007ac31b282c2aeeeb37f3385ee0de5f8e421d30b9e5ae8ba3d4375c1c77a86e77159bb697d9c456d6f8c02d22a94b1279b65b0d6a9957e7d3857423845ac758e300610ac1d2000000030001000000000000000000000000000000000000000000000000000000000000000400000000000005390000000000000000000000000000000000000000000000000000000000436f7265020000000000011358cc3ae5c097b213ce3c81979e1b9f9570746aa5ff6cb952589bde862c25ef4392132fb9d4a42157114de8460193bdf3a2fcf81f86a09765f4762fd1107a0086b32d7a0977926a205131d8731d39cbeb8c82b2fd82faed2711d59af0f2499d16e726f6b211b39756c042441be6d8650b69b54ebe715e234354ce5b4d348fb74b958e8966e2ec3dbd4958a7cdeb5f7389fa26941519f0863349c223b73a6ddee774a3bf913953d695260d88bc1aa25a4eee363ef0000ac0076727b35fbea2dac28fee5ccb0fea768eaf45ced136b9d9e24903464ae889f5c8a723fc14f93124b7c738843cbb89e864c862c38cddcccf95d2cc37a4dc036a8d232b48f62cdd4731412f4890da798f6896a3331f64b48c12d1d57fd9cbe7081171aa1be1d36cafe3867910f99c09e347899c19c38192b6e7387ccd768277c17dab1b7a5027c0b3cf178e21ad2e77ae06711549cfbb1f9c7a9d8096e85e1487f35515d02a92753504a8d75471b9f49edb6fbebc898f403e4773e95feb15e80c9a99c8348d"; + + // Real mainnet guardian set upgrade VAA #1 (guardian_set_index=1, 13 signatures). + const REAL_VAA_1: &str = "01000000010d0012e6b39c6da90c5dfd3c228edbb78c7a4c97c488ff8a346d161a91db067e51d638c17216f368aa9bdf4836b8645a98018ca67d2fec87d769cabfdf2406bf790a0002ef42b288091a670ef3556596f4f47323717882881eaf38e03345078d07a156f312b785b64dae6e9a87e3d32872f59cb1931f728cecf511762981baf48303668f0103cef2616b84c4e511ff03329e0853f1bd7ee9ac5ba71d70a4d76108bddf94f69c2a8a84e4ee94065e8003c334e899184943634e12043d0dda78d93996da073d190104e76d166b9dac98f602107cc4b44ac82868faf00b63df7d24f177aa391e050902413b71046434e67c770b19aecdf7fce1d1435ea0be7262e3e4c18f50ddc8175c0105d9450e8216d741e0206a50f93b750a47e0a258b80eb8fed1314cc300b3d905092de25cd36d366097b7103ae2d184121329ba3aa2d7c6cc53273f11af14798110010687477c8deec89d36a23e7948feb074df95362fc8dcbd8ae910ac556a1dee1e755c56b9db5d710c940938ed79bc1895a3646523a58bc55f475a23435a373ecfdd0107fb06734864f79def4e192497362513171530daea81f07fbb9f698afe7e66c6d44db21323144f2657d4a5386a954bb94eef9f64148c33aef6e477eafa2c5c984c01088769e82216310d1827d9bd48645ec23e90de4ef8a8de99e2d351d1df318608566248d80cdc83bdcac382b3c30c670352be87f9069aab5037d0b747208eae9c650109e9796497ff9106d0d1c62e184d83716282870cef61a1ee13d6fc485b521adcce255c96f7d1bca8d8e7e7d454b65783a830bddc9d94092091a268d311ecd84c26010c468c9fb6d41026841ff9f8d7368fa309d4dbea3ea4bbd2feccf94a92cc8a20a226338a8e2126cd16f70eaf15b4fc9be2c3fa19def14e071956a605e9d1ac4162010e23fcb6bd445b7c25afb722250c1acbc061ed964ba9de1326609ae012acdfb96942b2a102a2de99ab96327859a34a2b49a767dbdb62e0a1fb26af60fe44fd496a00106bb0bac77ac68b347645f2fb1ad789ea9bd76fb9b2324f25ae06f97e65246f142df717f662e73948317182c62ce87d79c73def0dba12e5242dfc038382812cfe00126da03c5e56cb15aeeceadc1e17a45753ab4dc0ec7bf6a75ca03143ed4a294f6f61bc3f478a457833e43084ecd7c985bf2f55a55f168aac0e030fc49e845e497101626e9d9a5d9e343f00010000000000000000000000000000000000000000000000000000000000000004c1759167c43f501c2000000000000000000000000000000000000000000000000000000000436f7265020000000000021358cc3ae5c097b213ce3c81979e1b9f9570746aa5ff6cb952589bde862c25ef4392132fb9d4a42157114de8460193bdf3a2fcf81f86a09765f4762fd1107a0086b32d7a0977926a205131d8731d39cbeb8c82b2fd82faed2711d59af0f2499d16e726f6b211b39756c042441be6d8650b69b54ebe715e234354ce5b4d348fb74b958e8966e2ec3dbd4958a7cd66b9590e1c41e0b226937bf9217d1d67fd4e91f574a3bf913953d695260d88bc1aa25a4eee363ef0000ac0076727b35fbea2dac28fee5ccb0fea768eaf45ced136b9d9e24903464ae889f5c8a723fc14f93124b7c738843cbb89e864c862c38cddcccf95d2cc37a4dc036a8d232b48f62cdd4731412f4890da798f6896a3331f64b48c12d1d57fd9cbe7081171aa1be1d36cafe3867910f99c09e347899c19c38192b6e7387ccd768277c17dab1b7a5027c0b3cf178e21ad2e77ae06711549cfbb1f9c7a9d8096e85e1487f35515d02a92753504a8d75471b9f49edb6fbebc898f403e4773e95feb15e80c9a99c8348d"; + + // Real mainnet guardian set upgrade VAA #2 (guardian_set_index=2, 13 signatures). + const REAL_VAA_2: &str = "01000000020d00ce45474d9e1b1e7790a2d210871e195db53a70ffd6f237cfe70e2686a32859ac43c84a332267a8ef66f59719cf91cc8df0101fd7c36aa1878d5139241660edc0010375cc906156ae530786661c0cd9aef444747bc3d8d5aa84cac6a6d2933d4e1a031cffa30383d4af8131e929d9f203f460b07309a647d6cd32ab1cc7724089392c000452305156cfc90343128f97e499311b5cae174f488ff22fbc09591991a0a73d8e6af3afb8a5968441d3ab8437836407481739e9850ad5c95e6acfcc871e951bc30105a7956eefc23e7c945a1966d5ddbe9e4be376c2f54e45e3d5da88c2f8692510c7429b1ea860ae94d929bd97e84923a18187e777aa3db419813a80deb84cc8d22b00061b2a4f3d2666608e0aa96737689e3ba5793810ff3a52ff28ad57d8efb20967735dc5537a2e43ef10f583d144c12a1606542c207f5b79af08c38656d3ac40713301086b62c8e130af3411b3c0d91b5b50dcb01ed5f293963f901fc36e7b0e50114dce203373b32eb45971cef8288e5d928d0ed51cd86e2a3006b0af6a65c396c009080009e93ab4d2c8228901a5f4525934000b2c26d1dc679a05e47fdf0ff3231d98fbc207103159ff4116df2832eea69b38275283434e6cd4a4af04d25fa7a82990b707010aa643f4cf615dfff06ffd65830f7f6cf6512dabc3690d5d9e210fdc712842dc2708b8b2c22e224c99280cd25e5e8bfb40e3d1c55b8c41774e287c1e2c352aecfc010b89c1e85faa20a30601964ccc6a79c0ae53cfd26fb10863db37783428cd91390a163346558239db3cd9d420cfe423a0df84c84399790e2e308011b4b63e6b8015010ca31dcb564ac81a053a268d8090e72097f94f366711d0c5d13815af1ec7d47e662e2d1bde22678113d15963da100b668ba26c0c325970d07114b83c5698f46097010dc9fda39c0d592d9ed92cd22b5425cc6b37430e236f02d0d1f8a2ef45a00bde26223c0a6eb363c8b25fd3bf57234a1d9364976cefb8360e755a267cbbb674b39501108db01e444ab1003dd8b6c96f8eb77958b40ba7a85fefecf32ad00b7a47c0ae7524216262495977e09c0989dd50f280c21453d3756843608eacd17f4fdfe47600001261025228ef5af837cb060bcd986fcfa84ccef75b3fa100468cfd24e7fadf99163938f3b841a33496c2706d0208faab088bd155b2e20fd74c625bb1cc8c43677a0163c53c409e0c5dfa000100000000000000000000000000000000000000000000000000000000000000046c5a054d7833d1e42000000000000000000000000000000000000000000000000000000000436f7265020000000000031358cc3ae5c097b213ce3c81979e1b9f9570746aa5ff6cb952589bde862c25ef4392132fb9d4a42157114de8460193bdf3a2fcf81f86a09765f4762fd1107a0086b32d7a0977926a205131d8731d39cbeb8c82b2fd82faed2711d59af0f2499d16e726f6b211b39756c042441be6d8650b69b54ebe715e234354ce5b4d348fb74b958e8966e2ec3dbd4958a7cd15e7caf07c4e3dc8e7c469f92c8cd88fb8005a2074a3bf913953d695260d88bc1aa25a4eee363ef0000ac0076727b35fbea2dac28fee5ccb0fea768eaf45ced136b9d9e24903464ae889f5c8a723fc14f93124b7c738843cbb89e864c862c38cddcccf95d2cc37a4dc036a8d232b48f62cdd4731412f4890da798f6896a3331f64b48c12d1d57fd9cbe7081171aa1be1d36cafe3867910f99c09e347899c19c38192b6e7387ccd768277c17dab1b7a5027c0b3cf178e21ad2e77ae06711549cfbb1f9c7a9d8096e85e1487f35515d02a92753504a8d75471b9f49edb6fbebc898f403e4773e95feb15e80c9a99c8348d"; + + /// Wormhole governance emitter address: all zeros except 0x04 at the last byte. + fn governance_emitter_address() -> [u8; 32] { + let mut addr = [0u8; 32]; + addr[31] = 0x04; + addr + } + + /// "Core" module identifier padded to 32 bytes (28 zero bytes + "Core"). + fn core_module_bytes() -> [u8; 32] { + let mut m = [0u8; 32]; + m[28] = b'C'; + m[29] = b'o'; + m[30] = b'r'; + m[31] = b'e'; + m + } + + /// Helper to run common assertions on a real mainnet guardian set upgrade VAA. + fn assert_guardian_set_upgrade_vaa( + env: &Env, + vaa: &Vaa, + expected_guardian_set_index: u32, + expected_num_signatures: u32, + expected_sequence: u64, + expected_new_guardian_set_index: u32, + ) { + // Header fields + assert_eq!(vaa.guardian_set_index, expected_guardian_set_index); + assert_eq!(vaa.signatures.len(), expected_num_signatures); + + // All mainnet upgrade VAAs are emitted on Solana (chain 1) + assert_eq!(vaa.body.emitter_chain, 1); + + // Governance emitter address + assert_eq!( + vaa.body.emitter_address, + BytesN::from_array(env, &governance_emitter_address()) + ); + + // Sequence + assert_eq!(vaa.body.sequence, expected_sequence); + + // Body bytes should be non-trivial (51 bytes minimum body + payload) + assert!(vaa.body_bytes.len() > 51); + + // Payload starts with "Core" module (32 bytes) + let core = core_module_bytes(); + for i in 0..32u32 { + assert_eq!( + vaa.body.payload.get(i).unwrap(), + core[i as usize], + "Core module mismatch at byte {i}" + ); + } + + // Action byte = 2 (guardian set upgrade) + assert_eq!(vaa.body.payload.get(32).unwrap(), 2); + + // Target chain = 0 (all chains) + assert_eq!(vaa.body.payload.get(33).unwrap(), 0); + assert_eq!(vaa.body.payload.get(34).unwrap(), 0); + + // New guardian set index (BE u32 at payload offset 35..39) + let new_gsi = ((vaa.body.payload.get(35).unwrap() as u32) << 24) + | ((vaa.body.payload.get(36).unwrap() as u32) << 16) + | ((vaa.body.payload.get(37).unwrap() as u32) << 8) + | (vaa.body.payload.get(38).unwrap() as u32); + assert_eq!(new_gsi, expected_new_guardian_set_index); + + // Number of guardians in upgrade payload = 19 + assert_eq!(vaa.body.payload.get(39).unwrap(), 19); + } + + #[test] + fn test_parse_real_mainnet_vaa_0() { + let env = Env::default(); + let raw = hex_decode(REAL_VAA_0); + let vaa_bytes = vec_to_bytes(&env, &raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_guardian_set_upgrade_vaa( + &env, + &vaa, + 0, // guardian_set_index + 1, // num_signatures (first VAA only has 1 signer) + 1337, // sequence + 1, // new guardian set index + ); + + // VAA[0] specific: timestamp and consistency_level + assert_eq!(vaa.body.timestamp, 1628094930); + assert_eq!(vaa.body.consistency_level, 0); + } + + #[test] + fn test_parse_real_mainnet_vaa_1() { + let env = Env::default(); + let raw = hex_decode(REAL_VAA_1); + let vaa_bytes = vec_to_bytes(&env, &raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_guardian_set_upgrade_vaa( + &env, + &vaa, + 1, // guardian_set_index + 13, // num_signatures (2/3+1 of 19) + 13940208096455381020, // sequence + 2, // new guardian set index + ); + + assert_eq!(vaa.body.timestamp, 1651416474); + assert_eq!(vaa.body.consistency_level, 32); + } + + #[test] + fn test_parse_real_mainnet_vaa_2() { + let env = Env::default(); + let raw = hex_decode(REAL_VAA_2); + let vaa_bytes = vec_to_bytes(&env, &raw); + + let vaa = parse_vaa(&env, &vaa_bytes).unwrap(); + + assert_guardian_set_upgrade_vaa( + &env, + &vaa, + 2, // guardian_set_index + 13, // num_signatures + 7807558734287458788, // sequence + 3, // new guardian set index + ); + + assert_eq!(vaa.body.timestamp, 1673870400); + assert_eq!(vaa.body.consistency_level, 32); + } +} diff --git a/lazer/contracts/stellar/scripts/deploy.sh b/lazer/contracts/stellar/scripts/deploy.sh new file mode 100755 index 0000000000..5e9416ad05 --- /dev/null +++ b/lazer/contracts/stellar/scripts/deploy.sh @@ -0,0 +1,210 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Deploy and initialize Pyth Lazer Stellar contracts to the Stellar network. +# +# Prerequisites: +# - stellar CLI v25+ (https://developers.stellar.org/docs/tools/cli/install-cli) +# - wasm32-unknown-unknown target: rustup target add wasm32-unknown-unknown +# - wasm-opt (optional, for WASM optimization): cargo install wasm-opt +# +# Usage: +# ./scripts/deploy.sh --secret [--network ] [--chain-id ] +# +# Options: +# --secret Stellar secret key (S...) or CLI identity alias +# --network Stellar network: "testnet" (default) or "mainnet" +# --chain-id Wormhole chain ID for this Stellar deployment (default: 28) +# --guardian-set Comma-separated guardian addresses (hex, no 0x prefix) +# --guardian-index Guardian set index (default: 0) +# --emitter-chain Governance emitter chain ID (default: 1 = Solana) +# --emitter-address Governance emitter address (32-byte hex, no 0x prefix) +# --fund Fund the account via friendbot (testnet only) + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +WORKSPACE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" + +# Defaults +NETWORK="testnet" +CHAIN_ID=30 +GUARDIAN_INDEX=0 +EMITTER_CHAIN=1 +FUND=false + +# Testnet defaults +TESTNET_GUARDIAN="13947bd48b18e53fdaeee77f3473391ac727c638" +TESTNET_EMITTER_ADDRESS="63278d271099bfd491951b3e648f08b1c71631e4a53674ad43e8f9f98068c385" + +# Pyth Lazer trusted signer public key (compressed secp256k1, hex) +LAZER_SIGNER_PUBKEY="03a4380f01136eb2640f90c17e1e319e02bbafbeef2e6e67dc48af53f9827e155b" +FAR_FUTURE_EXPIRY=9999999999 + +SECRET="" +GUARDIAN_SET="" +EMITTER_ADDRESS="" + +while [[ $# -gt 0 ]]; do + case $1 in + --secret) + SECRET="$2"; shift 2 ;; + --network) + NETWORK="$2"; shift 2 ;; + --chain-id) + CHAIN_ID="$2"; shift 2 ;; + --guardian-set) + GUARDIAN_SET="$2"; shift 2 ;; + --guardian-index) + GUARDIAN_INDEX="$2"; shift 2 ;; + --emitter-chain) + EMITTER_CHAIN="$2"; shift 2 ;; + --emitter-address) + EMITTER_ADDRESS="$2"; shift 2 ;; + --fund) + FUND=true; shift ;; + *) + echo "Unknown option: $1"; exit 1 ;; + esac +done + +if [[ -z "$SECRET" ]]; then + echo "Error: --secret is required" + exit 1 +fi + +# Apply testnet defaults if not overridden +if [[ "$NETWORK" == "testnet" ]]; then + if [[ -z "$GUARDIAN_SET" ]]; then + GUARDIAN_SET="$TESTNET_GUARDIAN" + fi + if [[ -z "$EMITTER_ADDRESS" ]]; then + EMITTER_ADDRESS="$TESTNET_EMITTER_ADDRESS" + fi +fi + +if [[ -z "$GUARDIAN_SET" ]]; then + echo "Error: --guardian-set is required for non-testnet deployments" + exit 1 +fi +if [[ -z "$EMITTER_ADDRESS" ]]; then + echo "Error: --emitter-address is required for non-testnet deployments" + exit 1 +fi + +COMMON_ARGS="--network $NETWORK --source $SECRET" + +echo "=== Pyth Lazer Stellar Deployment ===" +echo "Network: $NETWORK" +echo "Chain ID: $CHAIN_ID" +echo "Guardian Index: $GUARDIAN_INDEX" +echo "Emitter Chain: $EMITTER_CHAIN" +echo "" + +# Step 0: Fund account via friendbot (testnet only) +if [[ "$FUND" == "true" && "$NETWORK" == "testnet" ]]; then + echo "Funding account via friendbot..." + stellar keys fund "$SECRET" --network testnet 2>/dev/null || \ + echo "Warning: could not fund account (may already be funded)" + echo "" +fi + +# Step 1: Build contracts +echo "=== Building contracts ===" +cd "$WORKSPACE_DIR" +cargo build --release --target wasm32-unknown-unknown -p wormhole-executor-stellar -p pyth-lazer-stellar +echo "Build complete." +echo "" + +WASM_DIR="$WORKSPACE_DIR/target/wasm32-unknown-unknown/release" +EXECUTOR_WASM="$WASM_DIR/wormhole_executor_stellar.wasm" +LAZER_WASM="$WASM_DIR/pyth_lazer_stellar.wasm" + +# Optimize WASM files using wasm-opt if available +# This strips reference-types (required for Soroban VM) and reduces size +if command -v wasm-opt &> /dev/null; then + echo "=== Optimizing WASM files with wasm-opt ===" + wasm-opt -Oz --disable-reference-types \ + "$EXECUTOR_WASM" -o "${EXECUTOR_WASM%.wasm}.optimized.wasm" + EXECUTOR_WASM="${EXECUTOR_WASM%.wasm}.optimized.wasm" + + wasm-opt -Oz --disable-reference-types \ + "$LAZER_WASM" -o "${LAZER_WASM%.wasm}.optimized.wasm" + LAZER_WASM="${LAZER_WASM%.wasm}.optimized.wasm" +else + echo "Warning: wasm-opt not found. Install with: cargo install wasm-opt" + echo "Deploying unoptimized WASM (may fail if reference-types are present)." +fi + +echo "Executor WASM: $EXECUTOR_WASM ($(wc -c < "$EXECUTOR_WASM") bytes)" +echo "Lazer WASM: $LAZER_WASM ($(wc -c < "$LAZER_WASM") bytes)" +echo "" + +# Step 2: Prepare constructor args +echo "=== Preparing constructor arguments ===" + +# Build guardian set JSON array +IFS=',' read -ra GUARDIANS <<< "$GUARDIAN_SET" +GUARDIAN_JSON="[" +for i in "${!GUARDIANS[@]}"; do + addr="${GUARDIANS[$i]}" + addr=$(echo "$addr" | tr '[:upper:]' '[:lower:]' | sed 's/^0x//') + if [[ $i -gt 0 ]]; then + GUARDIAN_JSON+="," + fi + GUARDIAN_JSON+="\"$addr\"" +done +GUARDIAN_JSON+="]" + +# Pad emitter address to 64 hex chars (32 bytes). +PADDED_EMITTER=$(printf '%064s' "$EMITTER_ADDRESS" | tr ' ' '0') + +# Step 3: Deploy wormhole-executor-stellar (runs __constructor during deploy) +echo "=== Deploying wormhole-executor-stellar ===" +EXECUTOR_ID=$(stellar contract deploy \ + --wasm "$EXECUTOR_WASM" \ + $COMMON_ARGS \ + -- \ + --chain_id "$CHAIN_ID" \ + --owner_emitter_chain "$EMITTER_CHAIN" \ + --owner_emitter_address "$PADDED_EMITTER" \ + --initial_guardian_set "$GUARDIAN_JSON" \ + --guardian_set_index "$GUARDIAN_INDEX" \ + 2>&1 | tail -1) +echo "Executor contract ID: $EXECUTOR_ID" +echo "" + +# Step 4: Deploy pyth-lazer-stellar with initial trusted signer (__constructor) +echo "=== Deploying pyth-lazer-stellar ===" +LAZER_ID=$(stellar contract deploy \ + --wasm "$LAZER_WASM" \ + $COMMON_ARGS \ + -- \ + --executor "$EXECUTOR_ID" \ + --initial_signer "\"$LAZER_SIGNER_PUBKEY\"" \ + --initial_signer_expires_at "$FAR_FUTURE_EXPIRY" \ + 2>&1 | tail -1) +echo "Lazer contract ID: $LAZER_ID" +echo "Trusted signer: $LAZER_SIGNER_PUBKEY (expires: $FAR_FUTURE_EXPIRY)" +echo "" + +# Output summary +echo "=========================================" +echo "=== Deployment Complete ===" +echo "=========================================" +echo "" +echo "Network: $NETWORK" +echo "Wormhole Chain ID: $CHAIN_ID" +echo "Guardian Set Index: $GUARDIAN_INDEX" +echo "Emitter Chain: $EMITTER_CHAIN" +echo "" +echo "Executor Contract ID: $EXECUTOR_ID" +echo "Lazer Contract ID: $LAZER_ID" +echo "" +echo "Lazer Signer Pubkey: $LAZER_SIGNER_PUBKEY" +echo "Signer Expiry: $FAR_FUTURE_EXPIRY" +echo "" +echo "Next steps:" +echo " 1. Call verify_update on the Lazer contract with a signed price update" +echo "" +echo "Example - verify update:" +echo " stellar contract invoke --id $LAZER_ID --network $NETWORK --source -- \\" +echo " verify_update --data " diff --git a/lazer/contracts/stellar/scripts/e2e/package.json b/lazer/contracts/stellar/scripts/e2e/package.json new file mode 100644 index 0000000000..efc5a2e4e4 --- /dev/null +++ b/lazer/contracts/stellar/scripts/e2e/package.json @@ -0,0 +1,23 @@ +{ + "dependencies": { + "@pythnetwork/pyth-lazer-sdk": "^5.2.0", + "@stellar/stellar-sdk": "^13.0.0" + }, + "description": "End-to-end tests for the Pyth Lazer Stellar contracts", + "devDependencies": { + "@cprussin/tsconfig": "catalog:", + "@types/node": "catalog:", + "@types/yargs": "catalog:", + "tsx": "catalog:", + "yargs": "catalog:" + }, + "engines": { + "node": "^24.0.0" + }, + "name": "@pythnetwork/pyth-lazer-stellar-e2e", + "private": true, + "scripts": { + "test:e2e": "tsx src/test_real_update.ts" + }, + "type": "module" +} diff --git a/lazer/contracts/stellar/scripts/e2e/src/test_real_update.ts b/lazer/contracts/stellar/scripts/e2e/src/test_real_update.ts new file mode 100644 index 0000000000..4f280b49ce --- /dev/null +++ b/lazer/contracts/stellar/scripts/e2e/src/test_real_update.ts @@ -0,0 +1,387 @@ +/** biome-ignore-all lint/suspicious/noConsole: e2e test script */ + +import { execSync } from "node:child_process"; +import process from "node:process"; + +import { PythLazerClient } from "@pythnetwork/pyth-lazer-sdk"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; + +const NETWORK = "testnet"; +const PAYLOAD_MAGIC = 0x93_c7_d3_75; + +const CHANNEL_NAMES: Record = { + 1: "RealTime", + 2: "FixedRate50ms", + 3: "FixedRate200ms", + 4: "FixedRate1000ms", +}; + +const { secret, "contract-id": contractIdArg } = await yargs( + hideBin(process.argv), +) + .option("secret", { + description: + "Stellar secret key (S...). If omitted, a new keypair is generated and funded.", + type: "string", + }) + .option("contract-id", { + demandOption: true, + description: + "Lazer contract ID to test against. Deploy separately using deploy.sh first.", + type: "string", + }) + .help() + .parseAsync(); + +const { PYTH_LAZER_TOKEN } = process.env; +if (!PYTH_LAZER_TOKEN) { + throw new Error( + "'PYTH_LAZER_TOKEN' environment variable must be set to your Lazer auth token.", + ); +} + +function stellarCmd(args: string): string { + const cmd = `stellar ${args}`; + console.log(` $ ${cmd}`); + const out = execSync(cmd, { + encoding: "utf-8", + timeout: 120_000, + }).trim(); + if (out) console.log(` ${out}`); + return out; +} + +function readLeU16(buf: Buffer, offset: number): number { + return buf.readUInt16LE(offset); +} + +function readLeU32(buf: Buffer, offset: number): number { + return buf.readUInt32LE(offset); +} + +function readLeI64(buf: Buffer, offset: number): bigint { + return buf.readBigInt64LE(offset); +} + +function readLeU64(buf: Buffer, offset: number): bigint { + return buf.readBigUInt64LE(offset); +} + +/** Parse the verified payload and print price feed data. */ +function parseAndPrintPayload(hexPayload: string): void { + const buf = Buffer.from(hexPayload, "hex"); + let offset = 0; + + // Magic + const magic = readLeU32(buf, offset); + offset += 4; + if (magic !== PAYLOAD_MAGIC) { + throw new Error( + `Invalid payload magic: 0x${magic.toString(16)} (expected 0x${PAYLOAD_MAGIC.toString(16)})`, + ); + } + console.log(` Payload magic: 0x${magic.toString(16)} (valid)`); + + // Timestamp (microseconds since epoch) + const timestampUs = readLeU64(buf, offset); + offset += 8; + const timestampMs = Number(timestampUs / 1000n); + console.log( + ` Timestamp: ${timestampUs} us (${new Date(timestampMs).toISOString()})`, + ); + + // Channel + const channelId = buf[offset]; + offset += 1; + console.log( + ` Channel: ${channelId} (${CHANNEL_NAMES[channelId] ?? "Unknown"})`, + ); + + // Number of feeds + const numFeeds = buf[offset]; + offset += 1; + console.log(` Number of feeds: ${numFeeds}`); + + if (numFeeds === 0) { + throw new Error("Payload contains zero feeds"); + } + + for (let f = 0; f < numFeeds; f++) { + const feedId = readLeU32(buf, offset); + offset += 4; + const numProps = buf[offset]; + offset += 1; + console.log(`\n Feed #${f}: id=${feedId}, properties=${numProps}`); + + for (let p = 0; p < numProps; p++) { + const propId = buf[offset]; + offset += 1; + + switch (propId) { + case 0: { + // Price (i64) + const price = readLeI64(buf, offset); + offset += 8; + console.log( + ` [${propId}] Price: ${price}${price === 0n ? " (absent)" : ""}`, + ); + break; + } + case 1: { + // BestBidPrice (i64) + const val = readLeI64(buf, offset); + offset += 8; + console.log(` [${propId}] BestBidPrice: ${val}`); + break; + } + case 2: { + // BestAskPrice (i64) + const val = readLeI64(buf, offset); + offset += 8; + console.log(` [${propId}] BestAskPrice: ${val}`); + break; + } + case 3: { + // PublisherCount (u16) + const val = readLeU16(buf, offset); + offset += 2; + console.log(` [${propId}] PublisherCount: ${val}`); + break; + } + case 4: { + // Exponent (i16) + const val = buf.readInt16LE(offset); + offset += 2; + console.log(` [${propId}] Exponent: ${val}`); + break; + } + case 5: { + // Confidence (u64) + const val = readLeU64(buf, offset); + offset += 8; + console.log(` [${propId}] Confidence: ${val}`); + break; + } + case 6: { + // FundingRate (bool + i64) + const exists = buf[offset]; + offset += 1; + if (exists) { + const val = readLeI64(buf, offset); + offset += 8; + console.log(` [${propId}] FundingRate: ${val}`); + } else { + console.log(` [${propId}] FundingRate: (absent)`); + } + break; + } + case 7: { + // FundingTimestamp (bool + u64) + const exists = buf[offset]; + offset += 1; + if (exists) { + const val = readLeU64(buf, offset); + offset += 8; + console.log(` [${propId}] FundingTimestamp: ${val}`); + } else { + console.log(` [${propId}] FundingTimestamp: (absent)`); + } + break; + } + case 8: { + // FundingRateInterval (bool + u64) + const exists = buf[offset]; + offset += 1; + if (exists) { + const val = readLeU64(buf, offset); + offset += 8; + console.log(` [${propId}] FundingRateInterval: ${val}`); + } else { + console.log(` [${propId}] FundingRateInterval: (absent)`); + } + break; + } + case 9: { + // MarketSession (u16) + const val = readLeU16(buf, offset); + offset += 2; + const sessions = [ + "Regular", + "PreMarket", + "PostMarket", + "OverNight", + "Closed", + ]; + console.log(` [${propId}] MarketSession: ${sessions[val] ?? val}`); + break; + } + case 10: { + // EmaPrice (i64) + const val = readLeI64(buf, offset); + offset += 8; + console.log(` [${propId}] EmaPrice: ${val}`); + break; + } + case 11: { + // EmaConfidence (u64) + const val = readLeU64(buf, offset); + offset += 8; + console.log(` [${propId}] EmaConfidence: ${val}`); + break; + } + case 12: { + // FeedUpdateTimestamp (bool + u64) + const exists = buf[offset]; + offset += 1; + if (exists) { + const val = readLeU64(buf, offset); + offset += 8; + console.log(` [${propId}] FeedUpdateTimestamp: ${val}`); + } else { + console.log(` [${propId}] FeedUpdateTimestamp: (absent)`); + } + break; + } + default: + console.log(` [${propId}] Unknown property`); + } + } + } +} + +// --- Step 1: Set up Stellar keypair --- +let stellarSecret: string; +let accountId: string; +if (secret) { + stellarSecret = secret; + console.log("=== Using provided keypair ==="); + const { Keypair } = await import("@stellar/stellar-sdk"); + accountId = Keypair.fromSecret(stellarSecret).publicKey(); + console.log(` Account: ${accountId}`); +} else { + const { Keypair } = await import("@stellar/stellar-sdk"); + console.log("=== Generating Stellar test keypair ==="); + const kp = Keypair.random(); + stellarSecret = kp.secret(); + accountId = kp.publicKey(); + console.log(` Account: ${accountId}`); + + console.log("\n=== Funding account via Stellar friendbot ==="); + const fundResp = await fetch( + `https://friendbot.stellar.org?addr=${accountId}`, + ); + if (fundResp.ok) { + console.log(" Account funded."); + } else { + console.log( + ` Friendbot returned ${fundResp.status} (account may already be funded).`, + ); + } +} + +// --- Step 2: Use the provided contract ID --- +const contractId = contractIdArg; +console.log(`\n=== Using Lazer contract: ${contractId} ===`); + +// --- Step 3: Fetch real price update from Pyth Lazer --- +console.log("\n=== Fetching real price update from Pyth Lazer ==="); +const lazer = await PythLazerClient.create({ token: PYTH_LAZER_TOKEN }); +let updateHex: string; + +try { + const response = await lazer.getLatestPrice({ + channel: "fixed_rate@200ms", + formats: ["leEcdsa"], + jsonBinaryEncoding: "hex", + priceFeedIds: [1], + properties: ["price"], + }); + + const hex = response.leEcdsa?.data; + if (!hex) { + console.error(" Response:", JSON.stringify(response, null, 2)); + throw new Error("No leEcdsa data in response"); + } + updateHex = hex; + + const update = Buffer.from(updateHex, "hex"); + console.log(` Update size: ${update.length} bytes`); + console.log(` Update hex (first 80 chars): ${updateHex.slice(0, 80)}...`); +} finally { + lazer.close?.(); +} + +// --- Step 4: Verify the real update on-chain --- +console.log("\n=== Calling verify_update with real Lazer payload ==="); +const result = stellarCmd( + `contract invoke --id ${contractId} --network ${NETWORK} --source ${stellarSecret} --send=yes -- verify_update --data ${updateHex}`, +); + +// --- Step 5: Validate the result --- +console.log("\n=== Validating verify_update result ==="); +if (!result || result.length === 0) { + console.error("ERROR: verify_update returned empty result"); + process.exit(1); +} + +// The result from stellar CLI for a Bytes return type is typically a hex string or JSON. +// Strip any surrounding quotes if present. +let payloadHex = result.replace(/^["']|["']$/g, ""); +// If the result looks like a JSON string, parse it +if (payloadHex.startsWith('"')) { + payloadHex = JSON.parse(payloadHex) as string; +} + +console.log(` Result length: ${payloadHex.length} hex chars`); +console.log(` Result (first 80 chars): ${payloadHex.slice(0, 80)}...`); + +if (payloadHex.length < 28) { + // Minimum: 4 (magic) + 8 (timestamp) + 1 (channel) + 1 (num_feeds) = 14 bytes = 28 hex chars + console.error( + `ERROR: Payload too short (${payloadHex.length} hex chars, need at least 28)`, + ); + process.exit(1); +} + +// --- Step 6: Parse and print payload data --- +console.log("\n=== Parsing verified payload ==="); +parseAndPrintPayload(payloadHex); + +// --- Step 7: Get transaction hash from Horizon --- +console.log("\n=== Fetching transaction hash from Horizon ==="); +try { + const horizonUrl = `https://horizon-testnet.stellar.org/accounts/${accountId}/transactions?order=desc&limit=1`; + const txResp = await fetch(horizonUrl); + if (txResp.ok) { + const txData = (await txResp.json()) as { + _embedded?: { records?: Array<{ hash?: string }> }; + }; + const records = txData._embedded?.records; + if (records && records.length > 0) { + const txHash = records[0].hash; + console.log(` Transaction hash: ${txHash}`); + console.log( + ` Stellar Explorer: https://stellar.expert/explorer/testnet/tx/${txHash}`, + ); + } else { + console.log(" Warning: No transactions found for account on Horizon"); + } + } else { + console.log( + ` Warning: Horizon returned ${txResp.status} when fetching transactions`, + ); + } +} catch (err) { + console.log(` Warning: Could not fetch transaction hash: ${err}`); +} + +// --- Done --- +console.log("\n========================================="); +console.log("=== END-TO-END TEST PASSED ==="); +console.log("========================================="); +console.log(`\nLazer contract: ${contractId}`); +console.log(`Verified payload (hex): ${payloadHex}`); +console.log( + "\nThe real Pyth Lazer price update was successfully verified on Stellar testnet!", +); diff --git a/lazer/contracts/stellar/scripts/e2e/tsconfig.json b/lazer/contracts/stellar/scripts/e2e/tsconfig.json new file mode 100644 index 0000000000..588869e282 --- /dev/null +++ b/lazer/contracts/stellar/scripts/e2e/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "lib": ["ESNext"] + }, + "extends": "@cprussin/tsconfig/base.json", + "include": ["src"] +} diff --git a/lazer/contracts/stellar/scripts/e2e/turbo.json b/lazer/contracts/stellar/scripts/e2e/turbo.json new file mode 100644 index 0000000000..a9fceeca8c --- /dev/null +++ b/lazer/contracts/stellar/scripts/e2e/turbo.json @@ -0,0 +1,9 @@ +{ + "$schema": "https://turbo.build/schema.json", + "extends": ["//"], + "tasks": { + "test:e2e": { + "env": ["PYTH_LAZER_TOKEN"] + } + } +} diff --git a/packages/shared-lib/package.json b/packages/shared-lib/package.json index 557720fa67..746e19fff2 100644 --- a/packages/shared-lib/package.json +++ b/packages/shared-lib/package.json @@ -149,4 +149,4 @@ "type": "module", "types": "./dist/cjs/index.d.ts", "version": "0.0.0" -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 53883ad264..a3874e92ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,21 +6,399 @@ settings: catalogs: default: + '@amplitude/analytics-browser': + specifier: ^2.13.0 + version: 2.13.0 + '@amplitude/plugin-autocapture-browser': + specifier: ^1.0.0 + version: 1.1.3 + '@axe-core/react': + specifier: ^4.10.1 + version: 4.10.1 + '@babel/cli': + specifier: ^7.27.2 + version: 7.27.2 + '@babel/core': + specifier: ^7.27.1 + version: 7.28.6 + '@babel/preset-typescript': + specifier: ^7.27.1 + version: 7.28.5 + '@base-ui/react': + specifier: ^1.1.0 + version: 1.1.0 + '@better-builds/ts-duality': + specifier: ^1.3.2 + version: 1.3.2 + '@biomejs/biome': + specifier: ^2.3.14 + version: 2.3.14 + '@bonfida/spl-name-service': + specifier: ^3.0.10 + version: 3.0.10 + '@clickhouse/client': + specifier: ^1.15.0 + version: 1.15.0 + '@coral-xyz/anchor': + specifier: ^0.30.1 + version: 0.30.1 + '@cprussin/jest-config': + specifier: ^2.0.2 + version: 2.0.2 '@cprussin/tsconfig': specifier: ^4.0.2 version: 4.0.2 + '@floating-ui/react': + specifier: ^0.27.6 + version: 0.27.6 + '@headlessui/react': + specifier: ^2.2.0 + version: 2.2.0 + '@heroicons/react': + specifier: ^2.2.0 + version: 2.2.0 + '@next/third-parties': + specifier: ^16.1.1 + version: 16.1.1 + '@phosphor-icons/react': + specifier: ^2.1.7 + version: 2.1.7 + '@pythnetwork/client': + specifier: ^2.22.1 + version: 2.22.1 + '@react-hookz/web': + specifier: ^25.1.0 + version: 25.1.0 + '@solana/wallet-adapter-base': + specifier: ^0.9.24 + version: 0.9.24 + '@solana/wallet-adapter-react': + specifier: ^0.15.36 + version: 0.15.36 + '@solana/wallet-adapter-react-ui': + specifier: ^0.9.36 + version: 0.9.36 + '@solana/wallet-adapter-wallets': + specifier: ^0.19.33 + version: 0.19.33 + '@solana/web3.js': + specifier: ^1.98.0 + version: 1.98.0 + '@storybook/addon-styling-webpack': + specifier: ^3.0.0 + version: 3.0.0 + '@storybook/addon-themes': + specifier: ^10.1.11 + version: 10.1.11 + '@storybook/nextjs': + specifier: ^10.1.11 + version: 10.1.11 + '@storybook/react': + specifier: ^10.1.11 + version: 10.1.11 + '@svgr/webpack': + specifier: ^8.1.0 + version: 8.1.0 + '@tailwindcss/forms': + specifier: ^0.5.10 + version: 0.5.10 + '@tailwindcss/postcss': + specifier: ^4.1.6 + version: 4.1.6 + '@tanstack/react-query': + specifier: ^5.71.5 + version: 5.71.5 + '@testing-library/dom': + specifier: ^10.4.1 + version: 10.4.1 + '@testing-library/react': + specifier: ^16.3.0 + version: 16.3.0 + '@testing-library/user-event': + specifier: ^14.6.1 + version: 14.6.1 + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 + '@types/mdx': + specifier: ^2.0.13 + version: 2.0.13 '@types/node': specifier: ^22.14.0 version: 22.14.0 + '@types/papaparse': + specifier: ^5.5.1 + version: 5.5.1 + '@types/prompts': + specifier: 2.4.9 + version: 2.4.9 + '@types/react': + specifier: ^19.1.4 + version: 19.2.7 + '@types/react-dom': + specifier: ^19.1.4 + version: 19.2.3 '@types/yargs': specifier: ^17.0.33 version: 17.0.33 + '@vercel/analytics': + specifier: ^1.6.1 + version: 1.6.1 + '@vercel/functions': + specifier: ^2.0.0 + version: 2.0.0 + ag-grid-community: + specifier: ^34.2.0 + version: 34.2.0 + ag-grid-react: + specifier: ^34.2.0 + version: 34.2.0 + app-root-path: + specifier: ^3.1.0 + version: 3.1.0 + async-cache-dedupe: + specifier: ^3.0.0 + version: 3.0.0 + autoprefixer: + specifier: ^10.4.21 + version: 10.4.21 + babel-plugin-react-compiler: + specifier: 19.1.0-rc.1 + version: 19.1.0-rc.1 + bcp-47: + specifier: ^2.1.0 + version: 2.1.0 + bs58: + specifier: ^6.0.0 + version: 6.0.0 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + chalk: + specifier: ^5.6.2 + version: 5.6.2 + change-case: + specifier: ^5.4.4 + version: 5.4.4 + clsx: + specifier: ^2.1.1 + version: 2.1.1 + color: + specifier: ^5.0.3 + version: 5.0.3 + connectkit: + specifier: ^1.9.0 + version: 1.9.0 + copyfiles: + specifier: ^2.4.1 + version: 2.4.1 + css-loader: + specifier: ^7.1.2 + version: 7.1.2 + csv-stringify: + specifier: ^6.6.0 + version: 6.6.0 + date-fns: + specifier: ^4.1.0 + version: 4.1.0 + dayjs: + specifier: ^1.11.19 + version: 1.11.19 + dnum: + specifier: ^2.14.0 + version: 2.14.0 + framer-motion: + specifier: ^12.6.3 + version: 12.9.2 + fs-extra: + specifier: ^11.3.2 + version: 11.3.3 + fuels: + specifier: 0.103.0 + version: 0.103.0 + fumadocs-core: + specifier: ^16.4.7 + version: 16.4.7 + fumadocs-mdx: + specifier: ^14.2.5 + version: 14.2.5 + fumadocs-openapi: + specifier: ^10.2.4 + version: 10.2.4 + fumadocs-typescript: + specifier: ^5.0.1 + version: 5.0.1 + fumadocs-ui: + specifier: ^16.4.7 + version: 16.4.7 + glob: + specifier: ^13.0.0 + version: 13.0.0 + ioredis: + specifier: ^5.7.0 + version: 5.7.0 + ip-range-check: + specifier: ^0.2.0 + version: 0.2.0 + jest: + specifier: ^29.7.0 + version: 29.7.0 + katex: + specifier: ^0.16.22 + version: 0.16.22 + lightweight-charts: + specifier: ^5.0.5 + version: 5.0.5 + match-sorter: + specifier: ^8.1.0 + version: 8.1.0 + micromustache: + specifier: ^8.0.3 + version: 8.0.3 + modern-normalize: + specifier: ^3.0.1 + version: 3.0.1 + motion: + specifier: ^12.9.2 + version: 12.9.2 + next: + specifier: ^16.1.1 + version: 16.1.1 + next-themes: + specifier: ^0.4.6 + version: 0.4.6 + nuqs: + specifier: ^2.8.8 + version: 2.8.8 + papaparse: + specifier: ^5.5.3 + version: 5.5.3 + pino: + specifier: ^9.6.0 + version: 9.6.0 + postcss: + specifier: ^8.5.3 + version: 8.5.6 + postcss-loader: + specifier: ^8.1.1 + version: 8.1.1 + prom-client: + specifier: ^15.1.3 + version: 15.1.3 + prompts: + specifier: 2.4.2 + version: 2.4.2 + proxycheck-ts: + specifier: ^0.0.11 + version: 0.0.11 + react: + specifier: ^19.1.4 + version: 19.2.1 + react-aria: + specifier: ^3.42.0 + version: 3.42.0 + react-aria-components: + specifier: ^1.11.0 + version: 1.11.0 + react-dom: + specifier: ^19.1.4 + version: 19.2.1 + react-markdown: + specifier: ^10.1.0 + version: 10.1.0 + react-timeago: + specifier: ^8.2.0 + version: 8.2.0 + recharts: + specifier: ^2.15.1 + version: 2.15.1 + sass: + specifier: ^1.86.1 + version: 1.86.1 + sass-loader: + specifier: ^16.0.5 + version: 16.0.5 + shiki: + specifier: ^3.2.1 + version: 3.21.0 + simplestyle-js: + specifier: ^6.1.2 + version: 6.1.2 + sockette: + specifier: ^2.0.6 + version: 2.0.6 + storybook: + specifier: ^10.1.11 + version: 10.1.11 + style-loader: + specifier: ^4.0.0 + version: 4.0.0 + stylelint: + specifier: ^16.17.0 + version: 16.17.0 + stylelint-config-standard-scss: + specifier: ^14.0.0 + version: 14.0.0 + superjson: + specifier: ^2.2.2 + version: 2.2.2 + swr: + specifier: ^2.3.3 + version: 2.3.3 + tailwindcss: + specifier: ^3.0.0 + version: 3.4.17 + tailwindcss-animate: + specifier: ^1.0.7 + version: 1.0.7 + tailwindcss-react-aria-components: + specifier: ^2.0.0 + version: 2.0.0 + throttleit: + specifier: ^2.1.0 + version: 2.1.0 + ts-node: + specifier: ^10.9.2 + version: 10.9.2 tsx: specifier: 4.20.6 version: 4.20.6 + turbo: + specifier: ^2.7.4 + version: 2.7.4 + type-fest: + specifier: ^5.2.0 + version: 5.4.3 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + uuid: + specifier: ^13.0.0 + version: 13.0.0 + vercel: + specifier: ^50.32.4 + version: 50.32.4 + viem: + specifier: ^2.39.0 + version: 2.42.1 + wagmi: + specifier: ^2.14.16 + version: 2.14.16 yargs: specifier: ^18.0.0 version: 18.0.0 + zod: + specifier: ^3.24.2 + version: 3.25.76 + zod-search-params: + specifier: ^0.1.6 + version: 0.1.6 + zod-validation-error: + specifier: ^3.4.0 + version: 3.4.0 overrides: '@solana/web3.js@1.77.4>rpc-websockets': 7.11.0 @@ -99,7 +477,7 @@ importers: version: 2.1.1 connectkit: specifier: 'catalog:' - version: 1.9.0(@babel/core@7.28.6)(@tanstack/react-query@5.71.5(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react-is@18.3.1)(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4)) + version: 1.9.0(@babel/core@7.28.6)(@tanstack/react-query@5.71.5(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react-is@18.3.1)(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) framer-motion: specifier: 'catalog:' version: 12.9.2(@emotion/is-prop-valid@1.3.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -126,13 +504,13 @@ importers: version: 3.21.0 viem: specifier: 'catalog:' - version: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + version: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) wagmi: specifier: 'catalog:' - version: 2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4) + version: 2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) zod: specifier: 'catalog:' - version: 3.24.4 + version: 3.25.76 devDependencies: '@axe-core/react': specifier: 'catalog:' @@ -184,7 +562,7 @@ importers: version: 4.7.0(monaco-editor@0.55.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@next/third-parties': specifier: 'catalog:' - version: 16.1.1(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1) + version: 16.1.1(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1) '@phosphor-icons/react': specifier: 'catalog:' version: 2.1.7(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -208,7 +586,7 @@ importers: version: 25.1.0(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@vercel/analytics': specifier: 'catalog:' - version: 1.6.1(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1) + version: 1.6.1(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1) buffer: specifier: 'catalog:' version: 6.0.3 @@ -217,19 +595,19 @@ importers: version: 2.1.1 fumadocs-core: specifier: 'catalog:' - version: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4) + version: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) fumadocs-mdx: specifier: 'catalog:' - version: 14.2.5(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1)(vite@6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.0)) + version: 14.2.5(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1)(vite@6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.0)) fumadocs-openapi: specifier: 'catalog:' - version: 10.2.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + version: 10.2.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) fumadocs-typescript: specifier: 'catalog:' - version: 5.0.1(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(react@19.2.1)(typescript@5.9.3) + version: 5.0.1(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(react@19.2.1)(typescript@5.9.3) fumadocs-ui: specifier: 'catalog:' - version: 16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) + version: 16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) isomorphic-ws: specifier: ^5.0.0 version: 5.0.0(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@6.0.3)) @@ -241,7 +619,7 @@ importers: version: 8.1.0 next: specifier: 'catalog:' - version: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + version: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) next-themes: specifier: 'catalog:' version: 0.4.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -277,16 +655,16 @@ importers: version: 4.20.6 viem: specifier: 'catalog:' - version: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.24.4) + version: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) ws: specifier: ^8.19.0 version: 8.19.0(bufferutil@4.0.9)(utf-8-validate@6.0.3) zod: specifier: 'catalog:' - version: 3.24.4 + version: 3.25.76 zod-validation-error: specifier: 'catalog:' - version: 3.4.0(zod@3.24.4) + version: 3.4.0(zod@3.25.76) devDependencies: '@cprussin/tsconfig': specifier: 'catalog:' @@ -362,7 +740,7 @@ importers: version: 2.1.1 next: specifier: 'catalog:' - version: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + version: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) react: specifier: 'catalog:' version: 19.2.1 @@ -377,7 +755,7 @@ importers: version: 8.2.0(react@19.2.1) zod: specifier: 'catalog:' - version: 3.24.4 + version: 3.25.76 devDependencies: '@cprussin/tsconfig': specifier: 'catalog:' @@ -441,13 +819,13 @@ importers: version: 15.1.3 viem: specifier: 'catalog:' - version: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.24.4) + version: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76) yargs: specifier: ^17.5.1 version: 17.7.2 zod: specifier: 'catalog:' - version: 3.24.4 + version: 3.25.76 devDependencies: '@cprussin/tsconfig': specifier: 'catalog:' @@ -581,7 +959,7 @@ importers: version: 12.9.2(@emotion/is-prop-valid@1.3.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) next: specifier: 'catalog:' - version: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + version: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) next-themes: specifier: 'catalog:' version: 0.4.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -617,13 +995,13 @@ importers: version: 4.20.6 zod: specifier: 'catalog:' - version: 3.24.4 + version: 3.25.76 zod-search-params: specifier: 'catalog:' - version: 0.1.6(zod@3.24.4) + version: 0.1.6(zod@3.25.76) zod-validation-error: specifier: 'catalog:' - version: 3.4.0(zod@3.24.4) + version: 3.4.0(zod@3.25.76) devDependencies: '@cprussin/tsconfig': specifier: 'catalog:' @@ -805,7 +1183,7 @@ importers: version: 15.1.3 viem: specifier: ^2.19.4 - version: 2.24.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + version: 2.24.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) yaml: specifier: ^2.1.1 version: 2.7.1 @@ -875,13 +1253,13 @@ importers: version: 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-react': specifier: 'catalog:' - version: 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) + version: 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) '@solana/wallet-adapter-react-ui': specifier: 'catalog:' - version: 0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) + version: 0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) '@solana/wallet-adapter-wallets': specifier: 'catalog:' - version: 0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.4) + version: 0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bs58@6.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.7.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) '@solana/web3.js': specifier: 'catalog:' version: 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -932,7 +1310,7 @@ importers: version: 2.3.3(react@19.2.1) zod: specifier: 'catalog:' - version: 3.24.4 + version: 3.25.76 devDependencies: '@axe-core/react': specifier: 'catalog:' @@ -1156,7 +1534,7 @@ importers: version: 0.0.22 zod: specifier: 'catalog:' - version: 3.24.4 + version: 3.25.76 devDependencies: '@cprussin/tsconfig': specifier: 'catalog:' @@ -1417,10 +1795,10 @@ importers: version: 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) '@solana/wallet-adapter-react-ui': specifier: 'catalog:' - version: 0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) + version: 0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) '@solana/wallet-adapter-wallets': specifier: 'catalog:' - version: 0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2) + version: 0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(bs58@6.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.7.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2) '@solana/web3.js': specifier: ^1.73.0 version: 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -1523,6 +1901,31 @@ importers: specifier: 'catalog:' version: 18.0.0 + lazer/contracts/stellar/scripts/e2e: + dependencies: + '@pythnetwork/pyth-lazer-sdk': + specifier: ^5.2.0 + version: 5.2.1(bufferutil@4.0.9)(utf-8-validate@6.0.3) + '@stellar/stellar-sdk': + specifier: ^13.0.0 + version: 13.3.0 + devDependencies: + '@cprussin/tsconfig': + specifier: 'catalog:' + version: 4.0.2(typescript@5.9.3) + '@types/node': + specifier: 'catalog:' + version: 22.14.0 + '@types/yargs': + specifier: 'catalog:' + version: 17.0.33 + tsx: + specifier: 'catalog:' + version: 4.20.6 + yargs: + specifier: 'catalog:' + version: 18.0.0 + lazer/contracts/sui/sdk/js: dependencies: '@mysten/sui': @@ -1640,7 +2043,7 @@ importers: version: 7.28.6 '@babel/preset-typescript': specifier: 'catalog:' - version: 7.27.1(@babel/core@7.28.6) + version: 7.28.5(@babel/core@7.28.6) '@cprussin/tsconfig': specifier: 'catalog:' version: 4.0.2(typescript@5.9.3) @@ -1767,7 +2170,7 @@ importers: version: 2.4.9 type-fest: specifier: 'catalog:' - version: 5.4.0 + version: 5.4.3 packages/jest-config: dependencies: @@ -3007,10 +3410,6 @@ packages: resolution: {integrity: sha512-vSH118/wwM/pLR38g/Sgk05sNtro6TlTJKuiMXDaZqPUfjTFcudpCOt00IhOfj+1BFAX+UFAlzCU+6WXr3GLFQ==} engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.27.1': - resolution: {integrity: sha512-WnuuDILl9oOBbKnb4L+DyODx7iC47XfzmNCpTttFsSp6hTG7XZxu60+4IO+2/hPfcGOoKbFiwoI/+zwARbNQow==} - engines: {node: '>=6.9.0'} - '@babel/helper-annotate-as-pure@7.27.3': resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} engines: {node: '>=6.9.0'} @@ -3065,10 +3464,6 @@ packages: resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.27.1': - resolution: {integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==} - engines: {node: '>=6.9.0'} - '@babel/helper-module-imports@7.28.6': resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} engines: {node: '>=6.9.0'} @@ -3093,10 +3488,6 @@ packages: resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.27.1': - resolution: {integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==} - engines: {node: '>=6.9.0'} - '@babel/helper-plugin-utils@7.28.6': resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} engines: {node: '>=6.9.0'} @@ -4016,12 +4407,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.27.1': - resolution: {integrity: sha512-Q5sT5+O4QUebHdbwKedFBEwRLb02zJ7r4A5Gg2hUoLuU3FjdMcyqcywqUrLCaDsFCxzokf7u9kuy7qz51YUuAg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/plugin-transform-typescript@7.28.6': resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} engines: {node: '>=6.9.0'} @@ -4111,12 +4496,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.27.1': - resolution: {integrity: sha512-l7WfQfX0WK4M0v2RudjuQK4u99BS6yLHYEmdtVPP7lKV013zr9DygFuWNlnbvQ9LR+LS0Egz/XAvGx5U9MX0fQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.28.5': resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} engines: {node: '>=6.9.0'} @@ -4169,10 +4548,6 @@ packages: resolution: {integrity: sha512-+EzkxvLNfiUeKMgy/3luqfsCWFRXLb7U6wNQTk60tovuckwB15B191tJWvpp4HjiQWdJkCxO3Wbvc6jlk3Xb2Q==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.4': - resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} - engines: {node: '>=6.9.0'} - '@babel/types@7.28.6': resolution: {integrity: sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==} engines: {node: '>=6.9.0'} @@ -5584,24 +5959,12 @@ packages: '@fivebinaries/coin-selection@3.0.0': resolution: {integrity: sha512-h25Pn1ZA7oqQBQDodGAgIsQt66T2wDge9onBKNqE66WNWL0KJiKJbpij8YOLo5AAlEIg5IS7EB1QjBgDOIg6DQ==} - '@floating-ui/core@1.6.9': - resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} - '@floating-ui/core@1.7.3': resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==} - '@floating-ui/dom@1.6.13': - resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} - '@floating-ui/dom@1.7.4': resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==} - '@floating-ui/react-dom@2.1.2': - resolution: {integrity: sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - '@floating-ui/react-dom@2.1.6': resolution: {integrity: sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==} peerDependencies: @@ -5623,9 +5986,6 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} - '@floating-ui/utils@0.2.9': - resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} - '@formatjs/ecma402-abstract@2.3.4': resolution: {integrity: sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==} @@ -10583,6 +10943,17 @@ packages: '@starknet-io/types-js@0.7.10': resolution: {integrity: sha512-1VtCqX4AHWJlRRSYGSn+4X1mqolI1Tdq62IwzoU2vUuEE72S1OlEeGhpvd6XsdqXcfHmVzYfj8k1XtKBQqwo9w==} + '@stellar/js-xdr@3.1.2': + resolution: {integrity: sha512-VVolPL5goVEIsvuGqDc5uiKxV03lzfWdvYg1KikvwheDmTBO68CKDji3bAZ/kppZrx5iTA8z3Ld5yuytcvhvOQ==} + + '@stellar/stellar-base@13.1.0': + resolution: {integrity: sha512-90EArG+eCCEzDGj3OJNoCtwpWDwxjv+rs/RNPhvg4bulpjN/CSRj+Ys/SalRcfM4/WRC5/qAfjzmJBAuquWhkA==} + engines: {node: '>=18.0.0'} + + '@stellar/stellar-sdk@13.3.0': + resolution: {integrity: sha512-8+GHcZLp+mdin8gSjcgfb/Lb6sSMYRX6Nf/0LcSJxvjLQR0XHpjGzOiRbYb2jSXo51EnA6kAV5j+4Pzh5OUKUg==} + engines: {node: '>=18.0.0'} + '@storybook/addon-styling-webpack@3.0.0': resolution: {integrity: sha512-6iI7wGf/tEt5awB8NYAWU+I/hI7PwOdoaNb5V8Z+GkhEko4nZFpXfp8jz2nMblAnx9Jsl95LfIaH9Spa0JksuQ==} peerDependencies: @@ -12125,7 +12496,6 @@ packages: '@walletconnect/modal@2.7.0': resolution: {integrity: sha512-RQVt58oJ+rwqnPcIvRFeMGKuXb9qkgSmwz4noF8JZGUym3gUAzVs+uW2NQ1Owm9XOJAV+sANrtJ+VoVq1ftElw==} - deprecated: Please follow the migration guide on https://docs.reown.com/appkit/upgrade/wcm '@walletconnect/qrcode-modal@1.8.0': resolution: {integrity: sha512-BueaFefaAi8mawE45eUtztg3ZFbsAH4DDXh1UNwdUlsvFMjqcYzLUG0xZvDd6z2eOpbgDg2N3bl6gF0KONj1dg==} @@ -12372,11 +12742,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - acorn@8.15.0: - resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} - engines: {node: '>=0.4.0'} - hasBin: true - acorn@8.16.0: resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} engines: {node: '>=0.4.0'} @@ -12803,11 +13168,6 @@ packages: resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - babel-plugin-polyfill-corejs2@0.4.13: - resolution: {integrity: sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-corejs2@0.4.14: resolution: {integrity: sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==} peerDependencies: @@ -12828,11 +13188,6 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.4: - resolution: {integrity: sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==} - peerDependencies: - '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 - babel-plugin-polyfill-regenerator@0.6.5: resolution: {integrity: sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==} peerDependencies: @@ -12881,6 +13236,25 @@ packages: balanced-match@2.0.0: resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} + bare-addon-resolve@1.10.0: + resolution: {integrity: sha512-sSd0jieRJlDaODOzj0oe0RjFVC1QI0ZIjGIdPkbrTXsdVVtENg14c+lHHAhHwmWCZ2nQlMhy8jA3Y5LYPc/isA==} + peerDependencies: + bare-url: '*' + peerDependenciesMeta: + bare-url: + optional: true + + bare-module-resolve@1.12.1: + resolution: {integrity: sha512-hbmAPyFpEq8FoZMd5sFO3u6MC5feluWoGE8YKlA8fCrl6mNtx68Wjg4DTiDJcqRJaovTvOYKfYngoBUnbaT7eg==} + peerDependencies: + bare-url: '*' + peerDependenciesMeta: + bare-url: + optional: true + + bare-semver@1.0.3: + resolution: {integrity: sha512-HS/A30bi2+PiRJfU6R4+Kp+6KeLSCSByjYM2iiobOKzLAvtu1CT+S8xWfiU7wz0erknjkUoC+yXy108tzIuP5Q==} + base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} @@ -12898,6 +13272,10 @@ packages: base-x@5.0.1: resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + base32.js@0.1.0: + resolution: {integrity: sha512-n3TkB02ixgBOhTvANakDb4xaMXnYUVkNoRFJjQflcqMQhyEKxEHdj3E6N8t8sUQ0mjH/3/JxzlXuz3ul/J90pQ==} + engines: {node: '>=0.12.0'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -12912,6 +13290,7 @@ packages: basic-ftp@5.2.0: resolution: {integrity: sha512-VoMINM2rqJwJgfdHq6RiUudKt2BV+FY5ZFezP/ypmwayk68+NzzAQy4XXLlqsGD4MCzq3DrmNFD/uUmBJuGoXw==} engines: {node: '>=10.0.0'} + deprecated: Security vulnerability fixed in 5.2.1, please upgrade bchaddrjs@0.5.2: resolution: {integrity: sha512-OO7gIn3m7ea4FVx4cT8gdlWQR2+++EquhdpWQJH9BQjK63tJJ6ngB3QMZDO6DiBoXiIGUsTPHjlrHVxPGcGxLQ==} @@ -12950,6 +13329,9 @@ packages: bignumber.js@9.1.2: resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -13090,11 +13472,6 @@ packages: browserify-zlib@0.2.0: resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} - browserslist@4.24.4: - resolution: {integrity: sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - browserslist@4.28.1: resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -13281,9 +13658,6 @@ packages: camelize@1.0.1: resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} - caniuse-lite@1.0.30001707: - resolution: {integrity: sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==} - caniuse-lite@1.0.30001765: resolution: {integrity: sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==} @@ -13921,9 +14295,6 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - crossws@0.3.4: - resolution: {integrity: sha512-uj0O1ETYX1Bh6uSgktfPvwDiPYGQ3aI4qVsaC/LWpkIzGj1nUYm5FK3K+t11oOlpN01lGbprFCH4wBlKdJjVgw==} - crossws@0.3.5: resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} @@ -14323,9 +14694,6 @@ packages: des.js@1.1.0: resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} - destr@2.0.3: - resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} - destr@2.0.5: resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} @@ -14568,9 +14936,6 @@ packages: engines: {node: '>=0.10.0'} hasBin: true - electron-to-chromium@1.5.129: - resolution: {integrity: sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==} - electron-to-chromium@1.5.267: resolution: {integrity: sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==} @@ -14683,9 +15048,6 @@ packages: es-module-lexer@1.4.1: resolution: {integrity: sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==} - es-module-lexer@1.6.0: - resolution: {integrity: sha512-qqnD1yMU6tk/jnaMosogGySTZP8YtUgAffA9nMN+E/rjxcfRQ6IEk7IiozUjgxKoFHBGjTLnrHB/YC45r/59EQ==} - es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} @@ -15351,6 +15713,9 @@ packages: picomatch: optional: true + feaxios@0.0.23: + resolution: {integrity: sha512-eghR0A21fvbkcQBgZuMfQhrXxJzC0GNUGC9fXhBge33D+mFDTwl0aJ35zoQQn575BhyjQitRc5N4f+L4cP708g==} + fetch-cookie@3.0.1: resolution: {integrity: sha512-ZGXe8Y5Z/1FWqQ9q/CrJhkUD73DyBU9VF0hBQmEO/wPHe4A9PKTjplFDLeFX8aOsYypZUcX5Ji/eByn3VCVO3Q==} @@ -15889,20 +16254,20 @@ packages: glob@7.1.6: resolution: {integrity: sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.2.0: resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me glob@8.1.0: resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} engines: {node: '>=12'} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me global-modules@2.0.0: resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} @@ -16010,9 +16375,6 @@ packages: resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} engines: {node: '>=10'} - h3@1.15.1: - resolution: {integrity: sha512-+ORaOBttdUm1E2Uu/obAyCguiI7MbBvsLTndc3gyK3zU+SYLoZXlyCP9Xgy0gikkGufFLTZXCXD6+4BsufnmHA==} - h3@1.15.5: resolution: {integrity: sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg==} @@ -16618,6 +16980,10 @@ packages: resolution: {integrity: sha512-XVm7LOeLpTW4jV19QSH38vkswxoLud8sQ57YwJVTPWdiaI9I8keEhGFpBlslyVsgdQy4Opg8QOLb8YRgsyZiQg==} engines: {node: '>=10'} + is-retry-allowed@3.0.0: + resolution: {integrity: sha512-9xH0xvoggby+u0uGF7cZXdrutWiBiaFG8ZT4YFPXL8NzkyAwX3AKGLeFQLvzDpM430+nDFBZ1LHkie/8ocL06A==} + engines: {node: '>=12'} + is-root@2.1.0: resolution: {integrity: sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg==} engines: {node: '>=6'} @@ -16937,10 +17303,6 @@ packages: resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==} hasBin: true - jiti@2.4.2: - resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==} - hasBin: true - jiti@2.6.1: resolution: {integrity: sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==} hasBin: true @@ -17508,9 +17870,6 @@ packages: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true - magic-string@0.30.19: - resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} - magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} @@ -17989,10 +18348,6 @@ packages: resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} engines: {node: '>= 8'} - minizlib@3.0.2: - resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} - engines: {node: '>= 18'} - minizlib@3.1.0: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} @@ -18342,9 +18697,6 @@ packages: engines: {node: '>=14.18'} hasBin: true - node-fetch-native@1.6.6: - resolution: {integrity: sha512-8Mc2HhqPdlIfedsuZoc3yioPuzp6b+L5jRCRY1QzuWZh2EGJVQrGppC6V6cF0bLdbW0+O2YpqCA25aF/1lvipQ==} - node-fetch-native@1.6.7: resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} @@ -18399,9 +18751,6 @@ packages: node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} - node-mock-http@1.0.0: - resolution: {integrity: sha512-0uGYQ1WQL1M5kKvGRXWQ3uZCHtLTO8hln3oBjIusM75WoesZ909uQJs/Hb946i2SS+Gsrhkaa6iAO17jRIv6DQ==} - node-mock-http@1.0.4: resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} @@ -18411,9 +18760,6 @@ packages: peerDependencies: webpack: '>=5' - node-releases@2.0.19: - resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - node-releases@2.0.27: resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} @@ -18552,9 +18898,6 @@ packages: oboe@2.1.5: resolution: {integrity: sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==} - ofetch@1.4.1: - resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} - ofetch@1.5.1: resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} @@ -19872,6 +20215,10 @@ packages: requestidlecallback@0.3.0: resolution: {integrity: sha512-TWHFkT7S9p7IxLC5A1hYmAYQx2Eb9w1skrXmQ+dS1URyvR8tenMLl4lHbqEOUnpEYxNKpkVMXUgknVpBZWXXfQ==} + require-addon@1.2.0: + resolution: {integrity: sha512-VNPDZlYgIYQwWp9jMTzljx+k0ZtatKlcvOhktZ/anNPI3dQ9NXk7cq2U4iJ1wd9IrytRnYhyEocFWbkdPb+MYA==} + engines: {bare: '>=1.10.0'} + require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -20438,6 +20785,9 @@ packages: resolution: {integrity: sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==} engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + sodium-native@4.3.3: + resolution: {integrity: sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw==} + solc@0.8.26: resolution: {integrity: sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==} engines: {node: '>=10.0.0'} @@ -20480,10 +20830,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - source-map@0.7.4: - resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} - engines: {node: '>= 8'} - source-map@0.7.6: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} @@ -20879,9 +21225,6 @@ packages: symbol.inspect@1.0.1: resolution: {integrity: sha512-YQSL4duoHmLhsTD1Pw8RW6TZ5MaTX5rXJnqacJottr2P2LZBF/Yvrc3ku4NUpMOm8aM0KOCqM+UAkMA5HWQCzQ==} - tabbable@6.2.0: - resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} - tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} @@ -20953,15 +21296,12 @@ packages: tar@4.4.19: resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==} engines: {node: '>=4.5'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me tar@6.2.1: resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} engines: {node: '>=10'} - - tar@7.4.3: - resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} - engines: {node: '>=18'} - deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exhorbitant rates) by contacting i@izs.me + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me tar@7.5.7: resolution: {integrity: sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==} @@ -21443,10 +21783,6 @@ packages: resolution: {integrity: sha512-w2IGJU1tIgcrepg9ZJ82d8UmItNQtOFJG0HCUE3SzMokKkTsruVDALl2fAdiEzJlfduoU+VyXJWIIUZ+6jV+nw==} engines: {node: '>=16'} - type-fest@5.4.0: - resolution: {integrity: sha512-wfkA6r0tBpVfGiyO+zbf9e10QkRQSlK9F2UvyfnjoCmrvH2bjHyhPzhugSBOuq1dog3P0+FKckqe+Xf6WKVjwg==} - engines: {node: '>=20'} - type-fest@5.4.3: resolution: {integrity: sha512-AXSAQJu79WGc79/3e9/CR77I/KQgeY1AhNvcShIH4PTcGYyC4xv6H4R4AUOwkPS5799KlVDAu8zExeCrkGquiA==} engines: {node: '>=20'} @@ -21508,9 +21844,6 @@ packages: resolution: {integrity: sha512-z6PJ8Lml+v3ichVojCiB8toQJBuwR42ySM4ezjXIqXK3M0HczmKQ3LF4rhU55PfD99KEEXQG6yb7iOMyvYuHew==} hasBin: true - ufo@1.5.4: - resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - ufo@1.6.3: resolution: {integrity: sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==} @@ -21659,65 +21992,6 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unstorage@1.15.0: - resolution: {integrity: sha512-m40eHdGY/gA6xAPqo8eaxqXgBuzQTlAKfmB1iF7oCKXE1HfwHwzDJBywK+qQGn52dta+bPlZluPF7++yR3p/bg==} - peerDependencies: - '@azure/app-configuration': ^1.8.0 - '@azure/cosmos': ^4.2.0 - '@azure/data-tables': ^13.3.0 - '@azure/identity': ^4.6.0 - '@azure/keyvault-secrets': ^4.9.0 - '@azure/storage-blob': ^12.26.0 - '@capacitor/preferences': ^6.0.3 - '@deno/kv': '>=0.9.0' - '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 - '@planetscale/database': ^1.19.0 - '@upstash/redis': ^1.34.3 - '@vercel/blob': '>=0.27.1' - '@vercel/kv': ^1.0.1 - aws4fetch: ^1.0.20 - db0: '>=0.2.1' - idb-keyval: ^6.2.1 - ioredis: ^5.4.2 - uploadthing: ^7.4.4 - peerDependenciesMeta: - '@azure/app-configuration': - optional: true - '@azure/cosmos': - optional: true - '@azure/data-tables': - optional: true - '@azure/identity': - optional: true - '@azure/keyvault-secrets': - optional: true - '@azure/storage-blob': - optional: true - '@capacitor/preferences': - optional: true - '@deno/kv': - optional: true - '@netlify/blobs': - optional: true - '@planetscale/database': - optional: true - '@upstash/redis': - optional: true - '@vercel/blob': - optional: true - '@vercel/kv': - optional: true - aws4fetch: - optional: true - db0: - optional: true - idb-keyval: - optional: true - ioredis: - optional: true - uploadthing: - optional: true - unstorage@1.17.4: resolution: {integrity: sha512-fHK0yNg38tBiJKp/Vgsq4j0JEsCmgqH58HAn707S7zGkArbZsVr/CwINoi+nh3h98BRCwKvx1K3Xg9u3VV83sw==} peerDependencies: @@ -21787,12 +22061,6 @@ packages: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} - update-browserslist-db@1.1.3: - resolution: {integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - update-browserslist-db@1.2.3: resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} hasBin: true @@ -21865,11 +22133,6 @@ packages: peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - use-sync-external-store@1.5.0: - resolution: {integrity: sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==} - peerDependencies: - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: @@ -22929,9 +23192,6 @@ packages: zod@3.24.2: resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} - zod@3.24.4: - resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} - zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -23162,7 +23422,7 @@ snapshots: '@astrojs/telemetry@3.3.0': dependencies: ci-info: 4.3.1 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) dlv: 1.1.3 dset: 3.1.4 is-docker: 3.0.0 @@ -23595,7 +23855,7 @@ snapshots: '@babel/traverse': 7.27.0 '@babel/types': 7.27.0 convert-source-map: 2.0.0 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.0 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -23604,18 +23864,18 @@ snapshots: '@babel/core@7.28.6': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/generator': 7.28.6 + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) '@babel/helpers': 7.28.6 - '@babel/parser': 7.28.6 + '@babel/parser': 7.29.0 '@babel/template': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -23632,8 +23892,8 @@ snapshots: '@babel/generator@7.28.6': dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 @@ -23646,10 +23906,6 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 - '@babel/helper-annotate-as-pure@7.27.1': - dependencies: - '@babel/types': 7.28.6 - '@babel/helper-annotate-as-pure@7.27.3': dependencies: '@babel/types': 7.28.6 @@ -23658,7 +23914,7 @@ snapshots: dependencies: '@babel/compat-data': 7.26.8 '@babel/helper-validator-option': 7.25.9 - browserslist: 4.24.4 + browserslist: 4.28.1 lru-cache: 5.1.1 semver: 6.3.1 @@ -23678,20 +23934,7 @@ snapshots: '@babel/helper-optimise-call-expression': 7.27.1 '@babel/helper-replace-supers': 7.27.1(@babel/core@7.26.10) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - '@babel/helper-create-class-features-plugin@7.27.1(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.6) - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -23704,7 +23947,7 @@ snapshots: '@babel/helper-optimise-call-expression': 7.27.1 '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.6) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -23742,7 +23985,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -23753,7 +23996,7 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -23764,7 +24007,7 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.11 transitivePeerDependencies: @@ -23774,15 +24017,15 @@ snapshots: '@babel/helper-member-expression-to-functions@7.28.5': dependencies: - '@babel/traverse': 7.28.6(supports-color@5.5.0) - '@babel/types': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color - '@babel/helper-module-imports@7.27.1': + '@babel/helper-module-imports@7.28.6': dependencies: - '@babel/traverse': 7.28.6(supports-color@5.5.0) - '@babel/types': 7.28.4 + '@babel/traverse': 7.28.6 + '@babel/types': 7.28.6 transitivePeerDependencies: - supports-color @@ -23796,38 +24039,36 @@ snapshots: '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) + '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color '@babel/helper-module-transforms@7.28.6(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) + '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color '@babel/helper-module-transforms@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) + '@babel/helper-module-imports': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@babel/helper-plugin-utils@7.26.5': {} - '@babel/helper-plugin-utils@7.27.1': {} - '@babel/helper-plugin-utils@7.28.6': {} '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.26.10)': @@ -23835,16 +24076,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@babel/helper-remap-async-to-generator@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-wrap-function': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color @@ -23853,7 +24085,7 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -23862,16 +24094,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@babel/helper-replace-supers@7.27.1(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-member-expression-to-functions': 7.28.5 - '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color @@ -23880,13 +24103,13 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-member-expression-to-functions': 7.28.5 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 '@babel/types': 7.28.6 transitivePeerDependencies: - supports-color @@ -23904,8 +24127,8 @@ snapshots: '@babel/helper-wrap-function@7.28.6': dependencies: '@babel/template': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - '@babel/types': 7.28.6 + '@babel/traverse': 7.28.6 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color @@ -23917,7 +24140,7 @@ snapshots: '@babel/helpers@7.28.6': dependencies: '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@babel/parser@7.27.0': dependencies: @@ -23925,7 +24148,7 @@ snapshots: '@babel/parser@7.28.6': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@babel/parser@7.29.0': dependencies: @@ -23935,15 +24158,7 @@ snapshots: dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color @@ -23951,7 +24166,7 @@ snapshots: dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -23960,11 +24175,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -23975,11 +24185,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -23994,15 +24199,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.28.6) - transitivePeerDependencies: - - supports-color - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24016,15 +24212,7 @@ snapshots: dependencies: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color @@ -24032,7 +24220,7 @@ snapshots: dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -24057,7 +24245,7 @@ snapshots: '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.28.6)': dependencies: @@ -24072,7 +24260,7 @@ snapshots: '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-export-default-from@7.25.9(@babel/core@7.28.6)': dependencies: @@ -24089,11 +24277,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-assertions@7.26.0(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24104,11 +24287,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.26.0(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24132,12 +24310,12 @@ snapshots: '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.28.6)': dependencies: @@ -24211,11 +24389,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24226,16 +24399,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.10) - '@babel/traverse': 7.28.6(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-async-generator-functions@7.26.8(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.28.6) - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color @@ -24251,25 +24415,16 @@ snapshots: '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) + '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.26.10) transitivePeerDependencies: - supports-color - '@babel/plugin-transform-async-to-generator@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-remap-async-to-generator': 7.25.9(@babel/core@7.28.6) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) + '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.28.6) transitivePeerDependencies: @@ -24280,11 +24435,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoped-functions@7.26.5(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24295,11 +24445,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoping@7.27.0(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24313,14 +24458,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-properties@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24337,14 +24474,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-class-static-block@7.26.0(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24360,19 +24489,7 @@ snapshots: '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-replace-supers': 7.27.1(@babel/core@7.26.10) - '@babel/traverse': 7.28.6(supports-color@5.5.0) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-classes@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.6) - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -24385,7 +24502,7 @@ snapshots: '@babel/helper-globals': 7.28.0 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.6) - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -24395,12 +24512,6 @@ snapshots: '@babel/helper-plugin-utils': 7.28.6 '@babel/template': 7.28.6 - '@babel/plugin-transform-computed-properties@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/template': 7.28.6 - '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24412,16 +24523,11 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -24431,12 +24537,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dotall-regex@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24448,11 +24548,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24464,12 +24559,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24481,11 +24570,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24504,11 +24588,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-exponentiation-operator@7.26.3(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24519,11 +24598,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24543,14 +24617,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-for-of@7.26.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24564,16 +24630,7 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-function-name@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color @@ -24582,7 +24639,7 @@ snapshots: '@babel/core': 7.28.6 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -24591,11 +24648,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-json-strings@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24606,11 +24658,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24621,11 +24668,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24636,11 +24678,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24654,14 +24691,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-amd@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24686,14 +24715,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-commonjs@7.27.1(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24708,17 +24729,7 @@ snapshots: '@babel/helper-module-transforms': 7.28.6(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - '@babel/plugin-transform-modules-systemjs@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.28.6 transitivePeerDependencies: - supports-color @@ -24740,14 +24751,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-modules-umd@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-module-transforms': 7.28.6(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24762,12 +24765,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-named-capturing-groups-regex@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24779,11 +24776,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24794,11 +24786,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.26.6(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24809,11 +24796,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24826,13 +24808,6 @@ snapshots: '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.10) - '@babel/plugin-transform-object-rest-spread@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24840,7 +24815,7 @@ snapshots: '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.28.6) '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.28.6) - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 transitivePeerDependencies: - supports-color @@ -24852,19 +24827,11 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-object-super@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.6) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-replace-supers': 7.27.1(@babel/core@7.28.6) + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.28.6) transitivePeerDependencies: - supports-color @@ -24873,11 +24840,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-catch-binding@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24891,14 +24853,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-optional-chaining@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24912,11 +24866,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-parameters@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24930,14 +24879,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-methods@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24955,15 +24896,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-private-property-in-object@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24978,11 +24910,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-property-literals@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -24991,22 +24918,22 @@ snapshots: '@babel/plugin-transform-react-constant-elements@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-react-constant-elements@7.25.9(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-react-display-name@7.25.9(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-react-jsx-development@7.25.9(@babel/core@7.26.10)': dependencies: @@ -25035,36 +24962,36 @@ snapshots: '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.27.1 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.26.10) - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/plugin-transform-react-jsx@7.25.9(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.1 - '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.6) - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 transitivePeerDependencies: - supports-color '@babel/plugin-transform-react-pure-annotations@7.25.9(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-annotate-as-pure': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-react-pure-annotations@7.25.9(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.28.6 '@babel/plugin-transform-regenerator@7.27.0(@babel/core@7.26.10)': dependencies: @@ -25072,12 +24999,6 @@ snapshots: '@babel/helper-plugin-utils': 7.28.6 regenerator-transform: 0.15.2 - '@babel/plugin-transform-regenerator@7.27.0(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - regenerator-transform: 0.15.2 - '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25089,12 +25010,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.26.0(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25106,11 +25021,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25119,11 +25029,11 @@ snapshots: '@babel/plugin-transform-runtime@7.26.10(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-module-imports': 7.27.1 - '@babel/helper-plugin-utils': 7.27.1 - babel-plugin-polyfill-corejs2: 0.4.13(@babel/core@7.28.6) + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + babel-plugin-polyfill-corejs2: 0.4.15(@babel/core@7.28.6) babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.28.6) - babel-plugin-polyfill-regenerator: 0.6.4(@babel/core@7.28.6) + babel-plugin-polyfill-regenerator: 0.6.6(@babel/core@7.28.6) semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -25133,11 +25043,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-shorthand-properties@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25151,14 +25056,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-spread@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-spread@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25172,11 +25069,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-sticky-regex@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25187,11 +25079,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-template-literals@7.26.8(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25202,11 +25089,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typeof-symbol@7.27.0(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25223,17 +25105,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/plugin-transform-typescript@7.27.1(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-annotate-as-pure': 7.27.3 - '@babel/helper-create-class-features-plugin': 7.27.1(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.6) - transitivePeerDependencies: - - supports-color - '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25250,11 +25121,6 @@ snapshots: '@babel/core': 7.26.10 '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-escapes@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25266,12 +25132,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-property-regex@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25284,12 +25144,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25302,12 +25156,6 @@ snapshots: '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.26.10) '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-sets-regex@7.25.9(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.28.6) - '@babel/helper-plugin-utils': 7.28.6 - '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 @@ -25389,81 +25237,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-env@7.26.9(@babel/core@7.28.6)': - dependencies: - '@babel/compat-data': 7.28.6 - '@babel/core': 7.28.6 - '@babel/helper-compilation-targets': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.28.6) - '@babel/plugin-syntax-import-assertions': 7.26.0(@babel/core@7.28.6) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.28.6) - '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.28.6) - '@babel/plugin-transform-arrow-functions': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-async-generator-functions': 7.26.8(@babel/core@7.28.6) - '@babel/plugin-transform-async-to-generator': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-block-scoped-functions': 7.26.5(@babel/core@7.28.6) - '@babel/plugin-transform-block-scoping': 7.27.0(@babel/core@7.28.6) - '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-class-static-block': 7.26.0(@babel/core@7.28.6) - '@babel/plugin-transform-classes': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-computed-properties': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-destructuring': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-dotall-regex': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-duplicate-keys': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-dynamic-import': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-exponentiation-operator': 7.26.3(@babel/core@7.28.6) - '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-for-of': 7.26.9(@babel/core@7.28.6) - '@babel/plugin-transform-function-name': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-json-strings': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-literals': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-logical-assignment-operators': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-member-expression-literals': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-modules-amd': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-modules-systemjs': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-modules-umd': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-named-capturing-groups-regex': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-new-target': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-nullish-coalescing-operator': 7.26.6(@babel/core@7.28.6) - '@babel/plugin-transform-numeric-separator': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-object-super': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-optional-catch-binding': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-optional-chaining': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-private-methods': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-private-property-in-object': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-property-literals': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-regenerator': 7.27.0(@babel/core@7.28.6) - '@babel/plugin-transform-regexp-modifiers': 7.26.0(@babel/core@7.28.6) - '@babel/plugin-transform-reserved-words': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-shorthand-properties': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-spread': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-sticky-regex': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-template-literals': 7.26.8(@babel/core@7.28.6) - '@babel/plugin-transform-typeof-symbol': 7.27.0(@babel/core@7.28.6) - '@babel/plugin-transform-unicode-escapes': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-unicode-property-regex': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-unicode-regex': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-unicode-sets-regex': 7.25.9(@babel/core@7.28.6) - '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.28.6) - babel-plugin-polyfill-corejs2: 0.4.14(@babel/core@7.28.6) - babel-plugin-polyfill-corejs3: 0.11.1(@babel/core@7.28.6) - babel-plugin-polyfill-regenerator: 0.6.5(@babel/core@7.28.6) - core-js-compat: 3.47.0 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - '@babel/preset-env@7.29.0(@babel/core@7.28.6)': dependencies: '@babel/compat-data': 7.29.0 @@ -25564,7 +25337,7 @@ snapshots: '@babel/preset-react@7.26.3(@babel/core@7.26.10)': dependencies: '@babel/core': 7.26.10 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.10) '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.10) @@ -25576,7 +25349,7 @@ snapshots: '@babel/preset-react@7.26.3(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.27.1 + '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.28.6) '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.28.6) @@ -25596,24 +25369,13 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-typescript@7.27.1(@babel/core@7.28.6)': - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-plugin-utils': 7.28.6 - '@babel/helper-validator-option': 7.27.1 - '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-typescript': 7.27.1(@babel/core@7.28.6) - transitivePeerDependencies: - - supports-color - '@babel/preset-typescript@7.28.5(@babel/core@7.28.6)': dependencies: '@babel/core': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/helper-validator-option': 7.27.1 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.6) - '@babel/plugin-transform-modules-commonjs': 7.27.1(@babel/core@7.28.6) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.28.6) '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.28.6) transitivePeerDependencies: - supports-color @@ -25657,11 +25419,23 @@ snapshots: '@babel/parser': 7.28.6 '@babel/template': 7.28.6 '@babel/types': 7.28.6 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) globals: 11.12.0 transitivePeerDependencies: - supports-color + '@babel/traverse@7.28.6': + dependencies: + '@babel/code-frame': 7.28.6 + '@babel/generator': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.28.6 + '@babel/template': 7.28.6 + '@babel/types': 7.28.6 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + '@babel/traverse@7.28.6(supports-color@5.5.0)': dependencies: '@babel/code-frame': 7.28.6 @@ -25675,6 +25449,18 @@ snapshots: - supports-color '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.0 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.0 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3(supports-color@8.1.1) + transitivePeerDependencies: + - supports-color + + '@babel/traverse@7.29.0(supports-color@5.5.0)': dependencies: '@babel/code-frame': 7.29.0 '@babel/generator': 7.29.0 @@ -25696,11 +25482,6 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.28.5 - '@babel/types@7.28.4': - dependencies: - '@babel/helper-string-parser': 7.27.1 - '@babel/helper-validator-identifier': 7.28.5 - '@babel/types@7.28.6': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -27071,7 +26852,7 @@ snapshots: '@eslint/config-array@0.19.2': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -27089,7 +26870,7 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) espree: 10.3.0 globals: 14.0.0 ignore: 5.3.2 @@ -27822,30 +27603,15 @@ snapshots: '@emurgo/cardano-serialization-lib-browser': 13.2.1 '@emurgo/cardano-serialization-lib-nodejs': 13.2.0 - '@floating-ui/core@1.6.9': - dependencies: - '@floating-ui/utils': 0.2.9 - '@floating-ui/core@1.7.3': dependencies: '@floating-ui/utils': 0.2.10 - '@floating-ui/dom@1.6.13': - dependencies: - '@floating-ui/core': 1.6.9 - '@floating-ui/utils': 0.2.9 - '@floating-ui/dom@1.7.4': dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/utils': 0.2.10 - '@floating-ui/react-dom@2.1.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': - dependencies: - '@floating-ui/dom': 1.6.13 - react: 19.2.1 - react-dom: 19.2.1(react@19.2.1) - '@floating-ui/react-dom@2.1.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: '@floating-ui/dom': 1.7.4 @@ -27854,24 +27620,22 @@ snapshots: '@floating-ui/react@0.26.28(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) - '@floating-ui/utils': 0.2.9 + '@floating-ui/react-dom': 2.1.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@floating-ui/utils': 0.2.10 react: 19.2.1 react-dom: 19.2.1(react@19.2.1) - tabbable: 6.2.0 + tabbable: 6.4.0 '@floating-ui/react@0.27.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) - '@floating-ui/utils': 0.2.9 + '@floating-ui/react-dom': 2.1.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@floating-ui/utils': 0.2.10 react: 19.2.1 react-dom: 19.2.1(react@19.2.1) - tabbable: 6.2.0 + tabbable: 6.4.0 '@floating-ui/utils@0.2.10': {} - '@floating-ui/utils@0.2.9': {} - '@formatjs/ecma402-abstract@2.3.4': dependencies: '@formatjs/fast-memoize': 2.2.7 @@ -28416,9 +28180,9 @@ snapshots: '@fuels/vm-asm@0.62.0': {} - '@fumadocs/ui@16.4.7(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6)': + '@fumadocs/ui@16.4.7(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6)': dependencies: - fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4) + fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) next-themes: 0.4.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) postcss-selector-parser: 7.1.1 react: 19.2.1 @@ -28426,7 +28190,7 @@ snapshots: tailwind-merge: 3.4.0 optionalDependencies: '@types/react': 19.2.7 - next: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + next: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) tailwindcss: 4.1.6 '@fumari/json-schema-to-typescript@2.0.0(prettier@3.5.3)': @@ -29571,12 +29335,12 @@ snapshots: '@types/yargs': 17.0.33 chalk: 4.1.2 - '@jnwng/walletconnect-solana@0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': + '@jnwng/walletconnect-solana@0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@walletconnect/qrcode-modal': 1.8.0 - '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) + '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) bs58: 5.0.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -29592,6 +29356,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -29602,12 +29367,12 @@ snapshots: - utf-8-validate - zod - '@jnwng/walletconnect-solana@0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@jnwng/walletconnect-solana@0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': dependencies: '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) '@walletconnect/qrcode-modal': 1.8.0 - '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) bs58: 5.0.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -29623,6 +29388,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -29831,7 +29597,7 @@ snapshots: node-fetch: 2.7.0(encoding@0.1.13) nopt: 8.1.0 semver: 7.7.3 - tar: 7.4.3 + tar: 7.5.7 transitivePeerDependencies: - encoding - supports-color @@ -29951,7 +29717,7 @@ snapshots: axios: 1.8.4(debug@4.4.3) chai: 4.5.0 chalk: 4.1.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) fs-extra: 11.3.3 hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) proxyquire: 2.1.3 @@ -29993,7 +29759,7 @@ snapshots: '@nomiclabs/hardhat-docker': 2.0.2(encoding@0.1.13) chai: 4.5.0 chalk: 4.1.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) dockerode: 4.0.5 fs-extra: 11.3.3 hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) @@ -30060,7 +29826,7 @@ snapshots: cbor: 9.0.2 chai: 4.5.0 chalk: 4.1.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) semver: 7.7.3 sinon: 18.0.1 @@ -30100,7 +29866,7 @@ snapshots: '@types/estree-jsx': 1.0.5 '@types/hast': 3.0.4 '@types/mdx': 2.0.13 - acorn: 8.14.1 + acorn: 8.16.0 collapse-white-space: 2.1.0 devlop: 1.1.0 estree-util-is-identifier-name: 3.0.0 @@ -30109,13 +29875,13 @@ snapshots: hast-util-to-jsx-runtime: 2.3.6 markdown-extensions: 2.0.0 recma-build-jsx: 1.0.0 - recma-jsx: 1.0.0(acorn@8.14.1) + recma-jsx: 1.0.0(acorn@8.16.0) recma-stringify: 1.0.0 rehype-recma: 1.0.0 remark-mdx: 3.1.1 remark-parse: 11.0.0 remark-rehype: 11.1.2 - source-map: 0.7.4 + source-map: 0.7.6 unified: 11.0.5 unist-util-position-from-estree: 2.0.0 unist-util-stringify-position: 4.0.0 @@ -30214,7 +29980,7 @@ snapshots: bufferutil: 4.0.9 cross-fetch: 4.1.0(encoding@0.1.13) date-fns: 2.30.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) eciesjs: 0.4.14 eventemitter2: 6.4.9 readable-stream: 3.6.2 @@ -30230,7 +29996,7 @@ snapshots: '@metamask/sdk@0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.6 '@metamask/onboarding': 1.0.1 '@metamask/providers': 16.1.0 '@metamask/sdk-communication-layer': 0.32.0(cross-fetch@4.1.0(encoding@0.1.13))(eciesjs@0.4.14)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) @@ -30238,7 +30004,7 @@ snapshots: '@paulmillr/qr': 0.2.1 bowser: 2.11.0 cross-fetch: 4.1.0(encoding@0.1.13) - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) eciesjs: 0.4.14 eth-rpc-errors: 4.0.3 eventemitter2: 6.4.9 @@ -30261,7 +30027,7 @@ snapshots: dependencies: '@ethereumjs/tx': 4.2.0 '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) semver: 7.7.3 superstruct: 1.0.4 transitivePeerDependencies: @@ -30274,7 +30040,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) pony-cause: 2.1.11 semver: 7.7.3 uuid: 9.0.1 @@ -30288,7 +30054,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) pony-cause: 2.1.11 semver: 7.7.3 uuid: 9.0.1 @@ -30670,12 +30436,6 @@ snapshots: react: 19.2.1 third-party-capital: 1.0.20 - '@next/third-parties@16.1.1(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1)': - dependencies: - next: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) - react: 19.2.1 - third-party-capital: 1.0.20 - '@ngraveio/bc-ur@1.1.13': dependencies: '@keystonehq/alias-sampling': 0.1.2 @@ -30813,7 +30573,7 @@ snapshots: '@nomicfoundation/hardhat-ethers@3.0.8(ethers@5.8.0(bufferutil@4.0.7)(utf-8-validate@6.0.3))(hardhat@2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3))': dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) ethers: 5.8.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) lodash.isequal: 4.5.0 @@ -30822,7 +30582,7 @@ snapshots: '@nomicfoundation/hardhat-ethers@3.0.8(ethers@6.13.5(bufferutil@4.0.7)(utf-8-validate@6.0.3))(hardhat@2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3))': dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) ethers: 6.13.5(bufferutil@4.0.7)(utf-8-validate@6.0.3) hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) lodash.isequal: 4.5.0 @@ -30834,7 +30594,7 @@ snapshots: '@ethersproject/abi': 5.8.0 '@ethersproject/address': 5.8.0 cbor: 8.1.0 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) lodash.clonedeep: 4.5.0 picocolors: 1.1.1 @@ -30899,7 +30659,7 @@ snapshots: '@ethersproject/address': 5.8.0 cbor: 8.1.0 chalk: 2.4.2 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.0 fs-extra: 7.0.1 hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) lodash: 4.17.21 @@ -31290,7 +31050,7 @@ snapshots: '@openzeppelin/platform-deploy-client': 0.8.0(debug@4.4.0)(encoding@0.1.13) '@openzeppelin/upgrades-core': 1.42.2 chalk: 4.1.2 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.0 ethers: 5.8.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) proper-lockfile: 4.1.2 @@ -31306,7 +31066,7 @@ snapshots: '@openzeppelin/defender-sdk-network-client': 2.5.0(debug@4.4.3)(encoding@0.1.13) '@openzeppelin/upgrades-core': 1.42.2 chalk: 4.1.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) ethereumjs-util: 7.1.5 ethers: 6.13.5(bufferutil@4.0.7)(utf-8-validate@6.0.3) hardhat: 2.22.19(bufferutil@4.0.7)(ts-node@10.9.2(@swc/core@1.15.10)(@types/node@22.14.0)(typescript@5.9.3))(typescript@5.9.3)(utf-8-validate@6.0.3) @@ -31336,7 +31096,7 @@ snapshots: cbor: 10.0.3 chalk: 4.1.2 compare-versions: 6.1.1 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) ethereumjs-util: 7.1.5 minimatch: 9.0.5 minimist: 1.2.8 @@ -31509,11 +31269,11 @@ snapshots: crypto-js: 4.2.0 uuidv4: 6.2.13 - '@particle-network/solana-wallet@1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)': + '@particle-network/solana-wallet@1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)': dependencies: '@particle-network/auth': 1.3.1 '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - bs58: 5.0.0 + bs58: 6.0.0 '@paulmillr/qr@0.2.1': {} @@ -31534,7 +31294,7 @@ snapshots: loader-utils: 2.0.4 react-refresh: 0.14.2 schema-utils: 4.3.0 - source-map: 0.7.4 + source-map: 0.7.6 webpack: 5.98.0(@swc/core@1.15.10) optionalDependencies: type-fest: 4.39.0 @@ -31668,9 +31428,9 @@ snapshots: '@pythnetwork/hermes-client@1.4.0(axios@1.8.4)': dependencies: - '@zodios/core': 10.9.6(axios@1.8.4)(zod@3.24.4) + '@zodios/core': 10.9.6(axios@1.8.4)(zod@3.25.76) eventsource: 3.0.6 - zod: 3.24.4 + zod: 3.25.76 transitivePeerDependencies: - axios @@ -31952,7 +31712,7 @@ snapshots: '@radix-ui/react-popper@1.2.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@floating-ui/react-dom': 2.1.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@radix-ui/react-arrow': 1.1.2(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@radix-ui/react-compose-refs': 1.1.1(@types/react@19.2.7)(react@19.2.1) '@radix-ui/react-context': 1.1.1(@types/react@19.2.7)(react@19.2.1) @@ -31970,7 +31730,7 @@ snapshots: '@radix-ui/react-popper@1.2.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: - '@floating-ui/react-dom': 2.1.2(react-dom@19.2.1(react@19.2.1))(react@19.2.1) + '@floating-ui/react-dom': 2.1.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@radix-ui/react-arrow': 1.1.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.1) '@radix-ui/react-context': 1.1.2(@types/react@19.2.7)(react@19.2.1) @@ -32362,7 +32122,7 @@ snapshots: '@swc/helpers': 0.5.15 react: 19.2.1 react-dom: 19.2.1(react@19.2.1) - use-sync-external-store: 1.5.0(react@19.2.1) + use-sync-external-store: 1.6.0(react@19.2.1) '@react-aria/color@3.1.0(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: @@ -32574,7 +32334,7 @@ snapshots: '@swc/helpers': 0.5.15 react: 19.2.1 react-dom: 19.2.1(react@19.2.1) - use-sync-external-store: 1.5.0(react@19.2.1) + use-sync-external-store: 1.6.0(react@19.2.1) '@react-aria/link@3.8.4(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: @@ -33308,7 +33068,7 @@ snapshots: dependencies: '@swc/helpers': 0.5.15 react: 19.2.1 - use-sync-external-store: 1.5.0(react@19.2.1) + use-sync-external-store: 1.6.0(react@19.2.1) '@react-stately/toggle@3.9.0(react@19.2.1)': dependencies: @@ -33623,9 +33383,9 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.52.5': optional: true - '@safe-global/safe-apps-provider@0.18.5(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@safe-global/safe-apps-provider@0.18.5(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - bufferutil @@ -33633,10 +33393,10 @@ snapshots: - utf-8-validate - zod - '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@safe-global/safe-gateway-typescript-sdk': 3.22.9 - viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - bufferutil - typescript @@ -35251,16 +35011,7 @@ snapshots: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-base-ui@0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)': - dependencies: - '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) - '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - react: 19.2.1 - transitivePeerDependencies: - - bs58 - - react-native - - '@solana/wallet-adapter-base-ui@0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)': + '@solana/wallet-adapter-base-ui@0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)': dependencies: '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) @@ -35378,9 +35129,9 @@ snapshots: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-particle@0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)': + '@solana/wallet-adapter-particle@0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)': dependencies: - '@particle-network/solana-wallet': 1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0) + '@particle-network/solana-wallet': 1.3.2(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0) '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -35391,22 +35142,10 @@ snapshots: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-react-ui@0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)': - dependencies: - '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base-ui': 0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) - '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) - '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - react: 19.2.1 - react-dom: 19.2.1(react@19.2.1) - transitivePeerDependencies: - - bs58 - - react-native - - '@solana/wallet-adapter-react-ui@0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)': + '@solana/wallet-adapter-react-ui@0.9.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)': dependencies: '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-base-ui': 0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) + '@solana/wallet-adapter-base-ui': 0.1.3(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) '@solana/wallet-adapter-react': 0.15.36(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) react: 19.2.1 @@ -35537,9 +35276,9 @@ snapshots: '@solana/wallet-standard-util': 1.1.2 '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@solana/wallet-adapter-walletconnect@0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': + '@solana/wallet-adapter-walletconnect@0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@jnwng/walletconnect-solana': 0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) + '@jnwng/walletconnect-solana': 0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -35556,6 +35295,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -35566,9 +35306,9 @@ snapshots: - utf-8-validate - zod - '@solana/wallet-adapter-walletconnect@0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@solana/wallet-adapter-walletconnect@0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': dependencies: - '@jnwng/walletconnect-solana': 0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@jnwng/walletconnect-solana': 0.2.0(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) '@solana/wallet-adapter-base': 0.9.24(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -35585,6 +35325,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -35595,7 +35336,7 @@ snapshots: - utf-8-validate - zod - '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.4)': + '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bs58@6.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.7.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)': dependencies: '@solana/wallet-adapter-alpha': 0.1.11(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -35616,7 +35357,7 @@ snapshots: '@solana/wallet-adapter-nightly': 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-nufi': 0.1.18(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-onto': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0) + '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0) '@solana/wallet-adapter-phantom': 0.9.25(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-safepal': 0.5.19(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-saifu': 0.1.16(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -35631,7 +35372,7 @@ snapshots: '@solana/wallet-adapter-trezor': 0.1.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-trust': 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-unsafe-burner': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-walletconnect': 0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@solana/wallet-adapter-walletconnect': 0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@solana/wallet-adapter-xdefi': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -35651,6 +35392,7 @@ snapshots: - '@solana/sysvars' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bs58 @@ -35672,7 +35414,7 @@ snapshots: - ws - zod - '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2)': + '@solana/wallet-adapter-wallets@0.19.33(@babel/runtime@7.28.6)(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(bs58@6.0.0)(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(ioredis@5.7.0)(react-dom@19.2.1(react@19.2.1))(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(react@19.2.1)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.24.2)': dependencies: '@solana/wallet-adapter-alpha': 0.1.11(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-avana': 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -35693,7 +35435,7 @@ snapshots: '@solana/wallet-adapter-nightly': 0.1.17(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-nufi': 0.1.18(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-onto': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@5.0.0) + '@solana/wallet-adapter-particle': 0.1.13(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bs58@6.0.0) '@solana/wallet-adapter-phantom': 0.9.25(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-safepal': 0.5.19(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-saifu': 0.1.16(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) @@ -35708,7 +35450,7 @@ snapshots: '@solana/wallet-adapter-trezor': 0.1.3(@solana/sysvars@2.1.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(encoding@0.1.13)(fastestsmallesttextencoderdecoder@1.0.22)(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10))(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.19.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-trust': 0.1.14(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/wallet-adapter-unsafe-burner': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) - '@solana/wallet-adapter-walletconnect': 0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) + '@solana/wallet-adapter-walletconnect': 0.1.17(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) '@solana/wallet-adapter-xdefi': 0.1.8(@solana/web3.js@1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)) '@solana/web3.js': 1.98.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) transitivePeerDependencies: @@ -35728,6 +35470,7 @@ snapshots: - '@solana/sysvars' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bs58 @@ -35845,7 +35588,7 @@ snapshots: '@solana/web3.js@1.77.4(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10)': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.6 '@noble/curves': 1.9.6 '@noble/hashes': 1.8.0 '@solana/buffer-layout': 4.0.1 @@ -36013,6 +35756,35 @@ snapshots: '@starknet-io/types-js@0.7.10': {} + '@stellar/js-xdr@3.1.2': {} + + '@stellar/stellar-base@13.1.0': + dependencies: + '@stellar/js-xdr': 3.1.2 + base32.js: 0.1.0 + bignumber.js: 9.3.1 + buffer: 6.0.3 + sha.js: 2.4.11 + tweetnacl: 1.0.3 + optionalDependencies: + sodium-native: 4.3.3 + transitivePeerDependencies: + - bare-url + + '@stellar/stellar-sdk@13.3.0': + dependencies: + '@stellar/stellar-base': 13.1.0 + axios: 1.8.4(debug@4.4.3) + bignumber.js: 9.3.1 + eventsource: 2.0.2 + feaxios: 0.0.23 + randombytes: 2.1.0 + toml: 3.0.0 + urijs: 1.19.11 + transitivePeerDependencies: + - bare-url + - debug + '@storybook/addon-styling-webpack@3.0.0(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(utf-8-validate@6.0.3))(webpack@5.98.0(@swc/core@1.15.10))': dependencies: storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(utf-8-validate@6.0.3) @@ -36030,10 +35802,10 @@ snapshots: case-sensitive-paths-webpack-plugin: 2.4.0 cjs-module-lexer: 1.4.3 css-loader: 7.1.2(webpack@5.98.0(@swc/core@1.15.10)) - es-module-lexer: 1.6.0 + es-module-lexer: 1.7.0 fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.9.3)(webpack@5.98.0(@swc/core@1.15.10)) html-webpack-plugin: 5.6.3(webpack@5.98.0(@swc/core@1.15.10)) - magic-string: 0.30.19 + magic-string: 0.30.21 storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(utf-8-validate@6.0.3) style-loader: 4.0.0(webpack@5.98.0(@swc/core@1.15.10)) terser-webpack-plugin: 5.3.14(@swc/core@1.15.10)(webpack@5.98.0(@swc/core@1.15.10)) @@ -36070,16 +35842,16 @@ snapshots: '@babel/core': 7.28.6 '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.6) '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.28.6) - '@babel/plugin-syntax-import-assertions': 7.26.0(@babel/core@7.28.6) - '@babel/plugin-transform-class-properties': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-numeric-separator': 7.25.9(@babel/core@7.28.6) - '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.28.6) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.28.6) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.28.6) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.28.6) '@babel/plugin-transform-runtime': 7.26.10(@babel/core@7.28.6) - '@babel/preset-env': 7.26.9(@babel/core@7.28.6) + '@babel/preset-env': 7.29.0(@babel/core@7.28.6) '@babel/preset-react': 7.26.3(@babel/core@7.28.6) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.6) - '@babel/runtime': 7.27.0 + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.6) + '@babel/runtime': 7.28.6 '@pmmmwh/react-refresh-webpack-plugin': 0.5.16(react-refresh@0.14.2)(type-fest@4.39.0)(webpack-hot-middleware@2.26.1)(webpack@5.98.0(@swc/core@1.15.10)) '@storybook/builder-webpack5': 10.1.11(@swc/core@1.15.10)(msw@2.12.10(@types/node@22.14.0)(typescript@5.9.3))(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(utf-8-validate@6.0.3))(typescript@5.9.3)(vite@6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.0)) '@storybook/preset-react-webpack': 10.1.11(@swc/core@1.15.10)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(utf-8-validate@6.0.3))(typescript@5.9.3) @@ -36132,11 +35904,11 @@ snapshots: '@storybook/core-webpack': 10.1.11(storybook@10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(utf-8-validate@6.0.3)) '@storybook/react-docgen-typescript-plugin': 1.0.6--canary.9.0c3f3b7.0(typescript@5.9.3)(webpack@5.98.0(@swc/core@1.15.10)) '@types/semver': 7.7.0 - magic-string: 0.30.19 + magic-string: 0.30.21 react: 19.2.1 react-docgen: 7.1.1 react-dom: 19.2.1(react@19.2.1) - resolve: 1.22.10 + resolve: 1.22.11 semver: 7.7.3 storybook: 10.1.11(@testing-library/dom@10.4.1)(bufferutil@4.0.9)(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(utf-8-validate@6.0.3) tsconfig-paths: 4.2.0 @@ -36152,7 +35924,7 @@ snapshots: '@storybook/react-docgen-typescript-plugin@1.0.6--canary.9.0c3f3b7.0(typescript@5.9.3)(webpack@5.98.0(@swc/core@1.15.10))': dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) endent: 2.1.0 find-cache-dir: 3.3.2 flat-cache: 3.2.0 @@ -36290,12 +36062,12 @@ snapshots: '@svgr/hast-util-to-babel-ast@6.5.1': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 entities: 4.5.0 '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 entities: 4.5.0 '@svgr/plugin-jsx@6.5.1(@svgr/core@6.5.1)': @@ -36351,9 +36123,9 @@ snapshots: dependencies: '@babel/core': 7.28.6 '@babel/plugin-transform-react-constant-elements': 7.25.9(@babel/core@7.28.6) - '@babel/preset-env': 7.26.9(@babel/core@7.28.6) + '@babel/preset-env': 7.29.0(@babel/core@7.28.6) '@babel/preset-react': 7.26.3(@babel/core@7.28.6) - '@babel/preset-typescript': 7.27.1(@babel/core@7.28.6) + '@babel/preset-typescript': 7.28.5(@babel/core@7.28.6) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) '@svgr/plugin-svgo': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3))(typescript@5.9.3) @@ -36508,9 +36280,9 @@ snapshots: dependencies: '@ampproject/remapping': 2.3.0 enhanced-resolve: 5.18.1 - jiti: 2.4.2 + jiti: 2.6.1 lightningcss: 1.29.2 - magic-string: 0.30.19 + magic-string: 0.30.21 source-map-js: 1.2.1 tailwindcss: 4.1.6 @@ -36553,7 +36325,7 @@ snapshots: '@tailwindcss/oxide@4.1.6': dependencies: detect-libc: 2.1.2 - tar: 7.4.3 + tar: 7.5.7 optionalDependencies: '@tailwindcss/oxide-android-arm64': 4.1.6 '@tailwindcss/oxide-darwin-arm64': 4.1.6 @@ -36652,8 +36424,8 @@ snapshots: '@testing-library/dom@10.4.1': dependencies: - '@babel/code-frame': 7.28.6 - '@babel/runtime': 7.27.0 + '@babel/code-frame': 7.29.0 + '@babel/runtime': 7.28.6 '@types/aria-query': 5.0.4 aria-query: 5.3.0 dom-accessibility-api: 0.5.16 @@ -36673,7 +36445,7 @@ snapshots: '@testing-library/react@16.3.0(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)': dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.6 '@testing-library/dom': 10.4.1 react: 19.2.1 react-dom: 19.2.1(react@19.2.1) @@ -36783,7 +36555,7 @@ snapshots: dataloader: 2.2.3 symbol.inspect: 1.0.1 teslabot: 1.5.0 - zod: 3.24.4 + zod: 3.25.76 transitivePeerDependencies: - debug @@ -37236,24 +37008,24 @@ snapshots: '@types/babel__core@7.20.5': dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__generator': 7.6.8 '@types/babel__template': 7.4.4 '@types/babel__traverse': 7.20.7 '@types/babel__generator@7.6.8': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@types/babel__template@7.4.4': dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__traverse@7.20.7': dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@types/bip39@3.0.4': dependencies: @@ -37626,9 +37398,9 @@ snapshots: '@ungap/structured-clone@1.3.0': {} - '@vercel/analytics@1.6.1(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1)': + '@vercel/analytics@1.6.1(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1)': optionalDependencies: - next: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + next: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) react: 19.2.1 '@vercel/backends@0.0.45(encoding@0.1.13)(rollup@4.52.5)(typescript@5.9.3)': @@ -37880,8 +37652,8 @@ snapshots: dependencies: '@mapbox/node-pre-gyp': 2.0.0(encoding@0.1.13) '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 @@ -37899,8 +37671,8 @@ snapshots: dependencies: '@mapbox/node-pre-gyp': 2.0.0(encoding@0.1.13) '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - acorn: 8.15.0 - acorn-import-attributes: 1.9.5(acorn@8.15.0) + acorn: 8.16.0 + acorn-import-attributes: 1.9.5(acorn@8.16.0) async-sema: 3.1.1 bindings: 1.5.0 estree-walker: 2.0.2 @@ -38120,7 +37892,7 @@ snapshots: dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.19 + magic-string: 0.30.21 optionalDependencies: msw: 2.12.10(@types/node@22.14.0)(typescript@5.9.3) vite: 6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.0) @@ -38164,16 +37936,16 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 - '@wagmi/connectors@5.7.12(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(@wagmi/core@2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4)': + '@wagmi/connectors@5.7.12(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(@wagmi/core@2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)': dependencies: '@coinbase/wallet-sdk': 4.3.0 '@metamask/sdk': 0.32.0(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10) - '@safe-global/safe-apps-provider': 0.18.5(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - '@wagmi/core': 2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)) - '@walletconnect/ethereum-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@safe-global/safe-apps-provider': 0.18.5(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) cbw-sdk: '@coinbase/wallet-sdk@3.9.3' - viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -38191,6 +37963,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38203,11 +37976,11 @@ snapshots: - utf-8-validate - zod - '@wagmi/core@2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))': + '@wagmi/core@2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': dependencies: eventemitter3: 5.0.1 mipd: 0.0.7(typescript@5.9.3) - viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) zustand: 5.0.0(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(use-sync-external-store@1.4.0(react@19.2.1)) optionalDependencies: '@tanstack/query-core': 5.71.5 @@ -38253,21 +38026,21 @@ snapshots: '@walletconnect/window-metadata': 1.0.0 detect-browser: 5.2.0 - '@walletconnect/core@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@walletconnect/core@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/logger': 2.1.2 '@walletconnect/relay-api': 1.0.11 '@walletconnect/relay-auth': 1.1.0 '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -38286,6 +38059,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38296,21 +38070,21 @@ snapshots: - utf-8-validate - zod - '@walletconnect/core@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': + '@walletconnect/core@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': dependencies: '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/logger': 2.1.2 '@walletconnect/relay-api': 1.0.11 '@walletconnect/relay-auth': 1.1.0 '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) '@walletconnect/window-getters': 1.0.1 es-toolkit: 1.33.0 events: 3.3.0 @@ -38329,6 +38103,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38343,18 +38118,18 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/ethereum-provider@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@walletconnect/ethereum-provider@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/modal': 2.7.0(@types/react@19.2.7)(react@19.2.1) - '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) - '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) + '@walletconnect/universal-provider': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -38371,6 +38146,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38430,11 +38206,11 @@ snapshots: - bufferutil - utf-8-validate - '@walletconnect/keyvaluestorage@1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0)': + '@walletconnect/keyvaluestorage@1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0)': dependencies: '@walletconnect/safe-json': 1.0.2 idb-keyval: 6.2.1 - unstorage: 1.15.0(@vercel/blob@2.3.0)(idb-keyval@6.2.1)(ioredis@5.7.0) + unstorage: 1.17.4(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(idb-keyval@6.2.1)(ioredis@5.7.0) optionalDependencies: '@react-native-async-storage/async-storage': 1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)) transitivePeerDependencies: @@ -38450,6 +38226,7 @@ snapshots: - '@planetscale/database' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 @@ -38515,16 +38292,16 @@ snapshots: dependencies: tslib: 1.14.1 - '@walletconnect/sign-client@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@walletconnect/sign-client@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@walletconnect/core': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/core': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/logger': 2.1.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -38540,6 +38317,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38550,16 +38328,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': + '@walletconnect/sign-client@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': dependencies: - '@walletconnect/core': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) + '@walletconnect/core': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/logger': 2.1.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -38575,6 +38353,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38585,16 +38364,16 @@ snapshots: - utf-8-validate - zod - '@walletconnect/sign-client@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@walletconnect/sign-client@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@walletconnect/core': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/core': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-utils': 1.0.8 '@walletconnect/logger': 2.1.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) events: 3.3.0 transitivePeerDependencies: - '@azure/app-configuration' @@ -38610,6 +38389,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38626,12 +38406,12 @@ snapshots: '@walletconnect/types@1.8.0': {} - '@walletconnect/types@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0)': + '@walletconnect/types@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/heartbeat': 1.2.2 '@walletconnect/jsonrpc-types': 1.0.4 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/logger': 2.1.2 events: 3.3.0 transitivePeerDependencies: @@ -38648,24 +38428,25 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - db0 - ioredis - uploadthing - '@walletconnect/universal-provider@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@walletconnect/universal-provider@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@walletconnect/events': 1.0.1 '@walletconnect/jsonrpc-http-connection': 1.0.8(encoding@0.1.13) '@walletconnect/jsonrpc-provider': 1.0.14 '@walletconnect/jsonrpc-types': 1.0.4 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/logger': 2.1.2 - '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) - '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + '@walletconnect/sign-client': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) + '@walletconnect/utils': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) es-toolkit: 1.33.0 events: 3.3.0 transitivePeerDependencies: @@ -38682,6 +38463,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38693,25 +38475,25 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)': + '@walletconnect/utils@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/relay-api': 1.0.11 '@walletconnect/relay-auth': 1.1.0 '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 detect-browser: 5.3.0 query-string: 7.1.3 uint8arrays: 3.1.0 - viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) transitivePeerDependencies: - '@azure/app-configuration' - '@azure/cosmos' @@ -38726,6 +38508,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38736,18 +38519,18 @@ snapshots: - utf-8-validate - zod - '@walletconnect/utils@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': + '@walletconnect/utils@2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(bufferutil@4.0.9)(ioredis@5.7.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.2)': dependencies: '@noble/ciphers': 1.2.1 '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@walletconnect/jsonrpc-utils': 1.0.8 - '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/keyvaluestorage': 1.1.1(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/relay-api': 1.0.11 '@walletconnect/relay-auth': 1.1.0 '@walletconnect/safe-json': 1.0.2 '@walletconnect/time': 1.0.2 - '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(ioredis@5.7.0) + '@walletconnect/types': 2.19.2(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(ioredis@5.7.0) '@walletconnect/window-getters': 1.0.1 '@walletconnect/window-metadata': 1.0.1 bs58: 6.0.0 @@ -38769,6 +38552,7 @@ snapshots: - '@react-native-async-storage/async-storage' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -38930,10 +38714,10 @@ snapshots: axios: 1.8.4(debug@4.4.3) zod: 3.24.2 - '@zodios/core@10.9.6(axios@1.8.4)(zod@3.24.4)': + '@zodios/core@10.9.6(axios@1.8.4)(zod@3.25.76)': dependencies: axios: 1.8.4(debug@4.4.3) - zod: 3.24.4 + zod: 3.25.76 JSONStream@1.3.2: dependencies: @@ -38969,11 +38753,6 @@ snapshots: typescript: 5.9.3 zod: 3.24.2 - abitype@1.0.8(typescript@5.9.3)(zod@3.24.4): - optionalDependencies: - typescript: 5.9.3 - zod: 3.24.4 - abitype@1.0.8(typescript@5.9.3)(zod@3.25.76): optionalDependencies: typescript: 5.9.3 @@ -38984,10 +38763,10 @@ snapshots: typescript: 5.9.3 zod: 3.24.2 - abitype@1.1.0(typescript@5.9.3)(zod@3.24.4): + abitype@1.1.0(typescript@5.9.3)(zod@3.25.76): optionalDependencies: typescript: 5.9.3 - zod: 3.24.4 + zod: 3.25.76 abitype@1.1.0(typescript@5.9.3)(zod@4.3.5): optionalDependencies: @@ -39039,17 +38818,13 @@ snapshots: acorn-globals@7.0.1: dependencies: - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 acorn-import-attributes@1.9.5(acorn@8.14.1): dependencies: acorn: 8.14.1 - acorn-import-attributes@1.9.5(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - acorn-import-attributes@1.9.5(acorn@8.16.0): dependencies: acorn: 8.16.0 @@ -39064,15 +38839,13 @@ snapshots: acorn-walk@8.3.4: dependencies: - acorn: 8.14.1 + acorn: 8.16.0 acorn@7.1.1: optional: true acorn@8.14.1: {} - acorn@8.15.0: {} - acorn@8.16.0: {} address@1.2.2: {} @@ -39105,7 +38878,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -39358,7 +39131,7 @@ snapshots: '@capsizecss/unpack': 4.0.0 '@oslojs/encoding': 1.1.0 '@rollup/pluginutils': 5.3.0(rollup@4.52.5) - acorn: 8.15.0 + acorn: 8.16.0 aria-query: 5.3.2 axobject-query: 4.1.0 boxen: 8.0.1 @@ -39367,7 +39140,7 @@ snapshots: common-ancestor-path: 1.0.1 cookie: 1.1.1 cssesc: 3.0.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) deterministic-object-hash: 2.0.2 devalue: 5.6.2 diff: 8.0.3 @@ -39404,7 +39177,7 @@ snapshots: ultrahtml: 1.6.0 unifont: 0.7.3 unist-util-visit: 5.0.0 - unstorage: 1.17.4(@vercel/blob@2.3.0)(idb-keyval@6.2.1)(ioredis@5.7.0) + unstorage: 1.17.4(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(idb-keyval@6.2.1)(ioredis@5.7.0) vfile: 6.0.3 vite: 6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.0) vitefu: 1.1.1(vite@6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.0)) @@ -39499,8 +39272,8 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.3): dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001707 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001765 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -39509,8 +39282,8 @@ snapshots: autoprefixer@10.4.21(postcss@8.5.6): dependencies: - browserslist: 4.24.4 - caniuse-lite: 1.0.30001707 + browserslist: 4.28.1 + caniuse-lite: 1.0.30001765 fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.1.1 @@ -39635,19 +39408,10 @@ snapshots: babel-plugin-jest-hoist@29.6.3: dependencies: '@babel/template': 7.28.6 - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.7 - babel-plugin-polyfill-corejs2@0.4.13(@babel/core@7.28.6): - dependencies: - '@babel/compat-data': 7.26.8 - '@babel/core': 7.28.6 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.6) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.26.10): dependencies: '@babel/compat-data': 7.28.6 @@ -39657,15 +39421,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-corejs2@0.4.14(@babel/core@7.28.6): - dependencies: - '@babel/compat-data': 7.28.6 - '@babel/core': 7.28.6 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.6) - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-corejs2@0.4.15(@babel/core@7.28.6): dependencies: '@babel/compat-data': 7.29.0 @@ -39699,13 +39454,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.4(@babel/core@7.28.6): - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.6) - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.26.10): dependencies: '@babel/core': 7.26.10 @@ -39713,13 +39461,6 @@ snapshots: transitivePeerDependencies: - supports-color - babel-plugin-polyfill-regenerator@0.6.5(@babel/core@7.28.6): - dependencies: - '@babel/core': 7.28.6 - '@babel/helper-define-polyfill-provider': 0.6.5(@babel/core@7.28.6) - transitivePeerDependencies: - - supports-color - babel-plugin-polyfill-regenerator@0.6.6(@babel/core@7.28.6): dependencies: '@babel/core': 7.28.6 @@ -39729,11 +39470,11 @@ snapshots: babel-plugin-react-compiler@19.1.0-rc.1: dependencies: - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 babel-plugin-styled-components@2.1.4(@babel/core@7.28.6)(styled-components@5.3.11(@babel/core@7.28.6)(react-dom@19.2.1(react@19.2.1))(react-is@18.3.1)(react@19.2.1))(supports-color@5.5.0): dependencies: - '@babel/helper-annotate-as-pure': 7.27.1 + '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.6) lodash: 4.17.21 @@ -39760,7 +39501,7 @@ snapshots: '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.28.6) '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.28.6) '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.28.6) - '@babel/plugin-syntax-import-attributes': 7.26.0(@babel/core@7.28.6) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.28.6) '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.28.6) '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.28.6) '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.28.6) @@ -39788,6 +39529,20 @@ snapshots: balanced-match@2.0.0: {} + bare-addon-resolve@1.10.0: + dependencies: + bare-module-resolve: 1.12.1 + bare-semver: 1.0.3 + optional: true + + bare-module-resolve@1.12.1: + dependencies: + bare-semver: 1.0.3 + optional: true + + bare-semver@1.0.3: + optional: true + base-64@1.0.0: optional: true @@ -39803,6 +39558,8 @@ snapshots: base-x@5.0.1: {} + base32.js@0.1.0: {} + base64-js@1.5.1: {} base64url@3.0.1: {} @@ -39846,6 +39603,8 @@ snapshots: bignumber.js@9.1.2: {} + bignumber.js@9.3.1: {} + binary-extensions@2.3.0: {} binary-parser@2.2.1: {} @@ -39946,7 +39705,7 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) http-errors: 2.0.0 iconv-lite: 0.7.2 on-finished: 2.4.1 @@ -40066,13 +39825,6 @@ snapshots: dependencies: pako: 1.0.11 - browserslist@4.24.4: - dependencies: - caniuse-lite: 1.0.30001707 - electron-to-chromium: 1.5.129 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.24.4) - browserslist@4.28.1: dependencies: baseline-browser-mapping: 2.9.14 @@ -40270,8 +40022,6 @@ snapshots: camelize@1.0.1: {} - caniuse-lite@1.0.30001707: {} - caniuse-lite@1.0.30001765: {} capability@0.2.5: {} @@ -40720,12 +40470,12 @@ snapshots: transitivePeerDependencies: - supports-color - connectkit@1.9.0(@babel/core@7.28.6)(@tanstack/react-query@5.71.5(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react-is@18.3.1)(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4)): + connectkit@1.9.0(@babel/core@7.28.6)(@tanstack/react-query@5.71.5(react@19.2.1))(react-dom@19.2.1(react@19.2.1))(react-is@18.3.1)(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): dependencies: '@tanstack/react-query': 5.71.5(react@19.2.1) buffer: 6.0.3 detect-browser: 5.3.0 - family: 0.1.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4)) + family: 0.1.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) framer-motion: 6.5.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1) qrcode: 1.5.4 react: 19.2.1 @@ -40734,8 +40484,8 @@ snapshots: react-use-measure: 2.1.7(react-dom@19.2.1(react@19.2.1))(react@19.2.1) resize-observer-polyfill: 1.5.1 styled-components: 5.3.11(@babel/core@7.28.6)(react-dom@19.2.1(react@19.2.1))(react-is@18.3.1)(react@19.2.1) - viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - wagmi: 2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4) + viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) transitivePeerDependencies: - '@babel/core' - react-is @@ -41023,14 +40773,9 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - crossws@0.3.4: - dependencies: - uncrypto: 0.1.3 - crossws@0.3.5: dependencies: uncrypto: 0.1.3 - optional: true crypto-addr-codec@0.1.8: dependencies: @@ -41260,21 +41005,21 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.4.0(supports-color@8.1.1): + debug@4.4.0: dependencies: ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 - debug@4.4.3: + debug@4.4.3(supports-color@5.5.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 - debug@4.4.3(supports-color@5.5.0): + debug@4.4.3(supports-color@8.1.1): dependencies: ms: 2.1.3 optionalDependencies: - supports-color: 5.5.0 + supports-color: 8.1.1 decamelize@1.2.0: {} @@ -41374,10 +41119,7 @@ snapshots: inherits: 2.0.4 minimalistic-assert: 1.0.1 - destr@2.0.3: {} - - destr@2.0.5: - optional: true + destr@2.0.5: {} destroy@1.2.0: {} @@ -41462,7 +41204,7 @@ snapshots: docker-modem@3.0.8: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) readable-stream: 3.6.2 split-ca: 1.0.1 ssh2: 1.16.0 @@ -41471,7 +41213,7 @@ snapshots: docker-modem@5.0.6: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) readable-stream: 3.6.2 split-ca: 1.0.1 ssh2: 1.16.0 @@ -41659,8 +41401,6 @@ snapshots: dependencies: jake: 10.9.2 - electron-to-chromium@1.5.129: {} - electron-to-chromium@1.5.267: {} elliptic@6.5.4: @@ -41785,8 +41525,6 @@ snapshots: es-module-lexer@1.4.1: {} - es-module-lexer@1.6.0: {} - es-module-lexer@1.7.0: {} es-object-atoms@1.1.1: @@ -41836,7 +41574,7 @@ snapshots: esast-util-from-js@2.0.1: dependencies: '@types/estree-jsx': 1.0.5 - acorn: 8.14.1 + acorn: 8.16.0 esast-util-from-estree: 2.0.0 vfile-message: 4.0.2 @@ -42090,7 +41828,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.3.0 eslint-visitor-keys: 4.2.0 @@ -42163,7 +41901,7 @@ snapshots: dependencies: '@types/estree-jsx': 1.0.5 astring: 1.9.0 - source-map: 0.7.4 + source-map: 0.7.6 estree-util-value-to-estree@3.5.0: dependencies: @@ -42187,7 +41925,7 @@ snapshots: eth-block-tracker@4.4.3(@babel/core@7.28.6): dependencies: '@babel/plugin-transform-runtime': 7.26.10(@babel/core@7.28.6) - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.6 eth-query: 2.1.2 json-rpc-random-id: 1.0.1 pify: 3.0.0 @@ -42829,7 +42567,7 @@ snapshots: content-type: 1.0.5 cookie: 0.7.1 cookie-signature: 1.2.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 @@ -42883,12 +42621,12 @@ snapshots: dependencies: checkpoint-store: 1.1.0 - family@0.1.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4)): + family@0.1.1(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): optionalDependencies: react: 19.2.1 react-dom: 19.2.1(react@19.2.1) - viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) - wagmi: 2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4) + viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) fancy-canvas@2.1.0: {} @@ -42962,6 +42700,10 @@ snapshots: optionalDependencies: picomatch: 4.0.3 + feaxios@0.0.23: + dependencies: + is-retry-allowed: 3.0.0 + fetch-cookie@3.0.1: dependencies: set-cookie-parser: 2.7.1 @@ -43032,7 +42774,7 @@ snapshots: finalhandler@2.1.1: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -43119,11 +42861,11 @@ snapshots: follow-redirects@1.15.9(debug@4.4.0): optionalDependencies: - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.0 follow-redirects@1.15.9(debug@4.4.3): optionalDependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) fontace@0.4.0: dependencies: @@ -43150,7 +42892,7 @@ snapshots: fork-ts-checker-webpack-plugin@6.5.3(eslint@9.23.0(jiti@2.6.1))(typescript@5.9.3)(webpack@5.98.0): dependencies: - '@babel/code-frame': 7.28.6 + '@babel/code-frame': 7.29.0 '@types/json-schema': 7.0.15 chalk: 4.1.2 chokidar: 3.6.0 @@ -43170,7 +42912,7 @@ snapshots: fork-ts-checker-webpack-plugin@9.1.0(typescript@5.9.3)(webpack@5.98.0(@swc/core@1.15.10)): dependencies: - '@babel/code-frame': 7.28.6 + '@babel/code-frame': 7.29.0 chalk: 4.1.2 chokidar: 4.0.3 cosmiconfig: 8.3.6(typescript@5.9.3) @@ -43440,7 +43182,7 @@ snapshots: - supports-color - vitest - fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4): + fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76): dependencies: '@formatjs/intl-localematcher': 0.7.5 '@orama/orama': 3.1.18 @@ -43464,21 +43206,21 @@ snapshots: optionalDependencies: '@types/react': 19.2.7 lucide-react: 0.562.0(react@19.2.1) - next: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + next: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) react: 19.2.1 react-dom: 19.2.1(react@19.2.1) - zod: 3.24.4 + zod: 3.25.76 transitivePeerDependencies: - supports-color - fumadocs-mdx@14.2.5(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1)(vite@6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.0)): + fumadocs-mdx@14.2.5(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react@19.2.1)(vite@6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.0)): dependencies: '@mdx-js/mdx': 3.1.1 '@standard-schema/spec': 1.1.0 chokidar: 5.0.0 esbuild: 0.27.2 estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4) + fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) js-yaml: 4.1.1 mdast-util-to-markdown: 2.1.2 picocolors: 1.1.1 @@ -43493,13 +43235,13 @@ snapshots: zod: 4.3.5 optionalDependencies: '@types/react': 19.2.7 - next: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + next: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) react: 19.2.1 vite: 6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.0) transitivePeerDependencies: - supports-color - fumadocs-openapi@10.2.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1): + fumadocs-openapi@10.2.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(prettier@3.5.3)(react-dom@19.2.1(react@19.2.1))(react@19.2.1): dependencies: '@fumari/json-schema-to-typescript': 2.0.0(prettier@3.5.3) '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -43510,8 +43252,8 @@ snapshots: '@scalar/openapi-parser': 0.23.9 ajv: 8.17.1 class-variance-authority: 0.7.1 - fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4) - fumadocs-ui: 16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) + fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) + fumadocs-ui: 16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) github-slugger: 2.0.0 hast-util-to-jsx-runtime: 2.3.6 js-yaml: 4.1.1 @@ -43533,10 +43275,10 @@ snapshots: - prettier - supports-color - fumadocs-typescript@5.0.1(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(react@19.2.1)(typescript@5.9.3): + fumadocs-typescript@5.0.1(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6))(react@19.2.1)(typescript@5.9.3): dependencies: estree-util-value-to-estree: 3.5.0 - fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4) + fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) hast-util-to-estree: 3.1.3 hast-util-to-jsx-runtime: 2.3.6 react: 19.2.1 @@ -43548,13 +43290,13 @@ snapshots: unist-util-visit: 5.0.0 optionalDependencies: '@types/react': 19.2.7 - fumadocs-ui: 16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) + fumadocs-ui: 16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) transitivePeerDependencies: - supports-color - fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6): + fumadocs-ui@16.4.7(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6): dependencies: - '@fumadocs/ui': 16.4.7(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) + '@fumadocs/ui': 16.4.7(@types/react@19.2.7)(fumadocs-core@16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(tailwindcss@4.1.6) '@radix-ui/react-accordion': 1.2.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@radix-ui/react-collapsible': 1.1.12(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) '@radix-ui/react-dialog': 1.1.15(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) @@ -43566,7 +43308,7 @@ snapshots: '@radix-ui/react-slot': 1.2.4(@types/react@19.2.7)(react@19.2.1) '@radix-ui/react-tabs': 1.1.13(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.1(react@19.2.1))(react@19.2.1) class-variance-authority: 0.7.1 - fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.24.4) + fumadocs-core: 16.4.7(@types/react@19.2.7)(lucide-react@0.562.0(react@19.2.1))(next@16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1))(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(zod@3.25.76) lucide-react: 0.562.0(react@19.2.1) next-themes: 0.4.6(react-dom@19.2.1(react@19.2.1))(react@19.2.1) react: 19.2.1 @@ -43575,7 +43317,7 @@ snapshots: scroll-into-view-if-needed: 3.1.0 optionalDependencies: '@types/react': 19.2.7 - next: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + next: 16.1.1(@babel/core@7.28.6)(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) tailwindcss: 4.1.6 transitivePeerDependencies: - '@types/react-dom' @@ -43663,7 +43405,7 @@ snapshots: dependencies: basic-ftp: 5.2.0 data-uri-to-buffer: 6.0.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -43882,18 +43624,6 @@ snapshots: dependencies: duplexer: 0.1.2 - h3@1.15.1: - dependencies: - cookie-es: 1.2.2 - crossws: 0.3.4 - defu: 6.1.4 - destr: 2.0.3 - iron-webcrypto: 1.2.1 - node-mock-http: 1.0.0 - radix3: 1.1.2 - ufo: 1.5.4 - uncrypto: 0.1.3 - h3@1.15.5: dependencies: cookie-es: 1.2.2 @@ -43905,7 +43635,6 @@ snapshots: radix3: 1.1.2 ufo: 1.6.3 uncrypto: 0.1.3 - optional: true hamt-sharding@2.0.1: dependencies: @@ -43946,7 +43675,7 @@ snapshots: boxen: 5.1.2 chokidar: 4.0.3 ci-info: 2.0.0 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.0 enquirer: 2.4.1 env-paths: 2.2.1 ethereum-cryptography: 1.2.0 @@ -44302,14 +44031,14 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.3 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -44336,14 +44065,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.3 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -44503,7 +44232,7 @@ snapshots: dependencies: '@ioredis/commands': 1.3.0 cluster-key-slot: 1.1.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -44661,6 +44390,8 @@ snapshots: is-retry-allowed@2.2.0: {} + is-retry-allowed@3.0.0: {} + is-root@2.1.0: {} is-stream@2.0.1: {} @@ -44764,7 +44495,7 @@ snapshots: istanbul-lib-instrument@5.2.1: dependencies: '@babel/core': 7.28.6 - '@babel/parser': 7.28.6 + '@babel/parser': 7.29.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 6.3.1 @@ -44774,7 +44505,7 @@ snapshots: istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.28.6 - '@babel/parser': 7.28.6 + '@babel/parser': 7.29.0 '@istanbuljs/schema': 0.1.3 istanbul-lib-coverage: 3.2.2 semver: 7.7.3 @@ -44789,7 +44520,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -45481,10 +45212,10 @@ snapshots: jest-snapshot@29.7.0: dependencies: '@babel/core': 7.28.6 - '@babel/generator': 7.28.6 + '@babel/generator': 7.29.0 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.6) '@babel/plugin-syntax-typescript': 7.27.1(@babel/core@7.28.6) - '@babel/types': 7.28.6 + '@babel/types': 7.29.0 '@jest/expect-utils': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 @@ -45617,8 +45348,6 @@ snapshots: jiti@1.21.7: {} - jiti@2.4.2: {} - jiti@2.6.1: {} jito-ts@3.0.1(bufferutil@4.0.9)(encoding@0.1.13)(utf-8-validate@5.0.10): @@ -45723,7 +45452,7 @@ snapshots: jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): dependencies: abab: 2.0.6 - acorn: 8.14.1 + acorn: 8.16.0 acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 @@ -45757,7 +45486,7 @@ snapshots: jsdom@20.0.3(bufferutil@4.0.9)(utf-8-validate@6.0.3): dependencies: abab: 2.0.6 - acorn: 8.14.1 + acorn: 8.16.0 acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 @@ -46208,18 +45937,14 @@ snapshots: lz-string@1.5.0: {} - magic-string@0.30.19: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.5 - magic-string@0.30.21: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 magicast@0.5.1: dependencies: - '@babel/parser': 7.28.6 - '@babel/types': 7.28.6 + '@babel/parser': 7.29.0 + '@babel/types': 7.29.0 source-map-js: 1.2.1 optional: true @@ -46256,7 +45981,7 @@ snapshots: match-sorter@8.1.0: dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.6 remove-accents: 0.5.0 math-intrinsics@1.1.0: {} @@ -46281,7 +46006,7 @@ snapshots: '@types/mdast': 4.0.4 escape-string-regexp: 5.0.0 unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 + unist-util-visit-parents: 6.0.2 mdast-util-from-markdown@2.0.2: dependencies: @@ -46944,7 +46669,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) decode-named-character-reference: 1.1.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -47063,10 +46788,6 @@ snapshots: minipass: 3.3.6 yallist: 4.0.0 - minizlib@3.0.2: - dependencies: - minipass: 7.1.2 - minizlib@3.1.0: dependencies: minipass: 7.1.2 @@ -47111,7 +46832,7 @@ snapshots: ansi-colors: 4.1.3 browser-stdout: 1.3.1 chokidar: 3.6.0 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) diff: 5.2.0 escape-string-regexp: 4.0.0 find-up: 5.0.0 @@ -47440,7 +47161,7 @@ snapshots: '@next/env': 16.1.1 '@swc/helpers': 0.5.15 baseline-browser-mapping: 2.9.14 - caniuse-lite: 1.0.30001707 + caniuse-lite: 1.0.30001765 postcss: 8.4.31 react: 19.2.1 react-dom: 19.2.1(react@19.2.1) @@ -47462,12 +47183,12 @@ snapshots: - '@babel/core' - babel-plugin-macros - next@16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1): + next@16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1): dependencies: '@next/env': 16.1.1 '@swc/helpers': 0.5.15 baseline-browser-mapping: 2.9.14 - caniuse-lite: 1.0.30001707 + caniuse-lite: 1.0.30001765 postcss: 8.4.31 react: 19.2.1 react-dom: 19.2.1(react@19.2.1) @@ -47482,12 +47203,12 @@ snapshots: '@next/swc-win32-arm64-msvc': 16.1.1 '@next/swc-win32-x64-msvc': 16.1.1 '@opentelemetry/api': 1.9.0 - babel-plugin-react-compiler: 19.1.0-rc.1 sass: 1.86.1 sharp: 0.34.5 transitivePeerDependencies: - '@babel/core' - babel-plugin-macros + optional: true nise@6.1.1: dependencies: @@ -47495,7 +47216,7 @@ snapshots: '@sinonjs/fake-timers': 13.0.5 '@sinonjs/text-encoding': 0.7.3 just-extend: 6.2.0 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 nlcst-to-string@4.0.0: dependencies: @@ -47527,10 +47248,7 @@ snapshots: node-downloader-helper@2.1.9: {} - node-fetch-native@1.6.6: {} - - node-fetch-native@1.6.7: - optional: true + node-fetch-native@1.6.7: {} node-fetch@2.6.7(encoding@0.1.13): dependencies: @@ -47569,10 +47287,7 @@ snapshots: node-int64@0.4.0: {} - node-mock-http@1.0.0: {} - - node-mock-http@1.0.4: - optional: true + node-mock-http@1.0.4: {} node-polyfill-webpack-plugin@2.0.1(webpack@5.98.0(@swc/core@1.15.10)): dependencies: @@ -47603,8 +47318,6 @@ snapshots: vm-browserify: 1.1.2 webpack: 5.98.0(@swc/core@1.15.10) - node-releases@2.0.19: {} - node-releases@2.0.27: {} nofilter@3.1.0: {} @@ -47664,7 +47377,7 @@ snapshots: '@standard-schema/spec': 1.0.0 react: 19.2.1 optionalDependencies: - next: 16.1.1(@opentelemetry/api@1.9.0)(babel-plugin-react-compiler@19.1.0-rc.1)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) + next: 16.1.1(@opentelemetry/api@1.9.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(sass@1.86.1) nwsapi@2.2.20: {} @@ -47718,18 +47431,11 @@ snapshots: dependencies: http-https: 1.0.0 - ofetch@1.4.1: - dependencies: - destr: 2.0.3 - node-fetch-native: 1.6.6 - ufo: 1.5.4 - ofetch@1.5.1: dependencies: destr: 2.0.5 node-fetch-native: 1.6.7 ufo: 1.6.3 - optional: true ohash@2.0.11: optional: true @@ -47798,7 +47504,7 @@ snapshots: dependencies: '@apidevtools/swagger-parser': 10.1.1(openapi-types@12.1.3) '@liuli-util/fs-extra': 0.1.0 - '@zodios/core': 10.9.6(axios@1.8.4)(zod@3.24.4) + '@zodios/core': 10.9.6(axios@1.8.4)(zod@3.25.76) axios: 1.8.4(debug@4.4.3) cac: 6.7.14 handlebars: 4.7.8 @@ -47809,7 +47515,7 @@ snapshots: tanu: 0.1.13 ts-pattern: 5.7.0 whence: 2.0.2 - zod: 3.24.4 + zod: 3.25.76 transitivePeerDependencies: - debug - react @@ -47882,28 +47588,14 @@ snapshots: transitivePeerDependencies: - zod - ox@0.6.7(typescript@5.9.3)(zod@3.24.4): - dependencies: - '@adraffy/ens-normalize': 1.11.0 - '@noble/curves': 1.9.6 - '@noble/hashes': 1.8.0 - '@scure/bip32': 1.7.0 - '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3)(zod@3.24.4) - eventemitter3: 5.0.1 - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - zod - - ox@0.6.9(typescript@5.9.3)(zod@3.24.4): + ox@0.6.7(typescript@5.9.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/curves': 1.9.6 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.8(typescript@5.9.3)(zod@3.24.4) + abitype: 1.1.0(typescript@5.9.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 @@ -47917,14 +47609,14 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.0.8(typescript@5.9.3)(zod@3.25.76) + abitype: 1.1.0(typescript@5.9.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: - zod - ox@0.9.6(typescript@5.9.3)(zod@3.24.4): + ox@0.9.6(typescript@5.9.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.0 '@noble/ciphers': 1.3.0 @@ -47932,7 +47624,7 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3)(zod@3.24.4) + abitype: 1.1.0(typescript@5.9.3)(zod@3.25.76) eventemitter3: 5.0.1 optionalDependencies: typescript: 5.9.3 @@ -48034,7 +47726,7 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.3 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) get-uri: 6.0.5 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -48097,7 +47789,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.28.6 + '@babel/code-frame': 7.29.0 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -48630,7 +48322,7 @@ snapshots: proxy-agent@6.4.0: dependencies: agent-base: 7.1.3 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 lru-cache: 7.18.3 @@ -48832,7 +48524,7 @@ snapshots: dependencies: '@assemblyscript/loader': 0.9.4 bl: 5.1.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) minimist: 1.2.8 node-fetch: 2.7.0(encoding@0.1.13) readable-stream: 3.6.2 @@ -48914,7 +48606,7 @@ snapshots: react-aria: 3.42.0(react-dom@19.2.1(react@19.2.1))(react@19.2.1) react-dom: 19.2.1(react@19.2.1) react-stately: 3.40.0(react@19.2.1) - use-sync-external-store: 1.5.0(react@19.2.1) + use-sync-external-store: 1.6.0(react@19.2.1) react-aria@3.42.0(react-dom@19.2.1(react@19.2.1))(react@19.2.1): dependencies: @@ -48965,9 +48657,9 @@ snapshots: react-dev-utils@12.0.1(eslint@9.23.0(jiti@2.6.1))(typescript@5.9.3)(webpack@5.98.0): dependencies: - '@babel/code-frame': 7.28.6 + '@babel/code-frame': 7.29.0 address: 1.2.2 - browserslist: 4.24.4 + browserslist: 4.28.1 chalk: 4.1.2 cross-spawn: 7.0.6 detect-port-alt: 1.1.6 @@ -49012,14 +48704,14 @@ snapshots: react-docgen@7.1.1: dependencies: '@babel/core': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.7 '@types/doctrine': 0.0.9 '@types/resolve': 1.20.6 doctrine: 3.0.0 - resolve: 1.22.10 + resolve: 1.22.11 strip-indent: 4.0.0 transitivePeerDependencies: - supports-color @@ -49027,14 +48719,14 @@ snapshots: react-docgen@8.0.2: dependencies: '@babel/core': 7.28.6 - '@babel/traverse': 7.28.6(supports-color@5.5.0) - '@babel/types': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 '@types/babel__core': 7.20.5 '@types/babel__traverse': 7.20.7 '@types/doctrine': 0.0.9 '@types/resolve': 1.20.6 doctrine: 3.0.0 - resolve: 1.22.10 + resolve: 1.22.11 strip-indent: 4.0.0 transitivePeerDependencies: - supports-color @@ -49227,7 +48919,7 @@ snapshots: react-transition-group@4.4.5(react-dom@19.2.1(react@19.2.1))(react@19.2.1): dependencies: - '@babel/runtime': 7.27.0 + '@babel/runtime': 7.28.6 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 @@ -49350,7 +49042,7 @@ snapshots: rechoir@0.6.2: dependencies: - resolve: 1.22.10 + resolve: 1.22.11 recma-build-jsx@1.0.0: dependencies: @@ -49358,9 +49050,9 @@ snapshots: estree-util-build-jsx: 3.0.1 vfile: 6.0.3 - recma-jsx@1.0.0(acorn@8.14.1): + recma-jsx@1.0.0(acorn@8.16.0): dependencies: - acorn-jsx: 5.3.2(acorn@8.14.1) + acorn-jsx: 5.3.2(acorn@8.16.0) estree-util-to-js: 2.0.0 recma-parse: 1.0.0 recma-stringify: 1.0.0 @@ -49598,13 +49290,20 @@ snapshots: requestidlecallback@0.3.0: {} + require-addon@1.2.0: + dependencies: + bare-addon-resolve: 1.10.0 + transitivePeerDependencies: + - bare-url + optional: true + require-directory@2.1.1: {} require-from-string@2.0.2: {} require-in-the-middle@7.5.2: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) module-details-from-path: 1.0.3 resolve: 1.22.11 transitivePeerDependencies: @@ -49825,7 +49524,7 @@ snapshots: router@2.2.0: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 @@ -50040,7 +49739,7 @@ snapshots: send@1.2.1: dependencies: - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -50294,7 +49993,7 @@ snapshots: '@babel/core': 7.28.6 '@babel/preset-env': 7.29.0(@babel/core@7.28.6) '@babel/preset-typescript': 7.28.5(@babel/core@7.28.6) - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0 chokidar: 5.0.0 csstype: 3.2.3 deepmerge: 4.3.1 @@ -50413,7 +50112,7 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.3 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) socks: 2.8.4 transitivePeerDependencies: - supports-color @@ -50423,6 +50122,13 @@ snapshots: ip-address: 9.0.5 smart-buffer: 4.2.0 + sodium-native@4.3.3: + dependencies: + require-addon: 1.2.0 + transitivePeerDependencies: + - bare-url + optional: true + solc@0.8.26(debug@4.4.0): dependencies: command-exists: 1.2.9 @@ -50487,8 +50193,6 @@ snapshots: source-map@0.6.1: {} - source-map@0.7.4: {} - source-map@0.7.6: {} space-separated-tokens@2.0.2: {} @@ -50587,7 +50291,7 @@ snapshots: open: 10.2.0 recast: 0.23.11 semver: 7.7.3 - use-sync-external-store: 1.5.0(react@19.2.1) + use-sync-external-store: 1.6.0(react@19.2.1) ws: 8.19.0(bufferutil@4.0.9)(utf-8-validate@6.0.3) optionalDependencies: prettier: 3.5.3 @@ -50753,7 +50457,7 @@ snapshots: styled-components@5.3.11(@babel/core@7.28.6)(react-dom@19.2.1(react@19.2.1))(react-is@18.3.1)(react@19.2.1): dependencies: '@babel/helper-module-imports': 7.28.6(supports-color@5.5.0) - '@babel/traverse': 7.28.6(supports-color@5.5.0) + '@babel/traverse': 7.29.0(supports-color@5.5.0) '@emotion/is-prop-valid': 1.3.1 '@emotion/stylis': 0.8.5 '@emotion/unitless': 0.7.5 @@ -50825,7 +50529,7 @@ snapshots: cosmiconfig: 9.0.0(typescript@5.9.3) css-functions-list: 3.2.3 css-tree: 3.1.0 - debug: 4.4.0(supports-color@8.1.1) + debug: 4.4.3(supports-color@8.1.1) fast-glob: 3.3.3 fastest-levenshtein: 1.0.16 file-entry-cache: 10.0.7 @@ -50973,7 +50677,7 @@ snapshots: dependencies: dequal: 2.0.3 react: 19.2.1 - use-sync-external-store: 1.5.0(react@19.2.1) + use-sync-external-store: 1.6.0(react@19.2.1) symbol-observable@2.0.3: {} @@ -50983,8 +50687,6 @@ snapshots: symbol.inspect@1.0.1: {} - tabbable@6.2.0: {} - tabbable@6.4.0: {} table-layout@4.1.1: @@ -51145,15 +50847,6 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 - tar@7.4.3: - dependencies: - '@isaacs/fs-minipass': 4.0.1 - chownr: 3.0.0 - minipass: 7.1.2 - minizlib: 3.0.2 - mkdirp: 3.0.1 - yallist: 5.0.0 - tar@7.5.7: dependencies: '@isaacs/fs-minipass': 4.0.1 @@ -51189,7 +50882,7 @@ snapshots: terser@5.39.0: dependencies: '@jridgewell/source-map': 0.3.6 - acorn: 8.14.1 + acorn: 8.16.0 commander: 2.20.3 source-map-support: 0.5.21 @@ -51518,7 +51211,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 16.18.11 - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -51538,7 +51231,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 22.14.0 - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -51559,7 +51252,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 16.18.126 - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -51579,7 +51272,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 16.18.126 - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -51600,7 +51293,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 18.19.86 - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -51620,7 +51313,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 20.17.30 - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -51640,7 +51333,7 @@ snapshots: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.4 '@types/node': 22.14.0 - acorn: 8.14.1 + acorn: 8.16.0 acorn-walk: 8.3.4 arg: 4.1.3 create-require: 1.1.1 @@ -51709,7 +51402,7 @@ snapshots: cac: 6.7.14 chokidar: 4.0.3 consola: 3.4.2 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) esbuild: 0.27.2 fix-dts-default-cjs-exports: 1.0.1 joycon: 3.1.1 @@ -51807,10 +51500,6 @@ snapshots: type-fest@4.39.0: {} - type-fest@5.4.0: - dependencies: - tagged-tag: 1.0.0 - type-fest@5.4.3: dependencies: tagged-tag: 1.0.0 @@ -51858,8 +51547,6 @@ snapshots: ua-parser-js@1.0.40: {} - ufo@1.5.4: {} - ufo@1.6.3: {} uglify-js@3.19.3: {} @@ -51995,13 +51682,12 @@ snapshots: dependencies: '@types/unist': 3.0.3 unist-util-is: 6.0.0 - optional: true unist-util-visit@5.0.0: dependencies: '@types/unist': 3.0.3 unist-util-is: 6.0.0 - unist-util-visit-parents: 6.0.1 + unist-util-visit-parents: 6.0.2 universalify@0.1.2: {} @@ -52013,22 +51699,7 @@ snapshots: unpipe@1.0.0: {} - unstorage@1.15.0(@vercel/blob@2.3.0)(idb-keyval@6.2.1)(ioredis@5.7.0): - dependencies: - anymatch: 3.1.3 - chokidar: 4.0.3 - destr: 2.0.3 - h3: 1.15.1 - lru-cache: 10.4.3 - node-fetch-native: 1.6.6 - ofetch: 1.4.1 - ufo: 1.5.4 - optionalDependencies: - '@vercel/blob': 2.3.0 - idb-keyval: 6.2.1 - ioredis: 5.7.0 - - unstorage@1.17.4(@vercel/blob@2.3.0)(idb-keyval@6.2.1)(ioredis@5.7.0): + unstorage@1.17.4(@vercel/blob@2.3.0)(@vercel/functions@2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0))(idb-keyval@6.2.1)(ioredis@5.7.0): dependencies: anymatch: 3.1.3 chokidar: 5.0.0 @@ -52040,20 +51711,14 @@ snapshots: ufo: 1.6.3 optionalDependencies: '@vercel/blob': 2.3.0 + '@vercel/functions': 2.0.0(@aws-sdk/credential-provider-web-identity@3.777.0) idb-keyval: 6.2.1 ioredis: 5.7.0 - optional: true until-async@3.0.2: {} untildify@4.0.0: {} - update-browserslist-db@1.1.3(browserslist@4.24.4): - dependencies: - browserslist: 4.24.4 - escalade: 3.2.0 - picocolors: 1.1.1 - update-browserslist-db@1.2.3(browserslist@4.28.1): dependencies: browserslist: 4.28.1 @@ -52084,7 +51749,7 @@ snapshots: url@0.11.4: dependencies: punycode: 1.4.1 - qs: 6.14.0 + qs: 6.15.0 usb@2.15.0: dependencies: @@ -52125,10 +51790,6 @@ snapshots: dependencies: react: 19.2.1 - use-sync-external-store@1.5.0(react@19.2.1): - dependencies: - react: 19.2.1 - use-sync-external-store@1.6.0(react@19.2.1): dependencies: react: 19.2.1 @@ -52323,15 +51984,15 @@ snapshots: - utf-8-validate - zod - viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4): + viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.8.1 '@noble/hashes': 1.7.1 '@scure/bip32': 1.6.2 '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.3)(zod@3.24.4) + abitype: 1.0.8(typescript@5.9.3)(zod@3.25.76) isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.6.7(typescript@5.9.3)(zod@3.24.4) + ox: 0.6.7(typescript@5.9.3)(zod@3.25.76) ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -52340,23 +52001,6 @@ snapshots: - utf-8-validate - zod - viem@2.24.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4): - dependencies: - '@noble/curves': 1.8.1 - '@noble/hashes': 1.7.1 - '@scure/bip32': 1.6.2 - '@scure/bip39': 1.5.4 - abitype: 1.0.8(typescript@5.9.3)(zod@3.24.4) - isows: 1.0.6(ws@8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.6.9(typescript@5.9.3)(zod@3.24.4) - ws: 8.18.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) - optionalDependencies: - typescript: 5.9.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - - zod - viem@2.24.3(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.8.1 @@ -52374,15 +52018,15 @@ snapshots: - utf-8-validate - zod - viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4): + viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3)(zod@3.24.4) + abitype: 1.1.0(typescript@5.9.3)(zod@3.25.76) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) - ox: 0.9.6(typescript@5.9.3)(zod@3.24.4) + ox: 0.9.6(typescript@5.9.3)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) optionalDependencies: typescript: 5.9.3 @@ -52408,15 +52052,15 @@ snapshots: - utf-8-validate - zod - viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.24.4): + viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@6.0.3)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.1.0(typescript@5.9.3)(zod@3.24.4) + abitype: 1.1.0(typescript@5.9.3)(zod@3.25.76) isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3)) - ox: 0.9.6(typescript@5.9.3)(zod@3.24.4) + ox: 0.9.6(typescript@5.9.3)(zod@3.25.76) ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@6.0.3) optionalDependencies: typescript: 5.9.3 @@ -52428,7 +52072,7 @@ snapshots: vite-node@3.0.9(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 vite: 6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.20.6)(yaml@2.8.0) @@ -52449,7 +52093,7 @@ snapshots: vite-node@3.0.9(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.7.1): dependencies: cac: 6.7.14 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 vite: 6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.7.1) @@ -52470,7 +52114,7 @@ snapshots: vite-node@3.0.9(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.0): dependencies: cac: 6.7.14 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) es-module-lexer: 1.7.0 pathe: 2.0.3 vite: 6.4.1(@types/node@22.14.0)(jiti@2.6.1)(lightningcss@1.29.2)(sass@1.86.1)(terser@5.39.0)(tsx@4.21.0)(yaml@2.8.0) @@ -52557,7 +52201,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) expect-type: 1.2.2 magic-string: 0.30.21 pathe: 2.0.3 @@ -52598,7 +52242,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) expect-type: 1.2.2 magic-string: 0.30.21 pathe: 2.0.3 @@ -52639,7 +52283,7 @@ snapshots: '@vitest/spy': 3.0.9 '@vitest/utils': 3.0.9 chai: 5.2.0 - debug: 4.4.3(supports-color@5.5.0) + debug: 4.4.3(supports-color@8.1.1) expect-type: 1.2.2 magic-string: 0.30.21 pathe: 2.0.3 @@ -52684,14 +52328,14 @@ snapshots: dependencies: xml-name-validator: 4.0.0 - wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4): + wagmi@2.14.16(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@tanstack/query-core@5.71.5)(@tanstack/react-query@5.71.5(react@19.2.1))(@types/react@19.2.7)(@vercel/blob@2.3.0)(bufferutil@4.0.9)(encoding@0.1.13)(immer@9.0.21)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): dependencies: '@tanstack/react-query': 5.71.5(react@19.2.1) - '@wagmi/connectors': 5.7.12(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(@wagmi/core@2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4))(zod@3.24.4) - '@wagmi/core': 2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4)) + '@wagmi/connectors': 5.7.12(@react-native-async-storage/async-storage@1.24.0(react-native@0.78.2(@babel/core@7.28.6)(@babel/preset-env@7.29.0(@babel/core@7.28.6))(@types/react@19.2.7)(bufferutil@4.0.9)(react@19.2.1)(utf-8-validate@5.0.10)))(@types/react@19.2.7)(@vercel/blob@2.3.0)(@wagmi/core@2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(encoding@0.1.13)(ioredis@5.7.0)(react@19.2.1)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.16.7(@tanstack/query-core@5.71.5)(@types/react@19.2.7)(immer@9.0.21)(react@19.2.1)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.1))(viem@2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) react: 19.2.1 use-sync-external-store: 1.4.0(react@19.2.1) - viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.24.4) + viem: 2.42.1(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -52710,6 +52354,7 @@ snapshots: - '@types/react' - '@upstash/redis' - '@vercel/blob' + - '@vercel/functions' - '@vercel/kv' - aws4fetch - bufferutil @@ -53470,11 +53115,11 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.14.1 - browserslist: 4.24.4 + acorn: 8.16.0 + browserslist: 4.28.1 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.1 - es-module-lexer: 1.6.0 + es-module-lexer: 1.7.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -53500,11 +53145,11 @@ snapshots: '@webassemblyjs/ast': 1.14.1 '@webassemblyjs/wasm-edit': 1.14.1 '@webassemblyjs/wasm-parser': 1.14.1 - acorn: 8.14.1 - browserslist: 4.24.4 + acorn: 8.16.0 + browserslist: 4.28.1 chrome-trace-event: 1.0.4 enhanced-resolve: 5.18.1 - es-module-lexer: 1.6.0 + es-module-lexer: 1.7.0 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -54013,9 +53658,9 @@ snapshots: dependencies: ethers: 5.8.0(bufferutil@4.0.7)(utf-8-validate@6.0.3) - zod-search-params@0.1.6(zod@3.24.4): + zod-search-params@0.1.6(zod@3.25.76): dependencies: - zod: 3.24.4 + zod: 3.25.76 zod-to-json-schema@3.25.1(zod@3.25.76): dependencies: @@ -54027,16 +53672,14 @@ snapshots: zod: 3.25.76 optional: true - zod-validation-error@3.4.0(zod@3.24.4): + zod-validation-error@3.4.0(zod@3.25.76): dependencies: - zod: 3.24.4 + zod: 3.25.76 zod@3.22.4: {} zod@3.24.2: {} - zod@3.24.4: {} - zod@3.25.76: {} zod@4.3.5: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 1a6f83469c..6ef6216525 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -45,6 +45,7 @@ packages: - contract_manager - lazer/contracts/sui/sdk/js - lazer/contracts/cardano/sdk/js + - lazer/contracts/stellar/scripts/e2e catalog: "@amplitude/analytics-browser": ^2.13.0