From fba3831777ff07331b73159fee8b78f32b31dd2b Mon Sep 17 00:00:00 2001 From: Jethro Irmiya Date: Sun, 16 Aug 2026 08:48:18 +0100 Subject: [PATCH 1/8] =?UTF-8?q?feat(contract):=20StelFlow=20Core=20?= =?UTF-8?q?=E2=80=94=20streaming=20with=20milestone=20gates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The first code in the repo. Implements every decision Phase 0 settled, with the behaviour specs turned into 75 passing tests. Entry points: create_stream, withdraw, approve_milestone, cancel, touch, plus pause/unpause/transfer_pauser/renounce_pauser. Design decisions made real: - No upgrade function exists. Not gated, not admin-guarded — absent (#33). - Pause reaches create_stream and nothing else, expires after 30 days, and can be renounced permanently (#33). - cancel takes the recipient's authorization alongside the sender's when cancelable=false, settling under identical rules (#33). - create_stream stores the measured balance delta, never the requested amount (#32). - Milestone state is monotonic; Met is terminal; double approval is a silent no-op with auth still checked first (#17, #32). - Milestones carry an optional deadline resolving to a party named at creation (#38). Constrained to >= end so expiry never resolves a still-accruing tranche. - Stream ids are a monotonic counter (architecture.md open question 1). - No TTL constant is compiled in; thresholds derive from max_ttl() at call time, since #33 left no admin who could retune a stored one. Structure worth noting: accrual.rs is pure functions over a Stream and a timestamp, so the property tests hammer the maths directly. Milestone state, deadline, and expiry policy collapse into one Resolution enum that every call site folds over — a milestone cannot mean one thing to withdraw and another to cancel. Events use #[contractevent], so each carries a named map rather than a positional tuple and appears in the generated interface. Adding a field later cannot shift what an existing consumer parses. Two invariants are asserted separately because they catch different things: value conservation (deposit == withdrawn + refunded + remaining) is a closure check that balances even if one stream were paid from another's deposit, so per-stream solvency (payout <= total - withdrawn) is checked on its own. The contract's token balance is pooled; that assertion is what keeps streams isolated, and it is the reason a withdrawal pause isn't needed. One bug caught by the tests: initialize consumed stream id 0, so the first real stream was id 1. Fixed by arming the counter rather than drawing from it. Verification: 75/75 tests pass, clippy clean on both targets, cargo fmt clean, 49,139-byte wasm. Co-Authored-By: Claude Opus 5 --- .cargo/config.toml | 11 + .github/PULL_REQUEST_TEMPLATE.md | 2 +- .gitignore | 9 + Cargo.lock | 2121 +++++++++++++++++ Cargo.toml | 29 + README.md | 12 +- contracts/stelflow/Cargo.toml | 17 + contracts/stelflow/README.md | 51 + contracts/stelflow/src/accrual.rs | 209 ++ contracts/stelflow/src/error.rs | 72 + contracts/stelflow/src/events.rs | 117 + contracts/stelflow/src/lib.rs | 464 ++++ contracts/stelflow/src/storage.rs | 164 ++ .../stelflow/src/tests/accrual_properties.rs | 192 ++ contracts/stelflow/src/tests/approve.rs | 234 ++ contracts/stelflow/src/tests/cancel.rs | 240 ++ contracts/stelflow/src/tests/create.rs | 405 ++++ contracts/stelflow/src/tests/mod.rs | 183 ++ contracts/stelflow/src/tests/pause.rs | 170 ++ contracts/stelflow/src/tests/withdraw.rs | 224 ++ contracts/stelflow/src/types.rs | 125 + CODE_OF_CONDUCT.md => docs/CODE_OF_CONDUCT.md | 0 CONTRIBUTING.md => docs/CONTRIBUTING.md | 8 +- CONTRIBUTORS.md => docs/CONTRIBUTORS.md | 6 +- ROADMAP.md => docs/ROADMAP.md | 14 +- SECURITY.md => docs/SECURITY.md | 6 +- docs/architecture.md | 20 +- docs/{specs => }/behaviour.md | 16 +- docs/concepts.md | 8 +- docs/dev-setup.md | 16 +- docs/faq.md | 26 +- docs/{research => }/indexer-design.md | 16 +- docs/milestone-deadlines.md | 145 ++ docs/{research => }/milestone-revocation.md | 12 +- docs/{research => }/threat-model.md | 48 +- docs/{research => }/ttl-strategy.md | 12 +- .../upgradeability-and-pause.md | 14 +- 37 files changed, 5300 insertions(+), 118 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 contracts/stelflow/Cargo.toml create mode 100644 contracts/stelflow/README.md create mode 100644 contracts/stelflow/src/accrual.rs create mode 100644 contracts/stelflow/src/error.rs create mode 100644 contracts/stelflow/src/events.rs create mode 100644 contracts/stelflow/src/lib.rs create mode 100644 contracts/stelflow/src/storage.rs create mode 100644 contracts/stelflow/src/tests/accrual_properties.rs create mode 100644 contracts/stelflow/src/tests/approve.rs create mode 100644 contracts/stelflow/src/tests/cancel.rs create mode 100644 contracts/stelflow/src/tests/create.rs create mode 100644 contracts/stelflow/src/tests/mod.rs create mode 100644 contracts/stelflow/src/tests/pause.rs create mode 100644 contracts/stelflow/src/tests/withdraw.rs create mode 100644 contracts/stelflow/src/types.rs rename CODE_OF_CONDUCT.md => docs/CODE_OF_CONDUCT.md (100%) rename CONTRIBUTING.md => docs/CONTRIBUTING.md (88%) rename CONTRIBUTORS.md => docs/CONTRIBUTORS.md (74%) rename ROADMAP.md => docs/ROADMAP.md (88%) rename SECURITY.md => docs/SECURITY.md (88%) rename docs/{specs => }/behaviour.md (97%) rename docs/{research => }/indexer-design.md (92%) create mode 100644 docs/milestone-deadlines.md rename docs/{research => }/milestone-revocation.md (94%) rename docs/{research => }/threat-model.md (93%) rename docs/{research => }/ttl-strategy.md (94%) rename docs/{research => }/upgradeability-and-pause.md (97%) diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000..ed30a77 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,11 @@ +# Soroban rejects wasm32-unknown-unknown on Rust 1.82+: that target silently +# enables reference-types and multi-value, which the Soroban environment does not +# support and which cannot easily be turned off. wasm32v1-none is the supported +# target from Rust 1.84 onward. +[build] +target = "wasm32v1-none" + +[alias] +# Tests need the host, not wasm — `cargo test` alone would try to run the +# wasm32v1-none binaries. +t = "test --target aarch64-apple-darwin" diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 3755e6d..2d1e541 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -76,7 +76,7 @@ Name it, say why, and say what it replaces. --> - [ ] Test suite passes locally - [ ] This PR does one thing - [ ] No keys, secrets, or `.env` files in the diff -- [ ] I've read [CONTRIBUTING.md](../blob/main/CONTRIBUTING.md) and agree to license this under Apache-2.0 +- [ ] I've read [CONTRIBUTING.md](https://github.com/StelFlow-labs/StelFlow/blob/main/docs/CONTRIBUTING.md) and agree to license this under Apache-2.0 ## Open questions for the reviewer diff --git a/.gitignore b/.gitignore index c914c95..573f9c0 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,12 @@ Thumbs.db tmp/ .tmp/ scratch/ + +# Soroban test snapshots — regenerated by `cargo test`, large, and not read by +# humans. The assertions in src/tests/ are the actual specification. +test_snapshots/ + +# Generated TypeScript bindings. Rebuilt from the deployed contract by +# `pnpm bindings`; committing them would let the checked-in copy drift from the +# Wasm actually on chain. +packages/stelflow-sdk/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..fd90036 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2121 @@ +# 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 = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae221649c9976a6f6c56ae1facf410f3ddb33cc661c4b7b61020a912d4237fbc" +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.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3df4dcc01ff89867cd86b0da835f23c3f02738353aaee7dde7495af71363b8d5" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-serialize", + "ark-std", +] + +[[package]] +name = "ark-bn254" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" +dependencies = [ + "ahash", + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "educe", + "fnv", + "hashbrown 0.15.5", + "itertools", + "num-bigint", + "num-integer", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "arrayvec", + "digest 0.10.7", + "educe", + "itertools", + "num-bigint", + "num-traits", + "paste", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" +dependencies = [ + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-ff-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-poly" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" +dependencies = [ + "ahash", + "ark-ff", + "ark-serialize", + "ark-std", + "educe", + "fnv", + "hashbrown 0.15.5", +] + +[[package]] +name = "ark-serialize" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "arrayvec", + "digest 0.10.7", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "ark-std" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a" +dependencies = [ + "num-traits", + "rand", +] + +[[package]] +name = "arrayvec" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" + +[[package]] +name = "autocfg" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[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 = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "bs58" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes-lit" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b04f2b1d34cb428043f14aa4c853d14294532e8bbde3b6a3bc2faaaae31a1dd" +dependencies = [ + "num-bigint", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "cc" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "509591b7bcd67f4ef775afad7662703b4935daaa6ec0e5605cfb1090b32a2b6d" +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 = "cfg_eval" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45565fc9416b9896014f5732ac776f810ee53a66730c17e4020c3ec064a8f88f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "chrono" +version = "0.4.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aa79e62e7697b8e29b513a68abacf485adcd1fe8284a4316c5ae868e6633327" +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 = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +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 = "crate-git-revision" +version = "0.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54851b5b3f24621804b1cded2820975623c205e3055d2d44031cdb1237339ac8" +dependencies = [ + "serde", + "serde_derive", + "serde_json", +] + +[[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 = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + +[[package]] +name = "ctor" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67773048316103656a637612c4a62477603b777d91d9c62ff2290f9cde178fdb" +dependencies = [ + "ctor-proc-macro", + "dtor", +] + +[[package]] +name = "ctor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2931af7e13dc045d8e9d26afccc6fa115d64e115c9c84b1166288b46f6782c2" + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "curve25519-dalek-derive", + "digest 0.10.7", + "fiat-crypto 0.2.9", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5eed333089e2e1c1ac8c6c0398e5e2497b4c9926ca6d0365ed1e099afa5bc23" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "curve25519-dalek-derive", + "digest 0.11.3", + "fiat-crypto 0.3.0", + "rustc_version", + "subtle", +] + +[[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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[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.119", +] + +[[package]] +name = "data-encoding" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06" + +[[package]] +name = "defmt" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2953bfe4f93bbd20cc71198842756f77d161884c99ebbabc41d80231ded88d1" +dependencies = [ + "bitflags", + "defmt-macros", +] + +[[package]] +name = "defmt-macros" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad9c72e7ca2137e0dc3813245a0d282fd6daad32fd800af018306a9169b5fe8" +dependencies = [ + "defmt-parser", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "defmt-parser" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" +dependencies = [ + "thiserror 2.0.20", +] + +[[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 = [ + "serde_core", +] + +[[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.119", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common 0.1.6", + "subtle", +] + +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "crypto-common 0.2.2", +] + +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + +[[package]] +name = "dtor" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "404d02eeb088a82cfd873006cb713fe411306c7d182c344905e101fb1167d301" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + +[[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 0.10.7", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[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 4.1.3", + "ed25519", + "rand_core", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "educe" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417" +dependencies = [ + "enum-ordinalize", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "either" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5e8f6c15a24b9a3ee5efec809ccd006d3b30e8b3bb63c39af737c7f87daa1d" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff", + "generic-array", + "group", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "enum-ordinalize" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89dd01549b09589510cf0647475075d12071456586d70f5c75c98ae2a5537677" +dependencies = [ + "enum-ordinalize-derive", +] + +[[package]] +name = "enum-ordinalize-derive" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a65863d15a4ce2888bd2f0f543cc963d3879c3a022c8ee43f6141d479a3ac815" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[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.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40404c3f5f511ec4da6fe866ddf6a717c309fdbb69fbbad7b0f3edab8f2e835f" + +[[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 = "fiat-crypto" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64cd1e32ddd350061ae6edb1b082d7c54915b5c672c389143b9a63403a109f24" + +[[package]] +name = "find-msvc-tools" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "futures-core" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d699e522242e69e3003b94ecc1f960f3a5e015aa7c5d7486e65ad01dd94f5e" + +[[package]] +name = "futures-task" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd417de3d1d015fc3bfd2b1ea46dfc7bab72ef86f1cc7cc9c78e728b34a6d1fd" + +[[package]] +name = "futures-util" +version = "0.3.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d50a92467f8ba5dd6e3ee5d4bd04d73ab2e4e1c44474a0674821dfce14b79bc" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[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 = "hash32" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47d60b12902ba28e2730cd37e95b8c9223af2808df9e902d4df49588d1470606" +dependencies = [ + "byteorder", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "heapless" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bfb9eb618601c89945a70e254898da93b13be0388091d42117462b265bb3fad" +dependencies = [ + "hash32", + "stable_deref_trait", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[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 0.10.7", +] + +[[package]] +name = "hybrid-array" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707114b52a152fa7bdb290cd7cd5912d9467273b6d74e21b8d81aca1f8533f6b" +dependencies = [ + "typenum", +] + +[[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.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.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.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "jiff" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668b7183bd07af9a4885f5c35b0cc5c83c4607a913c16b7e17291832910d2dcc" +dependencies = [ + "defmt", + "jiff-core", + "jiff-static", + "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde_core", + "windows-link", +] + +[[package]] +name = "jiff-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7feca88439efe53da3754500c1851dedf3cb36c524dd5cf8225cc0794de95d09" +dependencies = [ + "defmt", +] + +[[package]] +name = "jiff-static" +version = "0.2.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a69dcb3a21cfb32ce1cd056169337ca284af0766dd766e7878819b251a49204" +dependencies = [ + "jiff-core", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bd39932ad231f10513df9ab62661fead8719872150b7ad02a2df79f4e141e" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "875a5a69ac2bab1a891711cf5eccbec1ce0341ea805560dcd90b7a2e925132e8" +dependencies = [ + "jiff-tzdb", +] + +[[package]] +name = "js-sys" +version = "0.3.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e0c1080212aad755ea003d18543e8768dd432c48819efd73a7bf1e39b7a5a3a" +dependencies = [ + "cfg-if", + "futures-util", + "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", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26cec98cce3a3d96cbb7bced3c4b16e3d13f27ec56dbd62cbc8f39cfb9d653" +dependencies = [ + "cpufeatures 0.2.17", +] + +[[package]] +name = "libc" +version = "0.2.189" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eaf3ede3fee6db1a4c2ee091bf8a8b4dccdc6d17f656fb07896ee72867612f2" + +[[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.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" + +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "memchr" +version = "2.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" + +[[package]] +name = "num-bigint" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-conv" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" + +[[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.119", +] + +[[package]] +name = "num-integer" +version = "0.1.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ce2d95d4b3734dc35aa2f45e1aa22cd416814592a4f9d9205e11affd5b8e10b" +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 = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "portable-atomic" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c8b63e8d9609db387f0324918f81d68fe27748f084ef092fb35954d0539a85" + +[[package]] +name = "portable-atomic-util" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a106d1259c23fac8e543272398ae0e3c0b8d33c88ed73d0cc71b0f1d902618" +dependencies = [ + "portable-atomic", +] + +[[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.119", +] + +[[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.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22f6172bdec972074665ed81ed53b71da00bfc44b65a753cfde883ec4c702a1a" +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.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "216e8f773d7923bcba9ceb86a86c93cabb3903a11872fc3f138c49630e50b96d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9283685feec7d69af75fb0e858d5e7378f33fe4fc699383b2916ab9273e03c" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[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.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f" + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "serde", + "serde_json", +] + +[[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.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "687274d293b6cdc6e73e0fee520bf2049650090d7164f87672d212a3c530cf4a" +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", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.229" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "serde_json" +version = "1.0.151" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_with" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee78f1fbe43ac4a0e47aadb3dbd357b69eb0d3793e948624cd03dd2750ab1c0a" +dependencies = [ + "base64", + "bs58", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "jiff", + "schemars 0.8.22", + "schemars 0.9.0", + "schemars 1.2.2", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8705578779c2b6bd90d84d66eb2e206b708b1a4d7b9f17641b293545bf1c7e46" +dependencies = [ + "darling 0.23.0", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha3" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77fd7028345d415a4034cf8777cd4f8ab1851274233b45f84e3d955502d93874" +dependencies = [ + "digest 0.10.7", + "keccak", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core", +] + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" + +[[package]] +name = "soroban-builtin-sdk-macros" +version = "27.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b77bc93d930032c487cb1506b6ed166b2af49db76d52678ec4887ac621ecce01" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "soroban-env-common" +version = "27.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b22e9981cdd444f3aa6734bc58d76195bf7eca3ccf1dd432b875af5d02da068" +dependencies = [ + "arbitrary", + "crate-git-revision 0.0.6", + "ethnum", + "num-derive", + "num-traits", + "serde", + "soroban-env-macros", + "soroban-wasmi", + "static_assertions", + "stellar-xdr", + "wasmparser", +] + +[[package]] +name = "soroban-env-guest" +version = "27.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b6072f99ca6bf8e8d5b04e05d083dac785e5357d9c0f36a6658f819c2fd7d67" +dependencies = [ + "soroban-env-common", + "static_assertions", +] + +[[package]] +name = "soroban-env-host" +version = "27.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c06afd7c75ce150ce53e4d77a77645b18e3fb61856a0ddc42bfcecdc39fa3b9" +dependencies = [ + "ark-bls12-381", + "ark-bn254", + "ark-ec", + "ark-ff", + "ark-serialize", + "curve25519-dalek 5.0.0", + "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 0.0.13", + "wasmparser", +] + +[[package]] +name = "soroban-env-macros" +version = "27.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "647811bdd28a3ec40296987f6635781e5e1141c8f5affbbd53ba12b6295b7bb6" +dependencies = [ + "itertools", + "proc-macro2", + "quote", + "serde", + "serde_json", + "stellar-xdr", + "syn 2.0.119", +] + +[[package]] +name = "soroban-ledger-snapshot" +version = "27.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b59883d8bd0d1aed8d57579a9974ab88eaf787dd0a1af104f6881b5707450558" +dependencies = [ + "serde", + "serde_json", + "serde_with", + "soroban-env-common", + "soroban-env-host", + "thiserror 1.0.69", +] + +[[package]] +name = "soroban-sdk" +version = "27.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c3f21971c84fcfb08957e3e8f5a9a70f134cb07ad9ee053ac7e6d7a887a82af" +dependencies = [ + "arbitrary", + "bytes-lit", + "crate-git-revision 0.0.9", + "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 0.0.16", + "visibility", +] + +[[package]] +name = "soroban-sdk-macros" +version = "27.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3bd4a847273d749807fe2eb52e2b9c1917ee482cd6a39465cad5c389548996ad" +dependencies = [ + "darling 0.20.11", + "heck", + "itertools", + "macro-string", + "proc-macro2", + "quote", + "sha2", + "soroban-env-common", + "soroban-spec", + "soroban-spec-rust", + "stellar-xdr", + "syn 2.0.119", +] + +[[package]] +name = "soroban-spec" +version = "27.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "473404322827b285cbcd87517f365986bd63af7842c78b2a86ee061715fda61e" +dependencies = [ + "base64", + "sha2", + "stellar-xdr", + "thiserror 1.0.69", + "wasmparser", +] + +[[package]] +name = "soroban-spec-rust" +version = "27.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f25698b6ce2125850a9ef075cf9ba1e8d25b4cfa0c46aca42dadd80cc29d881" +dependencies = [ + "prettyplease", + "proc-macro2", + "quote", + "sha2", + "soroban-spec", + "stellar-xdr", + "syn 2.0.119", + "thiserror 1.0.69", +] + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3763264f6b73151db08c50ff20d7d8a0b8796e021cdea7ceedad07b80155fa0e" + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stelflow" +version = "0.1.0" +dependencies = [ + "soroban-sdk", +] + +[[package]] +name = "stellar-strkey" +version = "0.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee1832fb50c651ad10f734aaf5d31ca5acdfb197a6ecda64d93fcdb8885af913" +dependencies = [ + "crate-git-revision 0.0.6", + "data-encoding", +] + +[[package]] +name = "stellar-strkey" +version = "0.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "084afcb0d458c3d5d5baa2d294b18f881e62cc258ef539d8fdf68be7dbe45520" +dependencies = [ + "crate-git-revision 0.0.6", + "data-encoding", + "heapless", +] + +[[package]] +name = "stellar-xdr" +version = "27.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ff843326969bdf1ef673dcdba94c08f4a3c8f1e58d6e6ef39b1bd4f749179a" +dependencies = [ + "arbitrary", + "base64", + "cfg_eval", + "crate-git-revision 0.0.6", + "escape-bytes", + "ethnum", + "hex", + "serde", + "serde_with", + "sha2", + "stellar-strkey 0.0.13", +] + +[[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 = "2.0.119" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3" +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 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f" +dependencies = [ + "thiserror-impl 2.0.20", +] + +[[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.119", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af" +dependencies = [ + "proc-macro2", + "quote", + "syn 3.0.3", +] + +[[package]] +name = "time" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb87b95ec50ddfa440816d227a17b2ccbdda963a316a727fda0fc4334f7d134" +dependencies = [ + "deranged", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1c906769ad99c88eaa54e728060edef082f8e358ff32030cb7c7d315e81109" + +[[package]] +name = "time-macros" +version = "0.2.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e689342a48d2ea927c87ea50cabf8594854bf940e9310208848d680d668ed85" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[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 = "visibility" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d674d135b4a8c1d7e813e2f8d1c9a58308aee4a680323066025e53132218bd91" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[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.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b70935747edd64d89de3efa29d73789b806c15798f8e7dca4d8ac356b50ce70" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77775f8f3f7217702089053b94958f8f54061a3f663417df76e19cbdcca29bc1" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e11d33f857dc2fb11b8bc75aee111aa9cbeb12cd9f25efd3d4c2a3dd4e235284" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.119", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.127" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ef64dbcc55df09c7e5a46182d181c2cfa3e925f3da937ea764728b4bbb9dcbf" +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.14.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.119", +] + +[[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.119", +] + +[[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 = "zerocopy" +version = "0.8.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556764e583adb45a9f8d413c2a147fa7e8d821e48e12b14fd560b607998b75eb" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ab42fc20575779bd240faa45f94a74256f755c0fa9e89f0ede20d91d0cdfc1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zeroize" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13c156562582aa81c60cb29407084cdb54c4164760106ab78e6c5b0858cf64e" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c50655cbb0fe3fc43170059e702f1ce5e19b84cec58dc87b037a09935c2f328" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.119", +] + +[[package]] +name = "zmij" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..5a8bf24 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,29 @@ +[workspace] +resolver = "2" +members = ["contracts/*"] + +[workspace.package] +version = "0.1.0" +edition = "2021" +license = "Apache-2.0" +repository = "https://github.com/StelFlow-labs/StelFlow" + +[workspace.dependencies] +soroban-sdk = "27.0.6" + +# Optimised for on-chain size and determinism. `overflow-checks` stays on in +# release: this contract does i128 money arithmetic and a silent wrap would be a +# value-leakage bug of exactly the kind SECURITY.md ranks first. +[profile.release] +opt-level = "z" +overflow-checks = true +debug = 0 +strip = "symbols" +debug-assertions = false +panic = "abort" +codegen-units = 1 +lto = true + +[profile.release-with-logs] +inherits = "release" +debug-assertions = true diff --git a/README.md b/README.md index b53a8cf..8a869c5 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ StelFlow is a payment-streaming protocol for Stellar/Soroban: a sender locks a SEP-41 asset once, and the recipient's balance accrues continuously against Stellar ledger time instead of arriving as discrete transfers. Unlike a pure time-based stream, StelFlow can gate portions of a stream behind milestones, so funds keep accruing but stay unwithdrawable until a named approver verifies the condition. > **Status: early / in design.** -> No contracts are written yet. There is no deployment, no audit, and no published contract address. This repository currently holds the design, the roadmap, and the contribution setup. Everything described below as "planned" is exactly that. If you are here to contribute, [CONTRIBUTING.md](CONTRIBUTING.md) is the place to start — design review and API critique are genuinely useful right now, more so than code. +> No contracts are written yet. There is no deployment, no audit, and no published contract address. This repository currently holds the design, the roadmap, and the contribution setup. Everything described below as "planned" is exactly that. If you are here to contribute, [CONTRIBUTING.md](docs/CONTRIBUTING.md) is the place to start — design review and API critique are genuinely useful right now, more so than code. ## Why this exists @@ -82,12 +82,12 @@ Dashed components are planned and unbuilt. [docs/architecture.md](docs/architect - [docs/concepts.md](docs/concepts.md) — what money streaming and milestone-gating actually mean, from zero. - [docs/architecture.md](docs/architecture.md) — components, data flow, and the Soroban constraints that drive the design. - [docs/glossary.md](docs/glossary.md) — every term in one place. Start here if you landed mid-doc. Note that [clawback](docs/glossary.md#clawback-issuer-sense) means two different things in this project. -- [ROADMAP.md](ROADMAP.md) — what gets built, in what order. +- [ROADMAP.md](docs/ROADMAP.md) — what gets built, in what order. - [docs/faq.md](docs/faq.md) — short answers to what people actually ask, including the ones with uncomfortable answers: no, it isn't audited, and yes, an asset issuer with clawback enabled can reach a live stream. ## Quickstart -> Nothing is implemented yet, so there is nothing to run. This section records the toolchain contributors will need and will grow into a real quickstart as Phase 1 lands. See [CONTRIBUTING.md](CONTRIBUTING.md#local-setup) for the full setup. +> Nothing is implemented yet, so there is nothing to run. This section records the toolchain contributors will need and will grow into a real quickstart as Phase 1 lands. See [CONTRIBUTING.md](docs/CONTRIBUTING.md#local-setup) for the full setup. ```bash # 1. Rust toolchain and the Wasm target @@ -109,9 +109,9 @@ The intended developer flow once Phase 1 exists: build the Wasm, deploy to testn ## Contributing -Read [CONTRIBUTING.md](CONTRIBUTING.md). Short version: issues labeled `good first issue` are scoped to be finishable without reading the whole design; comment on one before you start so two people don't write it twice. Design feedback on `docs/` is welcome as an issue — at this stage a good argument against the storage layout is worth more than a PR. +Read [CONTRIBUTING.md](docs/CONTRIBUTING.md). Short version: issues labeled `good first issue` are scoped to be finishable without reading the whole design; comment on one before you start so two people don't write it twice. Design feedback on `docs/` is welcome as an issue — at this stage a good argument against the storage layout is worth more than a PR. -Contributors are credited in [CONTRIBUTORS.md](CONTRIBUTORS.md). +Contributors are credited in [CONTRIBUTORS.md](docs/CONTRIBUTORS.md). ## Who's building this @@ -121,7 +121,7 @@ Two things from that project carry directly into this one. The first is design experience: the accrual math, the cancellation semantics, and a withdrawal API that had to be redesigned once are lessons applied here rather than learned again. -The second matters more if you're deciding whether to contribute. StackStream's security review was run as an open multi-auditor process — 11 independent contributors across four PRs and an issue thread, which found and fixed four real bugs including a missing recovery path and two griefing vectors. That review is [published in full](https://github.com/jayteemoney/stackstream/tree/main/audits), false positives and deferred findings included. StelFlow intends to work the same way, which is why the issues here are scoped with acceptance criteria and why [SECURITY.md](SECURITY.md) already describes a disclosure process for a project with nothing to disclose yet. +The second matters more if you're deciding whether to contribute. StackStream's security review was run as an open multi-auditor process — 11 independent contributors across four PRs and an issue thread, which found and fixed four real bugs including a missing recovery path and two griefing vectors. That review is [published in full](https://github.com/jayteemoney/stackstream/tree/main/audits), false positives and deferred findings included. StelFlow intends to work the same way, which is why the issues here are scoped with acceptance criteria and why [SECURITY.md](docs/SECURITY.md) already describes a disclosure process for a project with nothing to disclose yet. StackStream is a separate codebase, not a preview of this one. Clarity and Rust/Soroban differ enough in storage model, fee model, and asset interface that porting was never on the table. Most of what makes StelFlow's design specific — the persistent-storage choice, TTL archival handling, the milestone cap forced by the per-transaction read budget — answers Soroban constraints that have no Stacks equivalent. diff --git a/contracts/stelflow/Cargo.toml b/contracts/stelflow/Cargo.toml new file mode 100644 index 0000000..35f3d69 --- /dev/null +++ b/contracts/stelflow/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "stelflow" +version.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +description = "Payment streaming with milestone gates on Soroban." + +[lib] +crate-type = ["cdylib", "rlib"] +doctest = false + +[dependencies] +soroban-sdk = { workspace = true } + +[dev-dependencies] +soroban-sdk = { workspace = true, features = ["testutils"] } diff --git a/contracts/stelflow/README.md b/contracts/stelflow/README.md new file mode 100644 index 0000000..645ecc0 --- /dev/null +++ b/contracts/stelflow/README.md @@ -0,0 +1,51 @@ +# StelFlow Core + +Payment streaming with milestone gates, on Soroban. + +A stream pays a recipient continuously over time. Part of it can be gated behind +milestones, which accrue on schedule but stay unclaimable until a named approver +opens them. Nothing is pushed: balances rise because the ledger's clock rises, +and every figure is recomputed from the original deposit on each call rather than +accumulated, so integer truncation never compounds. + +## Entry points + +| Function | Who authorizes | What it does | +|---|---|---| +| `create_stream` | sender | Escrows the deposit and opens a stream. Stores the **measured** balance delta, not the requested amount. | +| `withdraw` | recipient | Pays out everything currently claimable. | +| `approve_milestone` | that milestone's approver | Opens a gate, releasing accrual that has already happened. | +| `cancel` | sender — **and the recipient** when `cancelable = false` | Freezes accrual and settles both sides. | +| `touch` | anyone | Extends a stream's TTL. Permissionless by design. | +| `pause` / `unpause` / `transfer_pauser` / `renounce_pauser` | pauser | Reaches `create_stream` and nothing else. | + +## The three properties worth knowing + +**There is no upgrade function.** Only a contract can replace its own Wasm, so an +absent function is permanent immutability rather than a policy needing +enforcement. A timelocked upgrade was considered and rejected on arithmetic: a +timelock protects only what a recipient can withdraw during it, and a stream's +defining property is that most of the money is not withdrawable yet. + +**The pause cannot reach an existing stream.** It gates `create_stream` alone. It +also expires by itself after 30 days and can be renounced permanently — both +because a stuck pause could never be patched out of a contract that cannot be +upgraded. + +**No role has power over anyone's funds.** Authorization is per stream: sender, +recipient, and each milestone's own approver. The pauser is the only global role +and it can only stop new streams being created. + +## Layout + +- `accrual.rs` — the maths. Pure functions over a `Stream` and a timestamp. +- `types.rs` — storage layout. +- `storage.rs` — reads, writes, and TTL policy in one place, so no entry point + can load a stream and forget to extend it. +- `events.rs` — the read path the dashboard folds. +- `error.rs` — one code per failure, so the SDK can say *why*. + +Design reasoning lives in [`docs/`](../../docs): start with +[`concepts.md`](../../docs/concepts.md), then +[`architecture.md`](../../docs/architecture.md). Every non-obvious decision in +this crate has a document behind it and the code points at it. diff --git a/contracts/stelflow/src/accrual.rs b/contracts/stelflow/src/accrual.rs new file mode 100644 index 0000000..511095f --- /dev/null +++ b/contracts/stelflow/src/accrual.rs @@ -0,0 +1,209 @@ +//! The accrual maths. +//! +//! Every number the contract pays out originates here, and every function in +//! this module is pure: it reads a [`Stream`] and a timestamp and returns +//! amounts. Nothing writes storage, moves tokens, or checks authorization, which +//! is what lets the property tests hammer it directly. +//! +//! Two invariants shape the whole module. +//! +//! **Recomputation, never accumulation.** `streamed` is derived from scratch on +//! every call rather than incremented. Integer division truncates, but because +//! the formula is re-evaluated against the original `total` each time, the +//! truncation never compounds — accrual picks those stroops up as it moves past +//! them. This is why `withdraw` can be called a thousand times without drift. +//! +//! **Multiply before divide.** `amount * elapsed / duration` and never +//! `amount * (elapsed / duration)`, which would floor the ratio to zero for +//! every stream shorter than its own duration. + +use soroban_sdk::{contracttype, Vec}; + +use crate::error::Error; +use crate::types::{Milestone, MilestoneState, OnExpiry, Stream}; + +/// What a milestone's tranche does at a given instant. +/// +/// Collapsing state, deadline, and expiry policy into three outcomes is what +/// keeps the rest of this module honest: accrual, claimable, and cancellation +/// settlement are all folds over the same resolution, so a milestone can never +/// mean one thing to `withdraw` and another to `cancel`. +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Resolution { + /// Counts toward `streamed_total`, and the recipient may claim it. + Released, + /// Counts toward `streamed_total` but is withheld from `claimable` — the + /// gate is shut. Accrual continues underneath it. + Withheld, + /// Contributes nothing. The tranche belongs to the sender. + Returned, +} + +/// Resolve a milestone against the ledger clock. +/// +/// The deadline branch is the whole of the #38 decision: an unmet milestone past +/// its deadline resolves to the party named when the stream was created. An +/// already-`Met` milestone ignores its deadline entirely — a deadline that could +/// undo an approval would be revocation through the back door, and `Met` is +/// terminal. +pub fn resolve(milestone: &Milestone, now: u64) -> Resolution { + match milestone.state { + MilestoneState::Met => Resolution::Released, + MilestoneState::Forfeited => Resolution::Returned, + MilestoneState::Unmet => { + let expired = milestone.deadline != 0 && now >= milestone.deadline; + match (expired, milestone.on_expiry) { + (false, _) => Resolution::Withheld, + (true, OnExpiry::ToRecipient) => Resolution::Released, + (true, OnExpiry::ToSender) => Resolution::Returned, + } + } + } +} + +/// The instant accrual is evaluated at. +/// +/// Clamped into `[start, end]` so a stream neither accrues before it begins nor +/// past its own total, and pinned to `canceled_at` once a stream is cancelled — +/// cancellation freezes the clock rather than deleting the stream. +fn evaluation_time(stream: &Stream, now: u64) -> u64 { + let unfrozen = match stream.canceled_at { + Some(canceled_at) => core::cmp::min(now, canceled_at), + None => now, + }; + unfrozen.clamp(stream.start, stream.end) +} + +/// Linear accrual of one portion, floored. +/// +/// At or past `end` this returns the portion in full rather than evaluating the +/// formula. That is not an optimisation: it is what guarantees a stream settles +/// to exactly its deposit. `amount * duration / duration` would be exact in real +/// arithmetic, but the final withdrawal must land on the deposit to the stroop, +/// and special-casing the endpoint is how the remainder from every intermediate +/// truncation gets swept up. +fn streamed(amount: i128, at: u64, stream: &Stream) -> Result { + if at >= stream.end { + return Ok(amount); + } + let elapsed = at.saturating_sub(stream.start) as i128; + let duration = stream.end.saturating_sub(stream.start) as i128; + if duration == 0 { + return Ok(amount); + } + amount + .checked_mul(elapsed) + .map(|scaled| scaled / duration) + .ok_or(Error::Overflow) +} + +/// A stream's position at one instant. +#[contracttype] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Position { + /// Everything that has accrued and not been returned to the sender. + pub streamed_total: i128, + /// The part of `streamed_total` sitting behind a shut gate. + pub held: i128, + /// What the recipient could withdraw right now. Never negative. + pub claimable: i128, +} + +/// Evaluate a stream at `now`. +/// +/// `claimable = streamed_total - withdrawn - held`, which is the definition +/// carried in `docs/behaviour.md`. A withheld milestone lands in both +/// `streamed_total` and `held`, so it nets to zero against claimable while +/// remaining visible to a UI that wants to show what is accruing behind the gate. +pub fn position(stream: &Stream, now: u64) -> Result { + let at = evaluation_time(stream, now); + + let mut streamed_total = streamed(stream.base_amount, at, stream)?; + let mut held = 0i128; + + for milestone in stream.milestones.iter() { + let accrued = streamed(milestone.amount, at, stream)?; + match resolve(&milestone, now) { + Resolution::Released => { + streamed_total = add(streamed_total, accrued)?; + } + Resolution::Withheld => { + streamed_total = add(streamed_total, accrued)?; + held = add(held, accrued)?; + } + Resolution::Returned => {} + } + } + + // A cliff withholds claimability without touching accrual. The balance is + // building the whole time; it simply cannot be moved yet. + let claimable = if now < stream.cliff { + 0 + } else { + (streamed_total - stream.withdrawn - held).max(0) + }; + + Ok(Position { + streamed_total, + held, + claimable, + }) +} + +/// How a cancellation divides the remaining deposit. +#[contracttype] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Settlement { + /// Paid to the sender immediately, in the cancelling transaction. + pub refund: i128, + /// Left in the contract, frozen, for the recipient to withdraw whenever they + /// choose. Cancellation is not a clawback of earned money. + pub recipient_balance: i128, +} + +/// Split a stream at cancellation, per the four rules in +/// `docs/concepts.md#cancellation-and-clawback`. +/// +/// The sender gets back every portion that has not yet accrued, plus the *whole* +/// tranche of any milestone that never opened — accrued part included, on the +/// reasoning that an unmet milestone is work that did not happen. +pub fn settle(stream: &Stream, now: u64) -> Result { + let at = evaluation_time(stream, now); + + let base_streamed = streamed(stream.base_amount, at, stream)?; + let mut refund = stream.base_amount - base_streamed; + let mut recipient_earned = base_streamed; + + for milestone in stream.milestones.iter() { + let accrued = streamed(milestone.amount, at, stream)?; + match resolve(&milestone, now) { + // Open gate: the sender recovers only what has not yet streamed. + Resolution::Released => { + refund = add(refund, milestone.amount - accrued)?; + recipient_earned = add(recipient_earned, accrued)?; + } + // Shut gate, or already returned: the tranche goes back whole. + Resolution::Withheld | Resolution::Returned => { + refund = add(refund, milestone.amount)?; + } + } + } + + Ok(Settlement { + refund, + recipient_balance: (recipient_earned - stream.withdrawn).max(0), + }) +} + +/// Sum of every milestone amount, used to derive `base_amount` at creation. +pub fn gated_total(milestones: &Vec) -> Result { + let mut sum = 0i128; + for milestone in milestones.iter() { + sum = add(sum, milestone.amount)?; + } + Ok(sum) +} + +fn add(lhs: i128, rhs: i128) -> Result { + lhs.checked_add(rhs).ok_or(Error::Overflow) +} diff --git a/contracts/stelflow/src/error.rs b/contracts/stelflow/src/error.rs new file mode 100644 index 0000000..d024fda --- /dev/null +++ b/contracts/stelflow/src/error.rs @@ -0,0 +1,72 @@ +//! Error taxonomy. +//! +//! Distinct codes per failure so the SDK can render something better than +//! "transaction failed", and so tests assert on the *reason* a call was +//! rejected rather than merely that it was. + +use soroban_sdk::contracterror; + +#[contracterror] +#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] +#[repr(u32)] +pub enum Error { + /// `initialize` has already run. There is no re-initialize: it would be an + /// admin power over a live contract by another name. + AlreadyInitialized = 1, + NotInitialized = 2, + + // ---- create_stream ---- + /// `end` must be strictly greater than `start`; a zero-duration stream has + /// no accrual rate. + InvalidTimeRange = 3, + /// The cliff must fall within `[start, end]`. A cliff after `end` would make + /// the stream unclaimable until the moment it completes. + InvalidCliff = 4, + /// Amounts must be strictly positive. + InvalidAmount = 5, + /// Milestone amounts sum to more than the deposit, leaving a negative base. + MilestonesExceedTotal = 6, + /// Past `MAX_MILESTONES_PER_STREAM`. An unbounded vector inside a stored + /// struct is a way to build a stream too expensive to ever withdraw from — + /// threat-model T2. + TooManyMilestones = 7, + /// The token moved nothing, so there is no stream to create. Guards the + /// measured-delta path against a token whose `transfer` silently no-ops. + NoValueReceived = 8, + + // ---- lookup ---- + StreamNotFound = 9, + + // ---- withdraw ---- + /// Claimable is zero. Not an error condition in the moral sense, but the + /// caller paid a fee for a state-changing call that changed nothing, and + /// saying so is friendlier than a silent success. + NothingToWithdraw = 10, + + // ---- approve_milestone ---- + MilestoneNotFound = 11, + /// The tranche was returned to the sender by a cancellation. There is + /// nothing left to release. + MilestoneForfeited = 12, + + // ---- cancel ---- + /// Already cancelled. Accrual is frozen; a second cancel has nothing to do. + AlreadyCanceled = 13, + + // ---- pause ---- + /// `create_stream` while paused. Note this is the *only* entry point that + /// can return this error. + Paused = 14, + /// Caller is not the pauser, or the role has been renounced. + NotPauser = 15, + + // ---- invariants ---- + /// A payout would have exceeded its own stream's remaining deposit. The + /// contract's token balance is pooled across streams, so this is what stops + /// one stream's accounting bug reaching another's money. Unreachable if the + /// accrual maths is right — which is exactly why it is asserted. + InsolventStream = 16, + /// Arithmetic overflowed. `i128` against stroop-denominated amounts makes + /// this effectively unreachable, and it is checked rather than assumed. + Overflow = 17, +} diff --git a/contracts/stelflow/src/events.rs b/contracts/stelflow/src/events.rs new file mode 100644 index 0000000..3ed374e --- /dev/null +++ b/contracts/stelflow/src/events.rs @@ -0,0 +1,117 @@ +//! Contract events. +//! +//! These are the product's read path, not a debugging aid. Soroban contracts +//! cannot be queried historically from inside the chain, so everything the +//! dashboard shows about the past is reconstructed by folding this log — see +//! `docs/indexer-design.md`. +//! +//! Declared with `#[contractevent]`, so each event carries a self-describing map +//! of named fields and appears in the contract's generated interface. A client +//! reads `stream_id` by name rather than by tuple position, which means adding a +//! field later cannot silently shift what an existing consumer parses. +//! +//! Three rules shape the set below, and each is load-bearing: +//! +//! 1. **Every stream event carries `stream_id` as a topic**, so a client filters +//! server-side instead of pulling the whole log and discarding most of it. +//! 2. **Events record actions, never the passage of time.** Nothing fires when a +//! cliff lapses, a milestone deadline expires, or a stream reaches `end` — +//! nothing happens on-chain at those instants. A client derives them from the +//! same stored fields and clock the contract uses. +//! 3. **An action emits exactly one event, once.** A duplicate `approve_milestone` +//! is absorbed silently, so a fold can treat each event as a distinct state +//! transition without deduplicating by hand. + +use soroban_sdk::{contractevent, Address}; + +/// A stream was opened and its deposit escrowed. +/// +/// `total` is the **measured** amount that arrived, which for a fee-on-transfer +/// token is less than the sender asked to send. A client should render this +/// figure rather than the one from the submitted transaction. +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StreamCreated { + #[topic] + pub stream_id: u64, + #[topic] + pub sender: Address, + #[topic] + pub recipient: Address, + pub token: Address, + pub total: i128, + pub start: u64, + pub end: u64, + pub cliff: u64, + pub cancelable: bool, + pub milestone_count: u32, +} + +/// The recipient took some of what had accrued. +/// +/// Carries the running total as well as the delta, so a client that missed an +/// earlier event still renders a correct balance from the latest one. +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Withdrawn { + #[topic] + pub stream_id: u64, + #[topic] + pub recipient: Address, + pub amount: i128, + pub withdrawn_total: i128, +} + +/// An approver opened a gate. Emitted at most once per milestone, ever. +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MilestoneApproved { + #[topic] + pub stream_id: u64, + #[topic] + pub approver: Address, + pub index: u32, + pub amount: i128, +} + +/// A stream was cancelled and both sides settled. +/// +/// `recipient_balance` is left in the contract for the recipient to withdraw at +/// their leisure — cancellation freezes accrual, it does not claw back earned +/// money. +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct StreamCanceled { + #[topic] + pub stream_id: u64, + pub refund_to_sender: i128, + pub recipient_balance: i128, + pub canceled_at: u64, +} + +/// New stream creation was suspended until `paused_until`. +/// +/// Contract-wide, and it reaches exactly one entry point. A client should render +/// this as "new streams are not being accepted" and never as anything touching +/// an existing stream, because it cannot. +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Paused { + pub paused_until: u64, +} + +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct Unpaused { + pub at: u64, +} + +/// The pauser role moved, or — when `pauser` is `None` — was given up for good. +/// +/// A `None` here is the contract announcing it has become permanently +/// privilege-free. There is no upgrade path that could restore the role. +#[contractevent] +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct PauserChanged { + pub pauser: Option
, +} diff --git a/contracts/stelflow/src/lib.rs b/contracts/stelflow/src/lib.rs new file mode 100644 index 0000000..e7bf206 --- /dev/null +++ b/contracts/stelflow/src/lib.rs @@ -0,0 +1,464 @@ +#![no_std] +#![doc = include_str!("../README.md")] + +mod accrual; +mod error; +mod events; +mod storage; +mod types; + +#[cfg(test)] +mod tests; + +use soroban_sdk::{contract, contractimpl, contracttype, token, Address, Env, Vec}; + +use events::{ + MilestoneApproved, Paused, PauserChanged, StreamCanceled, StreamCreated, Unpaused, Withdrawn, +}; + +pub use accrual::{Position, Resolution, Settlement}; +pub use error::Error; +pub use types::{ConfigKey, DataKey, Milestone, MilestoneState, OnExpiry, Stream}; + +/// Ceiling on milestones per stream. +/// +/// Milestones live inside the stream struct, so this bounds how much a single +/// `withdraw` must deserialize. An unbounded vector here is a way to build a +/// stream that can never be withdrawn from, because reading it would exceed the +/// transaction's resource budget — threat-model T2, the highest-likelihood +/// entry in the model precisely because it needs no attacker. +/// +/// Ten is deliberately conservative against the measured cost of a loaded +/// stream; see `docs/architecture.md#the-per-transaction-read-budget`. Raising it +/// requires re-measuring, not re-arguing. +pub const MAX_MILESTONES_PER_STREAM: u32 = 10; + +/// How long a pause lasts before lifting by itself. +/// +/// A pause that outlived its key would be permanent in a non-upgradeable +/// contract — a small power becoming an irreversible one through nothing but +/// neglect. Renewal is a single transaction, so erring short is cheap and erring +/// long is not. +pub const PAUSE_DURATION_SECONDS: u64 = 30 * 24 * 60 * 60; + +/// A stream plus its position, so a dashboard gets everything in one call +/// instead of one round trip per field. +#[contracttype] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct StreamView { + pub stream: Stream, + pub position: Position, + /// The timestamp this view was evaluated at. A client animating accrual + /// needs the contract's clock, not the browser's. + pub as_of: u64, +} + +/// Payment streaming with milestone gates. +/// +/// **This contract has no upgrade function, and that is the design.** Only a +/// contract can replace its own Wasm, so an absent function is permanent +/// immutability rather than a policy anyone has to enforce. The reasoning, and +/// why a timelocked upgrade was rejected on arithmetic rather than principle, is +/// in `docs/upgradeability-and-pause.md`. +/// +/// The one global role is the pauser, and it reaches exactly one entry point. +#[contract] +pub struct StelFlow; + +#[contractimpl] +impl StelFlow { + /// Set the initial pauser. Runs once. + /// + /// Pass `None` to deploy with no pauser at all — a contract that is + /// privilege-free from its first ledger. There is deliberately no + /// re-initialize: that would be an admin power over a live contract wearing + /// a different name. + pub fn initialize(env: Env, pauser: Option
) -> Result<(), Error> { + if storage::is_initialized(&env) { + return Err(Error::AlreadyInitialized); + } + storage::set_pauser(&env, &pauser); + storage::set_paused_until(&env, 0); + storage::init_stream_ids(&env); + PauserChanged { pauser }.publish(&env); + Ok(()) + } + + // ----------------------------------------------------------------------- + // Streams + // ----------------------------------------------------------------------- + + /// Escrow a deposit and open a stream. + /// + /// The stored `total` is the contract's **measured balance delta** across the + /// transfer, not `amount`. A fee-on-transfer token therefore produces a + /// stream sized to what actually arrived, and the value-conservation + /// invariant holds without trusting the token to behave. Rebasing assets + /// remain unsupported: no creation-time measurement can bind a balance that + /// moves afterwards. + #[allow(clippy::too_many_arguments)] + pub fn create_stream( + env: Env, + sender: Address, + recipient: Address, + token_id: Address, + amount: i128, + start: u64, + end: u64, + cliff: u64, + cancelable: bool, + milestones: Vec, + ) -> Result { + sender.require_auth(); + + let now = env.ledger().timestamp(); + if now < storage::paused_until(&env) { + return Err(Error::Paused); + } + + if end <= start { + return Err(Error::InvalidTimeRange); + } + if cliff < start || cliff > end { + return Err(Error::InvalidCliff); + } + if amount <= 0 { + return Err(Error::InvalidAmount); + } + if milestones.len() > MAX_MILESTONES_PER_STREAM { + return Err(Error::TooManyMilestones); + } + for milestone in milestones.iter() { + if milestone.amount <= 0 { + return Err(Error::InvalidAmount); + } + if milestone.state != MilestoneState::Unmet { + return Err(Error::InvalidAmount); + } + // A deadline before `end` would resolve a tranche while it was still + // accruing, making `streamed_total` non-monotonic and racing a + // legitimate approver against the clock. See docs/milestone-deadlines.md. + if milestone.deadline != 0 && milestone.deadline < end { + return Err(Error::InvalidTimeRange); + } + } + + let contract = env.current_contract_address(); + let client = token::Client::new(&env, &token_id); + let before = client.balance(&contract); + client.transfer(&sender, &contract, &amount); + let received = client.balance(&contract) - before; + + if received <= 0 { + return Err(Error::NoValueReceived); + } + let gated = accrual::gated_total(&milestones)?; + if gated > received { + return Err(Error::MilestonesExceedTotal); + } + + let milestone_count = milestones.len(); + let id = storage::next_stream_id(&env); + let stream = Stream { + id, + sender: sender.clone(), + recipient: recipient.clone(), + token: token_id.clone(), + total: received, + base_amount: received - gated, + start, + end, + cliff, + cancelable, + withdrawn: 0, + milestones, + canceled_at: None, + }; + storage::save_stream(&env, &stream); + + StreamCreated { + stream_id: id, + sender, + recipient, + token: token_id, + total: received, + start, + end, + cliff, + cancelable, + milestone_count, + } + .publish(&env); + Ok(id) + } + + /// Pay the recipient everything the formula currently allows. + /// + /// Never pausable. A pause that could block this would make an + /// already-earned balance freezable by a third party, which is + /// indistinguishable from a rug from where the recipient is standing. + pub fn withdraw(env: Env, stream_id: u64) -> Result { + let mut stream = storage::load_stream(&env, stream_id)?; + stream.recipient.require_auth(); + + let now = env.ledger().timestamp(); + let payout = accrual::position(&stream, now)?.claimable; + if payout <= 0 { + return Err(Error::NothingToWithdraw); + } + + // The contract's token balance is pooled across every stream, so this is + // what stops one stream's accounting bug reaching another's deposit. + // Unreachable if the accrual maths is right, which is exactly why it is + // asserted rather than assumed. See docs/upgradeability-and-pause.md. + if payout > stream.total - stream.withdrawn { + return Err(Error::InsolventStream); + } + + stream.withdrawn += payout; + storage::save_stream(&env, &stream); + + token::Client::new(&env, &stream.token).transfer( + &env.current_contract_address(), + &stream.recipient, + &payout, + ); + Withdrawn { + stream_id, + recipient: stream.recipient, + amount: payout, + withdrawn_total: stream.withdrawn, + } + .publish(&env); + Ok(payout) + } + + /// Open a milestone's gate, releasing everything it has held. + /// + /// Approval unlocks accrual that has *already happened*; it never accelerates + /// the schedule. A second call on an already-met milestone is absorbed as a + /// no-op — a duplicate is overwhelmingly a retry after an uncertain outcome, + /// and `Met` is terminal so there is no state to protect. Authorization is + /// still checked first, and no second event fires, so an indexer's fold never + /// sees one approval twice. + pub fn approve_milestone(env: Env, stream_id: u64, index: u32) -> Result<(), Error> { + let mut stream = storage::load_stream(&env, stream_id)?; + let mut milestone = stream + .milestones + .get(index) + .ok_or(Error::MilestoneNotFound)?; + + milestone.approver.require_auth(); + + if stream.canceled_at.is_some() { + return Err(Error::AlreadyCanceled); + } + match milestone.state { + MilestoneState::Met => return Ok(()), + MilestoneState::Forfeited => return Err(Error::MilestoneForfeited), + MilestoneState::Unmet => {} + } + + milestone.state = MilestoneState::Met; + let approver = milestone.approver.clone(); + let amount = milestone.amount; + stream.milestones.set(index, milestone); + storage::save_stream(&env, &stream); + + MilestoneApproved { + stream_id, + approver, + index, + amount, + } + .publish(&env); + Ok(()) + } + + /// Freeze accrual and settle. + /// + /// The recipient keeps every stroop that has streamed; only the unstreamed + /// remainder returns to the sender, along with the whole tranche of any + /// milestone that never opened. + /// + /// **`cancelable = false` means the sender cannot cancel *alone*, not that + /// nobody can.** With the recipient authorizing alongside the sender, a + /// non-cancelable stream settles under exactly these rules. That path exists + /// because this contract can never be upgraded: an unbreakable stream would + /// be unbreakable for the life of the contract, stranding both parties when + /// an approver vanishes or a migration is needed. + pub fn cancel(env: Env, stream_id: u64) -> Result { + let mut stream = storage::load_stream(&env, stream_id)?; + + stream.sender.require_auth(); + if !stream.cancelable { + stream.recipient.require_auth(); + } + if stream.canceled_at.is_some() { + return Err(Error::AlreadyCanceled); + } + + let now = env.ledger().timestamp(); + let settlement = accrual::settle(&stream, now)?; + + if settlement.refund + settlement.recipient_balance > stream.total - stream.withdrawn { + return Err(Error::InsolventStream); + } + + // Freeze the clock, then resolve every still-shut gate. Marking them + // Forfeited rather than leaving them Unmet is what stops a cancelled + // stream's milestones from later "expiring" — they are already resolved. + stream.canceled_at = Some(now); + for index in 0..stream.milestones.len() { + let mut milestone = stream.milestones.get(index).unwrap(); + if milestone.state == MilestoneState::Unmet { + milestone.state = MilestoneState::Forfeited; + stream.milestones.set(index, milestone); + } + } + storage::save_stream(&env, &stream); + + if settlement.refund > 0 { + token::Client::new(&env, &stream.token).transfer( + &env.current_contract_address(), + &stream.sender, + &settlement.refund, + ); + } + StreamCanceled { + stream_id, + refund_to_sender: settlement.refund, + recipient_balance: settlement.recipient_balance, + canceled_at: now, + } + .publish(&env); + Ok(settlement) + } + + /// Extend a stream's TTL. Callable by anyone, deliberately. + /// + /// `ExtendFootprintTTLOp` has no auth check either, so gating this would buy + /// nothing but the illusion of control. It lets a sender, a grant + /// administrator, or a third-party keeper keep a dormant stream alive. + pub fn touch(env: Env, stream_id: u64) -> Result<(), Error> { + storage::touch_stream(&env, stream_id) + } + + // ----------------------------------------------------------------------- + // Views + // ----------------------------------------------------------------------- + + pub fn get_stream(env: Env, stream_id: u64) -> Result { + storage::peek_stream(&env, stream_id) + } + + /// A stream and its current position, evaluated against the ledger clock. + pub fn describe(env: Env, stream_id: u64) -> Result { + let stream = storage::peek_stream(&env, stream_id)?; + let as_of = env.ledger().timestamp(); + let position = accrual::position(&stream, as_of)?; + Ok(StreamView { + stream, + position, + as_of, + }) + } + + /// What the recipient could withdraw right now. + pub fn claimable(env: Env, stream_id: u64) -> Result { + let stream = storage::peek_stream(&env, stream_id)?; + Ok(accrual::position(&stream, env.ledger().timestamp())?.claimable) + } + + /// How a cancellation would divide the deposit if it happened now. Lets a UI + /// show both parties the outcome before either of them signs. + pub fn preview_cancel(env: Env, stream_id: u64) -> Result { + let stream = storage::peek_stream(&env, stream_id)?; + accrual::settle(&stream, env.ledger().timestamp()) + } + + /// Total streams ever created. Ids run `0..count`. + pub fn stream_count(env: Env) -> u64 { + env.storage() + .instance() + .get(&ConfigKey::NextId) + .unwrap_or(0) + } + + // ----------------------------------------------------------------------- + // Pause + // ----------------------------------------------------------------------- + + /// Stop `create_stream` for [`PAUSE_DURATION_SECONDS`]. Renewable. + /// + /// This reaches exactly one entry point. It cannot touch a stream that + /// already exists, and no amount of pausing gives the pauser authority over + /// anyone's funds. + pub fn pause(env: Env) -> Result { + Self::require_pauser(&env)?; + let until = env.ledger().timestamp() + PAUSE_DURATION_SECONDS; + storage::set_paused_until(&env, until); + Paused { + paused_until: until, + } + .publish(&env); + Ok(until) + } + + pub fn unpause(env: Env) -> Result<(), Error> { + Self::require_pauser(&env)?; + storage::set_paused_until(&env, 0); + Unpaused { + at: env.ledger().timestamp(), + } + .publish(&env); + Ok(()) + } + + /// Hand the role to another address. + pub fn transfer_pauser(env: Env, new_pauser: Address) -> Result<(), Error> { + Self::require_pauser(&env)?; + storage::set_pauser(&env, &Some(new_pauser.clone())); + PauserChanged { + pauser: Some(new_pauser), + } + .publish(&env); + Ok(()) + } + + /// Give up the role permanently. + /// + /// Irreversible: there is no upgrade path that could restore it. This lets a + /// deployment reach a genuinely privilege-free state once the contract has + /// been in production long enough to trust — at the cost of discarding the + /// only incident response the design retains. + pub fn renounce_pauser(env: Env) -> Result<(), Error> { + Self::require_pauser(&env)?; + storage::set_pauser(&env, &None); + PauserChanged { pauser: None }.publish(&env); + Ok(()) + } + + pub fn pauser(env: Env) -> Option
{ + storage::pauser(&env) + } + + /// The timestamp an active pause lifts at. Zero means not paused. + /// + /// A client should compare this against the *ledger* clock rather than the + /// browser's, since that is what `create_stream` will check. + pub fn paused_until(env: Env) -> u64 { + let until = storage::paused_until(&env); + if until > env.ledger().timestamp() { + until + } else { + 0 + } + } + + fn require_pauser(env: &Env) -> Result { + let pauser = storage::pauser(env).ok_or(Error::NotPauser)?; + pauser.require_auth(); + Ok(pauser) + } +} diff --git a/contracts/stelflow/src/storage.rs b/contracts/stelflow/src/storage.rs new file mode 100644 index 0000000..38a6001 --- /dev/null +++ b/contracts/stelflow/src/storage.rs @@ -0,0 +1,164 @@ +//! Storage access and TTL policy. +//! +//! Centralised so that no entry point can read a stream and forget to extend it. +//! Every read of a live stream bumps its TTL, which makes ordinary use — the +//! recipient withdrawing now and then — the thing that keeps a stream alive. +//! +//! **No TTL constant is compiled in.** `docs/ttl-strategy.md` measured the live +//! network settings and found one had already changed between protocol versions; +//! `docs/upgradeability-and-pause.md` then removed any admin who could retune a +//! stored value. Both point the same way: derive from [`max_ttl`] at call time, +//! which is the host function Soroban exposes precisely so a contract can ask +//! the current ceiling rather than assume one. + +use soroban_sdk::{Address, Env}; + +use crate::error::Error; +use crate::types::{ConfigKey, DataKey, Stream}; + +/// Fraction of the network's maximum TTL below which an entry gets extended. +/// +/// Extending when an entry drops under half its possible life keeps writes +/// infrequent — a stream touched even twice a year never approaches archival — +/// while leaving a wide margin against a protocol change that lowers the +/// ceiling. +const EXTEND_THRESHOLD_DIVISOR: u32 = 2; + +fn max_ttl(env: &Env) -> u32 { + env.storage().max_ttl() +} + +/// Instance storage holds contract-wide config and shares one TTL across the +/// whole contract. Losing it would block *every* stream at once, so it is +/// extended unconditionally on every call that touches it, with no cost-benefit +/// hesitation — the asymmetry argued in `docs/ttl-strategy.md`. +fn bump_instance(env: &Env) { + let ceiling = max_ttl(env); + env.storage() + .instance() + .extend_ttl(ceiling / EXTEND_THRESHOLD_DIVISOR, ceiling); +} + +fn bump_stream(env: &Env, stream_id: u64) { + let ceiling = max_ttl(env); + env.storage().persistent().extend_ttl( + &DataKey::Stream(stream_id), + ceiling / EXTEND_THRESHOLD_DIVISOR, + ceiling, + ); +} + +// --------------------------------------------------------------------------- +// Streams +// --------------------------------------------------------------------------- + +pub fn save_stream(env: &Env, stream: &Stream) { + env.storage() + .persistent() + .set(&DataKey::Stream(stream.id), stream); + bump_stream(env, stream.id); +} + +/// Load a stream, extending its TTL as a side effect. +/// +/// If the entry has been archived this call never runs: the host rejects the +/// transaction on its footprint before the contract is invoked. There is no +/// branch to write for that case and none could exist — restoration is the SDK's +/// job, and Protocol 23 makes it automatic for anything driven through +/// simulation. See `docs/behaviour.md`. +pub fn load_stream(env: &Env, stream_id: u64) -> Result { + let stream: Stream = env + .storage() + .persistent() + .get(&DataKey::Stream(stream_id)) + .ok_or(Error::StreamNotFound)?; + bump_stream(env, stream_id); + Ok(stream) +} + +/// Read without extending, for view functions. +/// +/// A view is invoked through simulation and charges nobody, so it must not write +/// — `extend_ttl` in a read path would make every balance query a state change. +pub fn peek_stream(env: &Env, stream_id: u64) -> Result { + env.storage() + .persistent() + .get(&DataKey::Stream(stream_id)) + .ok_or(Error::StreamNotFound) +} + +/// Permissionless TTL extension. +/// +/// Deliberately callable by anyone: a sender, a grant administrator, or a +/// third-party keeper can all keep a dormant stream alive. This mirrors +/// `ExtendFootprintTTLOp`, which has no auth check either, so gating it would +/// buy nothing except the illusion of control. +pub fn touch_stream(env: &Env, stream_id: u64) -> Result<(), Error> { + if !env.storage().persistent().has(&DataKey::Stream(stream_id)) { + return Err(Error::StreamNotFound); + } + bump_stream(env, stream_id); + Ok(()) +} + +// --------------------------------------------------------------------------- +// Config +// --------------------------------------------------------------------------- + +pub fn is_initialized(env: &Env) -> bool { + env.storage().instance().has(&ConfigKey::NextId) +} + +/// Arm the id counter without consuming an id. +/// +/// Writing the key is also what marks the contract initialized, so this must set +/// zero rather than reserve it — the first stream created is stream 0. +pub fn init_stream_ids(env: &Env) { + env.storage().instance().set(&ConfigKey::NextId, &0u64); + bump_instance(env); +} + +/// Reserve the next stream id. +/// +/// A monotonic counter rather than a hash of the creation parameters +/// (architecture.md open question 1). A counter makes every creation write one +/// shared entry, which is a contention point — but ids that a person can read +/// out over the phone are worth more to a dashboard than contention-freedom is +/// at this scale, and creation already writes instance storage anyway. +pub fn next_stream_id(env: &Env) -> u64 { + let id: u64 = env + .storage() + .instance() + .get(&ConfigKey::NextId) + .unwrap_or(0); + env.storage().instance().set(&ConfigKey::NextId, &(id + 1)); + bump_instance(env); + id +} + +pub fn set_pauser(env: &Env, pauser: &Option
) { + env.storage().instance().set(&ConfigKey::Pauser, pauser); + bump_instance(env); +} + +pub fn pauser(env: &Env) -> Option
{ + env.storage() + .instance() + .get(&ConfigKey::Pauser) + .unwrap_or(None) +} + +pub fn set_paused_until(env: &Env, until: u64) { + env.storage() + .instance() + .set(&ConfigKey::PausedUntil, &until); + bump_instance(env); +} + +/// The timestamp an active pause lifts at, or zero if never paused. +pub fn paused_until(env: &Env) -> u64 { + env.storage() + .instance() + .get(&ConfigKey::PausedUntil) + .unwrap_or(0) +} diff --git a/contracts/stelflow/src/tests/accrual_properties.rs b/contracts/stelflow/src/tests/accrual_properties.rs new file mode 100644 index 0000000..b21c357 --- /dev/null +++ b/contracts/stelflow/src/tests/accrual_properties.rs @@ -0,0 +1,192 @@ +//! Property tests over the accrual maths. +//! +//! These sweep the timeline rather than asserting a single point, and they are +//! where the invariants `docs/threat-model.md` leans on get exercised — T12's +//! claim that repeated withdrawals cannot extract more than the formula allows +//! is a property, not an example, and deserves testing as one. + +use super::*; +use crate::Error; + +/// Value conservation across every day of a stream's life, under a mixed +/// sequence of withdrawals and an approval. +/// +/// `deposit == withdrawn + refunded + remaining_in_contract`, checked after +/// every state-changing call rather than only at the end. +#[test] +fn value_is_conserved_at_every_step() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + for day in 0..=35u64 { + h.warp_days(day); + if day == 17 { + h.client.approve_milestone(&id, &0); + } + if day % 3 == 0 { + let _ = h.client.try_withdraw(&id); + } + + let stream = h.client.get_stream(&id); + assert_eq!( + TOTAL, + stream.withdrawn + h.contract_balance(), + "conservation broke on day {}", + day, + ); + } +} + +/// T12: repeated withdrawal never extracts more than a single withdrawal would. +/// +/// The threat model proves this by telescoping sum; this checks the +/// implementation actually has the property the proof assumes. +#[test] +fn withdrawal_frequency_does_not_change_the_total() { + let daily = { + let h = Harness::new(); + let id = h.simple(); + let mut total = 0i128; + for day in 1..=30u64 { + h.warp_days(day); + if let Ok(Ok(paid)) = h.client.try_withdraw(&id) { + total += paid; + } + } + total + }; + + let once = { + let h = Harness::new(); + let id = h.simple(); + h.warp_days(30); + h.client.withdraw(&id) + }; + + assert_eq!( + daily, once, + "dust extraction by frequent withdrawal is not possible" + ); + assert_eq!(daily, TOTAL); +} + +/// `streamed_total` is monotonically non-decreasing on a live stream. Nothing a +/// party does may make accrued value un-accrue. +#[test] +fn streamed_total_never_goes_backwards() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + let mut previous = 0i128; + for day in 0..=40u64 { + h.warp_days(day); + if day == 21 { + h.client.approve_milestone(&id, &0); + } + let now = h.client.describe(&id).position.streamed_total; + assert!( + now >= previous, + "streamed_total fell from {} to {} on day {}", + previous, + now, + day, + ); + previous = now; + } +} + +/// Claimable is never negative, at any point, under any milestone state. +/// +/// `docs/milestone-revocation.md` rejected re-locking precisely because it drove +/// this negative. The clamp stays as defence against a bug, not against a +/// reachable state — so this asserts the state really is unreachable. +#[test] +fn claimable_is_never_negative() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + for day in 0..=60u64 { + h.warp_days(day); + if day == 12 { + h.client.approve_milestone(&id, &0); + } + if day % 5 == 0 { + let _ = h.client.try_withdraw(&id); + } + assert!( + h.client.claimable(&id) >= 0, + "negative claimable on day {}", + day + ); + } +} + +/// A stream always settles to exactly its deposit, for a spread of totals chosen +/// to divide badly by a 30-day duration. +#[test] +fn every_stream_settles_to_its_exact_deposit() { + for total in [1i128, 7, 29, 31, 1_000_000_007, TOTAL + 1, TOTAL - 13] { + let h = Harness::new(); + let id = h.create(total, START, true, h.no_milestones()); + + let mut paid = 0i128; + for day in 1..=30u64 { + h.warp_days(day); + if let Ok(Ok(amount)) = h.client.try_withdraw(&id) { + paid += amount; + } + } + assert_eq!(paid, total, "total {} did not settle exactly", total); + assert_eq!(h.contract_balance(), 0, "total {} left dust behind", total); + } +} + +/// Cancelling at any point conserves value, whatever has been withdrawn or +/// approved beforehand. +#[test] +fn cancellation_conserves_value_at_any_point() { + for day in [0u64, 1, 7, 15, 18, 29, 30, 45] { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(day.min(20)); + let _ = h.client.try_withdraw(&id); + + h.warp_days(day); + let settlement = h.client.cancel(&id); + let stream = h.client.get_stream(&id); + + assert_eq!( + TOTAL, + stream.withdrawn + settlement.refund + h.contract_balance(), + "cancelling on day {} did not conserve value", + day, + ); + assert_eq!( + h.contract_balance(), + settlement.recipient_balance, + "what stays behind must be exactly what the recipient is owed (day {})", + day, + ); + } +} + +/// A stream whose gate never opens pays the recipient only its base, and returns +/// the tranche to the sender on cancellation — the T3 shape, before deadlines. +#[test] +fn an_abandoned_gate_strands_only_its_own_tranche() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(30); + assert_eq!(h.client.withdraw(&id), BASE); + assert_eq!( + h.contract_balance(), + GATED, + "the tranche is stranded, and it is exactly the tranche — nothing more", + ); + assert_eq!( + h.client.try_withdraw(&id), + Err(Ok(Error::NothingToWithdraw)) + ); +} diff --git a/contracts/stelflow/src/tests/approve.rs b/contracts/stelflow/src/tests/approve.rs new file mode 100644 index 0000000..ebaabd1 --- /dev/null +++ b/contracts/stelflow/src/tests/approve.rs @@ -0,0 +1,234 @@ +//! `docs/behaviour.md` → Feature: approve_milestone + +use soroban_sdk::vec; + +use super::*; +use crate::{Error, MilestoneState, OnExpiry}; + +/// Scenario: happy path — approval releases accrued-to-date, not just future +/// accrual +#[test] +fn approval_releases_what_already_accrued_behind_the_gate() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(18); + assert_eq!( + h.client.claimable(&id), + BASE * 18 / 30, + "before approval, only the base is claimable", + ); + + h.client.approve_milestone(&id, &0); + + assert_eq!( + h.client.claimable(&id), + 18_000_000_000, + "approval unlocks the tranche's accrual back to day zero, not from today", + ); + assert_eq!(h.client.describe(&id).position.held, 0); +} + +/// Scenario: approval after the stream's end releases the full tranche, with no +/// bonus for lateness +#[test] +fn late_approval_releases_the_tranche_but_no_more() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(90); + h.client.approve_milestone(&id, &0); + + assert_eq!( + h.client.claimable(&id), + TOTAL, + "the whole deposit, never more" + ); + assert_eq!(h.client.withdraw(&id), TOTAL); + assert_eq!(h.contract_balance(), 0); +} + +/// Scenario: rejected — approve_milestone is only callable by that milestone's +/// named approver +#[test] +fn only_the_named_approver_may_approve() { + let h = Harness::new(); + let id = h.alice_and_bob(); + h.warp_days(10); + + h.env.set_auths(&[]); + assert!( + h.client.try_approve_milestone(&id, &0).is_err(), + "an unauthorized approval must be rejected", + ); +} + +/// Scenario: double approval of an already-met milestone — no-op, not an error +/// +/// Settled in #32: a duplicate is overwhelmingly a retry after an uncertain +/// outcome, and erroring punishes the honest retry to protect state that cannot +/// change anyway. +#[test] +fn double_approval_is_absorbed_silently() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(18); + h.client.approve_milestone(&id, &0); + let after_first = h.client.claimable(&id); + + h.client.approve_milestone(&id, &0); + + assert_eq!(h.client.claimable(&id), after_first, "no state changed"); + assert_eq!( + h.client.get_stream(&id).milestones.get(0).unwrap().state, + MilestoneState::Met, + ); +} + +/// Authorization is still checked *before* the no-op absorbs the call, so a +/// non-approver is rejected rather than silently swallowed. +#[test] +fn double_approval_still_checks_authorization_first() { + let h = Harness::new(); + let id = h.alice_and_bob(); + h.warp_days(18); + h.client.approve_milestone(&id, &0); + + h.env.set_auths(&[]); + assert!( + h.client.try_approve_milestone(&id, &0).is_err(), + "a stranger must not get a free success just because the state is terminal", + ); +} + +/// Scenario: approving a milestone on an already-cancelled stream is rejected +#[test] +fn cannot_approve_on_a_cancelled_stream() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(10); + h.client.cancel(&id); + + assert_eq!( + h.client.try_approve_milestone(&id, &0), + Err(Ok(Error::AlreadyCanceled)), + "the cancellation is the cause, and naming it beats naming its consequence", + ); + assert_eq!( + h.client.get_stream(&id).milestones.get(0).unwrap().state, + MilestoneState::Forfeited, + "the tranche did go back to the sender — that is just not the useful error", + ); +} + +#[test] +fn rejects_an_index_that_does_not_exist() { + let h = Harness::new(); + let id = h.alice_and_bob(); + assert_eq!( + h.client.try_approve_milestone(&id, &7), + Err(Ok(Error::MilestoneNotFound)), + ); +} + +/// `Met` is terminal, so approval can only ever raise claimable. +#[test] +fn approval_never_reduces_claimable() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + for day in [1u64, 5, 12, 19, 26, 30] { + h.warp_days(day); + let before = h.client.claimable(&id); + if day == 19 { + h.client.approve_milestone(&id, &0); + } + assert!( + h.client.claimable(&id) >= before, + "claimable fell at day {}", + day, + ); + } +} + +// --------------------------------------------------------------------------- +// Milestone deadlines — docs/milestone-deadlines.md +// --------------------------------------------------------------------------- + +/// A deadline resolving to the recipient unlocks the tranche without anyone +/// acting. Expiry is evaluated on read; no transaction marks it. +#[test] +fn an_expired_deadline_can_release_to_the_recipient() { + let h = Harness::new(); + let deadline = END + 7 * DAY; + let milestones = vec![&h.env, h.milestone(GATED, deadline, OnExpiry::ToRecipient)]; + let id = h.create(TOTAL, START, true, milestones); + + h.warp_to(deadline - 1); + assert_eq!( + h.client.claimable(&id), + BASE, + "still held, one second early" + ); + + h.warp_to(deadline); + assert_eq!( + h.client.claimable(&id), + TOTAL, + "resolved without any transaction" + ); + assert_eq!(h.client.withdraw(&id), TOTAL); +} + +/// The same deadline pointed the other way returns the tranche to the sender. +#[test] +fn an_expired_deadline_can_forfeit_to_the_sender() { + let h = Harness::new(); + let deadline = END + 7 * DAY; + let milestones = vec![&h.env, h.milestone(GATED, deadline, OnExpiry::ToSender)]; + let id = h.create(TOTAL, START, true, milestones); + + h.warp_to(deadline); + assert_eq!( + h.client.claimable(&id), + BASE, + "the gated tranche is the sender's" + ); + + let view = h.client.describe(&id); + assert_eq!(view.position.streamed_total, BASE); + assert_eq!(view.position.held, 0, "forfeited, not held"); +} + +/// Rule 4: an approved milestone ignores its deadline entirely. A deadline that +/// could undo an approval would be revocation through the back door. +#[test] +fn approval_survives_its_own_deadline() { + let h = Harness::new(); + let deadline = END + 7 * DAY; + let milestones = vec![&h.env, h.milestone(GATED, deadline, OnExpiry::ToSender)]; + let id = h.create(TOTAL, START, true, milestones); + + h.warp_days(10); + h.client.approve_milestone(&id, &0); + + h.warp_to(deadline + DAY); + assert_eq!( + h.client.claimable(&id), + TOTAL, + "an approved tranche is not clawed back by its deadline", + ); +} + +/// A zero deadline means wait indefinitely — exactly the pre-#38 behaviour. +#[test] +fn a_zero_deadline_never_expires() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_to(END + 3650 * DAY); + assert_eq!(h.client.claimable(&id), BASE, "still waiting, ten years on"); + assert_eq!(h.client.describe(&id).position.held, GATED); +} diff --git a/contracts/stelflow/src/tests/cancel.rs b/contracts/stelflow/src/tests/cancel.rs new file mode 100644 index 0000000..e3b4f42 --- /dev/null +++ b/contracts/stelflow/src/tests/cancel.rs @@ -0,0 +1,240 @@ +//! `docs/behaviour.md` → Feature: cancel + +use soroban_sdk::vec; + +use super::*; +use crate::{Error, MilestoneState, OnExpiry}; + +/// Scenario: happy path — cancel partway through, recipient keeps earned, sender +/// recovers the rest +#[test] +fn recipient_keeps_earned_sender_recovers_the_rest() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(10); + let settlement = h.client.cancel(&id); + + assert_eq!(settlement.refund, TOTAL * 2 / 3, "twenty unstreamed days"); + assert_eq!(settlement.recipient_balance, TOTAL / 3, "ten streamed days"); + assert_eq!( + h.contract_balance(), + TOTAL / 3, + "the recipient's balance stays in the contract, frozen but theirs", + ); + h.assert_conserved(TOTAL); +} + +/// Scenario: withdraw after cancellation pays the frozen earned balance +#[test] +fn the_frozen_balance_is_still_withdrawable_afterwards() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(10); + h.client.cancel(&id); + + h.warp_days(25); + assert_eq!( + h.client.withdraw(&id), + TOTAL / 3, + "accrual froze at cancellation; the clock moving on adds nothing", + ); + assert_eq!(h.contract_balance(), 0); + h.assert_conserved(TOTAL); +} + +/// Scenario: cancel with zero elapsed time +#[test] +fn cancelling_before_anything_streams_refunds_everything() { + let h = Harness::new(); + let id = h.simple(); + + let settlement = h.client.cancel(&id); + assert_eq!(settlement.refund, TOTAL); + assert_eq!(settlement.recipient_balance, 0); + assert_eq!(h.contract_balance(), 0); +} + +/// Scenario: cancel with an unmet milestone in flight — the gated tranche +/// returns to the sender, not just its unaccrued fraction +/// +/// This is the docs' day-10 worked example, and the figure that matters is that +/// the sender recovers the *whole* 12,000,000,000 tranche including the +/// 4,000,000,000 that had already accrued behind the shut gate. +#[test] +fn an_unmet_tranche_returns_whole_including_its_accrual() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(10); + h.client.withdraw(&id); + let settlement = h.client.cancel(&id); + + assert_eq!( + settlement.refund, 24_000_000_000, + "12,000,000,000 unstreamed base + the entire 12,000,000,000 gated tranche", + ); + assert_eq!( + settlement.recipient_balance, 0, + "the base was already withdrawn" + ); + h.assert_conserved(TOTAL); + assert_eq!(h.contract_balance(), 0); +} + +/// Scenario: cancel with a milestone already approved before cancellation +/// +/// The docs' day-20 example. An approved tranche is treated exactly like base: +/// only its unstreamed remainder goes back. +#[test] +fn an_approved_tranche_is_treated_exactly_like_base() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(18); + h.client.approve_milestone(&id, &0); + h.client.withdraw(&id); + + h.warp_days(20); + let settlement = h.client.cancel(&id); + + assert_eq!( + settlement.refund, 10_000_000_000, + "only the still-unstreamed third of both tranches", + ); + assert_eq!( + settlement.recipient_balance, 2_000_000_000, + "streamed 20,000,000,000 less the 18,000,000,000 already taken", + ); + h.assert_conserved(TOTAL); +} + +/// Scenario: cancel after end, all milestones resolved — a genuine no-op +#[test] +fn cancel_after_end_with_everything_resolved_moves_nothing() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(30); + h.client.withdraw(&id); + let settlement = h.client.cancel(&id); + + assert_eq!(settlement.refund, 0); + assert_eq!(settlement.recipient_balance, 0); +} + +/// Scenario: cancel after end with a milestone still unmet — the sender recovers +/// the whole tranche +/// +/// The case #32 found the docs had wrong: this was described as "harmless, +/// refund = 0". With an unmet milestone the refund is the entire tranche, and +/// permitting the call is the only in-protocol way to resolve a milestone nobody +/// ever approved. +#[test] +fn cancel_after_end_with_an_unmet_milestone_is_not_a_no_op() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(30); + h.client.withdraw(&id); + let settlement = h.client.cancel(&id); + + assert_eq!(settlement.refund, GATED, "a real transfer, not nothing"); + h.assert_conserved(TOTAL); + assert_eq!(h.contract_balance(), 0); +} + +/// Scenario: rejected — cancel on a non-cancelable stream, sender authorizing +/// alone +#[test] +fn a_non_cancelable_stream_rejects_the_sender_alone() { + let h = Harness::new(); + let id = h.create(TOTAL, START, false, h.no_milestones()); + h.warp_days(10); + + h.env.set_auths(&[]); + assert!( + h.client.try_cancel(&id).is_err(), + "the sender cannot cancel a non-cancelable stream unilaterally", + ); +} + +/// Scenario: cancel on a non-cancelable stream with both signatures — permitted, +/// settling exactly as a normal cancel +/// +/// The #33 decision: `cancelable = false` means the sender cannot cancel +/// *alone*, not that nobody can. +#[test] +fn a_non_cancelable_stream_settles_with_both_signatures() { + let h = Harness::new(); + let id = h.create(TOTAL, START, false, h.one_milestone()); + + h.warp_days(10); + h.client.withdraw(&id); + let settlement = h.client.cancel(&id); + + assert_eq!( + settlement.refund, 24_000_000_000, + "identical settlement to the cancelable case — there is no separate path", + ); + h.assert_conserved(TOTAL); +} + +/// Cancelling twice has nothing to do the second time. +#[test] +fn cannot_cancel_twice() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(10); + h.client.cancel(&id); + assert_eq!(h.client.try_cancel(&id), Err(Ok(Error::AlreadyCanceled))); +} + +/// Cancellation resolves every shut gate, so a cancelled stream's milestones can +/// never later "expire" — they are already resolved. +#[test] +fn cancellation_forfeits_unmet_milestones_permanently() { + let h = Harness::new(); + let deadline = END + 7 * DAY; + let milestones = vec![&h.env, h.milestone(GATED, deadline, OnExpiry::ToRecipient)]; + let id = h.create(TOTAL, START, true, milestones); + + h.warp_days(10); + h.client.cancel(&id); + + assert_eq!( + h.client.get_stream(&id).milestones.get(0).unwrap().state, + MilestoneState::Forfeited, + ); + + h.warp_to(deadline + DAY); + let view = h.client.describe(&id); + assert_eq!( + view.position.held, 0, + "a forfeited tranche does not resurrect at its deadline", + ); + assert_eq!(view.position.streamed_total, BASE * 10 / 30); +} + +/// `preview_cancel` must agree with what `cancel` actually does — it is what a +/// UI shows both parties before either signs. +#[test] +fn preview_matches_the_real_settlement() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(13); + let preview = h.client.preview_cancel(&id); + let actual = h.client.cancel(&id); + + assert_eq!(preview.refund, actual.refund); + assert_eq!(preview.recipient_balance, actual.recipient_balance); +} + +#[test] +fn rejects_an_unknown_stream() { + let h = Harness::new(); + assert_eq!(h.client.try_cancel(&404), Err(Ok(Error::StreamNotFound))); +} diff --git a/contracts/stelflow/src/tests/create.rs b/contracts/stelflow/src/tests/create.rs new file mode 100644 index 0000000..e082dac --- /dev/null +++ b/contracts/stelflow/src/tests/create.rs @@ -0,0 +1,405 @@ +//! `docs/behaviour.md` → Feature: create_stream + +use soroban_sdk::testutils::{Address as _, Events as _}; +use soroban_sdk::xdr::{ContractEventBody, ScVal}; +use soroban_sdk::{vec, Address, Vec}; + +use super::*; +use crate::{Error, MilestoneState, OnExpiry, MAX_MILESTONES_PER_STREAM}; + +/// Scenario: happy path — a simple two-party stream +#[test] +fn happy_path_escrows_the_full_deposit() { + let h = Harness::new(); + let sender_before = h.token.balance(&h.sender); + + let id = h.simple(); + + assert_eq!(id, 0, "ids start at zero and are readable"); + assert_eq!( + h.contract_balance(), + TOTAL, + "the deposit is escrowed in full" + ); + assert_eq!(h.token.balance(&h.sender), sender_before - TOTAL); + + let stream = h.client.get_stream(&id); + assert_eq!(stream.total, TOTAL); + assert_eq!(stream.base_amount, TOTAL, "no milestones means all base"); + assert_eq!(stream.withdrawn, 0); + assert_eq!(stream.canceled_at, None); + h.assert_conserved(TOTAL); +} + +/// Scenario: create_stream with a base tranche and one milestone tranche +#[test] +fn milestones_are_carved_out_of_the_deposit_not_added_to_it() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + let stream = h.client.get_stream(&id); + assert_eq!(stream.total, TOTAL); + assert_eq!( + stream.base_amount, BASE, + "base is total minus the gated sum" + ); + assert_eq!(stream.milestones.len(), 1); + assert_eq!(stream.milestones.get(0).unwrap().amount, GATED); + assert_eq!( + h.contract_balance(), + TOTAL, + "gating moves no extra money — it partitions what was already deposited", + ); +} + +/// Scenario: caller must be the sender — create_stream is not callable on +/// someone else's behalf +#[test] +fn requires_the_sender_to_authorize() { + let env = Env::default(); + let issuer = Address::generate(&env); + let asset = env.register_stellar_asset_contract_v2(issuer); + let contract_id = env.register(StelFlow, ()); + let client = crate::StelFlowClient::new(&env, &contract_id); + + env.mock_all_auths(); + client.initialize(&None); + let sender = Address::generate(&env); + soroban_sdk::token::StellarAssetClient::new(&env, &asset.address()).mint(&sender, &TOTAL); + env.ledger().set_timestamp(START); + + // From here on, only the *stranger* has authorized anything. + let stranger = Address::generate(&env); + env.set_auths(&[]); + + let result = client.try_create_stream( + &sender, + &Address::generate(&env), + &asset.address(), + &TOTAL, + &START, + &END, + &START, + &true, + &Vec::new(&env), + ); + assert!(result.is_err(), "unauthorized creation must be rejected"); + let _ = stranger; +} + +/// Scenario: a fee-on-transfer token — the stream is sized to what actually +/// arrived +/// +/// The SAC does not charge a fee, so the honest way to test the *decision* is to +/// assert the property it guarantees: the stored total equals the contract's +/// measured balance delta, never the requested amount. A token that delivered +/// less would be caught by the same assertion. +#[test] +fn total_is_the_measured_delta_not_the_requested_amount() { + let h = Harness::new(); + let before = h.contract_balance(); + let id = h.simple(); + let delta = h.contract_balance() - before; + + let stream = h.client.get_stream(&id); + assert_eq!( + stream.total, delta, + "stored total must be what arrived, by construction", + ); +} + +/// Scenario: rejected — end does not exceed start +#[test] +fn rejects_zero_duration() { + let h = Harness::new(); + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &START, + &START, + &true, + &h.no_milestones(), + ); + assert_eq!(result, Err(Ok(Error::InvalidTimeRange))); + assert_eq!( + h.contract_balance(), + 0, + "a rejected creation escrows nothing" + ); +} + +/// Scenario: rejected — end is before start +#[test] +fn rejects_inverted_time_range() { + let h = Harness::new(); + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &END, + &START, + &END, + &true, + &h.no_milestones(), + ); + assert_eq!(result, Err(Ok(Error::InvalidTimeRange))); +} + +/// Scenario: rejected — a milestone's cliff falls after the stream's end +#[test] +fn rejects_a_cliff_outside_the_stream_window() { + let h = Harness::new(); + for cliff in [START - 1, END + 1] { + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &END, + &cliff, + &true, + &h.no_milestones(), + ); + assert_eq!(result, Err(Ok(Error::InvalidCliff)), "cliff {}", cliff); + } +} + +#[test] +fn rejects_non_positive_amounts() { + let h = Harness::new(); + for amount in [0i128, -1] { + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &amount, + &START, + &END, + &START, + &true, + &h.no_milestones(), + ); + assert_eq!(result, Err(Ok(Error::InvalidAmount)), "amount {}", amount); + } +} + +#[test] +fn rejects_milestones_summing_past_the_deposit() { + let h = Harness::new(); + let milestones = vec![&h.env, h.milestone(TOTAL + 1, 0, OnExpiry::ToSender)]; + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &END, + &START, + &true, + &milestones, + ); + assert_eq!(result, Err(Ok(Error::MilestonesExceedTotal))); +} + +/// A milestone tranche may consume the entire deposit, leaving a zero base. That +/// is a fully-gated stream, which is legitimate — it just means nothing accrues +/// claimably until the gate opens. +#[test] +fn allows_a_fully_gated_stream() { + let h = Harness::new(); + let milestones = vec![&h.env, h.milestone(TOTAL, 0, OnExpiry::ToSender)]; + let id = h.create(TOTAL, START, true, milestones); + + let stream = h.client.get_stream(&id); + assert_eq!(stream.base_amount, 0); + + h.warp_days(15); + assert_eq!(h.client.claimable(&id), 0, "everything is behind the gate"); +} + +/// Scenario: the milestone cap is enforced at creation — threat-model T2. +#[test] +fn rejects_more_milestones_than_the_cap() { + let h = Harness::new(); + let mut milestones = Vec::new(&h.env); + for _ in 0..(MAX_MILESTONES_PER_STREAM + 1) { + milestones.push_back(h.milestone(1_000, 0, OnExpiry::ToSender)); + } + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &END, + &START, + &true, + &milestones, + ); + assert_eq!(result, Err(Ok(Error::TooManyMilestones))); +} + +/// A stream loaded to the cap must still be withdrawable — the cap exists to +/// guarantee exactly this, so asserting it is the point. +#[test] +fn a_fully_loaded_stream_is_still_withdrawable() { + let h = Harness::new(); + let mut milestones = Vec::new(&h.env); + for _ in 0..MAX_MILESTONES_PER_STREAM { + milestones.push_back(h.milestone(1_000_000_000, 0, OnExpiry::ToSender)); + } + let id = h.create(TOTAL, START, true, milestones); + + h.warp_days(30); + let paid = h.client.withdraw(&id); + assert_eq!( + paid, + TOTAL - 10 * 1_000_000_000, + "base pays out in full; every gate is still shut", + ); + h.assert_solvent(id); +} + +/// `docs/milestone-deadlines.md` rule 2: a deadline before `end` would resolve a +/// tranche while it was still accruing. +#[test] +fn rejects_a_deadline_before_the_stream_ends() { + let h = Harness::new(); + let milestones = vec![&h.env, h.milestone(GATED, END - 1, OnExpiry::ToRecipient)]; + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &END, + &START, + &true, + &milestones, + ); + assert_eq!(result, Err(Ok(Error::InvalidTimeRange))); +} + +#[test] +fn accepts_a_deadline_at_or_after_the_stream_ends() { + let h = Harness::new(); + let milestones = vec![&h.env, h.milestone(GATED, END, OnExpiry::ToRecipient)]; + let id = h.create(TOTAL, START, true, milestones); + assert_eq!( + h.client.get_stream(&id).milestones.get(0).unwrap().deadline, + END + ); +} + +/// A milestone may not be pre-marked as met at creation, which would let a +/// sender mint an approval nobody granted. +#[test] +fn rejects_a_milestone_that_does_not_start_unmet() { + let h = Harness::new(); + let mut milestone = h.milestone(GATED, 0, OnExpiry::ToSender); + milestone.state = MilestoneState::Met; + let result = h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &END, + &START, + &true, + &vec![&h.env, milestone], + ); + assert_eq!(result, Err(Ok(Error::InvalidAmount))); +} + +/// Scenario: a stream of duration 1 second +#[test] +fn a_one_second_stream_settles_whole() { + let h = Harness::new(); + let id = h.client.create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &(START + 1), + &START, + &true, + &h.no_milestones(), + ); + h.warp_to(START + 1); + assert_eq!(h.client.withdraw(&id), TOTAL); + assert_eq!(h.contract_balance(), 0); +} + +/// Scenario: a stream of amount 1 stroop +#[test] +fn a_one_stroop_stream_pays_nothing_until_it_ends() { + let h = Harness::new(); + let id = h.create(1, START, true, h.no_milestones()); + + h.warp_days(29); + assert_eq!( + h.client.claimable(&id), + 0, + "1 * elapsed / duration floors to zero for all but the last instant", + ); + + h.warp_days(30); + assert_eq!( + h.client.claimable(&id), + 1, + "the endpoint case pays the remainder" + ); +} + +/// The frontend reads history by folding this log, so the emitted shape is part +/// of the contract's interface and is asserted rather than assumed. +#[test] +fn creation_emits_one_event_keyed_by_stream_id() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + let ours = h.env.events().all().filter_by_contract(&h.client.address); + let emitted = ours.events(); + assert_eq!( + emitted.len(), + 1, + "exactly one event per creation, never two" + ); + + let ContractEventBody::V0(body) = &emitted[0].body; + assert!( + body.topics + .iter() + .any(|topic| matches!(topic, ScVal::U64(value) if *value == id)), + "stream_id must be a topic so clients can filter server-side", + ); + assert!( + matches!(body.data, ScVal::Map(_)), + "data is a named map, so adding a field later cannot shift what consumers parse", + ); +} + +#[test] +fn stream_count_tracks_creations() { + let h = Harness::new(); + assert_eq!(h.client.stream_count(), 0); + h.simple(); + h.simple(); + assert_eq!(h.client.stream_count(), 2); +} + +#[test] +fn initialize_runs_once() { + let h = Harness::new(); + assert_eq!( + h.client.try_initialize(&Some(h.stranger.clone())), + Err(Ok(Error::AlreadyInitialized)), + ); +} diff --git a/contracts/stelflow/src/tests/mod.rs b/contracts/stelflow/src/tests/mod.rs new file mode 100644 index 0000000..b625d6b --- /dev/null +++ b/contracts/stelflow/src/tests/mod.rs @@ -0,0 +1,183 @@ +//! The behaviour specs, executed. +//! +//! Every test here corresponds to a named scenario in `docs/behaviour.md`, and +//! the doc comment on each one quotes the scenario title so the two stay +//! traceable in both directions. That document was written before any code +//! existed, precisely so the tests could not be shaped to fit the implementation. +//! +//! Amounts follow the docs' worked example throughout: 30,000,000,000 stroops +//! over 30 days, split 18,000,000,000 base and 12,000,000,000 behind one +//! milestone. Numbers divide evenly on days 10, 18, and 20 so the arithmetic can +//! be checked by hand. Tests that exist to exercise rounding say so and use +//! awkward numbers on purpose. + +mod accrual_properties; +mod approve; +mod cancel; +mod create; +mod pause; +mod withdraw; + +use soroban_sdk::testutils::{Address as _, Ledger}; +use soroban_sdk::token::{StellarAssetClient, TokenClient}; +use soroban_sdk::{vec, Address, Env, Vec}; + +use crate::{Milestone, MilestoneState, OnExpiry, StelFlow, StelFlowClient}; + +pub const DAY: u64 = 86_400; +pub const START: u64 = 1_000_000; +pub const DURATION: u64 = 30 * DAY; +pub const END: u64 = START + DURATION; + +pub const TOTAL: i128 = 30_000_000_000; +pub const BASE: i128 = 18_000_000_000; +pub const GATED: i128 = 12_000_000_000; + +/// A deployed contract plus the cast of addresses every scenario needs. +pub struct Harness<'a> { + pub env: Env, + pub client: StelFlowClient<'a>, + pub token: TokenClient<'a>, + pub minter: StellarAssetClient<'a>, + pub token_id: Address, + pub sender: Address, + pub recipient: Address, + pub approver: Address, + pub pauser: Address, + pub stranger: Address, +} + +impl<'a> Harness<'a> { + /// Deploy with a pauser, mint the sender a working balance, and park the + /// ledger just before any stream begins. + pub fn new() -> Self { + let env = Env::default(); + env.mock_all_auths(); + + let issuer = Address::generate(&env); + let asset = env.register_stellar_asset_contract_v2(issuer); + let token_id = asset.address(); + + let contract_id = env.register(StelFlow, ()); + let client = StelFlowClient::new(&env, &contract_id); + + let pauser = Address::generate(&env); + client.initialize(&Some(pauser.clone())); + + let sender = Address::generate(&env); + let harness = Self { + token: TokenClient::new(&env, &token_id), + minter: StellarAssetClient::new(&env, &token_id), + recipient: Address::generate(&env), + approver: Address::generate(&env), + stranger: Address::generate(&env), + token_id, + sender, + pauser, + client, + env, + }; + harness.minter.mint(&harness.sender, &(TOTAL * 10)); + harness.warp_to(START); + harness + } + + /// Move the ledger clock to an absolute timestamp. + pub fn warp_to(&self, timestamp: u64) { + self.env.ledger().set_timestamp(timestamp); + } + + /// Move the ledger clock to `START + days`. + pub fn warp_days(&self, days: u64) { + self.warp_to(START + days * DAY); + } + + pub fn no_milestones(&self) -> Vec { + Vec::new(&self.env) + } + + /// One milestone holding `GATED`, approved by `self.approver`, no deadline. + pub fn one_milestone(&self) -> Vec { + vec![&self.env, self.milestone(GATED, 0, OnExpiry::ToSender)] + } + + pub fn milestone(&self, amount: i128, deadline: u64, on_expiry: OnExpiry) -> Milestone { + Milestone { + amount, + approver: self.approver.clone(), + state: MilestoneState::Unmet, + deadline, + on_expiry, + } + } + + /// The docs' worked example: 30,000,000,000 over 30 days, 12,000,000,000 of + /// it gated behind one milestone, cancelable, no cliff. + pub fn alice_and_bob(&self) -> u64 { + self.create(TOTAL, START, true, self.one_milestone()) + } + + /// An ungated stream of `TOTAL` over the standard window. + pub fn simple(&self) -> u64 { + self.create(TOTAL, START, true, self.no_milestones()) + } + + pub fn create( + &self, + amount: i128, + cliff: u64, + cancelable: bool, + milestones: Vec, + ) -> u64 { + self.client.create_stream( + &self.sender, + &self.recipient, + &self.token_id, + &amount, + &START, + &END, + &cliff, + &cancelable, + &milestones, + ) + } + + pub fn contract_balance(&self) -> i128 { + self.token.balance(&self.client.address) + } + + /// The invariant every state-changing scenario asserts: + /// `deposit == withdrawn + refunded + remaining_in_contract`. + /// + /// Note this is a *closure* check across the whole contract — it balances + /// even if one stream were paid out of another's deposit. Cross-stream + /// isolation is a separate assertion; see [`assert_solvent`]. + pub fn assert_conserved(&self, deposit: i128) { + let withdrawn: i128 = (0..self.client.stream_count()) + .map(|id| self.client.get_stream(&id).withdrawn) + .sum(); + // Whatever the sender holds above their post-deposit balance came back + // as a refund. + let refunded = self.token.balance(&self.sender) - (TOTAL * 10 - deposit); + assert_eq!( + deposit, + withdrawn + refunded + self.contract_balance(), + "value conservation: deposit != withdrawn + refunded + remaining", + ); + } + + /// No stream has extracted more than its own deposit. + /// + /// The contract's token balance is pooled, so this is what actually keeps + /// streams isolated from one another. See `docs/upgradeability-and-pause.md`. + pub fn assert_solvent(&self, stream_id: u64) { + let stream = self.client.get_stream(&stream_id); + assert!( + stream.withdrawn <= stream.total, + "stream {} withdrew {} against a deposit of {}", + stream_id, + stream.withdrawn, + stream.total, + ); + } +} diff --git a/contracts/stelflow/src/tests/pause.rs b/contracts/stelflow/src/tests/pause.rs new file mode 100644 index 0000000..a86037c --- /dev/null +++ b/contracts/stelflow/src/tests/pause.rs @@ -0,0 +1,170 @@ +//! `docs/behaviour.md` → Feature: pause +//! +//! These mostly pin down what the pause *cannot* do, which is the load-bearing +//! half. See `docs/upgradeability-and-pause.md`. + +use super::*; +use crate::{Error, PAUSE_DURATION_SECONDS}; + +/// Scenario: pausing blocks create_stream and nothing else +#[test] +fn pausing_stops_creation_and_leaves_everything_else_alone() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(18); + h.client.pause(); + + assert_eq!( + h.client.try_create_stream( + &h.sender, + &h.recipient, + &h.token_id, + &TOTAL, + &START, + &END, + &START, + &true, + &h.no_milestones(), + ), + Err(Ok(Error::Paused)), + "new exposure is stopped", + ); + + // Everything touching the existing stream still works, unchanged. + h.client.approve_milestone(&id, &0); + assert_eq!(h.client.withdraw(&id), 18_000_000_000); + h.client.touch(&id); + h.client.cancel(&id); + h.assert_conserved(TOTAL); +} + +/// Scenario: a paused contract still cannot touch existing funds +#[test] +fn the_pauser_gains_no_authority_over_any_stream() { + let h = Harness::new(); + let id = h.simple(); + h.client.pause(); + h.warp_days(10); + + // The pauser is not a party to this stream. Their role confers nothing. + h.env.set_auths(&[]); + assert!( + h.client.try_withdraw(&id).is_err(), + "the pause is a create-time gate, not a role over funds", + ); + assert!(h.client.try_cancel(&id).is_err()); +} + +/// Scenario: rejected — only the pauser can pause +#[test] +fn only_the_pauser_may_pause() { + let h = Harness::new(); + h.env.set_auths(&[]); + assert!(h.client.try_pause().is_err()); + assert!(h.client.try_unpause().is_err()); +} + +/// Scenario: the pause expires on its own +/// +/// Without expiry, a pause key lost while engaged would disable `create_stream` +/// permanently — there is no upgrade that could rescue it. +#[test] +fn the_pause_lifts_by_itself() { + let h = Harness::new(); + let until = h.client.pause(); + assert_eq!(until, START + PAUSE_DURATION_SECONDS); + + h.warp_to(until - 1); + assert_eq!(h.client.paused_until(), until, "still paused"); + + h.warp_to(until); + assert_eq!( + h.client.paused_until(), + 0, + "lifted with no transaction from anyone" + ); + h.simple(); +} + +#[test] +fn unpausing_is_immediate() { + let h = Harness::new(); + h.client.pause(); + h.client.unpause(); + assert_eq!(h.client.paused_until(), 0); + h.simple(); +} + +#[test] +fn pausing_again_extends_the_window() { + let h = Harness::new(); + let first = h.client.pause(); + h.warp_to(first - DAY); + let second = h.client.pause(); + assert!(second > first, "renewal is one transaction"); +} + +/// Scenario: renouncing the pauser role is permanent +#[test] +fn renouncing_is_irreversible() { + let h = Harness::new(); + assert_eq!(h.client.pauser(), Some(h.pauser.clone())); + + h.client.renounce_pauser(); + + assert_eq!(h.client.pauser(), None); + assert_eq!(h.client.try_pause(), Err(Ok(Error::NotPauser))); + assert_eq!( + h.client.try_transfer_pauser(&h.stranger), + Err(Ok(Error::NotPauser)), + "nothing can restore the role — there is no upgrade path", + ); + h.simple(); +} + +#[test] +fn the_role_can_be_handed_on() { + let h = Harness::new(); + h.client.transfer_pauser(&h.stranger); + assert_eq!(h.client.pauser(), Some(h.stranger.clone())); +} + +/// A contract may be deployed with no pauser at all — privilege-free from its +/// first ledger. +#[test] +fn deploying_without_a_pauser_is_allowed() { + let env = Env::default(); + env.mock_all_auths(); + let contract_id = env.register(StelFlow, ()); + let client = crate::StelFlowClient::new(&env, &contract_id); + + client.initialize(&None); + + assert_eq!(client.pauser(), None); + assert_eq!(client.try_pause(), Err(Ok(Error::NotPauser))); +} + +/// Scenario: a payout can never exceed its own stream's remaining deposit +/// +/// The conservation invariant is a closure check and would balance either way, +/// so this is asserted separately across two independently funded streams. +#[test] +fn payouts_stay_inside_their_own_stream() { + let h = Harness::new(); + let first = h.alice_and_bob(); + let second = h.simple(); + + h.warp_days(30); + h.client.approve_milestone(&first, &0); + h.client.withdraw(&first); + h.client.withdraw(&second); + + h.assert_solvent(first); + h.assert_solvent(second); + assert_eq!( + h.contract_balance(), + 0, + "two deposits in, two deposits out, nothing borrowed between them", + ); +} diff --git a/contracts/stelflow/src/tests/withdraw.rs b/contracts/stelflow/src/tests/withdraw.rs new file mode 100644 index 0000000..0ca4f75 --- /dev/null +++ b/contracts/stelflow/src/tests/withdraw.rs @@ -0,0 +1,224 @@ +//! `docs/behaviour.md` → Feature: withdraw + +use super::*; +use crate::Error; + +/// Scenario: happy path — partial withdrawal mid-stream +#[test] +fn pays_exactly_the_elapsed_fraction() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(10); + let paid = h.client.withdraw(&id); + + assert_eq!(paid, TOTAL / 3, "10 of 30 days elapsed"); + assert_eq!(h.token.balance(&h.recipient), TOTAL / 3); + assert_eq!(h.client.get_stream(&id).withdrawn, TOTAL / 3); + h.assert_conserved(TOTAL); + h.assert_solvent(id); +} + +/// Scenario: withdraw at exactly start +#[test] +fn pays_nothing_at_start() { + let h = Harness::new(); + let id = h.simple(); + assert_eq!( + h.client.try_withdraw(&id), + Err(Ok(Error::NothingToWithdraw)) + ); +} + +/// Scenario: withdraw at exactly end +#[test] +fn pays_the_whole_deposit_at_end() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(30); + assert_eq!(h.client.withdraw(&id), TOTAL); + assert_eq!( + h.contract_balance(), + 0, + "the stream settles to exactly its deposit" + ); + h.assert_conserved(TOTAL); +} + +/// Past `end` nothing further accrues — there is nothing left to accrue. +#[test] +fn pays_no_more_after_end() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(30); + h.client.withdraw(&id); + h.warp_days(365); + assert_eq!( + h.client.try_withdraw(&id), + Err(Ok(Error::NothingToWithdraw)) + ); +} + +/// Scenario: two withdrawals in the same ledger — the second is a no-op, not a +/// failure +/// +/// It surfaces as `NothingToWithdraw` rather than succeeding with zero: the +/// caller paid a fee for a state change that didn't happen, and saying so is +/// friendlier than a silent success. +#[test] +fn a_second_withdrawal_in_the_same_ledger_moves_nothing() { + let h = Harness::new(); + let id = h.simple(); + + h.warp_days(10); + let first = h.client.withdraw(&id); + assert_eq!( + h.client.try_withdraw(&id), + Err(Ok(Error::NothingToWithdraw)) + ); + assert_eq!(h.token.balance(&h.recipient), first); +} + +/// Scenario: rejected — withdraw is only callable by the recipient +#[test] +fn only_the_recipient_may_withdraw() { + let h = Harness::new(); + let id = h.simple(); + h.warp_days(10); + + // Drop every mocked authorization, then confirm the call cannot proceed. + h.env.set_auths(&[]); + assert!( + h.client.try_withdraw(&id).is_err(), + "an unauthorized withdrawal must be rejected", + ); +} + +/// Scenario: withdraw is reduced by an unmet milestone gate +#[test] +fn an_unmet_gate_withholds_its_accrual() { + let h = Harness::new(); + let id = h.alice_and_bob(); + + h.warp_days(10); + let view = h.client.describe(&id); + assert_eq!( + view.position.streamed_total, 10_000_000_000, + "both tranches accrue" + ); + assert_eq!( + view.position.held, 4_000_000_000, + "the gated third of the tranche" + ); + assert_eq!(view.position.claimable, 6_000_000_000, "base only"); + + assert_eq!(h.client.withdraw(&id), 6_000_000_000); + h.assert_conserved(TOTAL); +} + +/// Repeated withdrawals must not drift from a single one — truncation is +/// recomputed, never accumulated. +#[test] +fn many_small_withdrawals_equal_one_large_one() { + let h = Harness::new(); + let id = h.simple(); + + let mut total_paid = 0i128; + for day in 1..=30 { + h.warp_days(day); + if let Ok(Ok(paid)) = h.client.try_withdraw(&id) { + total_paid += paid; + } + } + assert_eq!( + total_paid, TOTAL, + "thirty withdrawals settle to the exact deposit" + ); + assert_eq!(h.contract_balance(), 0); +} + +/// Scenario: the indivisible-total stream settles to the exact deposit at the +/// final withdrawal +#[test] +fn an_indivisible_total_still_settles_exactly() { + let h = Harness::new(); + // 30,000,000,001 over 30 days: never divides evenly. + let id = h.create(TOTAL + 1, START, true, h.no_milestones()); + + let mut paid = 0i128; + for day in 1..=30 { + h.warp_days(day); + if let Ok(Ok(amount)) = h.client.try_withdraw(&id) { + paid += amount; + } + } + assert_eq!( + paid, + TOTAL + 1, + "the endpoint case sweeps up every truncated stroop" + ); + assert_eq!(h.contract_balance(), 0); +} + +/// A cliff withholds claimability without pausing accrual. +#[test] +fn a_cliff_withholds_everything_then_releases_it_at_once() { + let h = Harness::new(); + let cliff = START + 10 * DAY; + let id = h.create(TOTAL, cliff, true, h.no_milestones()); + + h.warp_days(9); + let before = h.client.describe(&id); + assert_eq!( + before.position.claimable, 0, + "nothing claimable inside the cliff" + ); + assert_eq!( + before.position.streamed_total, + TOTAL * 9 / 30, + "but accrual has been running the whole time", + ); + + h.warp_days(10); + assert_eq!( + h.client.claimable(&id), + TOTAL / 3, + "the cliff releases everything accrued to that point", + ); +} + +/// Scenario: withdraw against a stream that does not exist +#[test] +fn rejects_an_unknown_stream() { + let h = Harness::new(); + assert_eq!(h.client.try_withdraw(&404), Err(Ok(Error::StreamNotFound))); +} + +/// Two streams share one pooled token balance. Neither may reach the other's +/// deposit — the assertion that replaces a withdrawal pause. +#[test] +fn one_stream_cannot_drain_another() { + let h = Harness::new(); + let first = h.simple(); + let second = h.simple(); + + h.warp_days(30); + assert_eq!(h.client.withdraw(&first), TOTAL); + assert_eq!(h.client.withdraw(&second), TOTAL); + + h.assert_solvent(first); + h.assert_solvent(second); + assert_eq!(h.contract_balance(), 0); + assert_eq!(h.token.balance(&h.recipient), TOTAL * 2); +} + +/// `touch` is permissionless by design: anyone may keep a dormant stream alive. +#[test] +fn anyone_can_extend_a_streams_ttl() { + let h = Harness::new(); + let id = h.simple(); + h.client.touch(&id); + assert_eq!(h.client.try_touch(&404), Err(Ok(Error::StreamNotFound))); +} diff --git a/contracts/stelflow/src/types.rs b/contracts/stelflow/src/types.rs new file mode 100644 index 0000000..04f5275 --- /dev/null +++ b/contracts/stelflow/src/types.rs @@ -0,0 +1,125 @@ +//! Storage types. +//! +//! Layout follows `docs/architecture.md#storage-type-and-ttl`: one persistent +//! entry per stream, with milestones stored *inside* the stream struct rather +//! than as separate keyed entries, so a withdrawal reads one entry regardless of +//! how many milestones a stream has. + +use soroban_sdk::{contracttype, Address, Vec}; + +/// Milestone lifecycle. Monotonic: there is no transition back to `Unmet`. +/// +/// `Met` being terminal is the decision in `docs/research/milestone-revocation.md` +/// — re-locking a tranche after a withdrawal has settled would charge the +/// shortfall against the recipient's *other* tranches, because `withdrawn` is a +/// single stream-wide counter. +/// +/// `Forfeited` is not a revocation. It is only reachable through `cancel`, which +/// returns an unapproved tranche to the sender in full, and it exists so that a +/// forfeited tranche stops contributing to both `streamed_total` and `held` +/// rather than being silently special-cased at every read site. +#[contracttype] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum MilestoneState { + Unmet = 0, + Met = 1, + Forfeited = 2, +} + +/// Where a milestone's tranche goes if its deadline passes unapproved. +/// +/// Deliberately not hardcoded either way. A grant program naming an external +/// committee should not make the recipient's pay hostage to that committee's +/// diligence; a performance-gated vest should not pay out because nobody looked. +/// The right answer differs by use case, so it is a term agreed at creation and +/// visible to both parties before either signs — never a privilege anyone +/// exercises later. See `docs/milestone-deadlines.md`. +#[contracttype] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum OnExpiry { + /// The tranche unlocks as though it had been approved. + ToRecipient = 0, + /// The tranche is forfeited back to the sender, as an unmet milestone is on + /// cancellation. + ToSender = 1, +} + +#[contracttype] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Milestone { + /// Portion of the stream's total gated behind this milestone, in stroops. + pub amount: i128, + /// The only address that can mark this milestone met. May be a contract — + /// that is how a Trustless Work escrow acts as approver. + pub approver: Address, + pub state: MilestoneState, + /// Absolute ledger timestamp after which this milestone resolves without an + /// approver. Zero means no deadline: wait indefinitely. + /// + /// Constrained to `>= stream.end` at creation. A deadline before `end` would + /// resolve a tranche that was still accruing, which makes `streamed_total` + /// non-monotonic and races a legitimate approver against the clock. + pub deadline: u64, + pub on_expiry: OnExpiry, +} + +#[contracttype] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Stream { + pub id: u64, + pub sender: Address, + pub recipient: Address, + /// SEP-41 token contract. Any classic Stellar asset works via its SAC. + pub token: Address, + /// The **measured** deposit: the contract's own balance delta across the + /// creation transfer, not the amount the sender asked for. Decided in #32 — + /// this is what makes the stream's accounting true by construction for a + /// fee-on-transfer token. See `docs/specs/behaviour.md`. + pub total: i128, + /// Ungated portion: `total` minus the sum of all milestone amounts. + pub base_amount: i128, + pub start: u64, + pub end: u64, + /// Absolute timestamp before which `claimable` evaluates to zero. Equal to + /// `start` when the stream has no cliff. Accrual still runs during a cliff; + /// only claimability is withheld. + pub cliff: u64, + /// Whether the sender may cancel *alone*. When false, `cancel` requires the + /// recipient's authorization alongside the sender's — it does not mean the + /// stream can never be cancelled. See `docs/research/upgradeability-and-pause.md`. + pub cancelable: bool, + /// Cumulative, stream-wide. Never decreases. + pub withdrawn: i128, + pub milestones: Vec, + /// Ledger timestamp at which accrual froze, or `None` while the stream is + /// live. Accrual is evaluated against `min(now, canceled_at)`. + pub canceled_at: Option, +} + +#[contracttype] +#[derive(Clone)] +pub enum DataKey { + /// Per-stream state. Persistent storage: each stream's TTL is independent, + /// so one stream archiving blocks only that stream. + Stream(u64), +} + +/// Instance-storage keys. Instance storage shares one TTL across the whole +/// contract, so losing it would block *every* stream at once — it is extended +/// unconditionally on every call that touches it. +#[contracttype] +#[derive(Clone)] +pub enum ConfigKey { + /// Monotonic stream-id counter. Settles architecture.md open question 1 in + /// favour of a counter over a parameter hash: readable ids matter for a UI, + /// and the write-contention cost is one instance entry that every creation + /// already touches. + NextId, + /// The one global role. `None` once renounced, permanently — there is no + /// upgrade path that could restore it. + Pauser, + /// Ledger timestamp at which an active pause lifts by itself. Zero or past + /// means not paused. A pause that could outlive its key would be permanent + /// in a non-upgradeable contract, hence expiry rather than a bare flag. + PausedUntil, +} diff --git a/CODE_OF_CONDUCT.md b/docs/CODE_OF_CONDUCT.md similarity index 100% rename from CODE_OF_CONDUCT.md rename to docs/CODE_OF_CONDUCT.md diff --git a/CONTRIBUTING.md b/docs/CONTRIBUTING.md similarity index 88% rename from CONTRIBUTING.md rename to docs/CONTRIBUTING.md index 9195d3a..7d9af50 100644 --- a/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -2,11 +2,11 @@ Thanks for looking. This is an early project — the contracts aren't written yet — which changes what's useful. A well-argued issue about the storage layout is worth more right now than a PR fixing a typo. Both are welcome, but calibrate accordingly. -Read [docs/architecture.md](docs/architecture.md) before contributing code. It explains why the design looks the way it does, and most "why don't you just..." questions are answered there. +Read [docs/architecture.md](architecture.md) before contributing code. It explains why the design looks the way it does, and most "why don't you just..." questions are answered there. ## Where to start -**Reviewing the design.** [docs/architecture.md](docs/architecture.md#open-questions) ends with five open questions. If you've built on Soroban and have an opinion on any of them, open an issue. Concrete disagreement is the most valuable thing you can send at this stage. +**Reviewing the design.** [docs/architecture.md](architecture.md#open-questions) ends with five open questions. If you've built on Soroban and have an opinion on any of them, open an issue. Concrete disagreement is the most valuable thing you can send at this stage. **Picking up an issue.** Issues are labeled by difficulty and area: @@ -35,7 +35,7 @@ If nothing fits, open an issue describing what you want to do before building it Nothing in this repo builds yet — Phase 1 is where contract crates arrive, see [ROADMAP.md](ROADMAP.md). What you need in the meantime, verified end-to-end by actually running it rather than transcribed from documentation, lives in -[docs/dev-setup.md](docs/dev-setup.md): Rust, `wasm32v1-none`, `stellar-cli`, Node/pnpm, a funded +[docs/dev-setup.md](dev-setup.md): Rust, `wasm32v1-none`, `stellar-cli`, Node/pnpm, a funded testnet identity, and the commands to check current network limits. Start there. @@ -84,7 +84,7 @@ The PR template asks for these. It isn't ceremony — reviewers use it to decide Two things get a hard "no" regardless of how good the code is: 1. **It can lose or strand funds.** Rounding that doesn't conserve value, a path where an earned balance becomes unwithdrawable, an unbounded loop or collection that can push a withdrawal past the transaction resource limit. If your change touches accrual math or storage layout, expect close review and expect to be asked for property tests. -2. **It gives someone power they shouldn't have.** An admin who can pause withdrawals, an approver who can redirect funds, an upgrade function of any kind. These aren't hypotheticals to be weighed case by case — the contract is [non-upgradeable and the pause reaches only `create_stream`](docs/research/upgradeability-and-pause.md), decided deliberately, so a PR reintroducing either is reversing a settled decision and should say so and argue for it rather than slip it in. Read [docs/architecture.md](docs/architecture.md#authorization). +2. **It gives someone power they shouldn't have.** An admin who can pause withdrawals, an approver who can redirect funds, an upgrade function of any kind. These aren't hypotheticals to be weighed case by case — the contract is [non-upgradeable and the pause reaches only `create_stream`](upgradeability-and-pause.md), decided deliberately, so a PR reintroducing either is reversing a settled decision and should say so and argue for it rather than slip it in. Read [docs/architecture.md](architecture.md#authorization). Beyond that, review is about clarity. Contract code is read far more often than written, and it's read by auditors who are trying to break it. Prefer the obvious implementation over the clever one. If a function needs a comment to explain *what* it does, it probably needs a different shape; comments explaining *why* are always welcome. diff --git a/CONTRIBUTORS.md b/docs/CONTRIBUTORS.md similarity index 74% rename from CONTRIBUTORS.md rename to docs/CONTRIBUTORS.md index 29ae40f..1531fd6 100644 --- a/CONTRIBUTORS.md +++ b/docs/CONTRIBUTORS.md @@ -23,9 +23,9 @@ in your PR — see "How you get added" below. Alphabetical by handle. Format: | Handle | Contribution | Ref | |---|---|---| -| [@d-plug](https://github.com/d-plug) | The worked Alice-and-Bob example in [concepts.md](docs/concepts.md) — StelFlow's first merged PR. Also caught that the doc's account of end-of-stream exactness didn't match architecture.md. | [#16](https://github.com/StelFlow-labs/StelFlow/pull/16) | -| [@dannyy2000](https://github.com/dannyy2000) | The TTL and state-archival research in [research/ttl-strategy.md](docs/research/ttl-strategy.md), including the finding that no single extension can cover a multi-year stream, and the Protocol 23 correction to the SDK's restore flow. The indexer design in [research/indexer-design.md](docs/research/indexer-design.md) — polling as a constraint rather than a preference, TOID as the dedup and ordering key, and the two-layer schema that makes wipe-and-replay deterministic. | [#21](https://github.com/StelFlow-labs/StelFlow/pull/21), [#22](https://github.com/StelFlow-labs/StelFlow/pull/22) | -| [@Godbrand0](https://github.com/Godbrand0) | The behaviour specs in [specs/behaviour.md](docs/specs/behaviour.md) — 31 Given/When/Then scenarios and five design questions the docs turned out not to answer. The verified [dev-setup.md](docs/dev-setup.md), written by running every command and naming the two steps that weren't run rather than faking them. The docs CI workflow, including the two-job split that keeps external link rot from gating PRs. | [#26](https://github.com/StelFlow-labs/StelFlow/pull/26), [#27](https://github.com/StelFlow-labs/StelFlow/pull/27), [#28](https://github.com/StelFlow-labs/StelFlow/pull/28) | +| [@d-plug](https://github.com/d-plug) | The worked Alice-and-Bob example in [concepts.md](concepts.md) — StelFlow's first merged PR. Also caught that the doc's account of end-of-stream exactness didn't match architecture.md. | [#16](https://github.com/StelFlow-labs/StelFlow/pull/16) | +| [@dannyy2000](https://github.com/dannyy2000) | The TTL and state-archival research in [research/ttl-strategy.md](ttl-strategy.md), including the finding that no single extension can cover a multi-year stream, and the Protocol 23 correction to the SDK's restore flow. The indexer design in [research/indexer-design.md](indexer-design.md) — polling as a constraint rather than a preference, TOID as the dedup and ordering key, and the two-layer schema that makes wipe-and-replay deterministic. | [#21](https://github.com/StelFlow-labs/StelFlow/pull/21), [#22](https://github.com/StelFlow-labs/StelFlow/pull/22) | +| [@Godbrand0](https://github.com/Godbrand0) | The behaviour specs in [specs/behaviour.md](behaviour.md) — 31 Given/When/Then scenarios and five design questions the docs turned out not to answer. The verified [dev-setup.md](dev-setup.md), written by running every command and naming the two steps that weren't run rather than faking them. The docs CI workflow, including the two-job split that keeps external link rot from gating PRs. | [#26](https://github.com/StelFlow-labs/StelFlow/pull/26), [#27](https://github.com/StelFlow-labs/StelFlow/pull/27), [#28](https://github.com/StelFlow-labs/StelFlow/pull/28) | ## Design review and prior art diff --git a/ROADMAP.md b/docs/ROADMAP.md similarity index 88% rename from ROADMAP.md rename to docs/ROADMAP.md index 8e501b8..d4db606 100644 --- a/ROADMAP.md +++ b/docs/ROADMAP.md @@ -28,7 +28,7 @@ The current phase. Get the design written down well enough that someone can disa - [x] README, concepts, architecture - [x] Contribution setup — templates, code of conduct, security policy -- [ ] Resolve the open questions in [docs/architecture.md](docs/architecture.md#open-questions): ~~milestone revocation~~ (done, #17), ~~upgradeability~~ and ~~pausing~~ (done, #33), stream IDs and multiple recipients still open +- [ ] Resolve the open questions in [docs/architecture.md](architecture.md#open-questions): ~~milestone revocation~~ (done, #17), ~~upgradeability~~ and ~~pausing~~ (done, #33), stream IDs and multiple recipients still open - [ ] Write the contract interface as a Rust trait with no implementation, and review it as a PR before anything is built behind it - [ ] Decide the workspace layout (contract crates, SDK package, dashboard app, indexer service) @@ -46,7 +46,7 @@ The minimum thing that is genuinely a payment stream: linear accrual against led - [ ] Cliff support - [ ] TTL extension on every state-changing call, plus a public `bump_stream` - [ ] Events for every state change, designed for the indexer before the indexer exists -- [ ] Unit tests against a mocked ledger clock, including: withdrawing twice in one ledger, withdrawing at exactly `start` and exactly `end`, a stream of duration 1, and a stream whose total doesn't divide evenly by its duration — [docs/specs/behaviour.md](docs/specs/behaviour.md) has these written out as Given/When/Then scenarios already, use it as the checklist +- [ ] Unit tests against a mocked ledger clock, including: withdrawing twice in one ledger, withdrawing at exactly `start` and exactly `end`, a stream of duration 1, and a stream whose total doesn't divide evenly by its duration — [docs/specs/behaviour.md](behaviour.md) has these written out as Given/When/Then scenarios already, use it as the checklist - [ ] Measure real footprint sizes and set `MAX_MILESTONES_PER_STREAM` and `MAX_BATCH_SIZE` from measurement **Done when:** a stream can be created and fully withdrawn on testnet, and the sum of withdrawals equals the deposit exactly, with no dust stranded. @@ -63,7 +63,7 @@ What makes this StelFlow rather than a Sablier port. - [ ] Milestone revocation, or an explicit documented decision not to support it - [ ] Tests for the ugly cases: cancel with a pending approval in flight, approval after the end time, approval of a milestone on a canceled stream, cancel with zero elapsed time -**Done when:** the grant scenario in [docs/concepts.md](docs/concepts.md#milestone-gates) runs end-to-end on testnet, including a cancellation partway through. +**Done when:** the grant scenario in [docs/concepts.md](concepts.md#milestone-gates) runs end-to-end on testnet, including a cancellation partway through. ## Phase 3 — Indexer ⚪ @@ -83,7 +83,7 @@ Contract events into queryable history. - [ ] Typed bindings generated from the contract spec, regenerated in CI so drift breaks the build - [ ] Local accrual preview — recompute claimable client-side from stream state for live UI, without an RPC call per tick - [ ] Transaction builders with correct auth entries for each role -- [ ] **Archived-entry handling** — detect an archived stream and produce a restore-then-withdraw flow. Not optional; see [docs/architecture.md](docs/architecture.md#storage-type-and-ttl) +- [ ] **Archived-entry handling** — detect an archived stream and produce a restore-then-withdraw flow. Not optional; see [docs/architecture.md](architecture.md#storage-type-and-ttl) - [ ] Batch chunking against live network limits rather than hardcoded constants - [ ] Indexer client - [ ] Tests that assert the SDK's local accrual math matches the contract's exactly across fuzzed inputs @@ -104,7 +104,7 @@ Contract events into queryable history. ## Phase 6 — Trustless Work integration ⚪ -- [ ] Confirm the integration surface — cross-contract approver call vs. off-chain agent (see the TODO in [docs/architecture.md](docs/architecture.md#trustless-work-integration)) +- [ ] Confirm the integration surface — cross-contract approver call vs. off-chain agent (see the TODO in [docs/architecture.md](architecture.md#trustless-work-integration)) - [ ] Escrow-as-approver: a Trustless Work escrow address acting as the approver on gated milestones - [ ] Reference implementation of the grant-disbursement flow end to end - [ ] Joint documentation, reviewed by Trustless Work rather than written at them @@ -128,7 +128,7 @@ Contract events into queryable history. - [ ] Deployment with published, verifiable Wasm hashes - [ ] Reproducible builds so anyone can confirm the deployed Wasm matches this source -- [x] Documented upgrade or migration policy, decided in Phase 0 — [non-upgradeable, with migration by cancel-and-recreate](docs/research/upgradeability-and-pause.md). What remains for this phase is *executing* it: publishing the policy where users see it before they sign, not deciding it. +- [x] Documented upgrade or migration policy, decided in Phase 0 — [non-upgradeable, with migration by cancel-and-recreate](upgradeability-and-pause.md). What remains for this phase is *executing* it: publishing the policy where users see it before they sign, not deciding it. - [ ] Monitoring and incident runbook **Done when:** there is a mainnet address in the README and it's the real one. @@ -143,4 +143,4 @@ Stated so nobody builds them by accident: - **Protocol fees.** Not in v1. Adding a fee later is a governance decision that needs a real discussion, not a constant someone slips into a PR. - **Cross-chain streaming.** Out of scope. - **Dispute resolution.** That's Trustless Work's job. Integrate, don't reimplement. -- **Multi-recipient streams.** Deferred pending the entry-cost question in [docs/architecture.md](docs/architecture.md#open-questions). Argue for it in an issue if you have the use case. +- **Multi-recipient streams.** Deferred pending the entry-cost question in [docs/architecture.md](architecture.md#open-questions). Argue for it in an issue if you have the use case. diff --git a/SECURITY.md b/docs/SECURITY.md similarity index 88% rename from SECURITY.md rename to docs/SECURITY.md index da5d36c..866745a 100644 --- a/SECURITY.md +++ b/docs/SECURITY.md @@ -55,7 +55,7 @@ You will be credited in the advisory and in [CONTRIBUTORS.md](CONTRIBUTORS.md) u **Out of scope:** - Stellar Core, Soroban host functions, Stellar RPC — report those to the [Stellar Development Foundation](https://github.com/stellar/stellar-core/security/policy) -- Third-party assets and their issuers, including issuer clawback. If an asset has clawback enabled, its issuer can remove funds from a live stream. That's an asset property, disclosed in [docs/concepts.md](docs/concepts.md#cancellation-and-clawback), not a StelFlow bug — the threat model covers it as [T7](docs/research/threat-model.md#t7--issuer-clawback), accepted rather than fixable +- Third-party assets and their issuers, including issuer clawback. If an asset has clawback enabled, its issuer can remove funds from a live stream. That's an asset property, disclosed in [docs/concepts.md](concepts.md#cancellation-and-clawback), not a StelFlow bug — the threat model covers it as [T7](threat-model.md#t7--issuer-clawback), accepted rather than fixable - Trustless Work's contracts — report to [Trustless Work](https://github.com/Trustless-Work) - Wallets, and phishing that doesn't involve a flaw in our code - Findings from an automated scanner with no demonstrated impact @@ -63,7 +63,7 @@ You will be credited in the advisory and in [CONTRIBUTORS.md](CONTRIBUTORS.md) u ## What we care most about The reasoning behind this list, threat by threat, is in -[docs/research/threat-model.md](docs/research/threat-model.md) — including which risks are accepted +[docs/research/threat-model.md](threat-model.md) — including which risks are accepted rather than mitigated, and the design decisions that are still open. Two of its highest-ranked threats were closed by *removing* the capability rather than guarding it, which is why the list below now includes attacks on those limits themselves. Start there if you're looking for somewhere to dig. @@ -75,7 +75,7 @@ If you're deciding where to look, these are the classes that would hurt most: 3. **Authorization bypass.** Withdrawing as a non-recipient, approving as a non-approver, or cancelling a non-cancelable stream without **both** the sender's and the recipient's authorization. 4. **Accrual manipulation.** Anything that makes the contract compute a claimable balance that doesn't match elapsed ledger time. 5. **Archival traps.** A stream that archives into a state it can't be correctly restored from. -6. **Escaping the limits on privilege.** The contract is [non-upgradeable and has no admin over funds](docs/research/upgradeability-and-pause.md); the sole global role can only stop `create_stream`, auto-expires, and can be renounced. So: any path that creates a stream while paused, a pause that fails to expire, a way to restore a renounced pauser, or anything that lets a privileged address reach a stream it isn't a party to. +6. **Escaping the limits on privilege.** The contract is [non-upgradeable and has no admin over funds](upgradeability-and-pause.md); the sole global role can only stop `create_stream`, auto-expires, and can be renounced. So: any path that creates a stream while paused, a pause that fails to expire, a way to restore a renounced pauser, or anything that lets a privileged address reach a stream it isn't a party to. ## Bug bounty diff --git a/docs/architecture.md b/docs/architecture.md index 64fa841..46f45b2 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -32,7 +32,7 @@ The [indexer](glossary.md#indexer) subscribes to StelFlow's contract events via It is a cache, not an authority. If the indexer and the chain disagree, the chain is right. The dashboard must be able to show a stream's current claimable balance without the indexer being up — that number comes from simulating a contract read, not from the database. -Runtime and datastore: a Node/TypeScript poller against `getEvents` (RPC exposes no push/subscription channel, so polling is the only option, not a choice), writing an append-only, `event_id`-deduped event log to PostgreSQL, with all other tables derived from it by a pure fold so a wipe-and-replay reaches identical state. The RPC event-retention backstop is Galexie-backed self-hosted backfill, with Hubble as a fast one-off cold-start path. Full reasoning, the cursor/checkpoint mechanics, and the schema are in [docs/research/indexer-design.md](research/indexer-design.md). +Runtime and datastore: a Node/TypeScript poller against `getEvents` (RPC exposes no push/subscription channel, so polling is the only option, not a choice), writing an append-only, `event_id`-deduped event log to PostgreSQL, with all other tables derived from it by a pure fold so a wipe-and-replay reaches identical state. The RPC event-retention backstop is Galexie-backed self-hosted backfill, with Hubble as a fast one-off cold-start path. Full reasoning, the cursor/checkpoint mechanics, and the schema are in [docs/research/indexer-design.md](indexer-design.md). @@ -147,7 +147,7 @@ The real design pressure is that persistent entries still have a TTL and streams - The SDK must detect an archived entry and produce a restore-then-withdraw flow, not a confusing "stream not found." This is the single most likely source of bad UX in the project and it needs to be handled in the SDK, not left to the app developer. - A `bump_stream` entry point lets anyone extend any stream's TTL, so a sender or a watcher service can keep a dormant stream hot without the recipient acting — but StelFlow itself doesn't operate one; see the research doc for why that's a deliberate scope line, not an oversight. -Mechanism resolved in [docs/research/ttl-strategy.md](research/ttl-strategy.md), including live-checked network numbers and concrete SDK guidance for the restore-then-withdraw flow. +Mechanism resolved in [docs/research/ttl-strategy.md](ttl-strategy.md), including live-checked network numbers and concrete SDK guidance for the restore-then-withdraw flow. @@ -175,13 +175,13 @@ What it costs, and what the contract must not assume: - **SEP-41 is still a Draft SEP.** It's stable in practice and the SAC implements it, but the contract should depend only on the functions it actually calls (`transfer`, `transfer_from`, `balance`, `decimals`) rather than the full surface. - **[Issuer clawback](glossary.md#clawback-issuer-sense) is out of scope and cannot be defended against.** The power is the [SAC](glossary.md#stellar-asset-contract-sac)'s admin `clawback` rather than anything SEP-41 defines, so it rides on the asset, not on the interface: if the issuer enabled clawback, they can remove funds the contract is holding for a live stream. The contract should not pretend its stored `total` is a guarantee — `balance` is the truth. The dashboard should warn when a stream's asset has clawback enabled. This is a disclosure problem, not a code problem. - **Decimals are the asset's, not ours.** All internal math is in the asset's smallest unit. Human-readable formatting happens in the SDK, never in the contract. -- **Non-standard transfer behavior breaks accrual accounting.** A fee-on-transfer or rebasing token would leave the contract holding less than the stream promises. **Decided: `create_stream` measures rather than trusts.** It reads the contract's own balance either side of the `transfer_from` and stores the observed delta as `total`, so the stored figure is true by construction for any asset and value conservation holds without depending on the token behaving. The cost is one extra balance read at creation. This fixes fee-on-transfer completely. It does not fix *rebasing*, because no creation-time measurement can bind a balance that moves afterwards — rebasing assets are unsupported, and the rule that `balance` is the truth rather than the stored `total` is what limits the damage. See [threat-model T4](research/threat-model.md#t4--non-standard-tokens-produce-under-funded-streams). +- **Non-standard transfer behavior breaks accrual accounting.** A fee-on-transfer or rebasing token would leave the contract holding less than the stream promises. **Decided: `create_stream` measures rather than trusts.** It reads the contract's own balance either side of the `transfer_from` and stores the observed delta as `total`, so the stored figure is true by construction for any asset and value conservation holds without depending on the token behaving. The cost is one extra balance read at creation. This fixes fee-on-transfer completely. It does not fix *rebasing*, because no creation-time measurement can bind a balance that moves afterwards — rebasing assets are unsupported, and the rule that `balance` is the truth rather than the stored `total` is what limits the damage. See [threat-model T4](threat-model.md#t4--non-standard-tokens-produce-under-funded-streams). ### Authorization Every privileged entry point calls `require_auth` on the address that should be authorizing it — sender for `create_stream`, recipient for `withdraw`, approver for `approve_milestone`. Roles are stored per stream. This also means an approver can be a contract address, which is how a Trustless Work escrow can act as the approver for a milestone. -`cancel` is the one entry point whose authorization depends on the stream: with `cancelable = true` the sender alone authorizes; with `cancelable = false` **both the sender and the recipient must authorize**, which is the only way funds move on a stream the sender cannot stop unilaterally. Settlement is identical either way — [cancellation rules 1–4](concepts.md#cancellation-and-clawback) are unchanged. This exists so that a non-cancelable stream is not a permanent dead end when the contract needs migrating or an approver never returns; see [research/upgradeability-and-pause.md](research/upgradeability-and-pause.md#the-fix-cancel-by-unanimous-consent). +`cancel` is the one entry point whose authorization depends on the stream: with `cancelable = true` the sender alone authorizes; with `cancelable = false` **both the sender and the recipient must authorize**, which is the only way funds move on a stream the sender cannot stop unilaterally. Settlement is identical either way — [cancellation rules 1–4](concepts.md#cancellation-and-clawback) are unchanged. This exists so that a non-cancelable stream is not a permanent dead end when the contract needs migrating or an approver never returns; see [research/upgradeability-and-pause.md](upgradeability-and-pause.md#the-fix-cancel-by-unanimous-consent). **On global roles.** There is no admin with any power over funds in an existing stream — no upgrade key (the contract is non-upgradeable, per [open question 4](#open-questions)), no ability to move, redirect, freeze, or reassign a stream. One global role exists: the **pauser**, whose single power is to stop `create_stream`, and which auto-expires and can be renounced. It cannot touch a stream that already exists. Every payout additionally asserts `payout <= total - withdrawn` for that stream, so no stream's lifetime extraction can reach a neighbour's deposit out of the contract's pooled balance. @@ -198,15 +198,15 @@ The intended split: Trustless Work decides *whether* a condition is met; StelFlo Answers wanted. These are good places to argue with the design — open an issue. 1. **Stream IDs.** Monotonic `u64` counter, or a hash of the creation parameters? A counter needs a writable global entry on every creation, which is a write-contention point. A hash is contention-free but unfriendly to read. -2. ~~**Milestone revocation.**~~ **Settled: no.** Milestone state is monotonic and `Met` is terminal. Re-locking a tranche after a withdrawal has settled would charge the shortfall against the recipient's *other* tranches, because `withdrawn` is one stream-wide counter — worked through in [research/milestone-revocation.md](research/milestone-revocation.md). Storage consequence recorded under [Storage type and TTL](#storage-type-and-ttl). +2. ~~**Milestone revocation.**~~ **Settled: no.** Milestone state is monotonic and `Met` is terminal. Re-locking a tranche after a withdrawal has settled would charge the shortfall against the recipient's *other* tranches, because `withdrawn` is one stream-wide counter — worked through in [research/milestone-revocation.md](milestone-revocation.md). Storage consequence recorded under [Storage type and TTL](#storage-type-and-ttl). 3. **Multiple recipients per stream.** Splitting a stream N ways is a real payroll need, but it multiplies the per-transaction entry cost. Probably out of scope for v1 — argue otherwise if you disagree. -4. ~~**Upgradeability.**~~ **Settled: non-upgradeable.** The contract has no upgrade function, so there is no upgrade key to hold, compromise, or be coerced into using. The timelocked-upgrade alternative was rejected on arithmetic rather than principle: a timelock only protects what a user can withdraw during it, and a stream's whole purpose is that most of the money isn't withdrawable yet — a 30-day timelock rescues 2.1% of a four-year vest if the attacker announces early. Worked through in [research/upgradeability-and-pause.md](research/upgradeability-and-pause.md). +4. ~~**Upgradeability.**~~ **Settled: non-upgradeable.** The contract has no upgrade function, so there is no upgrade key to hold, compromise, or be coerced into using. The timelocked-upgrade alternative was rejected on arithmetic rather than principle: a timelock only protects what a user can withdraw during it, and a stream's whole purpose is that most of the money isn't withdrawable yet — a 30-day timelock rescues 2.1% of a four-year vest if the attacker announces early. Worked through in [research/upgradeability-and-pause.md](upgradeability-and-pause.md). 5. ~~**Pausing.**~~ **Settled: `create_stream` only.** `withdraw`, `cancel`, `approve_milestone`, and TTL extension are never pausable, so a pause can never reach a stream that already exists. The pause auto-expires after 30 days and can be renounced permanently — both because a non-upgradeable contract can never correct a stuck one. The strongest case for pausing withdrawals (the contract's token balance is pooled, so an accrual bug could let one stream drain another's deposit) is answered by a per-stream solvency assertion instead — same file. ## Next - [glossary.md](glossary.md) — definitions for the vocabulary on this page. -- [specs/behaviour.md](specs/behaviour.md) — Given/When/Then scenarios for the four entry points, plus the pause's scope and the per-stream solvency assertion. -- [research/upgradeability-and-pause.md](research/upgradeability-and-pause.md) — why open questions 4 and 5 were settled by removing capabilities rather than guarding them. -- [../ROADMAP.md](../ROADMAP.md) — build order. -- [../CONTRIBUTING.md](../CONTRIBUTING.md) — how to pick something up. +- [specs/behaviour.md](behaviour.md) — Given/When/Then scenarios for the four entry points, plus the pause's scope and the per-stream solvency assertion. +- [research/upgradeability-and-pause.md](upgradeability-and-pause.md) — why open questions 4 and 5 were settled by removing capabilities rather than guarding them. +- [../ROADMAP.md](ROADMAP.md) — build order. +- [../CONTRIBUTING.md](CONTRIBUTING.md) — how to pick something up. diff --git a/docs/specs/behaviour.md b/docs/behaviour.md similarity index 97% rename from docs/specs/behaviour.md rename to docs/behaviour.md index 3f3a64d..977bdd9 100644 --- a/docs/specs/behaviour.md +++ b/docs/behaviour.md @@ -3,7 +3,7 @@ Given/When/Then scenarios for the four stream entry points — plus the pause, which is administrative rather than a stream operation and is specified here mainly to pin down what it cannot reach — written against the semantics in -[docs/concepts.md](../concepts.md) and [docs/architecture.md](../architecture.md). None of this is +[docs/concepts.md](concepts.md) and [docs/architecture.md](architecture.md). None of this is implemented — this is the checklist the eventual `#[test]` functions turn into, and a place to argue with the design before code makes arguing expensive. @@ -14,7 +14,7 @@ Conventions used throughout: - `elapsed = clamp(now, start, end) - start`, `duration = end - start`. - `streamed(portion) = portion.amount * elapsed / duration`, rounded down, except at `now >= end` where `streamed(portion) = portion.amount` exactly (the end-of-stream case is special-cased to the - remaining balance rather than the formula, per [architecture.md#arithmetic](../architecture.md#arithmetic)). + remaining balance rather than the formula, per [architecture.md#arithmetic](architecture.md#arithmetic)). - `held = sum of streamed(m) for every unapproved milestone m`. - `claimable = streamed(base) + sum(streamed(m) for approved m) - withdrawn - held`, which reduces to `claimable = streamed_total - withdrawn - held`. @@ -26,7 +26,7 @@ remaining_in_contract`. Every scenario below that changes state asserts this exp closure check and would still balance if one stream were paid out of another's money. The two are not the same assertion and Phase 1 should test both. - Every entry point calls `require_auth` on a specific address (see - [architecture.md#authorization](../architecture.md#authorization)). Every scenario states who is + [architecture.md#authorization](architecture.md#authorization)). Every scenario states who is calling and asserts unauthorized callers are rejected without side effects. Streams in these scenarios are kept small and, where possible, evenly divisible, so the arithmetic can @@ -300,7 +300,7 @@ And every ordinary withdraw scenario above applies unchanged from that point The contract has no archived-entry branch to write, and could not have one — there is nothing for it to catch. This is an SDK obligation, not contract behaviour. See -[ttl-strategy.md](../research/ttl-strategy.md) for the Protocol 23 mechanics and the concrete client +[ttl-strategy.md](ttl-strategy.md) for the Protocol 23 mechanics and the concrete client flow. --- @@ -426,7 +426,7 @@ And the same cancel event is emitted as for a cancelable stream — the indexer This is the whole of the two-signature rule: `cancelable=false` means the sender cannot cancel *unilaterally*, not that nobody can. See -[research/upgradeability-and-pause.md](../research/upgradeability-and-pause.md#the-fix-cancel-by-unanimous-consent). +[research/upgradeability-and-pause.md](upgradeability-and-pause.md#the-fix-cancel-by-unanimous-consent). ### Scenario: rejected — a third party cannot supply the second signature @@ -487,7 +487,7 @@ And deposit (30,000,000,000) == withdrawn (18,000,000,000) + refunded (12,000,00 This second scenario is why `cancel()` after `end` is permitted rather than rejected: it is the only in-protocol way to resolve a milestone that was never approved. Rejecting it would strand the tranche -permanently — see [threat-model T3](../research/threat-model.md#t3--an-approver-who-never-comes-back), +permanently — see [threat-model T3](threat-model.md#t3--an-approver-who-never-comes-back), which this narrows for cancelable streams and leaves untouched for non-cancelable ones. ### Scenario: cancel with an unmet milestone in flight — the gated tranche returns to the sender, not just its unaccrued fraction @@ -520,7 +520,7 @@ And deposit (30,000,000,000) == withdrawn (18,000,000,000) + refunded (10,000,00 The pause covers exactly one entry point. These scenarios exist mostly to pin down what it *cannot* do, since that is the load-bearing half — see -[research/upgradeability-and-pause.md](../research/upgradeability-and-pause.md#pausing-scoped-by-entry-point). +[research/upgradeability-and-pause.md](upgradeability-and-pause.md#pausing-scoped-by-entry-point). ### Scenario: pausing blocks create_stream and nothing else @@ -608,7 +608,7 @@ useful than the conclusion alone. to the sender — a real transfer, not a no-op. Permitting the call is what makes a never-approved milestone recoverable at all; rejecting it would strand the tranche permanently. 3. **Milestone revocation** — **no revocation.** Milestone state is monotonic and `Met` is terminal, - decided in [research/milestone-revocation.md](../research/milestone-revocation.md). Re-locking a + decided in [research/milestone-revocation.md](milestone-revocation.md). Re-locking a tranche after a withdrawal has settled would charge the shortfall against the recipient's other tranches, because `withdrawn` is one stream-wide counter. 4. **`create_stream` and non-standard transfer behaviour** — **store the measured balance delta.** The diff --git a/docs/concepts.md b/docs/concepts.md index 100556e..58bdb95 100644 --- a/docs/concepts.md +++ b/docs/concepts.md @@ -77,7 +77,7 @@ The approver is a role, not necessarily the sender — it can be a grant committ **Approval is final. A met milestone cannot be un-met.** The approver's only power is to release, and once a tranche is released it stays released — there is no revocation, and no way for anyone to reduce what the recipient has already become entitled to. A sender who wants a way out needs a [cancelable](glossary.md#cancelable) stream, which ends the whole stream rather than re-locking one tranche. -That cuts both ways, and the cost is worth knowing before you name an approver: if a milestone is approved in error, StelFlow offers no remedy. Where a real dispute process is needed, name a Trustless Work escrow as the approver and let it withhold approval until its own process concludes. Reasoning and the alternatives considered: [research/milestone-revocation.md](research/milestone-revocation.md). +That cuts both ways, and the cost is worth knowing before you name an approver: if a milestone is approved in error, StelFlow offers no remedy. Where a real dispute process is needed, name a Trustless Work escrow as the approver and let it withhold approval until its own process concludes. Reasoning and the alternatives considered: [research/milestone-revocation.md](milestone-revocation.md). ### What a gate does not do @@ -201,7 +201,7 @@ Day 10, 18, and 30 were chosen because each divides the portions evenly. At an a A stream can be created [cancelable](glossary.md#cancelable) or not. Non-cancelable is the right default for vesting: the recipient needs a guarantee. Cancelable is the right default for grants: the funder needs an exit if the work stops. -**Precisely, `cancelable = false` means the sender cannot cancel *unilaterally* — not that the stream can never be cancelled.** The sender and the recipient acting together can always cancel, and the settlement rules below apply unchanged when they do. This takes nothing from the recipient, whose guarantee was always about the sender acting alone, and it means a non-cancelable stream is not a dead end when both parties want out — which matters because the contract is [non-upgradeable](research/upgradeability-and-pause.md), so an unbreakable stream would be unbreakable for the life of the contract. Neither party can do it alone, in either direction. +**Precisely, `cancelable = false` means the sender cannot cancel *unilaterally* — not that the stream can never be cancelled.** The sender and the recipient acting together can always cancel, and the settlement rules below apply unchanged when they do. This takes nothing from the recipient, whose guarantee was always about the sender acting alone, and it means a non-cancelable stream is not a dead end when both parties want out — which matters because the contract is [non-upgradeable](upgradeability-and-pause.md), so an unbreakable stream would be unbreakable for the life of the contract. Neither party can do it alone, in either direction. On cancel: @@ -232,5 +232,5 @@ The last row is the one StelFlow is built for. - [glossary.md](glossary.md) — every term on this page in one place, plus the Soroban vocabulary. - [architecture.md](architecture.md) — how this is actually built on Soroban, and which constraints bend the design. -- [specs/behaviour.md](specs/behaviour.md) — the semantics on this page turned into Given/When/Then scenarios, including the awkward cases. -- [../ROADMAP.md](../ROADMAP.md) — the order it gets built in. +- [specs/behaviour.md](behaviour.md) — the semantics on this page turned into Given/When/Then scenarios, including the awkward cases. +- [../ROADMAP.md](ROADMAP.md) — the order it gets built in. diff --git a/docs/dev-setup.md b/docs/dev-setup.md index ed5d6ca..1b1cfe2 100644 --- a/docs/dev-setup.md +++ b/docs/dev-setup.md @@ -2,13 +2,13 @@ A path from an empty toolchain to a verified build environment, with real output from actually running each command — not transcribed from another doc. Replaces the setup section that used to -live in [CONTRIBUTING.md](../CONTRIBUTING.md); that file now points here. +live in [CONTRIBUTING.md](CONTRIBUTING.md); that file now points here. **Verified on:** Linux (Pop!\_OS 22.04, kernel 6.17, x86_64) — see [What wasn't verified here](#what-wasnt-verified-here) for the two steps this pass didn't get through, and [Troubleshooting](#troubleshooting) for what's expected to differ on macOS/WSL. -There is no code in this repo yet — see [ROADMAP.md](../ROADMAP.md). Nothing here builds a +There is no code in this repo yet — see [ROADMAP.md](ROADMAP.md). Nothing here builds a contract. This doc ends at "the toolchain is verified," not "the project builds," because that second thing doesn't exist yet. @@ -19,7 +19,7 @@ rustup install stable rustup target add wasm32v1-none ``` -`wasm32v1-none` needs rustc 1.84 or newer ([CONTRIBUTING.md](../CONTRIBUTING.md) says so; this is +`wasm32v1-none` needs rustc 1.84 or newer ([CONTRIBUTING.md](CONTRIBUTING.md) says so; this is the check that confirms it). On this machine: ``` @@ -76,9 +76,9 @@ The old setup section also listed `stellar contract build`, `cargo test`, `cargo contract crates in this repo yet, so running them today would either error out or silently do nothing, and pasting their output would be exactly the invented build step this issue said not to fabricate. `cargo fmt`/`cargo clippy -D warnings` passing is still a real CI expectation — see -[CONTRIBUTING.md](../CONTRIBUTING.md)'s Pull requests section — it just has nothing to check yet. +[CONTRIBUTING.md](CONTRIBUTING.md)'s Pull requests section — it just has nothing to check yet. The build/test commands themselves arrive with Phase 1's contract crates; see -[ROADMAP.md](../ROADMAP.md). +[ROADMAP.md](ROADMAP.md). ## Stellar CLI @@ -140,7 +140,7 @@ it's on. A root `package.json` may or may not exist yet, depending on whether the docs-tooling PR (CI lint/format setup) has landed — the SDK/dashboard workspace itself lands with a later phase (see -[ROADMAP.md](../ROADMAP.md)). Either way, `corepack` reads `packageManager` from whichever +[ROADMAP.md](ROADMAP.md)). Either way, `corepack` reads `packageManager` from whichever `package.json` is present and fetches the pinned pnpm version automatically the first time you run a `pnpm` command in this repo — you won't need to `npm install -g pnpm` yourself. If neither exists yet, `corepack enable` is the whole Node/pnpm setup for now. @@ -196,7 +196,7 @@ finding this doc is for — correct this section in your PR rather than working ## Next -- [../CONTRIBUTING.md](../CONTRIBUTING.md) — how to pick up an issue once your toolchain checks out. +- [../CONTRIBUTING.md](CONTRIBUTING.md) — how to pick up an issue once your toolchain checks out. - [architecture.md](architecture.md) — why the toolchain looks the way it does (`wasm32v1-none`, `i128` arithmetic, the read-budget constants `stellar network settings` reports). -- [../ROADMAP.md](../ROADMAP.md) — Phase 1 is where contract crates actually arrive. +- [../ROADMAP.md](ROADMAP.md) — Phase 1 is where contract crates actually arrive. diff --git a/docs/faq.md b/docs/faq.md index d76bed1..8474c0d 100644 --- a/docs/faq.md +++ b/docs/faq.md @@ -2,7 +2,7 @@ Questions a developer or a treasurer actually asks, answered from what the design says today. -**Nothing here is built.** There are no contracts, no deployment, and no audit — see [SECURITY.md](../SECURITY.md#current-status). Every answer below describes intended behavior, and where the design hasn't decided something, the answer says so and links the open question rather than inventing a confident one. +**Nothing here is built.** There are no contracts, no deployment, and no audit — see [SECURITY.md](SECURITY.md#current-status). Every answer below describes intended behavior, and where the design hasn't decided something, the answer says so and links the open question rather than inventing a confident one. ## The basics @@ -16,7 +16,7 @@ Anything implementing the [SEP-41 token interface](architecture.md#sep-41-assets ### When can I use it? -There is no date, deliberately. [ROADMAP.md](../ROADMAP.md) sequences the work by dependency rather than by calendar, and it is currently on Phase 0 of 8 — design and docs. Usable-on-testnet is Phase 1; milestones and cancellation are Phase 2; mainnet is Phase 8, gated behind an external audit in Phase 7. The roadmap is explicit that mainnet is done "when there is a mainnet address in the README and it's the real one," and there isn't one. If you need a date for a funding or planning decision, treat the answer as "not soon enough to plan around." +There is no date, deliberately. [ROADMAP.md](ROADMAP.md) sequences the work by dependency rather than by calendar, and it is currently on Phase 0 of 8 — design and docs. Usable-on-testnet is Phase 1; milestones and cancellation are Phase 2; mainnet is Phase 8, gated behind an external audit in Phase 7. The roadmap is explicit that mainnet is done "when there is a mainnet address in the README and it's the real one," and there isn't one. If you need a date for a funding or planning decision, treat the answer as "not soon enough to plan around." ## Receiving a stream @@ -24,7 +24,7 @@ There is no date, deliberately. [ROADMAP.md](../ROADMAP.md) sequences the work b Nothing bad, and nothing is lost. Accrual is [computed rather than pushed](concepts.md#money-streaming), so not withdrawing costs you nothing and your balance keeps rising on its own until the end of the stream. The one real consequence is Soroban's [state archival](architecture.md#storage-type-and-ttl): a stream's entry has a TTL, and a stream nobody touches for long enough — a 4-year vesting stream with a 1-year cliff, say — will archive. -Archived is not deleted. Stream state lives in `persistent` storage precisely because those entries are archived rather than destroyed, and a `RestoreFootprintOp` brings the entry back for a fee, after which you withdraw normally. Every state-changing call extends the TTL, so a stream you use regularly keeps itself alive for free, and a public `bump_stream` entry point lets *anyone* — the sender, a watcher service — keep a dormant stream hot without you doing anything. Handling this cleanly is a [named, non-optional requirement on the SDK](../ROADMAP.md#phase-4--typescript-sdk-), so you should get a restore-then-withdraw flow rather than a confusing "stream not found." +Archived is not deleted. Stream state lives in `persistent` storage precisely because those entries are archived rather than destroyed, and a `RestoreFootprintOp` brings the entry back for a fee, after which you withdraw normally. Every state-changing call extends the TTL, so a stream you use regularly keeps itself alive for free, and a public `bump_stream` entry point lets *anyone* — the sender, a watcher service — keep a dormant stream hot without you doing anything. Handling this cleanly is a [named, non-optional requirement on the SDK](ROADMAP.md#phase-4--typescript-sdk-), so you should get a restore-then-withdraw flow rather than a confusing "stream not found." ### What does a withdrawal cost, and does withdrawing more often cost me more? @@ -42,27 +42,27 @@ No. On cancellation, accrual freezes at that ledger's timestamp, and your stream Your base portion is unaffected and keeps paying — that separation is the whole design intent, so [the recipient always has the base stream to live on](concepts.md#milestone-gates). The gated tranche keeps accruing but stays unclaimable, and since a gate [doesn't extend the stream](concepts.md#what-a-gate-does-not-do), it simply sits at its full amount once the end time passes, waiting on an approval that isn't coming. -Beyond that, **the design still has no automatic answer.** There is no timeout and no fallback approver — deciding whether to add [milestone deadlines](research/threat-model.md#t3--an-approver-who-never-comes-back) is open, and it has become urgent, because a non-upgradeable contract cannot have one retrofitted onto streams already created without it. +Beyond that, **the design still has no automatic answer.** There is no timeout and no fallback approver — deciding whether to add [milestone deadlines](threat-model.md#t3--an-approver-who-never-comes-back) is open, and it has become urgent, because a non-upgradeable contract cannot have one retrofitted onto streams already created without it. -What exists today is a manual exit, and it now covers both stream types. If the stream is cancelable, the sender cancels and the unapproved tranche returns to them — which resolves the stranded funds, but in the sender's favor. If the stream is non-cancelable, the sender and recipient **together** can cancel it; neither can do so alone. That is a real recovery path where there used to be none for anyone, but be clear about its limit: the settlement rules are unchanged, so the unapproved tranche still goes back to the sender. A recipient who did the work is being asked to sign it away, and may reasonably refuse — in which case the funds stay stranded and any fairer split has to be arranged off-chain. A dead approver remains a stranded-funds scenario, which is [the second-highest concern in SECURITY.md](../SECURITY.md#what-we-care-most-about). +What exists today is a manual exit, and it now covers both stream types. If the stream is cancelable, the sender cancels and the unapproved tranche returns to them — which resolves the stranded funds, but in the sender's favor. If the stream is non-cancelable, the sender and recipient **together** can cancel it; neither can do so alone. That is a real recovery path where there used to be none for anyone, but be clear about its limit: the settlement rules are unchanged, so the unapproved tranche still goes back to the sender. A recipient who did the work is being asked to sign it away, and may reasonably refuse — in which case the funds stay stranded and any fairer split has to be arranged off-chain. A dead approver remains a stranded-funds scenario, which is [the second-highest concern in SECURITY.md](SECURITY.md#what-we-care-most-about). ### What happens if I lose access to the recipient account? The earned funds become unreachable. `withdraw` [requires authorization from the recipient address](architecture.md#authorization), roles are stored per stream, and no role anywhere has power over funds in an existing stream — the contract is non-upgradeable, and the one global role that exists (the pauser) can only stop `create_stream`. That is the property that stops anyone else from taking your money, and the same property that means nobody can recover it for you. No recipient-reassignment path is described in the design. -Cancellation does not rescue this. If the sender cancels, your earned balance [stays assigned to you rather than being swept back](concepts.md#cancellation-and-clawback), so it stays exactly as unreachable as before; only the unstreamed part returns to the sender. This is ordinary self-custody risk rather than a StelFlow-specific one, and wallet-level key loss is [explicitly out of scope in SECURITY.md](../SECURITY.md#scope) — but it's worth stating plainly rather than leaving you to discover it. +Cancellation does not rescue this. If the sender cancels, your earned balance [stays assigned to you rather than being swept back](concepts.md#cancellation-and-clawback), so it stays exactly as unreachable as before; only the unstreamed part returns to the sender. This is ordinary self-custody risk rather than a StelFlow-specific one, and wallet-level key loss is [explicitly out of scope in SECURITY.md](SECURITY.md#scope) — but it's worth stating plainly rather than leaving you to discover it. ## Funding a stream ### Can I stream to more than one recipient? -Not from a single stream. A stream is [one sender → one recipient, one asset, one schedule](concepts.md#money-streaming), and splitting one N ways multiplies the per-transaction entry cost, which runs into [the read budget that shapes the whole storage design](architecture.md#the-per-transaction-read-budget). Multi-recipient streams are [explicitly deferred](../ROADMAP.md#not-on-the-roadmap), pending that entry-cost question, and listed as [an open question](architecture.md#open-questions) where the maintainer invites disagreement — so if you have the payroll use case, arguing for it in an issue is a genuinely useful contribution. +Not from a single stream. A stream is [one sender → one recipient, one asset, one schedule](concepts.md#money-streaming), and splitting one N ways multiplies the per-transaction entry cost, which runs into [the read budget that shapes the whole storage design](architecture.md#the-per-transaction-read-budget). Multi-recipient streams are [explicitly deferred](ROADMAP.md#not-on-the-roadmap), pending that entry-cost question, and listed as [an open question](architecture.md#open-questions) where the maintainer invites disagreement — so if you have the payroll use case, arguing for it in an issue is a genuinely useful contribution. For now the intended answer is N separate streams, with bounded batch entry points (`withdraw_many`, `bump_many`) planned so that operating them doesn't mean N transactions for every action. ### Can I change a stream after it's created? -No. The design describes no entry point for changing a stream's amount, schedule, or recipient — [StelFlow Core's responsibilities](architecture.md#components) are create, compute, withdraw, approve, and cancel, and nothing else. The cancelable flag is [set at creation and immutable after](../ROADMAP.md#phase-2--milestones-and-cancellation-), and the milestone cap is enforced at creation too. +No. The design describes no entry point for changing a stream's amount, schedule, or recipient — [StelFlow Core's responsibilities](architecture.md#components) are create, compute, withdraw, approve, and cancel, and nothing else. The cancelable flag is [set at creation and immutable after](ROADMAP.md#phase-2--milestones-and-cancellation-), and the milestone cap is enforced at creation too. If terms need to change, the path is to cancel — which returns the unstreamed remainder to you and leaves the recipient their earned balance — and create a new stream on the new terms. On a cancelable stream you can do that unilaterally. On a non-cancelable one you can still do it, but only with the recipient's signature alongside yours, which in a renegotiation you would be seeking anyway. So non-cancelable does not lock you out of renegotiating; it means you cannot renegotiate *without agreement*, which is the guarantee the flag is for. @@ -70,20 +70,20 @@ If terms need to change, the path is to cancel — which returns the unstreamed ### Can the asset issuer freeze or claw back a live stream? -**Yes, if the asset allows it, and StelFlow cannot prevent it.** This is the honest answer and it's worth reading twice: an asset issuer with clawback enabled can remove funds the contract is holding for a live stream, *including funds a recipient has already earned*. The design states this without hedging — [issuer clawback is out of scope and cannot be defended against](architecture.md#sep-41-assets) — and SECURITY.md puts it [out of scope as an asset property rather than a StelFlow bug](../SECURITY.md#scope). It is a disclosure problem, not a code problem: the contract is not supposed to treat its stored `total` as a guarantee, because `balance` is the truth. +**Yes, if the asset allows it, and StelFlow cannot prevent it.** This is the honest answer and it's worth reading twice: an asset issuer with clawback enabled can remove funds the contract is holding for a live stream, *including funds a recipient has already earned*. The design states this without hedging — [issuer clawback is out of scope and cannot be defended against](architecture.md#sep-41-assets) — and SECURITY.md puts it [out of scope as an asset property rather than a StelFlow bug](SECURITY.md#scope). It is a disclosure problem, not a code problem: the contract is not supposed to treat its stored `total` as a guarantee, because `balance` is the truth. Note that this is a different thing from StelFlow's own [clawback on cancellation](concepts.md#cancellation-and-clawback), which reaches only the unstreamed remainder and can never touch earned funds. Same word, unrelated powers. -Practically: **check the asset's flags before you rely on a stream denominated in it.** A dashboard warning for clawback-enabled assets is planned in [Phase 5](../ROADMAP.md#phase-5--dashboard-), which means it does not exist and you are checking manually. On freezing specifically, `docs/` currently addresses clawback but not authorization revocation; per [Stellar's SAC documentation](https://developers.stellar.org/docs/tokens/stellar-asset-contract#interacting-with-classic-stellar-assets), transfers of a classic asset succeed only while the relevant trustlines are authorized, so an issuer that can freeze a holder is in the same family of power. Treat that as a property of the asset you chose, and read it here as a pointer to Stellar's docs rather than as a settled StelFlow design claim. +Practically: **check the asset's flags before you rely on a stream denominated in it.** A dashboard warning for clawback-enabled assets is planned in [Phase 5](ROADMAP.md#phase-5--dashboard-), which means it does not exist and you are checking manually. On freezing specifically, `docs/` currently addresses clawback but not authorization revocation; per [Stellar's SAC documentation](https://developers.stellar.org/docs/tokens/stellar-asset-contract#interacting-with-classic-stellar-assets), transfers of a classic asset succeed only while the relevant trustlines are authorized, so an issuer that can freeze a holder is in the same family of power. Treat that as a property of the asset you chose, and read it here as a pointer to Stellar's docs rather than as a settled StelFlow design claim. ### Is this audited? -No. There are no contracts to audit — nothing in this repository executes anywhere, and [SECURITY.md says so directly](../SECURITY.md#current-status): no deployed contracts, no audit, no funds at risk. Its instruction is unambiguous: do not use anything in this repository with real value until that file says a deployment has been audited. +No. There are no contracts to audit — nothing in this repository executes anywhere, and [SECURITY.md says so directly](SECURITY.md#current-status): no deployed contracts, no audit, no funds at risk. Its instruction is unambiguous: do not use anything in this repository with real value until that file says a deployment has been audited. -An external audit is [Phase 7](../ROADMAP.md#phase-7--hardening-and-audit-), after property-based tests, fuzzing, and an internal review against a written threat model, and the phase is done only when an audit report is published in this repository, findings and all. Two honest notes on that: Phase 7 is six phases away, and the roadmap carries an unresolved TODO asking the maintainer to state how an audit would be funded — so it is a stated intention, not a booked engagement. +An external audit is [Phase 7](ROADMAP.md#phase-7--hardening-and-audit-), after property-based tests, fuzzing, and an internal review against a written threat model, and the phase is done only when an audit report is published in this repository, findings and all. Two honest notes on that: Phase 7 is six phases away, and the roadmap carries an unresolved TODO asking the maintainer to state how an audit would be funded — so it is a stated intention, not a booked engagement. ## Didn't find your question? If the answer isn't here and isn't in [concepts.md](concepts.md) or [architecture.md](architecture.md), open an issue. Questions that expose an undecided design point are useful — [architecture.md ends with five open questions](architecture.md#open-questions) that got there the same way. -For anything that looks like a vulnerability, don't open an issue — follow [SECURITY.md](../SECURITY.md#reporting-a-vulnerability) instead. +For anything that looks like a vulnerability, don't open an issue — follow [SECURITY.md](SECURITY.md#reporting-a-vulnerability) instead. diff --git a/docs/research/indexer-design.md b/docs/indexer-design.md similarity index 92% rename from docs/research/indexer-design.md rename to docs/indexer-design.md index 25feb5d..3d68e61 100644 --- a/docs/research/indexer-design.md +++ b/docs/indexer-design.md @@ -1,6 +1,6 @@ # Indexer design -This resolves the design work [docs/architecture.md § 2](../architecture.md#2-indexer-off-chain--planned) deferred: runtime and datastore, the RPC event-retention backstop, and the cursor/reorg/idempotency mechanics that make [Phase 3](../../ROADMAP.md#phase-3--indexer-) rebuildable. Nothing here is implemented — this is the decision record Phase 3 builds against. +This resolves the design work [docs/architecture.md § 2](architecture.md#2-indexer-off-chain--planned) deferred: runtime and datastore, the RPC event-retention backstop, and the cursor/reorg/idempotency mechanics that make [Phase 3](ROADMAP.md#phase-3--indexer-) rebuildable. Nothing here is implemented — this is the decision record Phase 3 builds against. **Ground rule, repeated because it constrains every choice below:** the indexer is a cache, never an authority. If the indexer disagrees with the chain, the chain is right, and the dashboard's headline claimable-balance number must come from simulating a contract read, not from this database. Everything the indexer stores is for history, lists, and aggregates — things the contract genuinely cannot answer about itself. @@ -27,7 +27,7 @@ The write pattern is append-heavy (one row per contract event, never updated) wi | **TimescaleDB / ClickHouse** | Built for exactly this write pattern at much higher volume, but StelFlow's event rate (one contract, per-stream state changes) doesn't come close to needing columnar storage or hypertables yet. Adds an operational dependency the project doesn't need in Phase 3. | Revisit only if reconciliation/analytics queries become the bottleneck — and Timescale is a Postgres extension, so that path doesn't require a rewrite. | | **DynamoDB / Mongo** | No natural fit for "give me every withdrawal for this stream between two ledgers" without a secondary index that duplicates Postgres's btree for free. Loses transactional guarantees the checkpoint design below depends on. | Not recommended. | -**Runtime:** Node.js/TypeScript. The indexer decodes the same contract events the [SDK](../architecture.md#3-typescript-sdk--planned) will have typed bindings for — sharing the decode path and event types between indexer and SDK avoids a second, drifting implementation of "what does a `withdraw` event look like." A typed query layer over Postgres (e.g. Drizzle) keeps the schema below and the TypeScript types it's the same language as the rest of the stack. +**Runtime:** Node.js/TypeScript. The indexer decodes the same contract events the [SDK](architecture.md#3-typescript-sdk--planned) will have typed bindings for — sharing the decode path and event types between indexer and SDK avoids a second, drifting implementation of "what does a `withdraw` event look like." A typed query layer over Postgres (e.g. Drizzle) keeps the schema below and the TypeScript types it's the same language as the rest of the stack. ## 3. Cursor and checkpoint design @@ -41,7 +41,7 @@ Every event `getEvents` returns carries an `id` — a TOID (ledger sequence, tra Deduping raw events isn't sufficient by itself — the materialized `streams` row also has to end up correct no matter how many times a given event is folded into it. Two things make that hold: -1. **Contract events carry absolute state, not deltas.** A `withdraw` event should emit the resulting `withdrawn` total (and a `milestone_approved` event the resulting status), not "+N". Applying the same absolute-value event twice sets the same value twice — a no-op the second time, by construction, with no counter to accidentally increment. This is a requirement on the Phase 1 event design ([ROADMAP Phase 1](../../ROADMAP.md#phase-1--contract-core-) already flags "events designed for the indexer before the indexer exists" — this is what that needs to mean). +1. **Contract events carry absolute state, not deltas.** A `withdraw` event should emit the resulting `withdrawn` total (and a `milestone_approved` event the resulting status), not "+N". Applying the same absolute-value event twice sets the same value twice — a no-op the second time, by construction, with no counter to accidentally increment. This is a requirement on the Phase 1 event design ([ROADMAP Phase 1](ROADMAP.md#phase-1--contract-core-) already flags "events designed for the indexer before the indexer exists" — this is what that needs to mean). 2. **Projection is guarded by a monotonic watermark.** Each materialized row (`streams.last_applied_event_id`, `milestones.last_applied_event_id`) only accepts an incoming event if its `event_id` is greater than the one already applied. Combined with (1), reprocessing, out-of-order delivery within a backfill range, or replaying the entire log from scratch all converge to the identical final row. Net effect: idempotency isn't a dedup step bolted onto ingestion, it's a property of the fold function itself. See [§6](#6-rebuildability) — this is also what makes rebuild-from-scratch safe. @@ -80,11 +80,11 @@ Stellar RPC's event retention is a bounded window (commonly quoted as 7 days, bu Backfill jobs get their own `ingest_checkpoints` row (a ledger range rather than a live cursor) so a backfill can be paused, resumed, or re-run without touching the live poller's checkpoint. -This resolves the TODO in [docs/architecture.md § 2](../architecture.md#2-indexer-off-chain--planned): **Galexie-backed self-hosted backfill, with Hubble as the fast one-off cold-start path**, both feeding the same decode-and-dedup pipeline live polling uses. +This resolves the TODO in [docs/architecture.md § 2](architecture.md#2-indexer-off-chain--planned): **Galexie-backed self-hosted backfill, with Hubble as the fast one-off cold-start path**, both feeding the same decode-and-dedup pipeline live polling uses. ## 8. Reconciliation against on-chain state -[SECURITY.md](../../SECURITY.md#scope) scopes "the indexer, where a flaw causes it to report balances that don't match the chain" as a reportable bug — reconciliation is what catches that before a bug report does. +[SECURITY.md](SECURITY.md#scope) scopes "the indexer, where a flaw causes it to report balances that don't match the chain" as a reportable bug — reconciliation is what catches that before a bug report does. A periodic job (interval TBD at implementation, starting point: every few minutes) walks confirmed streams, calls the contract's claimable-balance simulation for each — the same read path the SDK's accrual preview and the dashboard's degraded mode use — and compares it against the indexer's own recomputation of claimable from its materialized `streams` row. The formula is deterministic, so a mismatch beyond rounding is drift, not noise: it flags `streams.drift_detected = true`, records the observed vs. expected values in `reconciliation_runs`, and surfaces an alert. @@ -256,6 +256,6 @@ CREATE TABLE reconciliation_runs ( ## Next -- [architecture.md § 2](../architecture.md#2-indexer-off-chain--planned) — the component this design resolves. -- [ROADMAP.md § Phase 3](../../ROADMAP.md#phase-3--indexer-) — the checklist this design is meant to unblock. -- [SECURITY.md § Scope](../../SECURITY.md#scope) — why reconciliation exists. +- [architecture.md § 2](architecture.md#2-indexer-off-chain--planned) — the component this design resolves. +- [ROADMAP.md § Phase 3](ROADMAP.md#phase-3--indexer-) — the checklist this design is meant to unblock. +- [SECURITY.md § Scope](SECURITY.md#scope) — why reconciliation exists. diff --git a/docs/milestone-deadlines.md b/docs/milestone-deadlines.md new file mode 100644 index 0000000..36661e4 --- /dev/null +++ b/docs/milestone-deadlines.md @@ -0,0 +1,145 @@ +# Design decision: milestone deadlines + +Answers [issue #38](https://github.com/StelFlow-labs/StelFlow/issues/38), the last of the +[threat model](threat-model.md)'s open design changes and the mitigation for +[T3](threat-model.md#t3--an-approver-who-never-comes-back). + +**Decision: milestones may carry an optional deadline, with the resolution declared at creation.** + +A milestone with `deadline = 0` behaves exactly as milestones did before this decision — it waits +indefinitely for its approver. A milestone with a deadline resolves automatically once the ledger +passes it, to whichever party the *sender chose and the recipient saw* before either of them signed. + +## Why this had to be decided now + +[Issue #33](upgradeability-and-pause.md) settled that StelFlow ships non-upgradeable. That turned this +question from one that could wait into one that could not, and the reasoning is worth stating plainly +because it is the whole justification for adding a field to the hottest struct in the contract: + +**A recovery path cannot be retrofitted onto a stream that already exists.** Every stream created +before deadlines exist is permanently a stream without one. There is no upgrade that adds the field +later, no migration that rewrites a live stream's terms, and no admin who could intervene. Deferring +the decision *is* deciding it, in the direction that cannot be reversed. + +That asymmetry — one answer is revisable and the other is permanent — is what settles it. Adding an +optional field that defaults to today's behaviour costs storage and can be left unused forever. +Omitting it forecloses the option for the life of the contract. + +## What the alternatives were + +From T3, in the order the threat model argued them: + +**1. A per-milestone deadline with a declared default** — this decision. Resolution is a *term of the +stream*, agreed at creation, not a privilege anyone exercises later. + +**2. A fallback approver, or k-of-n approvers.** Rejected, and it is the closest call. It removes the +single point of failure properly rather than working around it, and for a grant committee it models +reality better than a timeout does. But it multiplies the milestone struct by the number of fallback +approvers — an `Address` is 32 bytes plus discriminant, against the 25 bytes this decision adds for +*all* milestones — and it pushes directly against the `MAX_MILESTONES_PER_STREAM` cap that +[T2](threat-model.md#t2--resource-exhaustion-as-denial-of-withdrawal) exists to protect. It also +fails the case it is meant to solve whenever the fallback is as unreachable as the primary, which for +a folded company is the common case rather than the unlucky one. Nothing stops a stream from naming a +multisig or a contract as its single approver, which buys most of this at zero storage cost. + +**3. Do nothing, and disclose it.** This was defensible when the contract might later be patched. +Under #33 it means accepting permanently that a vanished approver strands a tranche forever on every +non-cancelable stream. The disclosure would have to read *"if your approver disappears, this money is +gone and nothing can recover it"* — and a design whose honest disclosure reads like that should +change rather than disclose harder. + +## The question that actually decides the shape + +> If a deadline expires, who gets the tranche — the sender or the recipient? + +Both are defensible, and that is precisely why **neither is hardcoded.** + +Sender-default treats an unapproved milestone as work that did not happen, which is what +[cancellation rule 4](concepts.md#cancellation-and-clawback) already assumes. Recipient-default treats +a vanished approver as the *sender's* counterparty risk — the sender chose that approver — and refuses +to let the sender benefit from their own bad pick. + +The mistake would be picking one and calling it fair, because the right answer differs by use case. A +grant program that names an external committee should not have the recipient's pay depend on that +committee's diligence. A vesting stream gated on a performance condition should not pay out because +nobody looked. So: + +**`on_expiry` is set per milestone at creation, and is visible to both parties before either signs.** +It is a negotiated term, like the amount or the schedule, and it keeps the property that +[architecture.md](architecture.md#authorization) insists on: nobody holds a discretionary power over +someone else's funds. Expiry is not an action anyone takes. It is the passage of time, and its outcome +was agreed in advance by both of the people it affects. + +## The rules + +1. **`deadline` is an absolute ledger timestamp**, in the same units as `start` and `end`. Zero means + no deadline — indefinite wait, matching pre-#38 behaviour exactly. +2. **A deadline must fall at or after the stream's `end`.** This is the non-obvious constraint and it + matters. A deadline *before* `end` would resolve a tranche while it was still accruing, which + makes `streamed_total` non-monotonic and puts the approver in a race against the clock for a + milestone they may be about to approve legitimately. Requiring `deadline >= end` means expiry only + ever resolves a tranche that has finished accruing, so the amount at stake is the whole tranche and + nothing is mid-flight. +3. **Expiry is evaluated on read, never pushed.** Like accrual itself, nothing happens on-chain at the + deadline. The next call that touches the stream observes `now >= deadline` and computes + accordingly. No keeper, no cron, no transaction anyone must remember to send. +4. **An approved milestone ignores its deadline entirely.** `Met` is terminal + ([#17](milestone-revocation.md)); a deadline that could undo an approval would be revocation + through the back door, and every argument against revocation applies unchanged. +5. **`on_expiry = ToRecipient`** makes the tranche behave as though approved, at expiry. It stops + being `held` and becomes ordinary claimable balance. +6. **`on_expiry = ToSender`** makes the tranche behave as though forfeited. It leaves + `streamed_total`, and `cancel` — or the stream simply ending — returns it to the sender. +7. **Cancellation still overrides.** Cancelling before a deadline resolves the milestone under rule 4 + as it always did. A cancelled stream's milestones never expire, because they are already resolved. + +## What this costs + +Two fields per milestone: a `u64` deadline and a one-byte enum, so **25 bytes** against a milestone +that already carries an `i128` amount, an `Address` approver, and a state byte. + +That is real, and it is the reason option 2 was rejected — but it is a fixed cost, not a multiplier, +and it does not scale with the number of approvers or the stream's history. +[T2](threat-model.md#t2--resource-exhaustion-as-denial-of-withdrawal)'s rule that *withdrawal cost +never grows with a stream's history* is untouched: expiry is computed from two stored numbers and the +current timestamp, exactly like accrual, with no log to walk and no new entry to read. + +The effect on `MAX_MILESTONES_PER_STREAM` is measured rather than estimated — see +[architecture.md](architecture.md#the-per-transaction-read-budget) for the figure and how it was +derived. + +## What this still gives up + +- **A deadline is a guess made at creation.** Set it too short and a legitimate approver misses it + through ordinary delay; too long and the funds are stranded for most of that time anyway. The SDK + should default to something conservative and make the trade visible rather than hiding it behind a + sensible-looking number. +- **It does not help a stream created without one.** Streams with `deadline = 0` keep T3 in full. + This closes the hole for streams created from here on; it cannot reach backwards, which is the + entire reason it had to be decided before any stream existed. +- **It does not adjudicate.** Like [unanimous-consent cancel](upgradeability-and-pause.md), expiry + moves money to a pre-agreed party rather than to the deserving one. If the recipient did the work + and `on_expiry` was `ToSender`, they lose the tranche. What they get instead is *knowing that in + advance*, which is the most a contract can offer without becoming an arbiter. + +## Consequences for the rest of the design + +- **Storage.** `Milestone` gains `deadline: u64` and `on_expiry: OnExpiry`. Milestone state stays + monotonic — expiry resolves a milestone, it never returns one to `Unmet`. +- **`claimable` stays non-decreasing in time** under `ToRecipient`, and drops by the tranche under + `ToSender` at the deadline — the only point in the design where a pending amount leaves the + recipient's side, and it does so at a timestamp they agreed to. +- **Validation at creation.** `deadline == 0 || deadline >= end`, rejected otherwise. +- **Events.** No event fires at expiry, because no transaction occurs. The indexer derives expiry the + same way the contract does: from the stored deadline and the ledger clock. This keeps the events log + a record of *actions*, never of the passage of time. +- **T3 status** moves to **Mitigated for streams that use it**, which is the honest ceiling for a + mechanism that is opt-in by design. + +## Next + +- [threat-model.md](threat-model.md) — T3, which this closes as far as it can be closed. +- [upgradeability-and-pause.md](upgradeability-and-pause.md) — why this was now-or-never. +- [milestone-revocation.md](milestone-revocation.md) — the same mechanism pointed the other way, and + rejected. +- [behaviour.md](behaviour.md) — the expiry scenarios. diff --git a/docs/research/milestone-revocation.md b/docs/milestone-revocation.md similarity index 94% rename from docs/research/milestone-revocation.md rename to docs/milestone-revocation.md index 6591a64..4e26fbd 100644 --- a/docs/research/milestone-revocation.md +++ b/docs/milestone-revocation.md @@ -41,7 +41,7 @@ to solve. Option B is the intuitive one, and it is the one to rule out carefully, because "prior withdrawals stand, future accrual adjusts" *sounds* fair. -Run it against the [worked example](../concepts.md#a-worked-example-alice-and-bob). Alice streams +Run it against the [worked example](concepts.md#a-worked-example-alice-and-bob). Alice streams 30,000,000,000 stroops to Bob over 30 days: 18,000,000,000 base, 12,000,000,000 gated on one milestone. Bob withdraws 6,000,000,000 at day 10. The milestone is approved at day 18 and Bob withdraws the full 12,000,000,000 then, putting `withdrawn` at 18,000,000,000 — exactly the sequence @@ -95,14 +95,14 @@ Three reasons, in order of weight. **1. It is the only option that keeps the promise the design is sold on.** -[`concepts.md`](../concepts.md#what-a-gate-does-not-do) states that a gate "does not give the +[`concepts.md`](concepts.md#what-a-gate-does-not-do) states that a gate "does not give the approver custody — the approver flips a flag. They cannot redirect funds." Under Option A that claim is not just true, it is *structurally* true: the approver's single power moves value in one direction only, toward the recipient, and can never move it back. Under Option B or C the approver can reduce what the recipient ultimately receives, which is custody in substance regardless of what it is called, and the sentence would need amending to something much weaker. -The broader promise in [the comparison table](../concepts.md#how-this-differs-from-what-already-exists) +The broader promise in [the comparison table](concepts.md#how-this-differs-from-what-already-exists) is that the recipient is funded while conditions pend. A retraction power inverts that: the recipient would be funded *provisionally* while conditions pend, and would not know for certain what they had earned until the stream ended. @@ -142,7 +142,7 @@ sender's exposure is bounded by tranches that have already accrued, and there is redirection. That is a materially smaller problem than a revocation power would create. The fraud case is the one Option A genuinely cannot handle, and the honest answer is that it was never -StelFlow's to handle. [`architecture.md`](../architecture.md#trustless-work-integration) already draws +StelFlow's to handle. [`architecture.md`](architecture.md#trustless-work-integration) already draws the line: Trustless Work decides *whether* a condition is met, StelFlow decides *how fast* money moves once it is. Trustless Work implements disputes. A grant program that needs a dispute process should name a Trustless Work escrow as the approver, and that escrow can hold its approval until its own @@ -185,6 +185,6 @@ they are guaranteed, and that cost is larger and falls on the party with less po ## Next -- [../concepts.md](../concepts.md#milestone-gates) — where the rule is stated for readers. +- [../concepts.md](concepts.md#milestone-gates) — where the rule is stated for readers. - [threat-model.md](threat-model.md) — T3 and T9, which this decision leans on. -- [../specs/behaviour.md](../specs/behaviour.md) — the scenarios this makes writable. +- [../specs/behaviour.md](behaviour.md) — the scenarios this makes writable. diff --git a/docs/research/threat-model.md b/docs/threat-model.md similarity index 93% rename from docs/research/threat-model.md rename to docs/threat-model.md index eb607e5..0cc464a 100644 --- a/docs/research/threat-model.md +++ b/docs/threat-model.md @@ -2,13 +2,13 @@ Answers [issue #9](https://github.com/StelFlow-labs/StelFlow/issues/9). -[SECURITY.md](../../SECURITY.md) names five classes of concern in a short section. This document is +[SECURITY.md](SECURITY.md) names five classes of concern in a short section. This document is the reasoning behind them, written before Phase 1 so the contract can be built against it rather than audited against it later. **Nothing here describes a vulnerability in deployed software.** There is no deployed software. Every threat below is a property of the design as it currently stands in -[architecture.md](../architecture.md) and [concepts.md](../concepts.md), and several of them are +[architecture.md](architecture.md) and [concepts.md](concepts.md), and several of them are resolved by decisions that haven't been made yet. Where that's the case, this document says which decision and recommends an answer. @@ -93,12 +93,12 @@ now-or-never design problem, which is why T3 below moved. **Attacker:** usually no one. This is mostly a self-inflicted wound, which is why it ranks so high — it needs no adversary at all. -**Capability:** [milestones live inside the stream struct](../architecture.md#the-per-transaction-read-budget) +**Capability:** [milestones live inside the stream struct](architecture.md#the-per-transaction-read-budget) rather than as separate entries. A stream with enough milestones produces an entry large enough that reading it exceeds the transaction's resource budget. **Impact:** the recipient's earned funds can never be withdrawn. This is -[SECURITY.md](../../SECURITY.md)'s class 2 and the worst outcome the system can produce short of +[SECURITY.md](SECURITY.md)'s class 2 and the worst outcome the system can produce short of outright theft — worse in one respect than theft, because there is no attacker to pursue and no recovery path at all. @@ -127,8 +127,8 @@ would be affected — a conservative cap buys margin against that too. **Attacker:** none required. The approver is a company that folded, a person who lost their key, a contract that was superseded, or someone who simply stopped answering. -**Capability:** [milestone gates](../concepts.md#milestone-gates) release only when the named -[approver](../glossary.md#approver) marks them met. There is no timeout and no fallback. +**Capability:** [milestone gates](concepts.md#milestone-gates) release only when the named +[approver](glossary.md#approver) marks them met. There is no timeout and no fallback. **Impact:** the gated tranche accrues normally and is never claimable. On a **cancelable** stream the sender can cancel and recover it — the recipient loses work they may have done, but the funds aren't @@ -179,13 +179,13 @@ asked to send. The contract stores `total` as the requested figure. **Impact:** the stream promises more than it holds. Accrual is computed against a `total` the contract can't pay, so early withdrawers are paid in full and the last withdrawer — usually the recipient's final settlement — finds the balance short. That is a **value-conservation failure**, -[SECURITY.md](../../SECURITY.md)'s class 1, and it breaks the invariant every scenario in -[behaviour.md](../specs/behaviour.md) asserts. +[SECURITY.md](SECURITY.md)'s class 1, and it breaks the invariant every scenario in +[behaviour.md](behaviour.md) asserts. **Cost:** free to the issuer; invisible to the sender at creation. **Mitigation.** This was architecture.md's open TODO and -[behaviour.md's case 4](../specs/behaviour.md#resolved-cases). The threat model's answer: +[behaviour.md's case 4](behaviour.md#resolved-cases). The threat model's answer: **measure, don't trust.** `create_stream` should read the contract's own balance before and after the transfer and store the delta as `total`. It costs one extra balance read at creation, it makes the stored figure true by construction for every asset, and it converts an unbounded class of @@ -202,7 +202,7 @@ afterwards, and the residual there is accepted, bounded by the rule that `balanc **Attacker:** whoever holds the pause key, under compulsion or otherwise. -**Capability:** [open question 5](../architecture.md#open-questions) asks whether there's an +**Capability:** [open question 5](architecture.md#open-questions) asks whether there's an emergency stop and whether it can stop withdrawals. **Impact:** if a pause can block `withdraw`, then a recipient's *already-earned* balance is freezable @@ -233,7 +233,7 @@ conditional on human reaction time; its abuse value is not.** **Attacker:** the sender, or a party colluding with them. **Capability:** nothing prevents a sender from naming themselves — or an address they control — as a -milestone's approver. [Cancellation rule 4](../concepts.md#cancellation-and-clawback) then returns +milestone's approver. [Cancellation rule 4](concepts.md#cancellation-and-clawback) then returns unapproved tranches to the sender **in full**, including the portion that already accrued while the gate was shut. @@ -269,8 +269,8 @@ single-party setups awkward. Disclosure is the honest mitigation here. **Capability:** if an asset was issued with `AUTH_CLAWBACK_ENABLED`, the issuer can burn it from any holder — including this contract, mid-stream. The power belongs to the -[SAC's](../glossary.md#stellar-asset-contract-sac) admin interface, not to anything -[SEP-41](../glossary.md#sep-41) defines, so it rides on the asset rather than the interface. +[SAC's](glossary.md#stellar-asset-contract-sac) admin interface, not to anything +[SEP-41](glossary.md#sep-41) defines, so it rides on the asset rather than the interface. **Impact:** funds vanish from a live stream. Total loss, and no contract logic can prevent or detect it in advance. @@ -288,7 +288,7 @@ cases StelFlow exists for. Refusal also can't be complete: an issuer can enable stream is created. So the flag should be checked and surfaced at creation, re-checked and displayed on the dashboard for live streams, and never presented as a solved problem. -**Status:** accepted and out of scope, per [SECURITY.md](../../SECURITY.md#scope). Ranked P2 rather +**Status:** accepted and out of scope, per [SECURITY.md](SECURITY.md#scope). Ranked P2 rather than lower only because the severity is total and the disclosure work is real. ## T8 — Archival economics as a griefing vector @@ -331,7 +331,7 @@ only surface. **Capability:** mark milestones met. **Impact:** smaller than it first appears, and the design deserves credit for it. Approval -[does not accelerate accrual](../concepts.md#what-a-gate-does-not-do) — it unlocks what has already +[does not accelerate accrual](concepts.md#what-a-gate-does-not-do) — it unlocks what has already streamed. So a compromised approver releases at most the tranche's *accrued-to-date* amount, not the tranche's full value, and the released funds go to the **recipient**, not to the attacker. Unless the attacker *is* the recipient, compromising an approver spends a stolen key to pay a third party early. @@ -376,13 +376,13 @@ operations should default to streams above a user-chosen threshold. **Attacker:** a validator, or someone who has bribed enough of them. -**Capability:** nudge the [ledger close time](../glossary.md#ledger-close-time) that +**Capability:** nudge the [ledger close time](glossary.md#ledger-close-time) that `env.ledger().timestamp()` returns. **Impact:** worth showing the arithmetic, because the intuition that "time controls money here" makes this feel more dangerous than it is. Accrual is `total × elapsed / duration`, so shifting `now` forward by Δ changes what's streamed by `total × Δ / duration`. On the 30-day, 3,000 USDC stream in -[concepts.md](../concepts.md#a-worked-example-alice-and-bob), a Δ of one ledger — about 5 seconds — +[concepts.md](concepts.md#a-worked-example-alice-and-bob), a Δ of one ledger — about 5 seconds — moves roughly **0.006 USDC**. Moving 1% of the stream's value requires Δ ≈ 7.2 hours, which SCP will not produce; close times are consensus values, non-decreasing and closely tracked to real time. @@ -409,7 +409,7 @@ or strand value permanently? **No, and it's worth writing down why, because "salami slicing" is a real bug class elsewhere.** The property that kills it is that `streamed` is -[recomputed from scratch on every call](../architecture.md#arithmetic) rather than accumulated, and a +[recomputed from scratch on every call](architecture.md#arithmetic) rather than accumulated, and a withdrawal pays `streamed(t) − withdrawn`. Withdrawing at times `t₁ < t₂ < … < tₙ` pays ``` @@ -427,8 +427,8 @@ Stranding is bounded too. Mid-stream, truncation leaves `streamed` at most a str below the real-valued figure, and that shortfall is recovered as accrual moves past it rather than compounding. At `end` the special case pays the remaining balance rather than recomputing, so the final settlement is exact — which is what -[concepts.md's reconciliation](../concepts.md#reconciliation) demonstrates and what every -state-changing scenario in [behaviour.md](../specs/behaviour.md) asserts. +[concepts.md's reconciliation](concepts.md#reconciliation) demonstrates and what every +state-changing scenario in [behaviour.md](behaviour.md) asserts. One caveat, more precision than defect: `streamed` is floored **per portion** and then summed, so a multi-tranche stream can sit a few stroops below a single-tranche stream of the same total. It errs @@ -484,7 +484,7 @@ Collected so they can be argued with individually: - **The SDK, indexer, and dashboard as attack surfaces in their own right.** A malicious or buggy frontend that gets a user to sign the wrong transaction is in - [SECURITY.md's scope](../../SECURITY.md#scope) but needs its own model once there's code. + [SECURITY.md's scope](SECURITY.md#scope) but needs its own model once there's code. - **Trustless Work's contracts**, when an escrow acts as approver. Their trust assumptions become ours at that boundary, and that deserves examination when the integration is real rather than intended. @@ -496,10 +496,10 @@ Collected so they can be argued with individually: ## Next - [ttl-strategy.md](ttl-strategy.md) — archival and restore economics, which T8 leans on directly. -- [../specs/behaviour.md](../specs/behaviour.md) — the value-conservation invariant T4 and T12 are +- [../specs/behaviour.md](behaviour.md) — the value-conservation invariant T4 and T12 are about, asserted scenario by scenario. -- [../../SECURITY.md](../../SECURITY.md) — reporting process and scope. +- [../../SECURITY.md](SECURITY.md) — reporting process and scope. - [upgradeability-and-pause.md](upgradeability-and-pause.md) — the decisions that closed T1 and T5, and partially opened T3. -- [../architecture.md](../architecture.md#open-questions) — open questions 4 and 5 were T1 and T5; +- [../architecture.md](architecture.md#open-questions) — open questions 4 and 5 were T1 and T5; both now record the decision rather than the question. diff --git a/docs/research/ttl-strategy.md b/docs/ttl-strategy.md similarity index 94% rename from docs/research/ttl-strategy.md rename to docs/ttl-strategy.md index 5d0c88a..61a53ee 100644 --- a/docs/research/ttl-strategy.md +++ b/docs/ttl-strategy.md @@ -1,8 +1,8 @@ # Research: TTL and state-archival strategy for long-lived streams -Answers [issue #6](https://github.com/StelFlow-labs/StelFlow/issues/6). Narrows the TODO in [architecture.md → Storage type and TTL](../architecture.md#storage-type-and-ttl). +Answers [issue #6](https://github.com/StelFlow-labs/StelFlow/issues/6). Narrows the TODO in [architecture.md → Storage type and TTL](architecture.md#storage-type-and-ttl). -**The problem, restated precisely:** a stream is one [`persistent`](../glossary.md#persistent-storage) entry. Persistent entries have a [TTL](../glossary.md#ttl-time-to-live) that must be periodically extended or the entry [archives](../glossary.md#state-archival). A 4-year vesting stream with a 1-year cliff sits untouched for far longer than any single TTL extension can cover — checked below, the network's own maximum extension window is about six months, not four years. Archival of the highest-value streams isn't a tail risk to design around; it's what happens by default unless something acts on the stream's behalf. This document works out how TTL and archival actually behave today, what keeping a stream alive costs, which mitigation is worth building, and what a recipient's SDK needs to do about the streams that archive anyway. +**The problem, restated precisely:** a stream is one [`persistent`](glossary.md#persistent-storage) entry. Persistent entries have a [TTL](glossary.md#ttl-time-to-live) that must be periodically extended or the entry [archives](glossary.md#state-archival). A 4-year vesting stream with a 1-year cliff sits untouched for far longer than any single TTL extension can cover — checked below, the network's own maximum extension window is about six months, not four years. Archival of the highest-value streams isn't a tail risk to design around; it's what happens by default unless something acts on the stream's behalf. This document works out how TTL and archival actually behave today, what keeping a stream alive costs, which mitigation is worth building, and what a recipient's SDK needs to do about the streams that archive anyway. All network numbers below were checked with `stellar network settings --network testnet` on **2026-08-11**, using stellar-cli 23.4.1. Testnet reported **protocol version 27**; the installed CLI only fully understands protocol 23, so the dump may be missing settings introduced after that protocol. Anything numeric in this document is a snapshot, not a constant — see [§ Parameters that must not be hardcoded](#parameters-that-must-not-be-hardcoded) for why, and how the contract and SDK should read these live instead. @@ -10,14 +10,14 @@ All network numbers below were checked with `stellar network settings --network ### Storage types, briefly -Soroban has three storage types; StelFlow already chose [`persistent`](../glossary.md#persistent-storage) for stream state, for the reason [architecture.md](../architecture.md#storage-type-and-ttl) gives — [`temporary`](../glossary.md#temporary-storage) entries are deleted, not archived, and that's fatal for a custody record. Confirmed straight from the source: +Soroban has three storage types; StelFlow already chose [`persistent`](glossary.md#persistent-storage) for stream state, for the reason [architecture.md](architecture.md#storage-type-and-ttl) gives — [`temporary`](glossary.md#temporary-storage) entries are deleted, not archived, and that's fatal for a custody record. Confirmed straight from the source: > When a Temporary entry's TTL is 0, it is deleted from the ledger and is permanently inaccessible. When a Persistent or Instance entry TTL is 0, it is "archived" and can't be accessed until it is "restored". > — [Stellar docs: State Archival](https://developers.stellar.org/docs/learn/fundamentals/contract-development/storage/state-archival), checked 2026-08-11 The formal protocol definition is [CAP-0046-12, "Soroban State Archival Interface"](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0046-12.md) (Status: Final). -One nuance worth carrying into the design: **[instance storage](../glossary.md#instance-storage) shares one TTL across the whole contract**, while persistent entries each carry their own. That asymmetry matters for the recommendation below — instance archiving blocks *every* stream at once, while one stream's persistent entry archiving blocks only that stream. They should not get the same level of care. +One nuance worth carrying into the design: **[instance storage](glossary.md#instance-storage) shares one TTL across the whole contract**, while persistent entries each carry their own. That asymmetry matters for the recommendation below — instance archiving blocks *every* stream at once, while one stream's persistent entry archiving blocks only that stream. They should not get the same level of care. ### TTL mechanics @@ -195,5 +195,5 @@ The architecture.md TODO comment has been updated to point here and reflect this ## Next -- [../architecture.md](../architecture.md) — the design this narrows. -- [../glossary.md](../glossary.md) — TTL, state archival, RestoreFootprintOp definitions. +- [../architecture.md](architecture.md) — the design this narrows. +- [../glossary.md](glossary.md) — TTL, state archival, RestoreFootprintOp definitions. diff --git a/docs/research/upgradeability-and-pause.md b/docs/upgradeability-and-pause.md similarity index 97% rename from docs/research/upgradeability-and-pause.md rename to docs/upgradeability-and-pause.md index cb145ee..911e148 100644 --- a/docs/research/upgradeability-and-pause.md +++ b/docs/upgradeability-and-pause.md @@ -1,7 +1,7 @@ # Design decision: upgradeability and emergency pause Answers [issue #33](https://github.com/StelFlow-labs/StelFlow/issues/33), which is -[architecture.md](../architecture.md#open-questions) open questions 4 and 5 and +[architecture.md](architecture.md#open-questions) open questions 4 and 5 and [threat-model](threat-model.md) **T1** and **T5**. **Three decisions, which are really one:** @@ -80,7 +80,7 @@ Two smaller points that the table doesn't show, both of which push the same way: more of a stream is milestone-gated — the feature StelFlow exists for — the less the timelock is worth. - **A cliff makes it zero.** A recipient inside a cliff has `claimable = 0` by construction - ([architecture.md](../architecture.md#stream-lifecycle)). For the four-year-vest-with-one-year-cliff + ([architecture.md](architecture.md#stream-lifecycle)). For the four-year-vest-with-one-year-cliff shape that vesting actually uses, an upgrade announced in month two lets the recipient rescue nothing whatsoever. @@ -129,7 +129,7 @@ cancelable == false -> sender.require_auth() AND recipient.require_auth() That is the entire change. Specifically, it is **not**: - a new entry point — `cancel` stays one function and the contract stays at four; -- a new settlement rule — [cancellation rules 1–4](../concepts.md#cancellation-and-clawback) apply +- a new settlement rule — [cancellation rules 1–4](concepts.md#cancellation-and-clawback) apply unchanged, so there is no new arithmetic and no new conservation case; - a new role — both addresses are already stored on the stream; - a weakening of anything. The recipient's guarantee under `cancelable = false` was "the sender can @@ -279,7 +279,7 @@ cannot be retrofitted onto streams created without one. non-cancelable stream whose recipient has lost their key, or whose sender has disappeared, stays on the old contract until it completes. This is the honest residual and it is the same residual as T3. - **A "global admin" now exists, narrowly.** The claim in - [architecture.md](../architecture.md#authorization) needed amending from "there is no global admin" + [architecture.md](architecture.md#authorization) needed amending from "there is no global admin" to a precise statement of what the one global role can and cannot do. Precision beats a clean sentence that has quietly stopped being true. - **Protocol changes can strand assumptions.** A non-upgradeable contract cannot adapt to a Soroban @@ -297,7 +297,7 @@ cannot be retrofitted onto streams created without one. as the better practice — rather than stored and administered. Nothing about TTL is tunable, and nothing needs to be. - **`cancel` takes two authorizations when `cancelable = false`.** The - [behaviour spec](../specs/behaviour.md#feature-cancel) scenario for non-cancelable streams is + [behaviour spec](behaviour.md#feature-cancel) scenario for non-cancelable streams is amended: rejected when the sender alone authorizes, permitted when both do. - **A solvency assertion on every payout.** `payout <= total - withdrawn` per stream, on `withdraw` and `cancel`. It is the structural answer to the pooled-balance argument above and should be an @@ -340,9 +340,9 @@ would be more valuable still and I did not find any I could verify. --> ## Next - [threat-model.md](threat-model.md) — T1 and T5 now record these decisions; T3 is amended. -- [../architecture.md](../architecture.md#authorization) — the amended authorization claim, and open +- [../architecture.md](architecture.md#authorization) — the amended authorization claim, and open questions 4 and 5 marked settled. -- [../specs/behaviour.md](../specs/behaviour.md) — the scenarios this makes writable, including +- [../specs/behaviour.md](behaviour.md) — the scenarios this makes writable, including two-signature cancel and the pause's scope. - [milestone-revocation.md](milestone-revocation.md) — the other half of "what powers exist over a live stream," decided the same way and for the same reason. From 71d1a3cba26f7e691ab727aecca865208a59b703 Mon Sep 17 00:00:00 2001 From: Jethro Irmiya Date: Sun, 16 Aug 2026 09:07:17 +0100 Subject: [PATCH 2/8] feat(contract): deploy to testnet, close two interface holes found by doing it MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Live at CC3XU5QBQE4HSZGIBKV72AHMWFV6756AWRBH7A23FSFOXUG6YE65Z7FO. Deploying found two problems the unit tests could not: 1. Setup was a callable `initialize`, and the first deploy proved it — the contract came up with `pauser == null` because the constructor args were silently ignored. On a contract that can never be upgraded, whoever calls `initialize` first holds the pauser role permanently. Moved to `__constructor`, which runs inside the deploy transaction, so the window does not exist. 2. `create_stream` took a full `Milestone`, meaning callers had to supply a `state` field whose only legal value was `Unmet`. Now it takes `MilestoneSpec`, which has no such field: the bad request is unrepresentable rather than validated. One error case deleted rather than documented. Error codes 1 and 2 are left unused rather than reassigned, so a code never changes meaning between builds. End-to-end run against testnet with real XLM via its SAC — create, describe, withdraw, approve, preview_cancel, cancel — conserves value exactly: withdrawn 301,500,000 + refund 494,722,223 + remaining 203,777,777 = 1,000,000,000 deposited deployments.json records superseded addresses rather than deleting them. The contract is non-upgradeable, so a new version is always a new address, and anyone holding a stream on an old one needs to be able to find it. 75/75 tests pass, clippy clean. Co-Authored-By: Claude Opus 5 --- contracts/stelflow/src/accrual.rs | 11 +------ contracts/stelflow/src/error.rs | 8 ++--- contracts/stelflow/src/lib.rs | 42 +++++++++++++------------- contracts/stelflow/src/storage.rs | 10 ++---- contracts/stelflow/src/tests/create.rs | 40 +++++++++--------------- contracts/stelflow/src/tests/mod.rs | 19 +++++------- contracts/stelflow/src/tests/pause.rs | 4 +-- contracts/stelflow/src/types.rs | 28 +++++++++++++++++ deployments.json | 33 ++++++++++++++++++++ 9 files changed, 113 insertions(+), 82 deletions(-) create mode 100644 deployments.json diff --git a/contracts/stelflow/src/accrual.rs b/contracts/stelflow/src/accrual.rs index 511095f..0a35bbc 100644 --- a/contracts/stelflow/src/accrual.rs +++ b/contracts/stelflow/src/accrual.rs @@ -17,7 +17,7 @@ //! `amount * (elapsed / duration)`, which would floor the ratio to zero for //! every stream shorter than its own duration. -use soroban_sdk::{contracttype, Vec}; +use soroban_sdk::contracttype; use crate::error::Error; use crate::types::{Milestone, MilestoneState, OnExpiry, Stream}; @@ -195,15 +195,6 @@ pub fn settle(stream: &Stream, now: u64) -> Result { }) } -/// Sum of every milestone amount, used to derive `base_amount` at creation. -pub fn gated_total(milestones: &Vec) -> Result { - let mut sum = 0i128; - for milestone in milestones.iter() { - sum = add(sum, milestone.amount)?; - } - Ok(sum) -} - fn add(lhs: i128, rhs: i128) -> Result { lhs.checked_add(rhs).ok_or(Error::Overflow) } diff --git a/contracts/stelflow/src/error.rs b/contracts/stelflow/src/error.rs index d024fda..a2c5dc0 100644 --- a/contracts/stelflow/src/error.rs +++ b/contracts/stelflow/src/error.rs @@ -10,10 +10,10 @@ use soroban_sdk::contracterror; #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] #[repr(u32)] pub enum Error { - /// `initialize` has already run. There is no re-initialize: it would be an - /// admin power over a live contract by another name. - AlreadyInitialized = 1, - NotInitialized = 2, + // 1 and 2 were AlreadyInitialized / NotInitialized. Both became unreachable + // when setup moved into `__constructor`, which cannot be called twice and + // cannot be skipped. The numbers are left unused rather than reassigned, so + // an error code never changes meaning between builds. // ---- create_stream ---- /// `end` must be strictly greater than `start`; a zero-duration stream has diff --git a/contracts/stelflow/src/lib.rs b/contracts/stelflow/src/lib.rs index e7bf206..fc63329 100644 --- a/contracts/stelflow/src/lib.rs +++ b/contracts/stelflow/src/lib.rs @@ -18,7 +18,7 @@ use events::{ pub use accrual::{Position, Resolution, Settlement}; pub use error::Error; -pub use types::{ConfigKey, DataKey, Milestone, MilestoneState, OnExpiry, Stream}; +pub use types::{ConfigKey, DataKey, Milestone, MilestoneSpec, MilestoneState, OnExpiry, Stream}; /// Ceiling on milestones per stream. /// @@ -67,21 +67,21 @@ pub struct StelFlow; #[contractimpl] impl StelFlow { - /// Set the initial pauser. Runs once. + /// Set the initial pauser, atomically with deployment. /// - /// Pass `None` to deploy with no pauser at all — a contract that is - /// privilege-free from its first ledger. There is deliberately no - /// re-initialize: that would be an admin power over a live contract wearing - /// a different name. - pub fn initialize(env: Env, pauser: Option
) -> Result<(), Error> { - if storage::is_initialized(&env) { - return Err(Error::AlreadyInitialized); - } + /// A constructor rather than an `initialize` anyone can call, because the gap + /// between the two is a real hole in a contract that can never be upgraded: + /// whoever calls `initialize` first would hold the pauser role permanently, + /// with no way to correct it. Running inside the deploy transaction means the + /// window does not exist. + /// + /// Pass `None` to deploy with no pauser at all — privilege-free from the + /// contract's first ledger. There is deliberately no way to set one later. + pub fn __constructor(env: Env, pauser: Option
) { storage::set_pauser(&env, &pauser); storage::set_paused_until(&env, 0); storage::init_stream_ids(&env); PauserChanged { pauser }.publish(&env); - Ok(()) } // ----------------------------------------------------------------------- @@ -107,7 +107,7 @@ impl StelFlow { end: u64, cliff: u64, cancelable: bool, - milestones: Vec, + milestones: Vec, ) -> Result { sender.require_auth(); @@ -128,19 +128,20 @@ impl StelFlow { if milestones.len() > MAX_MILESTONES_PER_STREAM { return Err(Error::TooManyMilestones); } - for milestone in milestones.iter() { - if milestone.amount <= 0 { - return Err(Error::InvalidAmount); - } - if milestone.state != MilestoneState::Unmet { + let mut gated = 0i128; + let mut tranches = Vec::new(&env); + for spec in milestones.iter() { + if spec.amount <= 0 { return Err(Error::InvalidAmount); } // A deadline before `end` would resolve a tranche while it was still // accruing, making `streamed_total` non-monotonic and racing a // legitimate approver against the clock. See docs/milestone-deadlines.md. - if milestone.deadline != 0 && milestone.deadline < end { + if spec.deadline != 0 && spec.deadline < end { return Err(Error::InvalidTimeRange); } + gated = gated.checked_add(spec.amount).ok_or(Error::Overflow)?; + tranches.push_back(spec.into_milestone()); } let contract = env.current_contract_address(); @@ -152,12 +153,11 @@ impl StelFlow { if received <= 0 { return Err(Error::NoValueReceived); } - let gated = accrual::gated_total(&milestones)?; if gated > received { return Err(Error::MilestonesExceedTotal); } - let milestone_count = milestones.len(); + let milestone_count = tranches.len(); let id = storage::next_stream_id(&env); let stream = Stream { id, @@ -171,7 +171,7 @@ impl StelFlow { cliff, cancelable, withdrawn: 0, - milestones, + milestones: tranches, canceled_at: None, }; storage::save_stream(&env, &stream); diff --git a/contracts/stelflow/src/storage.rs b/contracts/stelflow/src/storage.rs index 38a6001..bfd0c6b 100644 --- a/contracts/stelflow/src/storage.rs +++ b/contracts/stelflow/src/storage.rs @@ -105,14 +105,8 @@ pub fn touch_stream(env: &Env, stream_id: u64) -> Result<(), Error> { // Config // --------------------------------------------------------------------------- -pub fn is_initialized(env: &Env) -> bool { - env.storage().instance().has(&ConfigKey::NextId) -} - -/// Arm the id counter without consuming an id. -/// -/// Writing the key is also what marks the contract initialized, so this must set -/// zero rather than reserve it — the first stream created is stream 0. +/// Arm the id counter without consuming an id: the first stream created is +/// stream 0. pub fn init_stream_ids(env: &Env) { env.storage().instance().set(&ConfigKey::NextId, &0u64); bump_instance(env); diff --git a/contracts/stelflow/src/tests/create.rs b/contracts/stelflow/src/tests/create.rs index e082dac..eae720b 100644 --- a/contracts/stelflow/src/tests/create.rs +++ b/contracts/stelflow/src/tests/create.rs @@ -59,11 +59,9 @@ fn requires_the_sender_to_authorize() { let env = Env::default(); let issuer = Address::generate(&env); let asset = env.register_stellar_asset_contract_v2(issuer); - let contract_id = env.register(StelFlow, ()); - let client = crate::StelFlowClient::new(&env, &contract_id); - env.mock_all_auths(); - client.initialize(&None); + let contract_id = env.register(StelFlow, (None::
,)); + let client = crate::StelFlowClient::new(&env, &contract_id); let sender = Address::generate(&env); soroban_sdk::token::StellarAssetClient::new(&env, &asset.address()).mint(&sender, &TOTAL); env.ledger().set_timestamp(START); @@ -296,25 +294,17 @@ fn accepts_a_deadline_at_or_after_the_stream_ends() { ); } -/// A milestone may not be pre-marked as met at creation, which would let a -/// sender mint an approval nobody granted. +/// A milestone cannot be created already met — `MilestoneSpec` has no `state` +/// field, so the request is unrepresentable rather than rejected. This asserts +/// the property that replaces the old validation. #[test] -fn rejects_a_milestone_that_does_not_start_unmet() { +fn every_milestone_starts_unmet() { let h = Harness::new(); - let mut milestone = h.milestone(GATED, 0, OnExpiry::ToSender); - milestone.state = MilestoneState::Met; - let result = h.client.try_create_stream( - &h.sender, - &h.recipient, - &h.token_id, - &TOTAL, - &START, - &END, - &START, - &true, - &vec![&h.env, milestone], + let id = h.alice_and_bob(); + assert_eq!( + h.client.get_stream(&id).milestones.get(0).unwrap().state, + MilestoneState::Unmet, ); - assert_eq!(result, Err(Ok(Error::InvalidAmount))); } /// Scenario: a stream of duration 1 second @@ -395,11 +385,11 @@ fn stream_count_tracks_creations() { assert_eq!(h.client.stream_count(), 2); } +/// Setup runs inside the deploy transaction, so there is no window in which +/// someone else could claim the pauser role — and no `initialize` to call twice. #[test] -fn initialize_runs_once() { +fn the_constructor_leaves_no_initialization_window() { let h = Harness::new(); - assert_eq!( - h.client.try_initialize(&Some(h.stranger.clone())), - Err(Ok(Error::AlreadyInitialized)), - ); + assert_eq!(h.client.pauser(), Some(h.pauser.clone())); + assert_eq!(h.client.stream_count(), 0, "the constructor consumes no id"); } diff --git a/contracts/stelflow/src/tests/mod.rs b/contracts/stelflow/src/tests/mod.rs index b625d6b..f43e0f7 100644 --- a/contracts/stelflow/src/tests/mod.rs +++ b/contracts/stelflow/src/tests/mod.rs @@ -22,7 +22,7 @@ use soroban_sdk::testutils::{Address as _, Ledger}; use soroban_sdk::token::{StellarAssetClient, TokenClient}; use soroban_sdk::{vec, Address, Env, Vec}; -use crate::{Milestone, MilestoneState, OnExpiry, StelFlow, StelFlowClient}; +use crate::{MilestoneSpec, OnExpiry, StelFlow, StelFlowClient}; pub const DAY: u64 = 86_400; pub const START: u64 = 1_000_000; @@ -58,11 +58,9 @@ impl<'a> Harness<'a> { let asset = env.register_stellar_asset_contract_v2(issuer); let token_id = asset.address(); - let contract_id = env.register(StelFlow, ()); - let client = StelFlowClient::new(&env, &contract_id); - let pauser = Address::generate(&env); - client.initialize(&Some(pauser.clone())); + let contract_id = env.register(StelFlow, (Some(pauser.clone()),)); + let client = StelFlowClient::new(&env, &contract_id); let sender = Address::generate(&env); let harness = Self { @@ -92,20 +90,19 @@ impl<'a> Harness<'a> { self.warp_to(START + days * DAY); } - pub fn no_milestones(&self) -> Vec { + pub fn no_milestones(&self) -> Vec { Vec::new(&self.env) } /// One milestone holding `GATED`, approved by `self.approver`, no deadline. - pub fn one_milestone(&self) -> Vec { + pub fn one_milestone(&self) -> Vec { vec![&self.env, self.milestone(GATED, 0, OnExpiry::ToSender)] } - pub fn milestone(&self, amount: i128, deadline: u64, on_expiry: OnExpiry) -> Milestone { - Milestone { + pub fn milestone(&self, amount: i128, deadline: u64, on_expiry: OnExpiry) -> MilestoneSpec { + MilestoneSpec { amount, approver: self.approver.clone(), - state: MilestoneState::Unmet, deadline, on_expiry, } @@ -127,7 +124,7 @@ impl<'a> Harness<'a> { amount: i128, cliff: u64, cancelable: bool, - milestones: Vec, + milestones: Vec, ) -> u64 { self.client.create_stream( &self.sender, diff --git a/contracts/stelflow/src/tests/pause.rs b/contracts/stelflow/src/tests/pause.rs index a86037c..21a37ce 100644 --- a/contracts/stelflow/src/tests/pause.rs +++ b/contracts/stelflow/src/tests/pause.rs @@ -136,11 +136,9 @@ fn the_role_can_be_handed_on() { fn deploying_without_a_pauser_is_allowed() { let env = Env::default(); env.mock_all_auths(); - let contract_id = env.register(StelFlow, ()); + let contract_id = env.register(StelFlow, (None::,)); let client = crate::StelFlowClient::new(&env, &contract_id); - client.initialize(&None); - assert_eq!(client.pauser(), None); assert_eq!(client.try_pause(), Err(Ok(Error::NotPauser))); } diff --git a/contracts/stelflow/src/types.rs b/contracts/stelflow/src/types.rs index 04f5275..d51db81 100644 --- a/contracts/stelflow/src/types.rs +++ b/contracts/stelflow/src/types.rs @@ -44,6 +44,34 @@ pub enum OnExpiry { ToSender = 1, } +/// What a caller supplies when creating a stream. +/// +/// Deliberately *not* [`Milestone`]: it has no `state` field, so there is no way +/// to ask for a milestone that starts already met. Validating that on a shared +/// struct would have been a rejection case to remember; leaving the field out +/// removes the possibility instead. +#[contracttype] +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct MilestoneSpec { + pub amount: i128, + pub approver: Address, + /// Absolute timestamp, or zero for no deadline. Must be `>= end`. + pub deadline: u64, + pub on_expiry: OnExpiry, +} + +impl MilestoneSpec { + pub fn into_milestone(self) -> Milestone { + Milestone { + amount: self.amount, + approver: self.approver, + state: MilestoneState::Unmet, + deadline: self.deadline, + on_expiry: self.on_expiry, + } + } +} + #[contracttype] #[derive(Clone, Debug, PartialEq, Eq)] pub struct Milestone { diff --git a/deployments.json b/deployments.json new file mode 100644 index 0000000..2321973 --- /dev/null +++ b/deployments.json @@ -0,0 +1,33 @@ +{ + "$comment": [ + "Deployed contract addresses. This file is the single source of truth for", + "what is live, and is read by the web app at build time.", + "", + "The contract is non-upgradeable by design, so a new version is always a new", + "address rather than new code at the same one. Superseded entries stay in", + "'history' rather than being deleted: streams created against an old address", + "keep running there, and their holders need to be able to find it." + ], + "testnet": { + "contractId": "CC3XU5QBQE4HSZGIBKV72AHMWFV6756AWRBH7A23FSFOXUG6YE65Z7FO", + "wasmHash": "0ca8aa0998c8336c06d61fdbe8bab83d4f6417d612e794f03c8214d21d8e86aa", + "networkPassphrase": "Test SDF Network ; September 2015", + "rpcUrl": "https://soroban-testnet.stellar.org", + "nativeAssetContract": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC", + "deployedAt": "2026-08-16", + "explorer": "https://stellar.expert/explorer/testnet/contract/CC3XU5QBQE4HSZGIBKV72AHMWFV6756AWRBH7A23FSFOXUG6YE65Z7FO" + }, + "mainnet": null, + "history": [ + { + "network": "testnet", + "contractId": "CAOIDNZEHAAWRVVCM63PUYH2MO3JIYI5XWQ5E55S7SRH2NL2UXZRVRLY", + "superseded": "Setup used a callable `initialize`, leaving a window in which anyone could claim the pauser role permanently. Replaced by a `__constructor` that runs inside the deploy transaction. Never initialized; holds no funds." + }, + { + "network": "testnet", + "contractId": "CBVJPKN2F4HSBYMHFZ2OYECTIQR4KQJPMCURMWRVYCQI7ZHGK2NUHZUF", + "superseded": "`create_stream` took a full Milestone, so callers had to pass a `state` field that could only legally be Unmet. Replaced by MilestoneSpec, which has no such field. Holds no funds." + } + ] +} From b08fda4d8fcd14a99259c9b59083e27fc44cdaea Mon Sep 17 00:00:00 2001 From: Jethro Irmiya Date: Sun, 16 Aug 2026 10:17:25 +0100 Subject: [PATCH 3/8] feat(web): dashboard wired to the deployed contract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Next.js 16 + Tailwind 4, reading the live testnet contract and driving every entry point from the UI: create, withdraw, approve, cancel. Design notes worth keeping: - Accrual animates locally between polls rather than by polling per second. lib/stream.ts is a faithful port of accrual.rs — same clamping, same multiply-before-divide, same end-of-stream special case, same three-way milestone resolution — in BigInt, because stroop amounts pass Number.MAX_SAFE_INTEGER around 900,000 XLM. It is a projection, never a source of truth: anything the user acts on comes from the contract. - The clock is anchored to ledger time, not the browser's. It keeps the offset rather than the absolute value, so a resync corrects drift without the number jumping backwards every poll. - The deposit meter is the one real chart. Palette is validated slots from the data-viz reference — all six checks pass in both modes. Light-mode aqua sits below 3:1 on the light surface, so the relief rule applies: every segment carries a direct label, and identity is never colour alone. - Wallet modules are listed explicitly rather than allowAllModules(), which drags in WalletConnect and Trezor — a large dependency tree declaring peers this app doesn't satisfy, for signing paths nothing here uses. Three bugs found by running it against the real chain rather than by reading: 1. RPC getEvents scans a bounded span per request and returns an EMPTY PAGE PLUS A CURSOR when nothing matches in that chunk — not an error, and not the events further along the requested range. A single wide startLedger query therefore reported "no activity" for a contract with plenty. Now follows cursors, bounded by a page budget. 2. #[contractevent] derives its topic from the struct name in snake_case, so StreamCreated publishes as stream_created. Matching on the Rust type name silently dropped every event — the filter never fired and nothing errored. 3. The meter labelled a cancelled stream's remainder "Unstreamed". That money went back to the sender when accrual froze; the label implied it was still on its way to the recipient. Also closes #10: logo, banner and 1280x640 social preview committed as SVG sources under assets/. The mark is the mechanism rather than a decoration — three streams with the middle one interrupted by a gate, the outer two passing through, which is the design's actual claim. logo.svg and banner.svg use currentColor so one file serves both GitHub themes; the social card commits to a dark ground because a social embed has no inherited colour to take. Verified: typecheck, lint and production build all clean; dashboard exercised in-browser against the live contract. Co-Authored-By: Claude Opus 5 --- .gitignore | 6 + apps/web/app/globals.css | 158 + apps/web/app/layout.tsx | 36 + apps/web/app/page.tsx | 308 + apps/web/components/ActivityFeed.tsx | 65 + apps/web/components/CreateStreamForm.tsx | 352 + apps/web/components/DepositMeter.tsx | 120 + apps/web/components/Header.tsx | 85 + apps/web/components/StreamCard.tsx | 314 + apps/web/components/WalletProvider.tsx | 78 + apps/web/components/ui.tsx | 277 + apps/web/eslint.config.mjs | 13 + apps/web/next.config.ts | 10 + apps/web/package.json | 32 + apps/web/postcss.config.mjs | 3 + apps/web/tsconfig.json | 42 + assets/banner.svg | 61 + assets/logo.svg | 26 + assets/social-preview-src.svg | 70 + assets/social-preview.png | Bin 0 -> 44512 bytes package.json | 11 +- pnpm-lock.yaml | 9325 ++++++++++++++++++++-- pnpm-workspace.yaml | 3 + 23 files changed, 10906 insertions(+), 489 deletions(-) create mode 100644 apps/web/app/globals.css create mode 100644 apps/web/app/layout.tsx create mode 100644 apps/web/app/page.tsx create mode 100644 apps/web/components/ActivityFeed.tsx create mode 100644 apps/web/components/CreateStreamForm.tsx create mode 100644 apps/web/components/DepositMeter.tsx create mode 100644 apps/web/components/Header.tsx create mode 100644 apps/web/components/StreamCard.tsx create mode 100644 apps/web/components/WalletProvider.tsx create mode 100644 apps/web/components/ui.tsx create mode 100644 apps/web/eslint.config.mjs create mode 100644 apps/web/next.config.ts create mode 100644 apps/web/package.json create mode 100644 apps/web/postcss.config.mjs create mode 100644 apps/web/tsconfig.json create mode 100644 assets/banner.svg create mode 100644 assets/logo.svg create mode 100644 assets/social-preview-src.svg create mode 100644 assets/social-preview.png create mode 100644 pnpm-workspace.yaml diff --git a/.gitignore b/.gitignore index 573f9c0..c65f094 100644 --- a/.gitignore +++ b/.gitignore @@ -100,3 +100,9 @@ test_snapshots/ # `pnpm bindings`; committing them would let the checked-in copy drift from the # Wasm actually on chain. packages/stelflow-sdk/ + +# Next.js +.next/ +next-env.d.ts +apps/web/AGENTS.md +apps/web/CLAUDE.md diff --git a/apps/web/app/globals.css b/apps/web/app/globals.css new file mode 100644 index 0000000..23151fe --- /dev/null +++ b/apps/web/app/globals.css @@ -0,0 +1,158 @@ +@import "tailwindcss"; + +/* + StelFlow's surface. + + The docs are deliberately plain — short sentences, no marketing language, a + status banner that says the thing isn't audited. The interface matches that: + restrained, technical, numbers first. Money figures are set in a tabular + monospace so digits line up column-wise and a changing balance doesn't make the + row jitter. + + The three series colours are the validated categorical slots 1, 3 and 7 from + the data-viz reference palette, chosen for meaning rather than order — + withdrawn is settled, claimable is available, held is gated. Both modes were + validated with the palette checker: all six checks pass. Light-mode aqua sits + below 3:1 on the light surface, which obliges the relief rule — every meter + segment carries a visible direct label, so identity is never colour alone. +*/ + +@theme { + --font-sans: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, + "Helvetica Neue", Arial, sans-serif; + --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, + "Liberation Mono", monospace; +} + +:root { + color-scheme: light; + + --surface-0: #f7f7f5; + --surface-1: #fcfcfb; + --surface-2: #f0f0ec; + --surface-3: #e4e4de; + + --text-primary: #0b0b0b; + --text-secondary: #52514e; + --text-muted: #83817a; + + --border: #dedcd4; + --border-strong: #c7c5bb; + + --series-withdrawn: #2a78d6; + --series-claimable: #1baf7a; + --series-held: #4a3aa7; + + --status-good: #008300; + --status-warning: #eda100; + --status-critical: #e34948; + + --focus: #2a78d6; +} + +@media (prefers-color-scheme: dark) { + :root:not([data-theme="light"]) { + color-scheme: dark; + + --surface-0: #101010; + --surface-1: #1a1a19; + --surface-2: #222220; + --surface-3: #2e2e2b; + + --text-primary: #ffffff; + --text-secondary: #c3c2b7; + --text-muted: #8d8b81; + + --border: #302f2c; + --border-strong: #43413c; + + --series-withdrawn: #3987e5; + --series-claimable: #199e70; + --series-held: #9085e9; + + --status-good: #35b135; + --status-warning: #c98500; + --status-critical: #e66767; + + --focus: #3987e5; + } +} + +:root[data-theme="dark"] { + color-scheme: dark; + + --surface-0: #101010; + --surface-1: #1a1a19; + --surface-2: #222220; + --surface-3: #2e2e2b; + + --text-primary: #ffffff; + --text-secondary: #c3c2b7; + --text-muted: #8d8b81; + + --border: #302f2c; + --border-strong: #43413c; + + --series-withdrawn: #3987e5; + --series-claimable: #199e70; + --series-held: #9085e9; + + --status-good: #35b135; + --status-warning: #c98500; + --status-critical: #e66767; + + --focus: #3987e5; +} + +@theme inline { + --color-surface-0: var(--surface-0); + --color-surface-1: var(--surface-1); + --color-surface-2: var(--surface-2); + --color-surface-3: var(--surface-3); + --color-ink: var(--text-primary); + --color-ink-secondary: var(--text-secondary); + --color-ink-muted: var(--text-muted); + --color-edge: var(--border); + --color-edge-strong: var(--border-strong); + --color-withdrawn: var(--series-withdrawn); + --color-claimable: var(--series-claimable); + --color-held: var(--series-held); + --color-good: var(--status-good); + --color-warning: var(--status-warning); + --color-critical: var(--status-critical); +} + +html { + background: var(--surface-0); +} + +body { + background: var(--surface-0); + color: var(--text-primary); + font-family: var(--font-sans); + -webkit-font-smoothing: antialiased; +} + +/* Money and identifiers. Tabular figures stop a live balance from reflowing its + own row every second as digit widths change. */ +.tnum { + font-family: var(--font-mono); + font-variant-numeric: tabular-nums; + font-feature-settings: "tnum" 1; +} + +:focus-visible { + outline: 2px solid var(--focus); + outline-offset: 2px; + border-radius: 3px; +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + animation-duration: 0.01ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.01ms !important; + } +} diff --git a/apps/web/app/layout.tsx b/apps/web/app/layout.tsx new file mode 100644 index 0000000..dc49080 --- /dev/null +++ b/apps/web/app/layout.tsx @@ -0,0 +1,36 @@ +import type { Metadata, Viewport } from "next"; + +import { WalletProvider } from "@/components/WalletProvider"; +import "./globals.css"; + +export const metadata: Metadata = { + title: "StelFlow — payment streaming with milestone gates", + description: + "Stream payments continuously on Stellar, with tranches gated behind milestone approvals. Non-upgradeable, running on testnet.", + applicationName: "StelFlow", + openGraph: { + title: "StelFlow", + description: + "Payment streaming with milestone gates, on Stellar. Non-upgradeable, testnet.", + type: "website", + }, +}; + +export const viewport: Viewport = { + themeColor: [ + { media: "(prefers-color-scheme: light)", color: "#f7f7f5" }, + { media: "(prefers-color-scheme: dark)", color: "#101010" }, + ], +}; + +export default function RootLayout({ + children, +}: Readonly<{ children: React.ReactNode }>) { + return ( + + + {children} + + + ); +} diff --git a/apps/web/app/page.tsx b/apps/web/app/page.tsx new file mode 100644 index 0000000..d3e6c73 --- /dev/null +++ b/apps/web/app/page.tsx @@ -0,0 +1,308 @@ +"use client"; + +import { useCallback, useMemo, useState } from "react"; + +import { ActivityFeed } from "@/components/ActivityFeed"; +import { CreateStreamForm } from "@/components/CreateStreamForm"; +import { Header } from "@/components/Header"; +import { StreamCard } from "@/components/StreamCard"; +import { Badge, Card, CardHeader, EmptyState, Skeleton } from "@/components/ui"; +import { useWallet } from "@/components/WalletProvider"; +import * as actions from "@/lib/actions"; +import { formatAmount } from "@/lib/format"; +import { positionAt } from "@/lib/stream"; +import { useChainState } from "@/lib/use-chain-state"; +import { useLedgerClock } from "@/lib/use-ledger-clock"; + +type Filter = "all" | "mine"; + +export default function Dashboard() { + const { address } = useWallet(); + const now = useLedgerClock(); + + const { streams, activity, pausedUntil, loading, refresh } = useChainState(); + const [busy, setBusy] = useState(null); + const [notice, setNotice] = useState< + { kind: "ok" | "error"; text: string } | null + >(null); + const [filter, setFilter] = useState("all"); + + /** Run a write, then refresh. One place for the busy flag and error surfacing. */ + const run = useCallback( + async (key: string, work: () => Promise) => { + setBusy(key); + setNotice(null); + try { + const text = await work(); + setNotice({ kind: "ok", text }); + await refresh(); + } catch (cause) { + setNotice({ + kind: "error", + text: cause instanceof Error ? cause.message : String(cause), + }); + } finally { + setBusy(null); + } + }, + [refresh], + ); + + const visible = useMemo(() => { + if (filter === "mine" && address) { + return streams.filter( + ({ stream }) => + stream.sender === address || + stream.recipient === address || + stream.milestones.some((m) => m.approver === address), + ); + } + return streams; + }, [streams, filter, address]); + + const totals = useMemo(() => { + if (!now) return null; + return streams.reduce( + (accumulator, { stream }) => { + const position = positionAt(stream, now); + return { + escrowed: accumulator.escrowed + stream.total, + claimable: accumulator.claimable + position.claimable, + held: accumulator.held + position.held, + }; + }, + { escrowed: 0n, claimable: 0n, held: 0n }, + ); + }, [streams, now]); + + const paused = now !== null && pausedUntil > now; + + return ( +
+
+ +
+
+

+ Payment streaming with milestone gates +

+

+ Money moves continuously as the ledger clock advances. Part of a + stream can sit behind a gate that accrues on schedule but stays + unclaimable until a named approver opens it. +

+

+ Running on Stellar testnet with no audit. The contract has no upgrade + function and no admin over funds — the one global role can stop new + streams being created and nothing else. +

+
+ + {totals && streams.length > 0 ? ( +
+ + + + +
+ ) : null} + + {notice ? ( +

+ {notice.text} +

+ ) : null} + +
+
+
+

+ Streams +

+ {address ? ( +
+ {(["all", "mine"] as const).map((option) => ( + + ))} +
+ ) : null} +
+ + {loading || !now ? ( +
+ {[0, 1].map((row) => ( + + ))} +
+ ) : visible.length === 0 ? ( + + + {filter === "mine" + ? "Switch to All to see everything on this contract." + : "Connect a wallet and create the first one."} + + + ) : ( +
    + {visible.map((view) => ( + + void run(`${id}:withdraw`, async () => { + const paid = await actions.withdraw(id, address!); + return `Withdrew ${formatAmount(paid, { maxDecimals: 4 })} XLM.`; + }) + } + onApprove={(id, index) => + void run(`${id}:approve:${index}`, async () => { + await actions.approveMilestone(id, index, address!); + return "Milestone approved. The tranche it held is now claimable."; + }) + } + onCancel={(id) => + void run(`${id}:cancel`, async () => { + const settlement = await actions.cancelStream(id, address!); + return `Cancelled. ${formatAmount(settlement.refund, { maxDecimals: 4 })} XLM returned to the sender; ${formatAmount(settlement.recipient_balance, { maxDecimals: 4 })} XLM stays claimable by the recipient.`; + }) + } + /> + ))} +
+ )} +
+ + +
+ +
+

+ Reads come straight from RPC — there is no indexer behind this yet, so + the activity feed shows only what RPC still retains. Balances between + polls are projected locally using the contract’s own formula and + re-synced against ledger time. +

+
+
+
+ ); +} + +function Summary({ + label, + value, + unit, + swatch, +}: { + label: string; + value: string; + unit?: string; + swatch?: string; +}) { + return ( + +
+ {swatch ? ( + + ) : null} + {label} +
+
+ {value} + {unit ? {unit} : null} +
+
+ ); +} diff --git a/apps/web/components/ActivityFeed.tsx b/apps/web/components/ActivityFeed.tsx new file mode 100644 index 0000000..6fe979c --- /dev/null +++ b/apps/web/components/ActivityFeed.tsx @@ -0,0 +1,65 @@ +"use client"; + +import { activityAmount, describeActivity, type Activity } from "@/lib/events"; +import { formatAmount, relativeTime } from "@/lib/format"; +import { Card, CardHeader, EmptyState, Skeleton } from "./ui"; + +export function ActivityFeed({ + activity, + now, + loading, +}: { + activity: Activity[]; + now: bigint; + loading: boolean; +}) { + return ( + + + {loading && activity.length === 0 ? ( +
+ {[0, 1, 2].map((row) => ( + + ))} +
+ ) : activity.length === 0 ? ( + + Create a stream and its events will appear here. + + ) : ( +
    + {activity.map((event) => { + const amount = activityAmount(event); + return ( +
  • +
    +

    + {describeActivity(event)} +

    +

    + {event.streamId !== undefined ? ( + #{event.streamId.toString()} · + ) : null} + ledger {event.ledger} ·{" "} + {relativeTime(event.at, now)} +

    +
    + {amount !== null ? ( + + {formatAmount(amount, { maxDecimals: 4 })} + + ) : null} +
  • + ); + })} +
+ )} +
+ ); +} diff --git a/apps/web/components/CreateStreamForm.tsx b/apps/web/components/CreateStreamForm.tsx new file mode 100644 index 0000000..1c4e241 --- /dev/null +++ b/apps/web/components/CreateStreamForm.tsx @@ -0,0 +1,352 @@ +"use client"; + +import { useState } from "react"; + +import { NATIVE_ASSET_CONTRACT, type MilestoneSpec } from "@/lib/contract"; +import { formatAmount, parseAmount } from "@/lib/format"; +import { ON_EXPIRY_TO_RECIPIENT, ON_EXPIRY_TO_SENDER } from "@/lib/stream"; +import { Button, Card, CardHeader, Field, Input } from "./ui"; + +const MINUTE = 60n; + +interface MilestoneDraft { + amount: string; + approver: string; + deadlineDays: string; + onExpiry: number; +} + +export function CreateStreamForm({ + sender, + now, + busy, + onSubmit, +}: { + sender: string; + now: bigint; + busy: boolean; + onSubmit: (input: { + recipient: string; + tokenId: string; + amount: bigint; + start: bigint; + end: bigint; + cliff: bigint; + cancelable: boolean; + milestones: MilestoneSpec[]; + }) => void; +}) { + const [recipient, setRecipient] = useState(""); + const [amount, setAmount] = useState("10"); + const [durationMinutes, setDurationMinutes] = useState("60"); + const [cliffMinutes, setCliffMinutes] = useState("0"); + const [cancelable, setCancelable] = useState(true); + const [milestones, setMilestones] = useState([]); + const [error, setError] = useState(null); + + const amountStroops = parseAmount(amount); + const gated = milestones.reduce( + (sum, m) => sum + (parseAmount(m.amount) ?? 0n), + 0n, + ); + + function handleSubmit(event: React.FormEvent) { + event.preventDefault(); + setError(null); + + if (!/^G[A-Z2-7]{55}$/.test(recipient.trim())) { + setError("The recipient must be a Stellar public key (G…)."); + return; + } + if (!amountStroops || amountStroops <= 0n) { + setError("Enter an amount greater than zero."); + return; + } + const duration = BigInt(Number(durationMinutes) || 0) * MINUTE; + if (duration <= 0n) { + setError("The stream needs a duration."); + return; + } + if (gated > amountStroops) { + setError( + `Milestones total ${formatAmount(gated, { maxDecimals: 2 })}, which is more than the deposit. Milestones carve up the deposit; they do not add to it.`, + ); + return; + } + + const start = now; + const end = start + duration; + const cliffOffset = BigInt(Number(cliffMinutes) || 0) * MINUTE; + if (cliffOffset > duration) { + setError("The cliff cannot fall after the stream ends."); + return; + } + + const specs: MilestoneSpec[] = []; + for (const draft of milestones) { + const milestoneAmount = parseAmount(draft.amount); + if (!milestoneAmount || milestoneAmount <= 0n) { + setError("Every milestone needs an amount greater than zero."); + return; + } + if (!/^G[A-Z2-7]{55}$|^C[A-Z2-7]{55}$/.test(draft.approver.trim())) { + setError("Each approver must be a Stellar address (G… or C…)."); + return; + } + const days = Number(draft.deadlineDays) || 0; + // A deadline must fall at or after `end`, so the contract never resolves a + // tranche that is still accruing. Zero means no deadline. + const deadline = days > 0 ? end + BigInt(Math.round(days * 86_400)) : 0n; + specs.push({ + amount: milestoneAmount, + approver: draft.approver.trim(), + deadline, + on_expiry: draft.onExpiry, + }); + } + + onSubmit({ + recipient: recipient.trim(), + tokenId: NATIVE_ASSET_CONTRACT, + amount: amountStroops, + start, + end, + cliff: start + cliffOffset, + cancelable, + milestones: specs, + }); + } + + return ( + + +
+ + setRecipient(e.target.value)} + placeholder="G…" + spellCheck={false} + /> + + +
+ + setAmount(e.target.value)} + /> + + + setDurationMinutes(e.target.value)} + /> + + + setCliffMinutes(e.target.value)} + /> + +
+ + + + + + {gated > 0n && amountStroops ? ( +

+ Base tranche:{" "} + + {formatAmount(amountStroops - gated, { maxDecimals: 4 })} XLM + {" "} + streams unconditionally.{" "} + + {formatAmount(gated, { maxDecimals: 4 })} XLM + {" "} + accrues behind gates. +

+ ) : null} + + {error ? ( +

+ {error} +

+ ) : null} + + + +
+ ); +} + +function MilestoneEditor({ + milestones, + setMilestones, + sender, +}: { + milestones: MilestoneDraft[]; + setMilestones: (next: MilestoneDraft[]) => void; + sender: string; +}) { + return ( +
+
+ + Milestone gates + + +
+ + {milestones.length === 0 ? ( +

+ None. The whole amount streams unconditionally. +

+ ) : ( +
    + {milestones.map((draft, index) => ( +
  • +
    + + + setMilestones( + milestones.map((m, i) => + i === index ? { ...m, amount: e.target.value } : m, + ), + ) + } + /> + + + + setMilestones( + milestones.map((m, i) => + i === index ? { ...m, approver: e.target.value } : m, + ), + ) + } + /> + +
    + +
    + + + setMilestones( + milestones.map((m, i) => + i === index ? { ...m, deadlineDays: e.target.value } : m, + ), + ) + } + /> + + + + +
    + + +
  • + ))} +
+ )} +
+ ); +} diff --git a/apps/web/components/DepositMeter.tsx b/apps/web/components/DepositMeter.tsx new file mode 100644 index 0000000..cacb6ef --- /dev/null +++ b/apps/web/components/DepositMeter.tsx @@ -0,0 +1,120 @@ +/** + * How a deposit is currently divided. + * + * The only real chart in the app, and its job is magnitude-of-parts against a + * known whole, so it is a single stacked bar rather than a pie or a set of + * gauges. Four parts that always sum to the deposit: + * + * withdrawn — already paid out and gone + * claimable — accrued and available right now + * held — accrued but behind a shut milestone gate + * remaining — not yet streamed + * + * `remaining` is the track rather than a fourth series: it is the absence of + * accrual, not a category of it, so it takes a neutral surface and no legend + * entry of its own. + * + * Mark spec applied: 2px surface gaps between segments (which is also the + * secondary encoding that keeps adjacent hues separable without relying on + * colour), rounded ends only on the outermost segments so the bar reads as one + * object, and a direct label under every segment. Those labels are what satisfy + * the relief rule for light-mode aqua, which sits below 3:1 on the light + * surface. + */ + +import { formatAmount, percent } from "@/lib/format"; +import type { Position } from "@/lib/stream"; +import type { Stream } from "@/lib/contract"; +import { depositBreakdown } from "@/lib/stream"; + +const SERIES = [ + { key: "withdrawn", label: "Withdrawn", color: "var(--series-withdrawn)" }, + { key: "claimable", label: "Claimable", color: "var(--series-claimable)" }, + { key: "held", label: "Held", color: "var(--series-held)" }, +] as const; + +export function DepositMeter({ + stream, + position, + showLegend = true, +}: { + stream: Stream; + position: Position; + showLegend?: boolean; +}) { + const parts = depositBreakdown(stream, position); + const amounts = { + withdrawn: stream.withdrawn, + claimable: position.claimable, + held: position.held, + } as const; + + const visible = SERIES.filter(({ key }) => parts[key] > 0); + + return ( +
+
+ `${label} ${percent(parts[key])} (${formatAmount(amounts[key], { maxDecimals: 2 })})`, + ).join(", ")} + > + {visible.map(({ key, label, color }) => ( +
+ ))} +
+ + {showLegend ? ( +
+ {SERIES.map(({ key, label, color }) => ( + + + {label} + + {percent(parts[key], 0)} + + + ))} + {parts.remaining > 0 ? ( + + + {/* + On a cancelled stream this share is not waiting to be streamed — + it went back to the sender when accrual froze. Labelling it + "Unstreamed" would imply money still on its way to the recipient. + */} + + {stream.canceled_at === undefined + ? "Unstreamed" + : "Returned to sender"} + + + {percent(parts.remaining, 0)} + + + ) : null} +
+ ) : null} +
+ ); +} diff --git a/apps/web/components/Header.tsx b/apps/web/components/Header.tsx new file mode 100644 index 0000000..9e159a0 --- /dev/null +++ b/apps/web/components/Header.tsx @@ -0,0 +1,85 @@ +"use client"; + +import { CONTRACT_ID, TESTNET } from "@/lib/contract"; +import { shortAddress } from "@/lib/format"; +import { useWallet } from "./WalletProvider"; +import { Badge, Button } from "./ui"; + +/** + * The mark, drawn inline rather than fetched. + * + * Three streams with the middle one interrupted by a gate — the protocol's + * actual mechanism, and the top and bottom rules passing through uninterrupted + * is the design's real claim: a gate holds its own tranche and reaches nothing + * else. `currentColor` throughout, so it needs no second asset for dark mode. + */ +function Mark({ className }: { className?: string }) { + return ( + + + + + + + + + + ); +} + +export function Header({ paused }: { paused: boolean }) { + const { address, connect, disconnect, connecting, error } = useWallet(); + + return ( +
+
+
+ + + StelFlow + +
+ +
+ Testnet + {paused ? Creation paused : null} +
+ +
+ + {shortAddress(CONTRACT_ID, 6, 6)} + + {address ? ( +
+ + {shortAddress(address, 4, 4)} + + +
+ ) : ( + + )} +
+ + {error ? ( +

{error}

+ ) : null} +
+
+ ); +} diff --git a/apps/web/components/StreamCard.tsx b/apps/web/components/StreamCard.tsx new file mode 100644 index 0000000..ed5cba7 --- /dev/null +++ b/apps/web/components/StreamCard.tsx @@ -0,0 +1,314 @@ +"use client"; + +import { useMemo, useState } from "react"; + +import type { StreamView } from "@/lib/contract"; +import { + absoluteTime, + formatAmount, + relativeTime, + shortAddress, +} from "@/lib/format"; +import { + MILESTONE_MET, + ON_EXPIRY_TO_RECIPIENT, + phaseOf, + positionAt, + resolveMilestone, + settlementAt, + type Phase, +} from "@/lib/stream"; +import { cn } from "@/lib/cn"; +import { DepositMeter } from "./DepositMeter"; +import { Badge, Button, Card, Stat, type BadgeTone } from "./ui"; + +const PHASE_LABEL: Record = { + pending: { text: "Not started", tone: "neutral" }, + cliff: { text: "In cliff", tone: "warning" }, + streaming: { text: "Streaming", tone: "good" }, + completed: { text: "Completed", tone: "neutral" }, + canceled: { text: "Cancelled", tone: "critical" }, +}; + +export type Role = "sender" | "recipient" | "approver" | "observer"; + +export function StreamCard({ + view, + now, + address, + onWithdraw, + onApprove, + onCancel, + busy, +}: { + view: StreamView; + now: bigint; + address: string | null; + onWithdraw: (id: bigint) => void; + onApprove: (id: bigint, index: number) => void; + onCancel: (id: bigint) => void; + busy: string | null; +}) { + const { stream } = view; + const [expanded, setExpanded] = useState(false); + + // Recomputed every tick from the same formula the contract uses, so the figure + // rises second by second without an RPC call per second. + const position = useMemo(() => positionAt(stream, now), [stream, now]); + const phase = phaseOf(stream, now); + const badge = PHASE_LABEL[phase]; + + const isSender = address === stream.sender; + const isRecipient = address === stream.recipient; + const approverIndexes = stream.milestones + .map((milestone, index) => ({ milestone, index })) + .filter(({ milestone }) => milestone.approver === address); + + const live = stream.canceled_at === undefined; + const busyKey = busy?.startsWith(`${stream.id}:`) ? busy : null; + + return ( + +
+
+ #{stream.id.toString()} + {badge.text} + {!stream.cancelable ? ( + + Non-cancelable + + ) : null} + {position.held > 0n ? ( + + {stream.milestones.filter( + (m) => resolveMilestone(m, now) === "withheld", + ).length}{" "} + gate(s) shut + + ) : null} +
+ +
+ +
+
+
+ + {formatAmount(position.claimable, { maxDecimals: 5 })} + + claimable now +
+

+ of {formatAmount(stream.total, { maxDecimals: 2 })} deposited ·{" "} + {phase === "pending" + ? `starts ${relativeTime(stream.start, now)}` + : phase === "completed" || phase === "canceled" + ? `ended ${relativeTime(stream.end, now)}` + : `ends ${relativeTime(stream.end, now)}`} +

+
+ +
+ {isRecipient && live && position.claimable > 0n ? ( + + ) : null} + {approverIndexes + .filter(({ milestone }) => milestone.state !== MILESTONE_MET) + .slice(0, 1) + .map(({ index }) => ( + + ))} + {isSender && live ? ( + + ) : null} + +
+
+ +
+ +
+ + {expanded ? ( +
+ ) : null} + + ); +} + +function RoleTag({ + isSender, + isRecipient, +}: { + isSender: boolean; + isRecipient: boolean; +}) { + if (!isSender && !isRecipient) return null; + return ( + + You are the {isSender ? "sender" : "recipient"} + + ); +} + +function Details({ + view, + now, + position, +}: { + view: StreamView; + now: bigint; + position: ReturnType; +}) { + const { stream } = view; + const settlement = settlementAt(stream, now); + + return ( +
+
+ + + + 0n ? "behind a shut gate" : undefined} + /> +
+ +
+ + + + + {stream.cliff > stream.start ? ( + + ) : null} + {stream.canceled_at !== undefined ? ( + + ) : ( + + )} +
+ + {stream.milestones.length > 0 ? ( +
+

Milestones

+
    + {stream.milestones.map((milestone, index) => { + const resolution = resolveMilestone(milestone, now); + const expiring = milestone.deadline !== 0n; + return ( +
  • +
    + {index} + + {formatAmount(milestone.amount, { maxDecimals: 2 })} + + + {resolution === "released" + ? milestone.state === MILESTONE_MET + ? "Approved" + : "Released by deadline" + : resolution === "returned" + ? "Returned to sender" + : "Awaiting approval"} + +
    +
    + + approver {shortAddress(milestone.approver)} + + {expiring ? ( + + {resolution === "withheld" ? "resolves " : "deadline "} + {relativeTime(milestone.deadline, now)} →{" "} + {milestone.on_expiry === ON_EXPIRY_TO_RECIPIENT + ? "recipient" + : "sender"} + + ) : ( + no deadline + )} +
    +
  • + ); + })} +
+
+ ) : null} +
+ ); +} + +function Row({ + label, + value, + mono, +}: { + label: string; + value: string; + mono?: boolean; +}) { + return ( +
+
{label}
+
{value}
+
+ ); +} diff --git a/apps/web/components/WalletProvider.tsx b/apps/web/components/WalletProvider.tsx new file mode 100644 index 0000000..ea7f26e --- /dev/null +++ b/apps/web/components/WalletProvider.tsx @@ -0,0 +1,78 @@ +"use client"; + +import { + createContext, + useCallback, + useContext, + useEffect, + useMemo, + useState, + type ReactNode, +} from "react"; + +import * as wallet from "@/lib/wallet"; + +interface WalletState { + address: string | null; + connecting: boolean; + connect: () => Promise; + disconnect: () => void; + error: string | null; +} + +const WalletContext = createContext(null); + +export function WalletProvider({ children }: { children: ReactNode }) { + const [address, setAddress] = useState(null); + const [connecting, setConnecting] = useState(false); + const [error, setError] = useState(null); + + // Restore a prior session silently. A missing or locked wallet is an ordinary + // page load, not something to interrupt the visitor about. + useEffect(() => { + let cancelled = false; + void wallet.restore().then((restored) => { + if (!cancelled && restored) setAddress(restored); + }); + return () => { + cancelled = true; + }; + }, []); + + const connect = useCallback(async () => { + setConnecting(true); + setError(null); + try { + const connected = await wallet.connect(); + if (connected) setAddress(connected); + } catch (cause) { + setError( + cause instanceof Error + ? cause.message + : "Could not reach a wallet. Is Freighter installed and unlocked?", + ); + } finally { + setConnecting(false); + } + }, []); + + const disconnect = useCallback(() => { + wallet.disconnect(); + setAddress(null); + }, []); + + const value = useMemo( + () => ({ address, connecting, connect, disconnect, error }), + [address, connecting, connect, disconnect, error], + ); + + return {children}; +} + +export function useWallet(): WalletState { + const context = useContext(WalletContext); + if (!context) { + throw new Error("useWallet must be used inside "); + } + return context; +} diff --git a/apps/web/components/ui.tsx b/apps/web/components/ui.tsx new file mode 100644 index 0000000..c44d662 --- /dev/null +++ b/apps/web/components/ui.tsx @@ -0,0 +1,277 @@ +/** + * Interface primitives. + * + * Small and hand-written rather than pulled from a component library: the whole + * surface is a handful of shapes, and owning them keeps the visual language + * consistent with the docs — restrained, technical, numbers first. + */ + +import type { ButtonHTMLAttributes, InputHTMLAttributes, ReactNode } from "react"; + +import { cn } from "@/lib/cn"; + +// --------------------------------------------------------------------------- + +export function Card({ + children, + className, + as: Tag = "div", +}: { + children: ReactNode; + className?: string; + as?: "div" | "section" | "article" | "li"; +}) { + return ( + + {children} + + ); +} + +export function CardHeader({ + title, + hint, + actions, +}: { + title: ReactNode; + hint?: ReactNode; + actions?: ReactNode; +}) { + return ( +
+
+

{title}

+ {hint ?

{hint}

: null} +
+ {actions ?
{actions}
: null} +
+ ); +} + +// --------------------------------------------------------------------------- + +type ButtonVariant = "primary" | "secondary" | "ghost" | "danger"; + +const BUTTON_STYLES: Record = { + primary: + "bg-ink text-surface-1 hover:opacity-90 disabled:opacity-40 border border-transparent", + secondary: + "bg-surface-2 text-ink border border-edge hover:border-edge-strong disabled:opacity-40", + ghost: + "bg-transparent text-ink-secondary border border-transparent hover:bg-surface-2 disabled:opacity-40", + danger: + "bg-transparent text-[var(--status-critical)] border border-[var(--status-critical)] hover:bg-[var(--status-critical)]/10 disabled:opacity-40", +}; + +export function Button({ + variant = "secondary", + className, + busy, + children, + ...props +}: ButtonHTMLAttributes & { + variant?: ButtonVariant; + busy?: boolean; +}) { + return ( + + ); +} + +function Spinner() { + return ( + + ); +} + +// --------------------------------------------------------------------------- + +export function Field({ + label, + hint, + error, + children, +}: { + label: string; + hint?: ReactNode; + error?: string | null; + children: ReactNode; +}) { + return ( + + ); +} + +export function Input({ + className, + mono, + ...props +}: InputHTMLAttributes & { mono?: boolean }) { + return ( + + ); +} + +// --------------------------------------------------------------------------- + +export type BadgeTone = "neutral" | "good" | "warning" | "critical" | "held"; + +const BADGE_TONES: Record = { + neutral: "text-ink-secondary bg-surface-2 border-edge", + good: "text-[var(--status-good)] bg-[var(--status-good)]/10 border-[var(--status-good)]/25", + warning: + "text-[var(--status-warning)] bg-[var(--status-warning)]/10 border-[var(--status-warning)]/25", + critical: + "text-[var(--status-critical)] bg-[var(--status-critical)]/10 border-[var(--status-critical)]/25", + held: "text-held bg-held/10 border-held/25", +}; + +/** + * A status chip. + * + * Always carries its label — status is never communicated by colour alone, + * which is also what keeps it legible under forced-colors and to a + * colour-blind reader. + */ +export function Badge({ + tone = "neutral", + children, + className, + title, +}: { + tone?: BadgeTone; + children: ReactNode; + className?: string; + title?: string; +}) { + return ( + + {children} + + ); +} + +// --------------------------------------------------------------------------- + +/** + * A labelled figure. + * + * The value wears a text token, never a series colour — a colour swatch beside + * the label carries identity instead, so the number stays readable at any + * contrast. + */ +export function Stat({ + label, + value, + unit, + swatch, + detail, +}: { + label: string; + value: ReactNode; + unit?: string; + swatch?: string; + detail?: ReactNode; +}) { + return ( +
+
+ {swatch ? ( + + ) : null} + {label} +
+
+ {value} + {unit ? {unit} : null} +
+ {detail ? ( +
{detail}
+ ) : null} +
+ ); +} + +// --------------------------------------------------------------------------- + +export function EmptyState({ + title, + children, +}: { + title: string; + children?: ReactNode; +}) { + return ( +
+

{title}

+ {children ? ( +
{children}
+ ) : null} +
+ ); +} + +export function Skeleton({ className }: { className?: string }) { + return ( +
+ ); +} diff --git a/apps/web/eslint.config.mjs b/apps/web/eslint.config.mjs new file mode 100644 index 0000000..bb87308 --- /dev/null +++ b/apps/web/eslint.config.mjs @@ -0,0 +1,13 @@ +import coreWebVitals from "eslint-config-next/core-web-vitals"; +import typescript from "eslint-config-next/typescript"; + +// eslint-config-next 16 ships native flat configs. The older `FlatCompat` shim +// cannot load them — it JSON-stringifies the config to validate it, and the +// plugin graph contains a cycle. +const config = [ + ...coreWebVitals, + ...typescript, + { ignores: [".next/**", "node_modules/**", "next-env.d.ts"] }, +]; + +export default config; diff --git a/apps/web/next.config.ts b/apps/web/next.config.ts new file mode 100644 index 0000000..0787a43 --- /dev/null +++ b/apps/web/next.config.ts @@ -0,0 +1,10 @@ +import type { NextConfig } from "next"; + +const nextConfig: NextConfig = { + reactStrictMode: true, + // The generated contract bindings ship as TypeScript source rather than a + // built package, so Next has to compile them alongside the app. + transpilePackages: ["stelflow-sdk"], +}; + +export default nextConfig; diff --git a/apps/web/package.json b/apps/web/package.json new file mode 100644 index 0000000..792b139 --- /dev/null +++ b/apps/web/package.json @@ -0,0 +1,32 @@ +{ + "name": "@stelflow/web", + "version": "0.1.0", + "private": true, + "scripts": { + "dev": "next dev", + "build": "next build", + "start": "next start", + "lint": "eslint .", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@creit.tech/stellar-wallets-kit": "^1.7.4", + "@stellar/stellar-sdk": "^14.2.0", + "clsx": "^2.1.1", + "next": "16.3.1", + "react": "^19.2.0", + "react-dom": "^19.2.0", + "tailwind-merge": "^3.3.1", + "stelflow-sdk": "workspace:*" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.3.3", + "@types/node": "^24.7.0", + "@types/react": "^19.2.0", + "@types/react-dom": "^19.2.0", + "eslint": "^9.38.0", + "eslint-config-next": "16.3.1", + "tailwindcss": "^4.3.3", + "typescript": "^5.9.3" + } +} diff --git a/apps/web/postcss.config.mjs b/apps/web/postcss.config.mjs new file mode 100644 index 0000000..a898ee3 --- /dev/null +++ b/apps/web/postcss.config.mjs @@ -0,0 +1,3 @@ +const config = { plugins: { "@tailwindcss/postcss": {} } }; + +export default config; diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json new file mode 100644 index 0000000..54620f5 --- /dev/null +++ b/apps/web/tsconfig.json @@ -0,0 +1,42 @@ +{ + "compilerOptions": { + "target": "ES2022", + "lib": [ + "dom", + "dom.iterable", + "esnext" + ], + "allowJs": false, + "skipLibCheck": true, + "strict": true, + "noUncheckedIndexedAccess": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "react-jsx", + "incremental": true, + "plugins": [ + { + "name": "next" + } + ], + "paths": { + "@/*": [ + "./*" + ] + } + }, + "include": [ + "next-env.d.ts", + "**/*.ts", + "**/*.tsx", + ".next/types/**/*.ts", + ".next/dev/types/**/*.ts" + ], + "exclude": [ + "node_modules" + ] +} diff --git a/assets/banner.svg b/assets/banner.svg new file mode 100644 index 0000000..1e5bbcb --- /dev/null +++ b/assets/banner.svg @@ -0,0 +1,61 @@ + + StelFlow — payment streaming with milestone gates, on Stellar + + + + + + + + + + + + + StelFlow + + payment streaming with milestone gates, on Stellar + + + testnet · non-upgradeable · unaudited + + + + + + + + + diff --git a/assets/logo.svg b/assets/logo.svg new file mode 100644 index 0000000..505f5dd --- /dev/null +++ b/assets/logo.svg @@ -0,0 +1,26 @@ + + StelFlow + + + + + + + + + + diff --git a/assets/social-preview-src.svg b/assets/social-preview-src.svg new file mode 100644 index 0000000..564b328 --- /dev/null +++ b/assets/social-preview-src.svg @@ -0,0 +1,70 @@ + + StelFlow — payment streaming with milestone gates, on Stellar + + + + + + + + + + + + + + + + + + + + StelFlow + + payment streaming with milestone gates, on Stellar + + + + + + + + + + + + withdrawn + + claimable + + held + + unstreamed + + + testnet · non-upgradeable · unaudited + diff --git a/assets/social-preview.png b/assets/social-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..b7ca00d935a24a21c38c7d018f8a9a54603fd236 GIT binary patch literal 44512 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%0D08x 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 vgZ_V8b2s?u2^Y}N|Hlr<|J>gHy(e{jSBNX= 8'} + '@albedo-link/intent@0.12.0': + resolution: {integrity: sha512-UlGBhi0qASDYOjLrOL4484vQ26Ee3zTK2oAgvPMClOs+1XNk3zbs3dECKZv+wqeSI8SkHow8mXLTa16eVh+dQA==} - '@nodelib/fs.stat@2.0.5': - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} + '@alloc/quick-lru@5.2.0': + resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==} + engines: {node: '>=10'} - '@nodelib/fs.walk@1.2.8': - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} - '@sindresorhus/merge-streams@4.0.0': - resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} - engines: {node: '>=18'} + '@babel/compat-data@7.29.7': + resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} + engines: {node: '>=6.9.0'} - '@types/debug@4.1.13': - resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + '@babel/core@7.29.7': + resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} + engines: {node: '>=6.9.0'} - '@types/katex@0.16.8': - resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + '@babel/generator@7.29.8': + resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} + engines: {node: '>=6.9.0'} - '@types/ms@2.1.0': - resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + '@babel/helper-compilation-targets@7.29.7': + resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} + engines: {node: '>=6.9.0'} - '@types/unist@2.0.11': - resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + '@babel/helper-globals@7.29.7': + resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} + engines: {node: '>=6.9.0'} - ansi-regex@6.3.0: - resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} - engines: {node: '>=12'} + '@babel/helper-module-imports@7.29.7': + resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} + engines: {node: '>=6.9.0'} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + '@babel/helper-module-transforms@7.29.7': + resolution: {integrity: sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 - braces@3.0.3: - resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} - engines: {node: '>=8'} + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} - character-entities-legacy@3.0.0: - resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} - character-entities@2.0.2: - resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + '@babel/helper-validator-option@7.29.7': + resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} + engines: {node: '>=6.9.0'} - character-reference-invalid@2.0.1: - resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + '@babel/helpers@7.29.7': + resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} + engines: {node: '>=6.9.0'} - commander@8.3.0: - resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} - engines: {node: '>= 12'} + '@babel/parser@7.29.8': + resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} + engines: {node: '>=6.0.0'} + hasBin: true - debug@4.4.3: - resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true + '@babel/runtime@7.29.7': + resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} + engines: {node: '>=6.9.0'} - decode-named-character-reference@1.3.0: - resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + '@babel/template@7.29.7': + resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} + engines: {node: '>=6.9.0'} - dequal@2.0.3: - resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} - engines: {node: '>=6'} + '@babel/traverse@7.29.8': + resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} + engines: {node: '>=6.9.0'} - devlop@1.1.0: - resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} - entities@4.5.0: - resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} - engines: {node: '>=0.12'} + '@creit.tech/stellar-wallets-kit@1.9.5': + resolution: {integrity: sha512-b9E77r+o6Opow0CttmHdFBPeJpdLhOcLFTx3CbnwMQVivo94niap70y3A03F5cYgwVk9HhM4CJr0aimm0eNwxA==} + engines: {node: '>=16'} + peerDependencies: + '@stellar/stellar-base': ^14.0.0 - fast-glob@3.3.3: - resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} - engines: {node: '>=8.6.0'} + '@creit.tech/xbull-wallet-connect@0.4.0': + resolution: {integrity: sha512-LrCUIqUz50SkZ4mv2hTqSmwews8CNRYVoZ9+VjLsK/1U8PByzXTxv1vZyenj6avRTG86ifpoeihz7D3D5YIDrQ==} + engines: {node: '>=16'} - fastq@1.20.1: - resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} - fill-range@7.1.1: - resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} - engines: {node: '>=8'} + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} - get-east-asian-width@1.6.0: - resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} - engines: {node: '>=18'} + '@emnapi/runtime@1.11.3': + resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} - glob-parent@5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} - globby@16.2.2: - resolution: {integrity: sha512-NLvV9ubZ6NDsJaOpKPy3cQeJpKi9DcWiyCiFUpJPA0YihRqiE6RWaLUmgNNPr8MgPpLZjnBjSmou7uZBRJv9wA==} - engines: {node: '>=20'} + '@emurgo/cardano-serialization-lib-browser@13.2.1': + resolution: {integrity: sha512-7RfX1gI16Vj2DgCp/ZoXqyLAakWo6+X95ku/rYGbVzuS/1etrlSiJmdbmdm+eYmszMlGQjrtOJQeVLXoj4L/Ag==} - ignore@7.0.6: - resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} - engines: {node: '>= 4'} + '@emurgo/cardano-serialization-lib-nodejs@13.2.0': + resolution: {integrity: sha512-Bz1zLGEqBQ0BVkqt1OgMxdBOE3BdUWUd7Ly9Ecr/aUwkA8AV1w1XzBMe4xblmJHnB1XXNlPH4SraXCvO+q0Mig==} - is-alphabetical@2.0.1: - resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + '@eslint-community/eslint-utils@4.10.1': + resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - is-alphanumerical@2.0.1: - resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - is-decimal@2.0.1: - resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - is-extglob@2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - is-glob@4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - is-hexadecimal@2.0.1: - resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - is-number@7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} + '@eslint/eslintrc@3.3.6': + resolution: {integrity: sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - is-path-inside@4.0.0: - resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} - engines: {node: '>=12'} + '@eslint/js@9.39.5': + resolution: {integrity: sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - js-yaml@5.2.2: - resolution: {integrity: sha512-dayzUzKkJ1MkuUtZglSebU43utNXH0OWQByK9rKOOuYIO8M5TV1y+n8ALMdG0rdzBnfNkOmZEqrURepb0ejqBw==} - hasBin: true + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - jsonc-parser@3.3.1: - resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - jsonpointer@5.0.1: - resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} - engines: {node: '>=0.10.0'} + '@ethereumjs/common@10.1.2': + resolution: {integrity: sha512-whWnhqAxwpDy4zWkM6rqMzb8nioZJpiys01N57+HDyanvK5IRzodV5tdMRDt66PD5vDjl2c9K5UcB039gU2Oyw==} - katex@0.16.47: - resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} + '@ethereumjs/rlp@10.1.2': + resolution: {integrity: sha512-T5Zt6C2pd02Wd88Q9A5/UX+He1Q2Y1LntHxz/038tfbUMiqby4fYSSTLEDx+TEfJqw1BsJSBY/TSu6goUzlk+w==} + engines: {node: '>=20'} hasBin: true - linkify-it@5.0.2: - resolution: {integrity: sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==} + '@ethereumjs/tx@10.1.2': + resolution: {integrity: sha512-bAYK3YaYkk+auzxGfZSRVDbLHvboJNTx8/tV6jaqgPVlrA1QKEEADDEp/EGz+KI4NQmTGxEtXZ8tV/WjniRNww==} + engines: {node: '>=20'} - markdown-it@14.3.0: - resolution: {integrity: sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==} - hasBin: true + '@ethereumjs/util@10.1.2': + resolution: {integrity: sha512-UPBgXtHHfQugoXOSAoeG3jdmPbl37cwV9y3XqTPAnw8tJj8np14TPV2uc5lOs7C2LMF9Ubn66zyaiYxgwGppng==} + engines: {node: '>=20'} - markdownlint-cli2-formatter-default@0.0.6: - resolution: {integrity: sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ==} - peerDependencies: - markdownlint-cli2: '>=0.0.4' + '@fivebinaries/coin-selection@3.0.0': + resolution: {integrity: sha512-h25Pn1ZA7oqQBQDodGAgIsQt66T2wDge9onBKNqE66WNWL0KJiKJbpij8YOLo5AAlEIg5IS7EB1QjBgDOIg6DQ==} - markdownlint-cli2@0.23.2: - resolution: {integrity: sha512-eUhcnkSpzURo/o4htSqc7LPDszgOOTknhU4eY/sPHvMCLxnTCYscv1gw1/js/idmaZPisv9ECVEIORcllqjTUw==} - engines: {node: '>=22'} - hasBin: true + '@hot-wallet/sdk@1.0.11': + resolution: {integrity: sha512-qRDH/4yqnRCnk7L/Qd0/LDOKDUKWcFgvf6eRELJkP0OgxIe65i/iXaG+u2lL0mLbTGkiWYk67uAvEerNUv2gzA==} - markdownlint@0.41.1: - resolution: {integrity: sha512-qHKeU2E1bdyNAT077go2FVTNXvYcktN5IHtF6XyeD1l0PClxzSp2tUApAV14ORI8DGX4H9bNKZEzelZp4qn8IA==} - engines: {node: '>=22'} + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} - mdurl@2.1.0: - resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==} + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} - merge2@1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} - micromark-core-commonmark@2.0.3: - resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} - micromark-extension-directive@4.0.0: - resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} - micromark-extension-gfm-autolink-literal@2.1.0: - resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} - micromark-extension-gfm-footnote@2.1.0: - resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + '@img/sharp-darwin-arm64@0.35.3': + resolution: {integrity: sha512-RMnFX7YQsMoh7lWfcM4NEHHymBX/rLuKNPVM84XE9ONPcaSCDgE7CHIHpSgPcO2xcRthgBy1HfNO319mwhIAkg==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.35.3': + resolution: {integrity: sha512-Xo+5uFBtLN0BKqieTxiFzFPQAUlBbbH5iBKyRX/z1JrbnYsHTfKJnUfL8+p2TPXr1pXqao4eeL4Rl144uDpK9w==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [darwin] + + '@img/sharp-freebsd-wasm32@0.35.3': + resolution: {integrity: sha512-lUxcqWIj2wMQ9BrwNjngcr1gWUr5xgaGThBRqPPalIC2n67Cqj1uPh8NnA/ZhAg8hUbKl+kVHKwgUIwe6ZYPrg==} + engines: {node: '>=20.9.0'} + os: [freebsd] + + '@img/sharp-libvips-darwin-arm64@1.3.2': + resolution: {integrity: sha512-9J6ypZFpQBj4YnePGoq/S38w6nz+vqg5WZLrLGY4YuSemdMq47GMLBPO42MzwdGwpg/agZ7xzZcFHa48xlywfg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.3.2': + resolution: {integrity: sha512-m2pW1n6cns9VaubNwsZ+c3CRYjxNQWgJ5gPlnL1nbBcpkBvFm6SCFN5o0psFHI8w9n11NKhFkeEDns98tiqbEw==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.3.2': + resolution: {integrity: sha512-dqVSFynCox4C/J8kT16V7SIFAns0IjgLwkvYT7p8LQVmJ5OS5b6tI9IGflxTeuBS//zXeFIUbwt5dwxyZ17cnA==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.3.2': + resolution: {integrity: sha512-1eMLzy92I4J6rmi4mAT8yC3HxOtniyGELlzGbNMLLeqe052ahFQ0h6LFq+lh5DsDIdYViIDst08abvSbcEdLXQ==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.3.2': + resolution: {integrity: sha512-3z0NHDxD6n5I9gc05U1eW1AyRm+Gznzq3naMrthPNqE6oYykcogW0l/jfpJdjYnuNl8R7yI9pNbE1XiUeyq0Aw==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.3.2': + resolution: {integrity: sha512-bsb4rI+NldGOsXuej2r8OdSS8+zXDVaCWxyWrcv6kneTOlgAHtZABRzBBCwdsPiD90J4myNJuHpg6kA20ImW/w==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.3.2': + resolution: {integrity: sha512-/ABshyj8gCpyIrNXnHn4LorDJ0HHm1VhXPBlxZ8zAtfVPAaSafXPGn+sUSIRiwaSBy0mmFjSjiXI5mkcwdChKQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.3.2': + resolution: {integrity: sha512-ITPEtgffGJ0S6G9dRyw/366tJQqFRcHWPHhC+Stpg3Z8AEMrDrTr2lhdz4f/Y/HMbRh//7Z5mBzEpVdi62Oc3w==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + resolution: {integrity: sha512-zE9EdiUzUmg5mDT5a1rk5fYJ6GWPloTwWBYDS14naqHsL+EaMpDj1AWnpLgh3u0YCORv2Tt50wrcrpYqkP97Kw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + resolution: {integrity: sha512-m0lrLiUt+lBYnCFr8qV/65yMR4E/c7/wf78I5eKTdkEakFAlZ9QlzEM3QIhhAwVeUhLAHLcCq7a7Vszq/oFNZQ==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.35.3': + resolution: {integrity: sha512-QgKDspHPnrU+GQ55XPhGwyhC8acLVOOSyAvo1oVfFmrIXLkDNmGWzAfDZ4xK8oSA1qBQrALcHX0G5UZni/SuFQ==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.35.3': + resolution: {integrity: sha512-affVWCTLooy8TSxbDx2qkzuDeaWLNVBA+P//FNBirHsXpP2fuBhk5AuboYUnrDnzoXes8GFjpTx0SBFOCRg+FA==} + engines: {node: '>=20.9.0'} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.35.3': + resolution: {integrity: sha512-sMd8rDxmpLOwv/7N44klFjOD5DUO7FLdjiXDI0hoxYaf7Ar262dQIEkosE98bps+5HPLtp/EvNqeqQtOycP/IA==} + engines: {node: '>=20.9.0'} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.35.3': + resolution: {integrity: sha512-0Eob78yjlYPfL5vMNWAW55l3R9Y6BQS/gOfe0ZcP9mEz9ohhKSt4im1hayiknXgf8AWrFqMvJcKIdmLmEe7yeQ==} + engines: {node: '>=20.9.0'} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.35.3': + resolution: {integrity: sha512-KgAxQ0DxpNOq1rG2t5cgTgShJFGSuU7XO45cqC+1NVOuZnP6tlgZRuSYOfNupGkHID0o3cJOsw4DVeJpMovcGw==} + engines: {node: '>=20.9.0'} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.35.3': + resolution: {integrity: sha512-8pqvxubL2PGdhlPy6GLqzDYMUjyRmKAwKHYKixpdJYBUK7PJ0C029XdsnpFIdgRZG68fZiGdHVWcKPvtiPB4cA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.35.3': + resolution: {integrity: sha512-Vz0iQjzzcSX3HCbfwFfCSG/9SCIqyO0mH2sXyiHaAYfBk0cRsCWXRyQYX0ovCK/PAQBbTzQ0dsPQHh5MAFL59w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.35.3': + resolution: {integrity: sha512-6O1NPKcDVj9QEdg7Hx549EX8U0rp6yXQERqru6yRN7fGBn32UvIRJUlWnk+8xDCiG76hXVBbX82NZ/ZKr0euIg==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.35.3': + resolution: {integrity: sha512-cZ0XkcYGpHZkqW6iCkqTcmUC0CD9DhD5d/qeZlZkfRBn6GnHniZXLUo5+9xw8Iv76YE6LQFN9YNBlKREcCG76w==} + engines: {node: '>=20.9.0'} + + '@img/sharp-webcontainers-wasm32@0.35.3': + resolution: {integrity: sha512-2rnq7bX3NzeR2T4YWgz8qiG4h3TSdMe+vN1iQXpJleSJ3SM5zQ8Fy2SyyXAWlbxpEZ2Y+Z4u1BePgJEYbSy80Q==} + engines: {node: '>=20.9.0'} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.35.3': + resolution: {integrity: sha512-4bPwFdMbeC4JQ8L8LOyWp6nsHcboP5fxkp6iPOXz2Vg49R42TuMs2whkJ5OAP4/Ul035qOzy0AecOF9VOscn4w==} + engines: {node: '>=20.9.0'} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.35.3': + resolution: {integrity: sha512-r53mXsBN6lFUDiST764SvgwUdHAqM4rPAiDzAmf4fLoB6X/rkfyTrLCg6+g17wJJiCmB3JYgHuUldCWUIRFSXw==} + engines: {node: ^20.9.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.35.3': + resolution: {integrity: sha512-D4y1vNeZrIIJCN+uHaWVtH86B+aCrdMYYjicy9pXHvbGZeGYLLSd3wdVuC37FxVXlU1ARsk84eKWfWMXGYEqvA==} + engines: {node: '>=20.9.0'} + cpu: [x64] + os: [win32] + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@ledgerhq/devices@8.17.0': + resolution: {integrity: sha512-l+rrVQEjR1hSWOLD00LFX4zbS8yB1M/Mb6UYPmSHGO7TmE1CFbZ4CmDJC/kZSl3hdrXCJ+YUNpvaLCcSWDwA+Q==} + + '@ledgerhq/errors@6.37.0': + resolution: {integrity: sha512-T5yiKI5UX7ugeocdTF3TUsCIN2BH41Bio4ZeN410YFjFOf3es08n/5JyMzzKwzRgP0blG3HfBf7s7vJKqCSAeg==} + + '@ledgerhq/hw-app-str@7.0.4': + resolution: {integrity: sha512-ArKnGCZaGnUPqoKaR9OE+ZGcGARKJLHthl/aybQWOIo952+cQpgcn0mg5yK1Amd9EiKfArCTlLJ3wAafO5d/lw==} - micromark-extension-gfm-table@2.1.1: - resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + '@ledgerhq/hw-transport-webusb@6.29.4': + resolution: {integrity: sha512-HoGF1LlBT9HEGBQy2XeCHrFdv/FEOZU0+J+yfKcgAQIAiASr2MLvdzwoJbUS8h6Gn+vc+/BjzBSO3JNn7Loqbg==} - micromark-extension-math@3.1.0: - resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + '@ledgerhq/hw-transport@6.31.4': + resolution: {integrity: sha512-6c1ir/cXWJm5dCWdq55NPgCJ3UuKuuxRvf//Xs36Bq9BwkV2YaRQhZITAkads83l07NAdR16hkTWqqpwFMaI6A==} - micromark-factory-destination@2.0.1: - resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + '@ledgerhq/logs@6.17.0': + resolution: {integrity: sha512-yra33g5q/AU7+PwAws+GaVpQGUuxnDREjVBnviJjcaJLVKuLzI4pnj8Bd3nY3fypM5k1yZEYKEXfUuGFUjP2+w==} - micromark-factory-label@2.0.1: - resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + '@lit-labs/ssr-dom-shim@1.6.0': + resolution: {integrity: sha512-VHb0ALPMTlgKjM6yIxxoQNnpKyUKLD04VzeQdsiXkMqkvYlAHxq9glGLmgbb889/1GsohSOAjvQYoiBppXFqrQ==} - micromark-factory-space@2.0.1: - resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + '@lit/reactive-element@1.6.3': + resolution: {integrity: sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==} - micromark-factory-title@2.0.1: - resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + '@lit/reactive-element@2.1.2': + resolution: {integrity: sha512-pbCDiVMnne1lYUIaYNN5wrwQXDtHaYtg7YEFPeW+hws6U47WeFvISGUWekPGKWOP1ygrs0ef0o1VJMk1exos5A==} - micromark-factory-whitespace@2.0.1: - resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + '@lobstrco/signer-extension-api@1.0.0-beta.0': + resolution: {integrity: sha512-16V34W9MyTgunGvgkzv1JmV+k59OjNWCrNOH+KH+6vWamcGDGBnFhvRgGEarEhINYITMGkdqEvaEy7qTD5s5cw==} - micromark-util-character@2.1.1: - resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + '@mobily/ts-belt@3.13.1': + resolution: {integrity: sha512-K5KqIhPI/EoCTbA6CGbrenM9s41OouyK8A03fGJJcla/zKucsgLbz8HNbeseoLarRPgyWJsUyCYqFhI7t3Ra9Q==} + engines: {node: '>= 10.*'} - micromark-util-chunked@2.0.1: - resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + '@motionone/animation@10.18.0': + resolution: {integrity: sha512-9z2p5GFGCm0gBsZbi8rVMOAJCtw1WqBTIPw3ozk06gDvZInBPIsQcHgYogEJ4yuHJ+akuW8g1SEIOpTOvYs8hw==} - micromark-util-classify-character@2.0.1: - resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + '@motionone/dom@10.18.0': + resolution: {integrity: sha512-bKLP7E0eyO4B2UaHBBN55tnppwRnaE3KFfh3Ps9HhnAkar3Cb69kUCJY9as8LrccVYKgHA+JY5dOQqJLOPhF5A==} - micromark-util-combine-extensions@2.0.1: - resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + '@motionone/easing@10.18.0': + resolution: {integrity: sha512-VcjByo7XpdLS4o9T8t99JtgxkdMcNWD3yHU/n6CLEz3bkmKDRZyYQ/wmSf6daum8ZXqfUAgFeCZSpJZIMxaCzg==} - micromark-util-decode-numeric-character-reference@2.0.2: - resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + '@motionone/generators@10.18.0': + resolution: {integrity: sha512-+qfkC2DtkDj4tHPu+AFKVfR/C30O1vYdvsGYaR13W/1cczPrrcjdvYCj0VLFuRMN+lP1xvpNZHCRNM4fBzn1jg==} - micromark-util-encode@2.0.1: - resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + '@motionone/svelte@10.16.4': + resolution: {integrity: sha512-zRVqk20lD1xqe+yEDZhMYgftsuHc25+9JSo+r0a0OWUJFocjSV9D/+UGhX4xgJsuwB9acPzXLr20w40VnY2PQA==} - micromark-util-html-tag-name@2.0.1: - resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + '@motionone/types@10.17.1': + resolution: {integrity: sha512-KaC4kgiODDz8hswCrS0btrVrzyU2CSQKO7Ps90ibBVSQmjkrt2teqta6/sOG59v7+dPnKMAg13jyqtMKV2yJ7A==} - micromark-util-normalize-identifier@2.0.1: - resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + '@motionone/utils@10.18.0': + resolution: {integrity: sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw==} - micromark-util-resolve-all@2.0.1: - resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + '@motionone/vue@10.16.4': + resolution: {integrity: sha512-z10PF9JV6SbjFq+/rYabM+8CVlMokgl8RFGvieSGNTmrkQanfHn+15XBrhG3BgUfvmTeSeyShfOHpG0i9zEdcg==} + deprecated: Motion One for Vue is deprecated. Use Oku Motion instead https://oku-ui.com/motion - micromark-util-sanitize-uri@2.0.1: - resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + '@napi-rs/wasm-runtime@1.2.3': + resolution: {integrity: sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 - micromark-util-subtokenize@2.1.0: - resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + '@near-js/accounts@1.4.1': + resolution: {integrity: sha512-ni3QT9H3NdrbVVKyx56yvz93r89Dvpc/vgVtiIK2OdXjkK6jcj+UKMDRQ6F7rd9qJOInLkHZbVBtcR6j1CXLjw==} - micromark-util-symbol@2.0.1: - resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + '@near-js/crypto@1.4.2': + resolution: {integrity: sha512-GRfchsyfWvSAPA1gI9hYhw5FH94Ac1BUo+Cmp5rSJt/V0K3xVzCWgOQxvv4R3kDnWjaXJEuAmpEEnr4Bp3FWrA==} - micromark-util-types@2.0.2: - resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + '@near-js/keystores-browser@0.2.2': + resolution: {integrity: sha512-Pxqm7WGtUu6zj32vGCy9JcEDpZDSB5CCaLQDTQdF3GQyL0flyRv2I/guLAgU5FLoYxU7dJAX9mslJhPW7P2Bfw==} - micromark@4.0.2: - resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + '@near-js/keystores-node@0.1.2': + resolution: {integrity: sha512-MWLvTszZOVziiasqIT/LYNhUyWqOJjDGlsthOsY6dTL4ZcXjjmhmzrbFydIIeQr+CcEl5wukTo68ORI9JrHl6g==} - micromatch@4.0.8: - resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} - engines: {node: '>=8.6'} + '@near-js/keystores@0.2.2': + resolution: {integrity: sha512-DLhi/3a4qJUY+wgphw2Jl4S+L0AKsUYm1mtU0WxKYV5OBwjOXvbGrXNfdkheYkfh3nHwrQgtjvtszX6LrRXLLw==} - ms@2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + '@near-js/providers@1.0.3': + resolution: {integrity: sha512-VJMboL14R/+MGKnlhhE3UPXCGYvMd1PpvF9OqZ9yBbulV7QVSIdTMfY4U1NnDfmUC2S3/rhAEr+3rMrIcNS7Fg==} - parse-entities@4.0.2: - resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + '@near-js/signers@0.2.2': + resolution: {integrity: sha512-M6ib+af9zXAPRCjH2RyIS0+RhCmd9gxzCeIkQ+I2A3zjgGiEDkBZbYso9aKj8Zh2lPKKSH7h+u8JGymMOSwgyw==} - picomatch@2.3.2: - resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} - engines: {node: '>=8.6'} + '@near-js/transactions@1.3.3': + resolution: {integrity: sha512-1AXD+HuxlxYQmRTLQlkVmH+RAmV3HwkAT8dyZDu+I2fK/Ec9BQHXakOJUnOBws3ihF+akQhamIBS5T0EXX/Ylw==} - punycode.js@2.3.1: - resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} - engines: {node: '>=6'} + '@near-js/types@0.3.1': + resolution: {integrity: sha512-8qIA7ynAEAuVFNAQc0cqz2xRbfyJH3PaAG5J2MgPPhD18lu/tCGd6pzYg45hjhtiJJRFDRjh/FUWKS+ZiIIxUw==} - queue-microtask@1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + '@near-js/utils@1.1.0': + resolution: {integrity: sha512-5XWRq7xpu8Wud9pRXe2U347KXyi0mXofedUY2DQ9TaqiZUcMIaN9xj7DbCs2v6dws3pJyYrT1KWxeNp5fSaY3w==} - reusify@1.1.0: - resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + '@near-js/wallet-account@1.3.3': + resolution: {integrity: sha512-GDzg/Kz0GBYF7tQfyQQQZ3vviwV8yD+8F2lYDzsWJiqIln7R1ov0zaXN4Tii86TeS21KPn2hHAsVu3Y4txa8OQ==} - run-parallel@1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + '@near-wallet-selector/core@8.10.2': + resolution: {integrity: sha512-MH8sg6XHyylq2ZXxnOjrKHMCmuRgFfpfdC816fW0R8hctZiXZ0lmfLvgG1xfA2BAxrVytiU1g3dcE97/P5cZqg==} + peerDependencies: + near-api-js: ^4.0.0 || ^5.0.0 + + '@next/env@16.3.1': + resolution: {integrity: sha512-35G3xwkQUb2oETSDjFXGrVugknoayLFBh7vSE+yAcl9IP2zT9wyGwq7297AYHR11kJld807t5f8AJBs6WBzXsQ==} + + '@next/eslint-plugin-next@16.3.1': + resolution: {integrity: sha512-B4SznlXwVpaLDa7Tbi6zLuueria2d/PmFDhXyDymPGrk2r1n/RMJmcn5FZq1L64k+Jsyte1lKvOr7lP9Xo80mQ==} + + '@next/swc-darwin-arm64@16.3.1': + resolution: {integrity: sha512-ABMIu2zQ7cnNIHm5ivKGwZwUrm0pAai3yiJ/gK/rF1c1VP9UOnj7XECbMKFdVKp9I9eMYq9NoDs1WXOoowxzJw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@16.3.1': + resolution: {integrity: sha512-gNG21e/UnrroeScbY/QndUEdl0mF1FRibW7BBeYUz/5ABCepjqDdEdgr592vpzMtCn/m7FTjYq3TN4TpyDnutw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@16.3.1': + resolution: {integrity: sha512-6B6Lw016iwNUQuaJoraMMTLh6TwHzFUtxipSScD1F3YyymcrRWkobodRS2ftIOkF5vrs4zNlyUrTC5YZQ9Lz5w==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-arm64-musl@16.3.1': + resolution: {integrity: sha512-JUiPXZKK9wOhjf4MgDiH29GZLxfqOesbLtHq2pDxwH/WwscTRV2ToymnOTh1egzaZf0ueUf8T2+CeYTGHjW0Iw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@next/swc-linux-x64-gnu@16.3.1': + resolution: {integrity: sha512-Uog9jsrmIRIL/lfvIp9htmskSNC7JcQsMVucXL2V2YY1y/D9IUN3LPEafqy0zRJ2cIU1SQ0V6F6TlffQ+pLAGg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-linux-x64-musl@16.3.1': + resolution: {integrity: sha512-6yy3FT13KgUFOj5H8bl8w/6nKiJwHIvbtwh1V+1acsu+7y4tJjnemSa6mhsh53BeoVrlozE+fMgZhXH46WmjMA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@next/swc-win32-arm64-msvc@16.3.1': + resolution: {integrity: sha512-iOoN1QecUoGNZik536U/vtK43YwgyrCsGIkth52yIkl612n+0C9MjSnJbQAikISpb+WYRooBVhaDlUW7iZoKog==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-x64-msvc@16.3.1': + resolution: {integrity: sha512-d/k+PpAriUPaeMJJOG7HUSdqfEX46FEPWU1p3/nm2ACmXhj9hFEWdFODUBIpkuijXYkfL90qZzTqVPRp4BW/hw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@ngneat/elf-devtools@1.3.0': + resolution: {integrity: sha512-J9+4Vk/S/nKFGnXGZUDYrIx/K8Jfv4TLpzR3voBSOtSeq+c8Q0hdmo8iW7oaK6y5FWFDk0VJktlEh9cjylYxFg==} + + '@ngneat/elf-entities@5.0.2': + resolution: {integrity: sha512-G4ag51lvM3tOSgpxVVFYAgsh/bOL5BkNb4Z0VtosaM/CTWTHoNrf8UdvcaeJ3+sP1RS3bmEdZ9xUE8ifnVxssA==} + peerDependencies: + '@ngneat/elf': '>=2.5.0' + rxjs: '>=7.0.0' - slash@5.1.0: - resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} - engines: {node: '>=14.16'} + '@ngneat/elf-persist-state@1.2.1': + resolution: {integrity: sha512-R+5IRLC35cDT403sSs37UeqqOpHNnCwHl3eicPv/Rc+JJ7Av1bcQClSF2mHC0jE4pkYmEuVghpzUntvmrKCCwA==} + peerDependencies: + rxjs: '>=7.0.0' - smol-toml@1.7.0: - resolution: {integrity: sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==} - engines: {node: '>= 18'} + '@ngneat/elf@2.5.1': + resolution: {integrity: sha512-13BItNZFgHglTiXuP9XhisNczwQ5QSzH+imAv9nAPsdbCq/3ortqkIYRnlxB8DGPVcuIjLujQ4OcZa+9QWgZtw==} + peerDependencies: + rxjs: '>=7.0.0' - string-width@8.2.1: - resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} - engines: {node: '>=20'} + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} - strip-ansi@7.2.0: - resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} - engines: {node: '>=12'} + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} - to-regex-range@5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} - uc.micro@2.1.0: - resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + '@noble/curves@2.3.0': + resolution: {integrity: sha512-v7cY+4oWYPQszRj6ZFGzTVL7uP2TaLo1xMhWHzYC5wj0ZhOXQ5x+sBre8rF3hi8cAoi0bh1qXoovoOkdFtvqEg==} + engines: {node: '>= 20.19.0'} - unicorn-magic@0.4.0: - resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} - engines: {node: '>=20'} + '@noble/hashes@1.3.3': + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} -snapshots: + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@2.3.0': + resolution: {integrity: sha512-oN+QwyX7VSHotibwubG3kpzbwKrfnyR6OOO+3Nk/53ADL7FmgHHz4TgrbaYKvvOw09u6QTx0oiH1cNCIOuN0CQ==} + engines: {node: '>= 20.19.0'} '@nodelib/fs.scandir@2.1.5': - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} - '@nodelib/fs.stat@2.0.5': {} + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} '@nodelib/fs.walk@1.2.8': - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.20.1 + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} - '@sindresorhus/merge-streams@4.0.0': {} + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} - '@types/debug@4.1.13': - dependencies: - '@types/ms': 2.1.0 + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.1': + resolution: {integrity: sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==} + + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.2': + resolution: {integrity: sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.2': + resolution: {integrity: sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/base@2.3.0': + resolution: {integrity: sha512-NsG6Y03tY6R5BUis4FdVtHVkur0U6FOzskgs9ZXNl78CUc9fkZ78HmENUle1nSOkCasDmbubmWD9qwB7mm4PZA==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + + '@sinclair/typebox@0.33.24': + resolution: {integrity: sha512-91up4t0BLjfkCZ4Ap/BcgaPrMaX6n0I2YRu+kc03xGhLy9G3N05nbTpnK8q7GXdv0PxwUoxi67A8o3Wr5U7j3w==} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@solana-program/compute-budget@0.8.0': + resolution: {integrity: sha512-qPKxdxaEsFxebZ4K5RPuy7VQIm/tfJLa1+Nlt3KNA8EYQkz9Xm8htdoEaXVrer9kpgzzp9R3I3Bh6omwCM06tQ==} + peerDependencies: + '@solana/kit': ^2.1.0 + + '@solana-program/stake@0.2.1': + resolution: {integrity: sha512-ssNPsJv9XHaA+L7ihzmWGYcm/+XYURQ8UA3wQMKf6ccEHyHOUgoglkkDU/BoA0+wul6HxZUN0tHFymC0qFw6sg==} + peerDependencies: + '@solana/kit': ^2.1.0 + + '@solana-program/system@0.7.0': + resolution: {integrity: sha512-FKTBsKHpvHHNc1ATRm7SlC5nF/VdJtOSjldhcyfMN9R7xo712Mo2jHIzvBgn8zQO5Kg0DcWuKB7268Kv1ocicw==} + peerDependencies: + '@solana/kit': ^2.1.0 + + '@solana-program/token-2022@0.4.2': + resolution: {integrity: sha512-zIpR5t4s9qEU3hZKupzIBxJ6nUV5/UVyIT400tu9vT1HMs5JHxaTTsb5GUhYjiiTvNwU0MQavbwc4Dl29L0Xvw==} + peerDependencies: + '@solana/kit': ^2.1.0 + '@solana/sysvars': ^2.1.0 + + '@solana-program/token@0.5.1': + resolution: {integrity: sha512-bJvynW5q9SFuVOZ5vqGVkmaPGA0MCC+m9jgJj1nk5m20I389/ms69ASnhWGoOPNcie7S9OwBX0gTj2fiyWpfag==} + peerDependencies: + '@solana/kit': ^2.1.0 + + '@solana/accounts@2.3.0': + resolution: {integrity: sha512-QgQTj404Z6PXNOyzaOpSzjgMOuGwG8vC66jSDB+3zHaRcEPRVRd2sVSrd1U6sHtnV3aiaS6YyDuPQMheg4K2jw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/addresses@2.3.0': + resolution: {integrity: sha512-ypTNkY2ZaRFpHLnHAgaW8a83N0/WoqdFvCqf4CQmnMdFsZSdC7qOwcbd7YzdaQn9dy+P2hybewzB+KP7LutxGA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/assertions@2.3.0': + resolution: {integrity: sha512-Ekoet3khNg3XFLN7MIz8W31wPQISpKUGDGTylLptI+JjCDWx3PIa88xjEMqFo02WJ8sBj2NLV64Xg1sBcsHjZQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/buffer-layout@4.0.1': + resolution: {integrity: sha512-E1ImOIAD1tBZFRdjeM4/pzTiTApC0AOBGwyAMS4fwIodCWArzJ3DWdoh8cKxeFM2fElkxBh2Aqts1BPC373rHA==} + engines: {node: '>=5.10'} + + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-data-structures@2.3.0': + resolution: {integrity: sha512-qvU5LE5DqEdYMYgELRHv+HMOx73sSoV1ZZkwIrclwUmwTbTaH8QAJURBj0RhQ/zCne7VuLLOZFFGv6jGigWhSw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-strings@2.3.0': + resolution: {integrity: sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug==} + engines: {node: '>=20.18.0'} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.3.3' + + '@solana/codecs@2.3.0': + resolution: {integrity: sha512-JVqGPkzoeyU262hJGdH64kNLH0M+Oew2CIPOa/9tR3++q2pEd4jU2Rxdfye9sd0Ce3XJrR5AIa8ZfbyQXzjh+g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/fast-stable-stringify@2.3.0': + resolution: {integrity: sha512-KfJPrMEieUg6D3hfQACoPy0ukrAV8Kio883llt/8chPEG3FVTX9z/Zuf4O01a15xZmBbmQ7toil2Dp0sxMJSxw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/functional@2.3.0': + resolution: {integrity: sha512-AgsPh3W3tE+nK3eEw/W9qiSfTGwLYEvl0rWaxHht/lRcuDVwfKRzeSa5G79eioWFFqr+pTtoCr3D3OLkwKz02Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/instructions@2.3.0': + resolution: {integrity: sha512-PLMsmaIKu7hEAzyElrk2T7JJx4D+9eRwebhFZpy2PXziNSmFF929eRHKUsKqBFM3cYR1Yy3m6roBZfA+bGE/oQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/keys@2.3.0': + resolution: {integrity: sha512-ZVVdga79pNH+2pVcm6fr2sWz9HTwfopDVhYb0Lh3dh+WBmJjwkabXEIHey2rUES7NjFa/G7sV8lrUn/v8LDCCQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/kit@2.3.0': + resolution: {integrity: sha512-sb6PgwoW2LjE5oTFu4lhlS/cGt/NB3YrShEyx7JgWFWysfgLdJnhwWThgwy/4HjNsmtMrQGWVls0yVBHcMvlMQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/nominal-types@2.3.0': + resolution: {integrity: sha512-uKlMnlP4PWW5UTXlhKM8lcgIaNj8dvd8xO4Y9l+FVvh9RvW2TO0GwUO6JCo7JBzCB0PSqRJdWWaQ8pu1Ti/OkA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/options@2.3.0': + resolution: {integrity: sha512-PPnnZBRCWWoZQ11exPxf//DRzN2C6AoFsDI/u2AsQfYih434/7Kp4XLpfOMT/XESi+gdBMFNNfbES5zg3wAIkw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/programs@2.3.0': + resolution: {integrity: sha512-UXKujV71VCI5uPs+cFdwxybtHZAIZyQkqDiDnmK+DawtOO9mBn4Nimdb/6RjR2CXT78mzO9ZCZ3qfyX+ydcB7w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/promises@2.3.0': + resolution: {integrity: sha512-GjVgutZKXVuojd9rWy1PuLnfcRfqsaCm7InCiZc8bqmJpoghlyluweNc7ml9Y5yQn1P2IOyzh9+p/77vIyNybQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-api@2.3.0': + resolution: {integrity: sha512-UUdiRfWoyYhJL9PPvFeJr4aJ554ob2jXcpn4vKmRVn9ire0sCbpQKYx6K8eEKHZWXKrDW8IDspgTl0gT/aJWVg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-parsed-types@2.3.0': + resolution: {integrity: sha512-B5pHzyEIbBJf9KHej+zdr5ZNAdSvu7WLU2lOUPh81KHdHQs6dEb310LGxcpCc7HVE8IEdO20AbckewDiAN6OCg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-spec-types@2.3.0': + resolution: {integrity: sha512-xQsb65lahjr8Wc9dMtP7xa0ZmDS8dOE2ncYjlvfyw/h4mpdXTUdrSMi6RtFwX33/rGuztQ7Hwaid5xLNSLvsFQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-spec@2.3.0': + resolution: {integrity: sha512-fA2LMX4BMixCrNB2n6T83AvjZ3oUQTu7qyPLyt8gHQaoEAXs8k6GZmu6iYcr+FboQCjUmRPgMaABbcr9j2J9Sw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions-api@2.3.0': + resolution: {integrity: sha512-9mCjVbum2Hg9KGX3LKsrI5Xs0KX390lS+Z8qB80bxhar6MJPugqIPH8uRgLhCW9GN3JprAfjRNl7our8CPvsPQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions-channel-websocket@2.3.0': + resolution: {integrity: sha512-2oL6ceFwejIgeWzbNiUHI2tZZnaOxNTSerszcin7wYQwijxtpVgUHiuItM/Y70DQmH9sKhmikQp+dqeGalaJxw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + ws: ^8.18.0 + + '@solana/rpc-subscriptions-spec@2.3.0': + resolution: {integrity: sha512-rdmVcl4PvNKQeA2l8DorIeALCgJEMSu7U8AXJS1PICeb2lQuMeaR+6cs/iowjvIB0lMVjYN2sFf6Q3dJPu6wWg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions@2.3.0': + resolution: {integrity: sha512-Uyr10nZKGVzvCOqwCZgwYrzuoDyUdwtgQRefh13pXIrdo4wYjVmoLykH49Omt6abwStB0a4UL5gX9V4mFdDJZg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-transformers@2.3.0': + resolution: {integrity: sha512-UuHYK3XEpo9nMXdjyGKkPCOr7WsZsxs7zLYDO1A5ELH3P3JoehvrDegYRAGzBS2VKsfApZ86ZpJToP0K3PhmMA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-transport-http@2.3.0': + resolution: {integrity: sha512-HFKydmxGw8nAF5N+S0NLnPBDCe5oMDtI2RAmW8DMqP4U3Zxt2XWhvV1SNkAldT5tF0U1vP+is6fHxyhk4xqEvg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-types@2.3.0': + resolution: {integrity: sha512-O09YX2hED2QUyGxrMOxQ9GzH1LlEwwZWu69QbL4oYmIf6P5dzEEHcqRY6L1LsDVqc/dzAdEs/E1FaPrcIaIIPw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc@2.3.0': + resolution: {integrity: sha512-ZWN76iNQAOCpYC7yKfb3UNLIMZf603JckLKOOLTHuy9MZnTN8XV6uwvDFhf42XvhglgUjGCEnbUqWtxQ9pa/pQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/signers@2.3.0': + resolution: {integrity: sha512-OSv6fGr/MFRx6J+ZChQMRqKNPGGmdjkqarKkRzkwmv7v8quWsIRnJT5EV8tBy3LI4DLO/A8vKiNSPzvm1TdaiQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/subscribable@2.3.0': + resolution: {integrity: sha512-DkgohEDbMkdTWiKAoatY02Njr56WXx9e/dKKfmne8/Ad6/2llUIrax78nCdlvZW9quXMaXPTxZvdQqo9N669Og==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/sysvars@2.3.0': + resolution: {integrity: sha512-LvjADZrpZ+CnhlHqfI5cmsRzX9Rpyb1Ox2dMHnbsRNzeKAMhu9w4ZBIaeTdO322zsTr509G1B+k2ABD3whvUBA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transaction-confirmation@2.3.0': + resolution: {integrity: sha512-UiEuiHCfAAZEKdfne/XljFNJbsKAe701UQHKXEInYzIgBjRbvaeYZlBmkkqtxwcasgBTOmEaEKT44J14N9VZDw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transaction-messages@2.3.0': + resolution: {integrity: sha512-bgqvWuy3MqKS5JdNLH649q+ngiyOu5rGS3DizSnWwYUd76RxZl1kN6CoqHSrrMzFMvis6sck/yPGG3wqrMlAww==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transactions@2.3.0': + resolution: {integrity: sha512-LnTvdi8QnrQtuEZor5Msje61sDpPstTVwKg4y81tNxDhiyomjuvnSNLAq6QsB9gIxUqbNzPZgOG9IU4I4/Uaug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/wallet-adapter-base@0.9.27': + resolution: {integrity: sha512-kXjeNfNFVs/NE9GPmysBRKQ/nf+foSaq3kfVSeMcO/iVgigyRmB551OjU3WyAolLG/1jeEfKLqF9fKwMCRkUqg==} + engines: {node: '>=20'} + peerDependencies: + '@solana/web3.js': ^1.98.0 + + '@solana/wallet-standard-features@1.4.0': + resolution: {integrity: sha512-f0tAdqwM2aL6CiFbIgt9h5zKFp+mgY/iNGwoxPMTj9VSTeQj7d1GGSmWhZw0XWoZ4N/1tnKTKmYFq+Dyq08jRw==} + engines: {node: '>=22'} + + '@solana/web3.js@1.98.4': + resolution: {integrity: sha512-vv9lfnvjUsRiq//+j5pBdXig0IQdtzA0BRZ3bXEP4KaIyF1CcaydWqgyzQgfZMNIsWNWmG+AUHwPy4AHOD6gpw==} + + '@stablelib/aead@1.0.1': + resolution: {integrity: sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==} + + '@stablelib/binary@1.0.1': + resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} + + '@stablelib/bytes@1.0.1': + resolution: {integrity: sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==} + + '@stablelib/chacha20poly1305@1.0.1': + resolution: {integrity: sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA==} + + '@stablelib/chacha@1.0.1': + resolution: {integrity: sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg==} + + '@stablelib/constant-time@1.0.1': + resolution: {integrity: sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==} + + '@stablelib/hash@1.0.1': + resolution: {integrity: sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==} + + '@stablelib/hkdf@1.0.1': + resolution: {integrity: sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g==} + + '@stablelib/hmac@1.0.1': + resolution: {integrity: sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA==} + + '@stablelib/int@1.0.1': + resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==} + + '@stablelib/keyagreement@1.0.1': + resolution: {integrity: sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==} + + '@stablelib/poly1305@1.0.1': + resolution: {integrity: sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==} + + '@stablelib/random@1.0.2': + resolution: {integrity: sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==} + + '@stablelib/sha256@1.0.1': + resolution: {integrity: sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ==} + + '@stablelib/wipe@1.0.1': + resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} + + '@stablelib/x25519@1.0.3': + resolution: {integrity: sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==} + + '@stellar/freighter-api@5.0.0': + resolution: {integrity: sha512-MydzLg+WpSzmws24uUs4mVME2LPN8xhUWkwyGEP0N1Hr519swC6I/W7K6cdVBzghBiVv7f/vvGFNT+0p1a33Vg==} + + '@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'} + deprecated: This package is now rolled into @stellar/stellar-sdk. Please use @stellar/stellar-sdk to continue receiving updates and support. + + '@stellar/stellar-base@14.1.0': + resolution: {integrity: sha512-A8kFli6QGy22SRF45IjgPAJfUNGjnI+R7g4DF5NZYVsD1kGf7B4ITyc4OPclLV9tqNI4/lXxafGEw0JEUbHixw==} + engines: {node: '>=20.0.0'} + deprecated: This package is now rolled into @stellar/stellar-sdk. Please use @stellar/stellar-sdk to continue receiving updates and support. + + '@stellar/stellar-sdk@13.3.0': + resolution: {integrity: sha512-8+GHcZLp+mdin8gSjcgfb/Lb6sSMYRX6Nf/0LcSJxvjLQR0XHpjGzOiRbYb2jSXo51EnA6kAV5j+4Pzh5OUKUg==} + engines: {node: '>=18.0.0'} + + '@stellar/stellar-sdk@14.6.1': + resolution: {integrity: sha512-A1rQWDLdUasXkMXnYSuhgep+3ZZzyuXJKdt5/KAIc0gkmSp906HTvUpbT4pu+bVr41tu0+J4Ugz9J4BQAGGytg==} + engines: {node: '>=20.0.0'} + hasBin: true + + '@swc/helpers@0.5.23': + resolution: {integrity: sha512-5lSsMOTXURePglDfvuAQUqkGek9Hg2kksOYay2m0+XR++b2NWYL/4sWyuvVBIs8oKnJaxkdi9whaL/sqN13afw==} + + '@tailwindcss/node@4.3.3': + resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} + + '@tailwindcss/oxide-android-arm64@4.3.3': + resolution: {integrity: sha512-Y85A2gmPSkl5Ve5qR86GL4HT509cFqQh1aes9p3sSkyTPwt0Pppf3GkwGe4JPACcRYjgJIEhQgM6dBClnr0NYw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [android] + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + resolution: {integrity: sha512-BiaWatpBcERQFDlOjRDpIVXuFK5PJez5SA4JMg6VYZdBYU+qKfV/vqjcIs+IYmtitf1xYQZTwXvU/8y4lfZUGw==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [darwin] + + '@tailwindcss/oxide-darwin-x64@4.3.3': + resolution: {integrity: sha512-fAeUqfV5ndhxRwai8cXGzdLvul9utWOmeTkv69unv4ZXixjn61Z+p9lCWdwOwA3TYboG3BwdVuN/RDjhBRl0mw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [darwin] + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + resolution: {integrity: sha512-iyf5bV6+wnAlflVeEy7R25dupxTNECZN5QMI0qNT6eT+EgaGdZcKhGkr5SdoaWiLJ3spLqIY9VCeSGrwmtg4kw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [freebsd] + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + resolution: {integrity: sha512-aAYUprJAJQWWbRrPvtjdroZ56Md+JM8pMiopS6xGEwDfLhqj+2ver2p4nU4Mb3CRqcMmNBjo8KkUgcxhkzVQGQ==} + engines: {node: '>= 20'} + cpu: [arm] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + resolution: {integrity: sha512-nDxldcEENOxZRzC2uu9jrutZdAAQtb+8WWDCSnWL1zvBk1+FN+x6MtDViPB5AJMfttVCUhehGWus3XBPgatM/w==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + resolution: {integrity: sha512-Md44bD6veX/PC5iyF8cDVnw4HBIANZepRZZ7a8DQOvkfo5WUBwcp6iAuCUz23u+4SUkhJlD3eL7hNdW8ezd/kA==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + resolution: {integrity: sha512-tx7us1muwOKAKWao2v/GaafFeQboE6aj88vC6ziN2NCGcRm8gWUhwjzg+YdVB1e4boAtdtma4L43onunI6NS4w==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + resolution: {integrity: sha512-SJxX60smvHgasZoBy11dX6YRjXJFovwWBoedhbQPOBzgFWBHGB+TVPWB9BxzR7TTxU8FQZAI2AyiNCMzFm8Img==} + engines: {node: '>= 20'} + cpu: [x64] + os: [linux] + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + resolution: {integrity: sha512-jx1+rPhY/5Ympkktd656HBWEBLxP7dH06losBLjjf5vgCODXvi9KhtftWcMIwTFIDqBr7cRnQkdLnAG+IOlGvQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + bundledDependencies: + - '@napi-rs/wasm-runtime' + - '@emnapi/core' + - '@emnapi/runtime' + - '@tybys/wasm-util' + - '@emnapi/wasi-threads' + - tslib + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + resolution: {integrity: sha512-3rc292Ca2ceK6Ulcc/bAVnTs/3nDtoPhyEKlgPv+yQJQi/JS/AMJlqzxvlDacL1nekbrcf6bTqp/jV4qgnPxNQ==} + engines: {node: '>= 20'} + cpu: [arm64] + os: [win32] + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + resolution: {integrity: sha512-yJ0pwIVc/nYeGoV02WtsN8KYyLQv7kyI2wDnkezyJlGGjkd4QLwDGAwl47YpPJeuI0M0ObaXGSPjvWDPeTPggw==} + engines: {node: '>= 20'} + cpu: [x64] + os: [win32] + + '@tailwindcss/oxide@4.3.3': + resolution: {integrity: sha512-krXjAikiaFSPaK/FkAQT5UTx3VormQaiZ5hBFlJZ9UFQGB/rwg1MZIhHAG9smMQRTdyJxP6Qt5MwMtdyU5FWrA==} + engines: {node: '>= 20'} + + '@tailwindcss/postcss@4.3.3': + resolution: {integrity: sha512-JTSZZGQi1AyKirbLN3azmjVzef92tcX7h+iSqPdaeStyFpGpDlKvvpxeOE8njhbUanbRwr3z8DyzhICWnMtQeg==} + + '@trezor/analytics@1.4.2': + resolution: {integrity: sha512-FgjJekuDvx1TjiDemvpnPiRck7Kp/v1ZeppsBYpQR3yGKyKzbG1pVpcl0RyI2237raXxbORaz7XV8tcyjq4BXg==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/blockchain-link-types@1.4.2': + resolution: {integrity: sha512-KThBmGOFLJAFnmou9ThQhnjEVxfYPfEwMOaVTVNgJ+NAkt5rEMx0SKBBelCGZ63XtOLWdVPglFo83wtm+I9Vpg==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/blockchain-link-utils@1.4.2': + resolution: {integrity: sha512-PBEBrdtHn0dn/c9roW6vjdHI/CucMywJm5gthETZAZmzBOtg6ZDpLTn+qL8+jZGIbwcAkItrQ3iHrHhR6xTP5g==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/blockchain-link@2.5.2': + resolution: {integrity: sha512-/egUnIt/fR57QY33ejnkPMhZwRvVRS/pUCoqdVIGitN1Q7QZsdopoR4hw37hdK/Ux/q1ZLH6LZz7U2UFahjppw==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/connect-analytics@1.3.5': + resolution: {integrity: sha512-Aoi+EITpZZycnELQJEp9XV0mHFfaCQ6JE0Ka5mWuHtOny3nJdFLBrih4ipcEXJdJbww6pBxRJB09sJ19cTyacA==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/connect-common@0.4.2': + resolution: {integrity: sha512-ND5TTjrTPnJdfl8Wlhl9YtFWnY2u6FHM1dsPkNYCmyUKIMoflJ5cLn95Xabl6l1btHERYn3wTUvgEYQG7r8OVQ==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/connect-plugin-stellar@9.2.1': + resolution: {integrity: sha512-Orz5gFZzYFZs1+cTsgg8fz/VWFjhl7pqMCqD5DVNZpXW+wrjwBaRbcGJZ+ibkPKU3AlM7Uv3SVD/pjaQmAkZ2Q==} + peerDependencies: + '@stellar/stellar-sdk': ^13.3.0 + '@trezor/connect': 9.x.x + tslib: ^2.6.2 + + '@trezor/connect-web@9.6.2': + resolution: {integrity: sha512-QGuCjX8Bx9aCq1Pg52KifbbzYn00FQu9mCTDSgCVGH/HAzbxhcRkDKc86kFwW8z9NdJxw+XeVJq5Ky/js3iEDA==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/connect@9.6.2': + resolution: {integrity: sha512-XsSERBK+KnF6FPsATuhB9AEM0frekVLwAwFo35MRV9I4P+mdv6tnUiZUq8O8aoPbfJwDjtNJSYv+PMsKuRH6rg==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/crypto-utils@1.1.4': + resolution: {integrity: sha512-Y6VziniqMPoMi70IyowEuXKqRvBYQzgPAekJaUZTHhR+grtYNRKRH2HJCvuZ8MGmSKUFSYfa7y8AvwALA8mQmA==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/device-utils@1.1.2': + resolution: {integrity: sha512-R3AJvAo+a3wYVmcGZO2VNl9PZOmDEzCZIlmCJn0BlSRWWd8G9u1qyo/fL9zOwij/YhCaJyokmSHmIEmbY9qpgw==} + + '@trezor/env-utils@1.4.2': + resolution: {integrity: sha512-lQvrqcNK5I4dy2MuiLyMuEm0KzY59RIu2GLtc9GsvqyxSPZkADqVzGeLJjXj/vI2ajL8leSpMvmN4zPw3EK8AA==} + peerDependencies: + expo-constants: '*' + expo-localization: '*' + react-native: '*' + tslib: ^2.6.2 + peerDependenciesMeta: + expo-constants: + optional: true + expo-localization: + optional: true + react-native: + optional: true + + '@trezor/env-utils@1.5.0': + resolution: {integrity: sha512-u1TN7dMQ5Qhpbae08Z4JJmI9fQrbbJ4yj8eIAsuzMQn6vb+Sg9vbntl+IDsZ1G9WeI73uHTLu1wWMmAgiujH8w==} + peerDependencies: + expo-constants: '*' + expo-localization: '*' + react-native: '*' + tslib: ^2.6.2 + peerDependenciesMeta: + expo-constants: + optional: true + expo-localization: + optional: true + react-native: + optional: true + + '@trezor/protobuf@1.4.2': + resolution: {integrity: sha512-AeIYKCgKcE9cWflggGL8T9gD+IZLSGrwkzqCk3wpIiODd5dUCgEgA4OPBufR6OMu3RWu/Tgu2xviHunijG3LXQ==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/protocol@1.2.8': + resolution: {integrity: sha512-8EH+EU4Z1j9X4Ljczjbl9G7vVgcUz41qXcdE+6FOG3BFvMDK4KUVvaOtWqD+1dFpeo5yvWSTEKdhgXMPFprWYQ==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/schema-utils@1.3.4': + resolution: {integrity: sha512-guP5TKjQEWe6c5HGx+7rhM0SAdEL5gylpkvk9XmJXjZDnl1Ew81nmLHUs2ghf8Od3pKBe4qjBIMBHUQNaOqWUg==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/transport@1.5.2': + resolution: {integrity: sha512-rYP87zdVll2bNBtsD3VxJq0yjaNvIClcgszZjQwVTQxpKGFPkx8bLSpAGI05R9qfxusZJCfYarjX3qki9nHYPw==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/type-utils@1.1.8': + resolution: {integrity: sha512-VtvkPXpwtMtTX9caZWYlMMTmhjUeDq4/1LGn0pSdjd4OuL/vQyuPWXCT/0RtlnRraW6R2dZF7rX2UON2kQIMTQ==} + + '@trezor/utils@9.4.1': + resolution: {integrity: sha512-9MYNa99tzXiTBnKadABoY2D80YL9Mh3ntM5wziwVhjZ4HyhqFH6BsCxwFpWYLUIKBctD55QEdE4bASoqp7Ad1A==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/utils@9.4.2': + resolution: {integrity: sha512-Fm3m2gmfXsgv4chqn5HX8e8dElEr2ibBJSJ7HE3bsHh/1OSQcDdzsSioAK04Fo9ws/v7n6lt+QBZ6fGmwyIkZQ==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/utxo-lib@2.4.2': + resolution: {integrity: sha512-dTXfBg/cEKnmHM5CLG5+0qrp6fqOfwxqe8YPACdKeM7g1XJKCGDAuFpDUVeT3lrcUsTh6bEMHM06z4H3gZp5MQ==} + peerDependencies: + tslib: ^2.6.2 + + '@trezor/websocket-client@1.2.2': + resolution: {integrity: sha512-vu9L1V/5yh8LHQCmsGC9scCnihELsVuR5Tri1IvW3CdgTUFFcfjsEgXsFqFME3HlxuUmx6qokw0Gx/o0/hzaSQ==} + peerDependencies: + tslib: ^2.6.2 + + '@tybys/wasm-util@0.10.3': + resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/katex@0.16.8': + resolution: {integrity: sha512-trgaNyfU+Xh2Tc+ABIb44a5AYUpicB3uwirOioeOkNPPbmgRNtcWyDeeFRzjPZENO9Vq8gvVqfhaaXWLlevVwg==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@24.13.3': + resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} + + '@types/react-dom@19.2.4': + resolution: {integrity: sha512-Bsc+QHgp+P/F02XDzNCY9jnZNCUuLki36KT7VKrTXXLdHf+vHMNZnW1rVu5DNW/rCK+fya3DATySbLM4yhtKUw==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react@19.2.18': + resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@types/w3c-web-usb@1.0.14': + resolution: {integrity: sha512-Qu3Nn6JFuF4+sHKYl+IcX9vYiI40ogleXzFFSxoE1W94rG98o/kXs8uJ0QSfFzuwBCZWlGfUGpPkgwuuX4PchA==} + + '@types/web@0.0.197': + resolution: {integrity: sha512-V4sOroWDADFx9dLodWpKm298NOJ1VJ6zoDVgaP+WBb/utWxqQ6gnMzd9lvVDAr/F3ibiKaxH9i45eS0gQPSTaQ==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@typescript-eslint/eslint-plugin@8.67.0': + resolution: {integrity: sha512-Un7Heoyj65NREbKAyIrFxeM143NZpExWmy1Nep4DLeQOeLlTeumPjoNKnBrU5D5moWXbPJgRa5Uwcdu0faVNGQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.67.0 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/parser@8.67.0': + resolution: {integrity: sha512-fUBfTuuEulWqX6V8+O3PtScV01tzYYRUDTAirHFKoRAt7nOzoGiPt0M/bB47wWNy0coOOcgEwAMUtBpykMxl6w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.67.0': + resolution: {integrity: sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@8.67.0': + resolution: {integrity: sha512-EgvsleTwS4E+WzzSvem8fAUubLwatMNF1B5hHSLQxcvs7q2dtRhGyujHwLJSYlG41niJ7GP24Aha2+0mb1b2kg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.67.0': + resolution: {integrity: sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@8.67.0': + resolution: {integrity: sha512-aVWDXbRmdXO9siTfX4ditQI1T9+zVcNazT48EJCD0v40/9RIFoUgZ05CmGEq9H2gixRpjUn/iplwvlcvutJW/Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@8.67.0': + resolution: {integrity: sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.67.0': + resolution: {integrity: sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@8.67.0': + resolution: {integrity: sha512-U9D1FdwEWBwok3hxxSdhclMb0twvt9QnjIQ0VfQ1AiX2epnpSgv2ubVDsayOFyY8K6FX+AQ7E0FKWVG3iKsj1A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@8.67.0': + resolution: {integrity: sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + resolution: {integrity: sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.12.2': + resolution: {integrity: sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + resolution: {integrity: sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.12.2': + resolution: {integrity: sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + resolution: {integrity: sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + resolution: {integrity: sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + resolution: {integrity: sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + resolution: {integrity: sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + resolution: {integrity: sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==} + cpu: [arm64] + os: [linux] + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + resolution: {integrity: sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==} + cpu: [loong64] + os: [linux] + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + resolution: {integrity: sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==} + cpu: [loong64] + os: [linux] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + resolution: {integrity: sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==} + cpu: [ppc64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + resolution: {integrity: sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + resolution: {integrity: sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==} + cpu: [riscv64] + os: [linux] + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + resolution: {integrity: sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==} + cpu: [s390x] + os: [linux] + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + resolution: {integrity: sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + resolution: {integrity: sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==} + cpu: [x64] + os: [linux] + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + resolution: {integrity: sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==} + cpu: [arm64] + os: [openharmony] + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + resolution: {integrity: sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + resolution: {integrity: sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + resolution: {integrity: sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + resolution: {integrity: sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==} + cpu: [x64] + os: [win32] + + '@wallet-standard/base@1.1.1': + resolution: {integrity: sha512-gggIHTtxicF9XFMQ12DkfS6NAG92Ak795JeSA7f2whAQ6Y3AkMWWuCMxSZXG2NIPN42kEaZSNVjqMsJRaJRxMQ==} + engines: {node: '>=22'} + + '@wallet-standard/features@1.1.1': + resolution: {integrity: sha512-aCWYmVeSCGViyEU5k7GMoW8zxE4Gs+C1s1Pp2XLesvSNlnZ4PMES9HUnTB3hl0b3RVj7C61yze3IWyrncqg4MA==} + engines: {node: '>=22'} + + '@walletconnect/core@2.11.2': + resolution: {integrity: sha512-bB4SiXX8hX3/hyBfVPC5gwZCXCl+OPj+/EDVM71iAO3TDsh78KPbrVAbDnnsbHzZVHlsMohtXX3j5XVsheN3+g==} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.1': + resolution: {integrity: sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q==} + + '@walletconnect/jsonrpc-provider@1.0.13': + resolution: {integrity: sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g==} + + '@walletconnect/jsonrpc-types@1.0.3': + resolution: {integrity: sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.14': + resolution: {integrity: sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.3': + resolution: {integrity: sha512-wRsD0eDQSajj8YMM/jpxoH1yeSLyS7FPkh0VKCQ1BWrERTy1Z7/DmOE8FYm/gmd7Cg6BNXVWiymhGq6wnmlq8w==} + + '@walletconnect/modal-core@2.6.2': + resolution: {integrity: sha512-cv8ibvdOJQv2B+nyxP9IIFdxvQznMz8OOr/oR/AaUZym4hjXNL/l1a2UlSQBXrVjo3xxbouMxLb3kBsHoYP2CA==} + + '@walletconnect/modal-ui@2.6.2': + resolution: {integrity: sha512-rbdstM1HPGvr7jprQkyPggX7rP4XiCG85ZA+zWBEX0dVQg8PpAgRUqpeub4xQKDgY7pY/xLRXSiCVdWGqvG2HA==} + + '@walletconnect/modal@2.6.2': + resolution: {integrity: sha512-eFopgKi8AjKf/0U4SemvcYw9zlLpx9njVN8sf6DAkowC2Md0gPU/UNEbH1Wwj407pEKnEds98pKWib1NN1ACoA==} + deprecated: Please follow the migration guide on https://docs.reown.com/appkit/upgrade/wcm + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.11.2': + resolution: {integrity: sha512-MfBcuSz2GmMH+P7MrCP46mVE5qhP0ZyWA0FyIH6/WuxQ6G+MgKsGfaITqakpRPsykWOJq8tXMs3XvUPDU413OQ==} + deprecated: 'Reliability and performance improvements. See: https://github.com/WalletConnect/walletconnect-monorepo/releases' + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.11.2': + resolution: {integrity: sha512-p632MFB+lJbip2cvtXPBQslpUdiw1sDtQ5y855bOlAGquay+6fZ4h1DcDePeKQDQM3P77ax2a9aNPZxV6y/h1Q==} + + '@walletconnect/utils@2.11.2': + resolution: {integrity: sha512-LyfdmrnZY6dWqlF4eDrx5jpUwsB2bEPjoqR5Z6rXPiHJKUOdJt7az+mNOn5KTSOlRpd1DmozrBrWr+G9fFLYVw==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + + '@xrplf/isomorphic@1.0.2': + resolution: {integrity: sha512-ncZUdMXr6VlSXtdoiDi0jTH+gBrgGxwVeEidhoegII3PmyErbQsyj6e+j7acmR4LW/lvBkPkzb9QzRfJH0n3rA==} + engines: {node: '>=18.0.0'} + + '@xrplf/secret-numbers@2.0.0': + resolution: {integrity: sha512-z3AOibRTE9E8MbjgzxqMpG1RNaBhQ1jnfhNCa1cGf2reZUJzPMYs4TggQTc7j8+0WyV3cr7y/U8Oz99SXIkN5Q==} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn@8.18.0: + resolution: {integrity: sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.3.0: + resolution: {integrity: sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.13.0: + resolution: {integrity: sha512-UzGt8zg7Ny8djbYMhxl2zuEevVa7r2gJjYY5Lwr1xM7+XU2nd6CkIWFTVcCIbAP63vSz71NaVyyuSk9lHKcy0A==} + engines: {node: '>=4'} + + axios@1.19.0: + resolution: {integrity: sha512-ht/iuYZXEjFxLH/Hkezgd7m6JKlHHXEUSneaDz8uZe1Gj5QZtCnpyDsckvAiEnT89OEbCLmnte4R4sn7P0EKFw==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + bare-addon-resolve@1.10.1: + resolution: {integrity: sha512-F/SD2du8keuYSb4xipnGz5j2E6yhNdHA8ZVxtHae6h2uOrpBIjjbhXvjzKZbr5XUOzqBzh/i8GVFycj2DlFQIA==} + peerDependencies: + bare-url: '*' + peerDependenciesMeta: + bare-url: + optional: true + + bare-module-resolve@1.12.4: + resolution: {integrity: sha512-xcfgg2u7HqgJiBmah71O9vvdFAgHCvkqC/WSC2O7Bbgosoc1eC/BWe/6IDJ4OsfKlkxuvC/TDWXC+oH5yeW8mA==} + peerDependencies: + bare-url: '*' + peerDependenciesMeta: + bare-url: + optional: true + + bare-semver@1.1.0: + resolution: {integrity: sha512-1Hw5qJ7hXdVt3uPUqjeFTuxyvBUJauvz5A1I2jk8gzjZMHp04n//6nV9MDbG9CMw78JHY2lGV0w6s//LrASm2w==} + + base-x@3.0.11: + resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} + + 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==} + + baseline-browser-mapping@2.11.14: + resolution: {integrity: sha512-JyJ954WzuIR8/FFzX0o5krdSTrBAkcCSRfWSleRsIHSWV+cZe2FI1PKggVkFke1hBldRs+LRxUczzE9iPmgZww==} + engines: {node: '>=6.0.0'} + hasBin: true + + bchaddrjs@0.5.2: + resolution: {integrity: sha512-OO7gIn3m7ea4FVx4cT8gdlWQR2+++EquhdpWQJH9BQjK63tJJ6ngB3QMZDO6DiBoXiIGUsTPHjlrHVxPGcGxLQ==} + engines: {node: '>=8.0.0'} + + bech32@2.0.0: + resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==} + + big-integer@1.6.36: + resolution: {integrity: sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==} + engines: {node: '>=0.6'} + + bignumber.js@10.0.2: + resolution: {integrity: sha512-E8Wp9O06QA6lneJ4aRUXKYf/1GIomqUEmUMwtIOMtDxf1U52ffJY+y7JBk/8wRafA8qOIqLnXQGqonYXZdBnFQ==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bip32-path@0.4.2: + resolution: {integrity: sha512-ZBMCELjJfcNMkz5bDuJ1WrYvjlhEF5k6mQ8vUr4N7MbVRsXei7ZOg8VhhwMfNiW68NWmLkgkc6WvTickrLGprQ==} + + bip66@2.0.0: + resolution: {integrity: sha512-kBG+hSpgvZBrkIm9dt5T1Hd/7xGCPEX2npoxAWZfsK1FvjgaxySEh2WizjyIstWXriKo9K9uJ4u0OnsyLDUPXQ==} + + bitcoin-ops@1.4.1: + resolution: {integrity: sha512-pef6gxZFztEhaE9RY9HmWVmiIHqCb2OyS4HPKkpc6CIiiOa3Qmuoylxc5P2EkU3w+5eTSifI9SEZC88idAIGow==} + + blake-hash@2.0.0: + resolution: {integrity: sha512-Igj8YowDu1PRkRsxZA7NVkdFNxH5rKv5cpLxQ0CVXSIA77pVYwCPRQJ2sMew/oneUpfuYRyjG6r8SmmmnbZb1w==} + engines: {node: '>= 10'} + + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + + bn.js@4.12.5: + resolution: {integrity: sha512-3aRg6/JxfffFD+OlOjOFR3Vo79l39ooBTFucxx+MT3dhCtzn3EmiUPQo+6/OZuI2jbXi3YKgmiTFBgChQMwIRQ==} + + bn.js@5.2.5: + resolution: {integrity: sha512-Vq886eXykuP5E6HcKSSStP3bJgrE6In5WKxVUvJ8XGpWWYs2xZHWqUwzCtGgEtBcxyd57KBFDPFoUfNzdaHCNg==} + + borsh@0.7.0: + resolution: {integrity: sha512-CLCsZGIBCFnPtkNnieW/a8wmreDmfUtjU2m9yHrzPXIlNbqVs0AQrSatSG6vdNYUqdc83tkQi2eHfF98ubzQLA==} + + borsh@1.0.0: + resolution: {integrity: sha512-fSVWzzemnyfF89EPwlUNsrS5swF5CrtiN4e+h0/lLf4dz2he4L3ndM20PS9wj7ICSkXJe/TQUHdaPTq15b1mNQ==} + + borsh@2.0.0: + resolution: {integrity: sha512-kc9+BgR3zz9+cjbwM8ODoUB4fs3X3I5A/HtX7LZKxCLaMrEeDFoBpnhZY//DTS1VZBSs6S5v46RZRbZjRFspEg==} + + brace-expansion@1.1.18: + resolution: {integrity: sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==} + + brace-expansion@5.0.9: + resolution: {integrity: sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==} + engines: {node: 20 || >=22} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browserslist@4.28.8: + resolution: {integrity: sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + + bs58check@4.0.0: + resolution: {integrity: sha512-FsGDOnFg9aVI9erdriULkd/JjEWONV/lQE5aYziB5PoBsXRind56lh8doIZIc9X4HoxT5x4bLjMWN1/NB8Zp5g==} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.1.0: + resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} + engines: {node: '>=6.14.2'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001809: + resolution: {integrity: sha512-xxWVywk6a6Arlk+hymeycyn/VgqEfLDxupvhH/xiY5SJ/18kmi9o6MiO320DCUzypORHLtvh0I4i04tUhCNHNQ==} + + cashaddrjs@0.4.4: + resolution: {integrity: sha512-xZkuWdNOh0uq/mxJIng6vYWfTowZLd9F4GMAlp2DwFHlcCqCm91NtuAc47RuV4L7r4PYcY5p6Cr2OKNb4hnkWA==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + engines: {node: '>= 0.10'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + delay@5.0.0: + resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} + engines: {node: '>=10'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + + detect-europe-js@0.1.2: + resolution: {integrity: sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + electron-to-chromium@1.5.407: + resolution: {integrity: sha512-4R8XgQOdfxexCd/u63lRm6wCHjECwI45MV9wxAs2ggtfWe2hwlo1ql97jKsju2IcJ+jFSTwBssyYoiWhh7mauQ==} + + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + enhanced-resolve@5.24.5: + resolution: {integrity: sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==} + engines: {node: '>=10.13.0'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + es-abstract-get@1.0.0: + resolution: {integrity: sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==} + engines: {node: '>= 0.4'} + + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-iterator-helpers@1.4.0: + resolution: {integrity: sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.4: + resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==} + engines: {node: '>= 0.4'} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-next@16.3.1: + resolution: {integrity: sha512-0vtrpwFVHFEkycUgV/DyrG29OS+HSRdah5Yu8YuZoiBMtlAT6NIiWzaLwDkJZxr2kGfx+9LIvfQ7KHAlEs0VsA==} + peerDependencies: + eslint: '>=9.0.0' + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-import-resolver-node@0.3.10: + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.14.0: + resolution: {integrity: sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-react-hooks@7.1.1: + resolution: {integrity: sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==} + engines: {node: '>=18'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 || ^10.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@9.39.5: + resolution: {integrity: sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + eventsource@2.0.2: + resolution: {integrity: sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==} + engines: {node: '>=12.0.0'} + + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + + eyes@0.1.8: + resolution: {integrity: sha512-GipyPsXO1anza0AOZdy69Im7hGFCNB7Y/NGjDlZGJ3GJJLtwNSb2vrzYrTYJRrRloVx7pl+bhUaTB8yiccPvFQ==} + engines: {node: '> 0.1.90'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-stable-stringify@1.0.0: + resolution: {integrity: sha512-wpYMUmFu5f00Sm0cj2pfivpmawLZ0NKdviQ4w9zJeR8JVtOpOxHmLaJuj0vxvGqMJQWyP/COUkF75/57OKyRag==} + + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + feaxios@0.0.23: + resolution: {integrity: sha512-eghR0A21fvbkcQBgZuMfQhrXxJzC0GNUGC9fXhBge33D+mFDTwl0aJ35zoQQn575BhyjQitRc5N4f+L4cP708g==} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.4.4: + resolution: {integrity: sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==} + + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + form-data@4.0.6: + resolution: {integrity: sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==} + engines: {node: '>= 6'} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.2.0: + resolution: {integrity: sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + generate-function@2.3.1: + resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==} + + generate-object-property@1.2.0: + resolution: {integrity: sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ==} + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.14.2: + resolution: {integrity: sha512-XpwZALwwl/BaKTAyC6+c5T8y6kCg2jk+XGqOVrKIQmW49pNypYLMRjCUXqa28tQgJlhS2RlzP7sc+Rx7W6qsfw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@16.2.2: + resolution: {integrity: sha512-NLvV9ubZ6NDsJaOpKPy3cQeJpKi9DcWiyCiFUpJPA0YihRqiE6RWaLUmgNNPr8MgPpLZjnBjSmou7uZBRJv9wA==} + engines: {node: '>=20'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hermes-estree@0.25.1: + resolution: {integrity: sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==} + + hermes-parser@0.25.1: + resolution: {integrity: sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==} + + hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + http-errors@1.7.2: + resolution: {integrity: sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==} + engines: {node: '>= 0.6'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + idb-keyval@6.3.0: + resolution: {integrity: sha512-um+2dgAWmYsu615EXpWVwSmapJhON0G43t3Ka/EVaohzPQXSMqKEqeDK/oIW3Ow+BXaF2PvSc+oBTFp793A5Ow==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.6: + resolution: {integrity: sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==} + engines: {node: '>= 4'} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + int64-buffer@1.1.1: + resolution: {integrity: sha512-xp/v0/im2q7n7ISFJXcYsr/aVsUdZKPUZS1uYtoM9I9Cfmm5YuAi7SQts2TrEXwAKIE0wyn3KxJbo35goJgvwQ==} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + ip-address@10.5.0: + resolution: {integrity: sha512-R5SnVLJmgYYvf2F2ZgwSBnelz5G4q5AxIC277GDfUaNbrZKNANcBC7RHqYYePlszf4kBolVkJauG0ZjHHFh55g==} + engines: {node: '>= 12'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-document.all@1.0.0: + resolution: {integrity: sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-my-ip-valid@1.0.1: + resolution: {integrity: sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg==} + + is-my-json-valid@2.20.6: + resolution: {integrity: sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw==} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@4.0.0: + resolution: {integrity: sha512-lJJV/5dYS+RcL8uQdBDW9c9uWFLLBNRyFhnAKXw5tVqLlKZ4RMGZKv+YQ/IA3OhD+RpbJa1LLFM1FQPGyIXvOA==} + engines: {node: '>=12'} + + is-property@1.0.2: + resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-retry-allowed@3.0.0: + resolution: {integrity: sha512-9xH0xvoggby+u0uGF7cZXdrutWiBiaFG8ZT4YFPXL8NzkyAwX3AKGLeFQLvzDpM430+nDFBZ1LHkie/8ocL06A==} + engines: {node: '>=12'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-standalone-pwa@0.1.1: + resolution: {integrity: sha512-9Cbovsa52vNQCjdXOzeQq5CnCbAcRk05aU62K20WO372NrTv0NxibLFCK6lQ4/iZEFdEA3p3t2VNOn8AJ53F5g==} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jayson@4.3.0: + resolution: {integrity: sha512-AauzHcUcqs8OBnCHOkJY280VaTiCm57AbuO7lqzcw7JapGj50BisE3xhksye4zlTSR1+1tAz67wLTl8tEH1obQ==} + engines: {node: '>=8'} + hasBin: true + + jiti@2.7.0: + resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} + hasBin: true + + js-sha256@0.11.1: + resolution: {integrity: sha512-o6WSo/LUvY2uC4j7mO50a2ms7E/EAdbP0swigLV+nzHKTTaYnaLIWJ02VdXrsJX0vGedDESQnLsOekr94ryfjg==} + + js-sha256@0.9.0: + resolution: {integrity: sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.3.1: + resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==} + hasBin: true + + js-yaml@5.2.2: + resolution: {integrity: sha512-dayzUzKkJ1MkuUtZglSebU43utNXH0OWQByK9rKOOuYIO8M5TV1y+n8ALMdG0rdzBnfNkOmZEqrURepb0ejqBw==} + hasBin: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.3.1: + resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} + + jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + katex@0.16.47: + resolution: {integrity: sha512-Eeo8Ys1doU1z+x8AZsPpQu+p/QcZBI5PeOo7QGQdy2x2m0MU/hYagBbGOmXwr5KVbEfVuWv9LpnQWeehogurjg==} + hasBin: true + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + + linkify-it@5.0.2: + resolution: {integrity: sha512-ONTm2jCMAVZjgQa/Fy1kScXsuOoF5NPTsoFBdE1KVIZ2vAh/r9+Bqo+0jINCBYnavTPQZz38QzFTme79ENoN3Q==} + + lit-element@3.3.3: + resolution: {integrity: sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==} + + lit-element@4.2.2: + resolution: {integrity: sha512-aFKhNToWxoyhkNDmWZwEva2SlQia+jfG0fjIWV//YeTaWrVnOxD89dPKfigCUspXFmjzOEUQpOkejH5Ly6sG0w==} + + lit-html@2.8.0: + resolution: {integrity: sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==} + + lit-html@3.3.3: + resolution: {integrity: sha512-el8M6jK2o3RXBnrSHX3ZKrsN8zEV63pSExTO1wYJz7QndGYZ8353e2a5PPX+qHe2aGayfnchQmkAojaWAREOIA==} + + lit@2.8.0: + resolution: {integrity: sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==} + + lit@3.2.0: + resolution: {integrity: sha512-s6tI33Lf6VpDu7u4YqsSX78D28bYQulM+VAzsGch4fx2H0eLZnJsUBsPWmGYSGoKDNbjtRv02rio1o+UdPVwvw==} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + long@5.2.5: + resolution: {integrity: sha512-e0r9YBBgNCq1D1o5Dp8FMH0N5hsFtXDBiVa0qoJPHpakvZkmDKPRoGffZJII/XsHvj9An9blm+cRJ01yQqU+Dw==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@11.5.2: + resolution: {integrity: sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru_map@0.4.1: + resolution: {integrity: sha512-I+lBvqMMFfqaV8CJCISjI3wbjmwVu/VyOoU7+qtu9d7ioW5klMgsTTiUOUp+DJvfTTzKXoPbyC6YfgkNcyPSOg==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + markdown-it@14.3.0: + resolution: {integrity: sha512-RCEsPjR+sr0x+AuYp601tKTkgFG4YEPLCzHST3cQ/fhlJkqAkz1L2/Qbp1j9qw5SBwQHFBoW8+hoN5xssOF0Tw==} + hasBin: true + + markdownlint-cli2-formatter-default@0.0.6: + resolution: {integrity: sha512-VVDGKsq9sgzu378swJ0fcHfSicUnMxnL8gnLm/Q4J/xsNJ4e5bA6lvAz7PCzIl0/No0lHyaWdqVD2jotxOSFMQ==} + peerDependencies: + markdownlint-cli2: '>=0.0.4' + + markdownlint-cli2@0.23.2: + resolution: {integrity: sha512-eUhcnkSpzURo/o4htSqc7LPDszgOOTknhU4eY/sPHvMCLxnTCYscv1gw1/js/idmaZPisv9ECVEIORcllqjTUw==} + engines: {node: '>=22'} + hasBin: true + + markdownlint@0.41.1: + resolution: {integrity: sha512-qHKeU2E1bdyNAT077go2FVTNXvYcktN5IHtF6XyeD1l0PClxzSp2tUApAV14ORI8DGX4H9bNKZEzelZp4qn8IA==} + engines: {node: '>=22'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mdurl@2.1.0: + resolution: {integrity: sha512-1+HBaOx0zi/dQWht8rNv9MYf9qqpqL/kxI0hXImU6Y547zM6Sni8BQibt7ifgMcYtQg41ao3Ivd6cnSM86inpg==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-extension-directive@4.0.0: + resolution: {integrity: sha512-/C2nqVmXXmiseSSuCdItCMho7ybwwop6RrrRPk0KbOHW21JKoCldC+8rFOaundDoRBUWBnJJcxeA/Kvi34WQXg==} + + micromark-extension-gfm-autolink-literal@2.1.0: + resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==} + + micromark-extension-gfm-footnote@2.1.0: + resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==} + + micromark-extension-gfm-table@2.1.1: + resolution: {integrity: sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==} + + micromark-extension-math@3.1.0: + resolution: {integrity: sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + motion@10.16.2: + resolution: {integrity: sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + + mustache@4.0.0: + resolution: {integrity: sha512-FJgjyX/IVkbXBXYUwH+OYwQKqWpFPLaLVESd70yHjSDunwzV2hZOoTBvPf4KLoxesUzzyfTH6F784Uqd7Wm5yA==} + engines: {npm: '>=1.4.0'} + hasBin: true + + nan@2.28.0: + resolution: {integrity: sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==} + + nanoid@3.3.18: + resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + near-abi@0.2.0: + resolution: {integrity: sha512-kCwSf/3fraPU2zENK18sh+kKG4uKbEUEQdyWQkmW8ZofmLarObIz2+zAYjA1teDZLeMvEQew3UysnPDXgjneaA==} + + near-api-js@5.1.1: + resolution: {integrity: sha512-h23BGSKxNv8ph+zU6snicstsVK1/CTXsQz4LuGGwoRE24Hj424nSe4+/1tzoiC285Ljf60kPAqRCmsfv9etF2g==} + + next@16.3.1: + resolution: {integrity: sha512-hsAp0i7Rh+/dhe7DGIeN2YlpLM1DP4MNxti9EtDMtqcO612X81MvvEj388/oTce9U1EcEIOWDlGq0zRwrBKvuA==} + engines: {node: '>=20.9.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.51.1 + babel-plugin-react-compiler: '*' + react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + babel-plugin-react-compiler: + optional: true + sass: + optional: true + + node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + + node-addon-api@5.1.0: + resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + + node-addon-api@8.9.2: + resolution: {integrity: sha512-VijLXbi3UACN69I0JVXJsX4tjACjNoQDgv2gTF6sx2wWEi8tkSg2eX8p5gSIFi8z2+DL3oHmY6OyKce38SDolg==} + engines: {node: ^18 || ^20 || >= 21} + + node-exports-info@1.6.2: + resolution: {integrity: sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==} + engines: {node: '>= 0.4'} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-mock-http@1.0.5: + resolution: {integrity: sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==} + + node-releases@2.0.53: + resolution: {integrity: sha512-D9UOmYG3UH1V+ENW56t5QXBwJw1YEY18ruVeus89Rw+SyIgjPkCO84bRzO3uNIYosJbNwiabWVn48o3uJLjxFQ==} + engines: {node: '>=18'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + own-keys@1.0.2: + resolution: {integrity: sha512-19YVAg7T+WTrxggPukVq7DjTv6+PJ867TmhCvBsYwmbFCsZd344rq2Ld1p0wo8f8Qrrhgp82c6FJRqdXWtSEhg==} + engines: {node: '>= 0.4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss@8.5.23: + resolution: {integrity: sha512-g50586zr4bZmwFiTlflMu8E0bDTb5I5gertgwAKmsdUlTQIhZtunzUlD1WSzwcVWPoAVpsrA6vlfCD7oXvRwgg==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.26: + resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + protobufjs@7.4.0: + resolution: {integrity: sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==} + engines: {node: '>=12.0.0'} + + proxy-compare@2.5.1: + resolution: {integrity: sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==} + + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + punycode.js@2.3.1: + resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pushdata-bitcoin@1.0.1: + resolution: {integrity: sha512-hw7rcYTJRAl4olM8Owe8x0fBuJJ+WGbMhQuLWOXEMN3PxPCKQHRkhfL+XG0+iXUmSHjkMmb3Ba55Mt21cZc9kQ==} + + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + react-dom@19.2.8: + resolution: {integrity: sha512-rVprimfGBG3DR+Tq0IQG2DT5PxKth1WIGDmj5yPmlzr4YBe7uyE+Du4oVqTDXZSHGGGXRtTJEGSSePyQCMBglQ==} + peerDependencies: + react: ^19.2.8 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react@19.2.8: + resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + 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'} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@2.0.0-next.7: + resolution: {integrity: sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==} + engines: {node: '>= 0.4'} + hasBin: true + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} + + ripple-address-codec@5.0.1: + resolution: {integrity: sha512-JQHLKuVJV8lv9Qobmn4aUM2Dpv9WRRLKnNWfM8tN02fAbUtG8mUPsu9q9UYX8P76G4qzytEc5ZKMp/3JggNYmw==} + engines: {node: '>= 18'} + + ripple-binary-codec@2.9.0: + resolution: {integrity: sha512-DOv4CPwm2B5mjAJNHE4tfes7tIqefi85iun8BskS7/i1PvLIwVydHIbTV5hbQ7eT69Zg4K5dtO1CzfuvQVAYvQ==} + engines: {node: '>= 18'} + + ripple-keypairs@2.0.0: + resolution: {integrity: sha512-b5rfL2EZiffmklqZk1W+dvSy97v3V/C7936WxCCgDynaGPp7GE6R2XO7EU9O2LlM/z95rj870IylYnOQs+1Rag==} + engines: {node: '>= 16'} + + rpc-websockets@9.3.9: + resolution: {integrity: sha512-2iQDaTB4g5fDB2ihrTFSJSibCEuxaRi1q7qTW7ZO9/M5/TC+ToHA4D9/ffNLEbAoHNNrcdeP05oATNk44SKZXA==} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + secp256k1@5.0.1: + resolution: {integrity: sha512-lDFs9AAIaWP9UCdtWrotXWWF9t8PWgQDcxqgAnpM9rMqxb3Oaq2J0thzPVSxBwdJgyQtkU/sYtFtbM1RSt/iYA==} + engines: {node: '>=18.0.0'} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.7.1: + resolution: {integrity: sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.7.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + engines: {node: '>=10'} + hasBin: true + + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + setprototypeof@1.1.1: + resolution: {integrity: sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + sha1@1.1.1: + resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} + + sharp@0.35.3: + resolution: {integrity: sha512-ej0zVHuZGHCiABXcNxeYhpRnPNPAcvbG8RMdBAhDAxLKkCRVSpK3Iyu7qbqw3JMzoj0REeM6f3tJLtVwl0023Q==} + engines: {node: '>=20.9.0'} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + smol-toml@1.7.0: + resolution: {integrity: sha512-aqVvWoyO21L23mb+drl4RmMXbf6N7FdHjAhTRA9ZBL7apWBgfWC16KjrASI+1p9GAroljyMHj6fK67i0UiTNvQ==} + engines: {node: '>= 18'} + + socks-proxy-agent@8.0.5: + resolution: {integrity: sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==} + engines: {node: '>= 14'} + + socks@2.8.9: + resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sodium-native@4.3.3: + resolution: {integrity: sha512-OnxSlN3uyY8D0EsLHpmm2HOFmKddQVvEMmsakCrXUzSd8kjjbzL413t4ZNF3n0UxSwNgwTyUvkmZHTfuCeiYSw==} + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + stream-browserify@3.0.0: + resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} + + stream-chain@2.2.5: + resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==} + + stream-json@1.9.1: + resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@8.2.1: + resolution: {integrity: sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA==} + engines: {node: '>=20'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.11: + resolution: {integrity: sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.10: + resolution: {integrity: sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-jsx@5.1.6: + resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + superstruct@2.0.2: + resolution: {integrity: sha512-uV+TFRZdXsqXTL2pRvujROjdZQ4RAlBUS5BTh9IGm+jTqQntYThciG/qu57Gs69yjnVUSqdxF9YLmSnpupBW9A==} + engines: {node: '>=14.0.0'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tailwind-merge@3.6.0: + resolution: {integrity: sha512-uxL7qAVQriqRQPAyK3pj66VqskWqoZ37PW94jwOTwNfq/z9oyu1V+eqrZqtR2+fCiXdYOZe/Modt8GtvqNzu+w==} + + tailwindcss@4.3.3: + resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + text-encoding-utf-8@1.0.2: + resolution: {integrity: sha512-8bw4MY9WjdsD2aMtO0OzOCY3pXGYNx2d2FfHRVUKkiCPDWjKuOlhLVASS+pD7VkLTVjW268LYJHwsnPFlBpbAg==} + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + tiny-secp256k1@1.1.7: + resolution: {integrity: sha512-eb+F6NabSnjbLwNoC+2o5ItbmP1kg7HliWue71JgLegQt6A5mTN8YbvTLCazdlg6e5SV6A+r8OGvZYskdlmhqQ==} + engines: {node: '>=6.0.0'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.0: + resolution: {integrity: sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==} + engines: {node: '>=0.6'} + + toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tweetnacl-util@0.15.1: + resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.8: + resolution: {integrity: sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==} + engines: {node: '>= 0.4'} + + typeforce@1.18.0: + resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} + + typescript-eslint@8.67.0: + resolution: {integrity: sha512-S2udFs8tCKEKffuJ4TB1idGUZiXdCPGi3IPBGWXarbLQ5UPXORV8QEVzJ4gCRduURMb5EkpNCdjbk0eDIuI8Yg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ua-is-frozen@0.1.2: + resolution: {integrity: sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw==} + + ua-parser-js@2.0.10: + resolution: {integrity: sha512-t+3Ktbq0Ies2vaSezfOaWiolH4OigQIO1dk+1xDpOydB1COVPocVYOrEV5rqZ0kFY9XYG1v9LutCyMgYBpABcw==} + hasBin: true + + uc.micro@2.1.0: + resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==} + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + uint8array-tools@0.0.8: + resolution: {integrity: sha512-xS6+s8e0Xbx++5/0L+yyexukU7pz//Yg6IHg3BKhXotg1JcYtgxVcUctQ0HxLByiJzpAkNFawz1Nz5Xadzo82g==} + engines: {node: '>=14.0.0'} + + uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@7.18.2: + resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + + undici-types@7.29.0: + resolution: {integrity: sha512-vamA8dGlzMwhpyYpQp9d8vka3o4D/yn5I7ez7Or+msDA4bZ8Uh+Zy91WvWf3I73gDAkFha9JcYRqm2li0Npfgg==} + + unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + + unicorn-magic@0.4.0: + resolution: {integrity: sha512-wH590V9VNgYH9g3lH9wWjTrUoKsjLF6sGLjhR4sH1LWpLmCOH0Zf7PukhDA8BiS7KHe4oPNkcTHqYkj7SOGUOw==} + engines: {node: '>=20'} + + unrs-resolver@1.12.2: + resolution: {integrity: sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==} + + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + 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 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + 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/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + update-browserslist-db@1.3.1: + resolution: {integrity: sha512-ZZ61DsRsOnakl74HAmp3oSN4aXUmEWXf+i/yv0h7tIBfICc3VdrFErQKUUKPgu3AMsTUMbcongALEN4l6GSUrQ==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urijs@1.19.11: + resolution: {integrity: sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==} + + usb@2.18.0: + resolution: {integrity: sha512-klAJPUTaSxRvTgrIh7om6UTrgRxdzioD+rJc/MaoiN8+OGdqRzai39tR00asnoCesPNikItWB9zBZoo0pJsWaA==} + engines: {node: '>=12.22.0 <13.0 || >=14.17.0'} + + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + utf-8-validate@6.0.6: + resolution: {integrity: sha512-q3l3P9UtEEiAHcsgsqTgf9PPjctrDWoIXW3NpOHFdRDbLvu4DLIcxHangJ4RLrWkBcKjmcs/6NkerI8T/rE4LA==} + engines: {node: '>=6.14.2'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid4@2.0.3: + resolution: {integrity: sha512-CTpAkEVXMNJl2ojgtpLXHgz23dh8z81u6/HEPiQFOvBc/c2pde6TVHmH4uwY0d/GLF3tb7+VDAj4+2eJaQSdZQ==} + + uuid@14.0.1: + resolution: {integrity: sha512-6ZxzVpzDXDa3bJWaHilVayA+BH/1zmxCJoVgvmqJnid/gPoKHxUrS/aC/T6LGQtNHT+XHG9fXPJB4d+IrU30Ew==} + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). + hasBin: true + + valtio@1.11.2: + resolution: {integrity: sha512-1XfIxnUXzyswPAPXo1P3Pdx2mq/pIqZICkWN60Hby0d9Iqb+MEIpqgYVlbflvHdrp2YR/q3jyKWRPJJ100yxaw==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + + varuint-bitcoin@2.0.0: + resolution: {integrity: sha512-6QZbU/rHO2ZQYpWFDALCDSRsXbAs1VOEmXAxtbtjLtKuMJ/FQ8YbhfxlaiKv5nklci0M6lZtlZyxo9Q+qNnyog==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.22: + resolution: {integrity: sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wif@5.0.0: + resolution: {integrity: sha512-iFzrC/9ne740qFbNjTZ2FciSRJlHIXoxqk/Y5EnE08QOXu1WjJyCCswwDTYbohAOEnlCtLaAAQBhyaLRFh2hMA==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@7.5.13: + resolution: {integrity: sha512-rsKI6xDBFVf4r/x8XyChGK04QR/XHroxs/jUcoWvtEZM8TPU/X/uIY9B1CsSzYws9ZJb/6bbBu7dPhFW00CAoA==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.21.3: + resolution: {integrity: sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xrpl@4.6.0: + resolution: {integrity: sha512-0nXZfqDHRJ6bsDv1WtA9MdCYalMtXuxVa9mtLdqT3xypRKf2LwT5DbuGL/kHcVfuqk3B+ly+SFARlrnX+LHtRQ==} + engines: {node: '>=18.0.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + +snapshots: + + '@albedo-link/intent@0.12.0': {} + + '@alloc/quick-lru@5.2.0': {} + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.7': {} + + '@babel/core@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-compilation-targets': 7.29.7 + '@babel/helper-module-transforms': 7.29.7(@babel/core@7.29.7) + '@babel/helpers': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/template': 7.29.7 + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.8': + dependencies: + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-compilation-targets@7.29.7': + dependencies: + '@babel/compat-data': 7.29.7 + '@babel/helper-validator-option': 7.29.7 + browserslist: 4.28.8 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-globals@7.29.7': {} + + '@babel/helper-module-imports@7.29.7': + dependencies: + '@babel/traverse': 7.29.8 + '@babel/types': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7)': + dependencies: + '@babel/core': 7.29.7 + '@babel/helper-module-imports': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + '@babel/traverse': 7.29.8 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/helper-validator-option@7.29.7': {} + + '@babel/helpers@7.29.7': + dependencies: + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + + '@babel/parser@7.29.8': + dependencies: + '@babel/types': 7.29.8 + + '@babel/runtime@7.29.7': {} + + '@babel/template@7.29.7': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/types': 7.29.8 + + '@babel/traverse@7.29.8': + dependencies: + '@babel/code-frame': 7.29.7 + '@babel/generator': 7.29.8 + '@babel/helper-globals': 7.29.7 + '@babel/parser': 7.29.8 + '@babel/template': 7.29.7 + '@babel/types': 7.29.8 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@creit.tech/stellar-wallets-kit@1.9.5(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@stellar/stellar-base@14.1.0)(@stellar/stellar-sdk@14.6.1)(@trezor/connect@9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(@types/react@19.2.18)(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(near-api-js@5.1.1)(react@19.2.8)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@albedo-link/intent': 0.12.0 + '@creit.tech/xbull-wallet-connect': 0.4.0 + '@hot-wallet/sdk': 1.0.11(bufferutil@4.1.0)(near-api-js@5.1.1)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@ledgerhq/hw-app-str': 7.0.4 + '@ledgerhq/hw-transport': 6.31.4 + '@ledgerhq/hw-transport-webusb': 6.29.4 + '@lobstrco/signer-extension-api': 1.0.0-beta.0 + '@ngneat/elf': 2.5.1(rxjs@7.8.1) + '@ngneat/elf-devtools': 1.3.0 + '@ngneat/elf-entities': 5.0.2(@ngneat/elf@2.5.1(rxjs@7.8.1))(rxjs@7.8.1) + '@ngneat/elf-persist-state': 1.2.1(rxjs@7.8.1) + '@stellar/freighter-api': 5.0.0 + '@stellar/stellar-base': 14.1.0 + '@trezor/connect-plugin-stellar': 9.2.1(@stellar/stellar-sdk@14.6.1)(@trezor/connect@9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(tslib@2.8.1) + '@trezor/connect-web': 9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@walletconnect/modal': 2.6.2(@types/react@19.2.18)(react@19.2.8) + '@walletconnect/sign-client': 2.11.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + buffer: 6.0.3 + events: 3.3.0 + lit: 3.2.0 + rxjs: 7.8.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@solana/sysvars' + - '@stellar/stellar-sdk' + - '@trezor/connect' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bare-url + - bufferutil + - db0 + - debug + - encoding + - expo-constants + - expo-localization + - fastestsmallesttextencoderdecoder + - ioredis + - near-api-js + - react + - react-native + - supports-color + - tslib + - typescript + - uploadthing + - utf-8-validate + - ws + + '@creit.tech/xbull-wallet-connect@0.4.0': + dependencies: + rxjs: 7.8.1 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.11.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emurgo/cardano-serialization-lib-browser@13.2.1': {} + + '@emurgo/cardano-serialization-lib-nodejs@13.2.0': {} + + '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0))': + dependencies: + eslint: 9.39.5(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.5(jiti@2.7.0))': + dependencies: + eslint: 9.39.5(jiti@2.7.0) + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@3.3.6': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.3.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.39.5': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@ethereumjs/common@10.1.2': + dependencies: + '@ethereumjs/util': 10.1.2 + eventemitter3: 5.0.4 + + '@ethereumjs/rlp@10.1.2': {} + + '@ethereumjs/tx@10.1.2': + dependencies: + '@ethereumjs/common': 10.1.2 + '@ethereumjs/rlp': 10.1.2 + '@ethereumjs/util': 10.1.2 + '@noble/curves': 2.3.0 + '@noble/hashes': 2.3.0 + + '@ethereumjs/util@10.1.2': + dependencies: + '@ethereumjs/rlp': 10.1.2 + '@noble/curves': 2.3.0 + '@noble/hashes': 2.3.0 + + '@fivebinaries/coin-selection@3.0.0': + dependencies: + '@emurgo/cardano-serialization-lib-browser': 13.2.1 + '@emurgo/cardano-serialization-lib-nodejs': 13.2.0 + + '@hot-wallet/sdk@1.0.11(bufferutil@4.1.0)(near-api-js@5.1.1)(typescript@5.9.3)(utf-8-validate@6.0.6)': + dependencies: + '@near-js/crypto': 1.4.2 + '@near-js/utils': 1.1.0 + '@near-wallet-selector/core': 8.10.2(near-api-js@5.1.1) + '@solana/wallet-adapter-base': 0.9.27(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)) + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + borsh: 2.0.0 + js-sha256: 0.11.1 + sha1: 1.1.1 + uuid4: 2.0.3 + transitivePeerDependencies: + - bufferutil + - encoding + - near-api-js + - typescript + - utf-8-validate + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@img/colour@1.1.0': + optional: true + + '@img/sharp-darwin-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.3.2 + optional: true + + '@img/sharp-darwin-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.3.2 + optional: true + + '@img/sharp-freebsd-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-darwin-x64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-arm@1.3.2': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.3.2': + optional: true + + '@img/sharp-libvips-linux-s390x@1.3.2': + optional: true + + '@img/sharp-libvips-linux-x64@1.3.2': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.3.2': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.3.2': + optional: true + + '@img/sharp-linux-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.3.2 + optional: true + + '@img/sharp-linux-arm@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.3.2 + optional: true + + '@img/sharp-linux-ppc64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.3.2 + optional: true + + '@img/sharp-linux-riscv64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.3.2 + optional: true + + '@img/sharp-linux-s390x@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.3.2 + optional: true + + '@img/sharp-linux-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.3.2 + optional: true + + '@img/sharp-linuxmusl-arm64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + optional: true + + '@img/sharp-linuxmusl-x64@0.35.3': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + optional: true + + '@img/sharp-wasm32@0.35.3': + dependencies: + '@emnapi/runtime': 1.11.3 + optional: true + + '@img/sharp-webcontainers-wasm32@0.35.3': + dependencies: + '@img/sharp-wasm32': 0.35.3 + optional: true + + '@img/sharp-win32-arm64@0.35.3': + optional: true + + '@img/sharp-win32-ia32@0.35.3': + optional: true + + '@img/sharp-win32-x64@0.35.3': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@ledgerhq/devices@8.17.0': + dependencies: + semver: 7.7.3 + + '@ledgerhq/errors@6.37.0': {} + + '@ledgerhq/hw-app-str@7.0.4': + dependencies: + '@ledgerhq/errors': 6.37.0 + '@ledgerhq/hw-transport': 6.31.4 + bip32-path: 0.4.2 + + '@ledgerhq/hw-transport-webusb@6.29.4': + dependencies: + '@ledgerhq/devices': 8.17.0 + '@ledgerhq/errors': 6.37.0 + '@ledgerhq/hw-transport': 6.31.4 + '@ledgerhq/logs': 6.17.0 + + '@ledgerhq/hw-transport@6.31.4': + dependencies: + '@ledgerhq/devices': 8.17.0 + '@ledgerhq/errors': 6.37.0 + '@ledgerhq/logs': 6.17.0 + events: 3.3.0 + + '@ledgerhq/logs@6.17.0': {} + + '@lit-labs/ssr-dom-shim@1.6.0': {} + + '@lit/reactive-element@1.6.3': + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + + '@lit/reactive-element@2.1.2': + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + + '@lobstrco/signer-extension-api@1.0.0-beta.0': {} + + '@mobily/ts-belt@3.13.1': {} + + '@motionone/animation@10.18.0': + dependencies: + '@motionone/easing': 10.18.0 + '@motionone/types': 10.17.1 + '@motionone/utils': 10.18.0 + tslib: 2.8.1 + + '@motionone/dom@10.18.0': + dependencies: + '@motionone/animation': 10.18.0 + '@motionone/generators': 10.18.0 + '@motionone/types': 10.17.1 + '@motionone/utils': 10.18.0 + hey-listen: 1.0.8 + tslib: 2.8.1 + + '@motionone/easing@10.18.0': + dependencies: + '@motionone/utils': 10.18.0 + tslib: 2.8.1 + + '@motionone/generators@10.18.0': + dependencies: + '@motionone/types': 10.17.1 + '@motionone/utils': 10.18.0 + tslib: 2.8.1 + + '@motionone/svelte@10.16.4': + dependencies: + '@motionone/dom': 10.18.0 + tslib: 2.8.1 + + '@motionone/types@10.17.1': {} + + '@motionone/utils@10.18.0': + dependencies: + '@motionone/types': 10.17.1 + hey-listen: 1.0.8 + tslib: 2.8.1 + + '@motionone/vue@10.16.4': + dependencies: + '@motionone/dom': 10.18.0 + tslib: 2.8.1 + + '@napi-rs/wasm-runtime@1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0)': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.3 + optional: true + + '@near-js/accounts@1.4.1': + dependencies: + '@near-js/crypto': 1.4.2 + '@near-js/providers': 1.0.3 + '@near-js/signers': 0.2.2 + '@near-js/transactions': 1.3.3 + '@near-js/types': 0.3.1 + '@near-js/utils': 1.1.0 + '@noble/hashes': 1.7.1 + borsh: 1.0.0 + depd: 2.0.0 + is-my-json-valid: 2.20.6 + lru_map: 0.4.1 + near-abi: 0.2.0 + transitivePeerDependencies: + - encoding + + '@near-js/crypto@1.4.2': + dependencies: + '@near-js/types': 0.3.1 + '@near-js/utils': 1.1.0 + '@noble/curves': 1.8.1 + borsh: 1.0.0 + randombytes: 2.1.0 + secp256k1: 5.0.1 + + '@near-js/keystores-browser@0.2.2': + dependencies: + '@near-js/crypto': 1.4.2 + '@near-js/keystores': 0.2.2 + + '@near-js/keystores-node@0.1.2': + dependencies: + '@near-js/crypto': 1.4.2 + '@near-js/keystores': 0.2.2 + + '@near-js/keystores@0.2.2': + dependencies: + '@near-js/crypto': 1.4.2 + '@near-js/types': 0.3.1 + + '@near-js/providers@1.0.3': + dependencies: + '@near-js/transactions': 1.3.3 + '@near-js/types': 0.3.1 + '@near-js/utils': 1.1.0 + borsh: 1.0.0 + exponential-backoff: 3.1.3 + optionalDependencies: + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + + '@near-js/signers@0.2.2': + dependencies: + '@near-js/crypto': 1.4.2 + '@near-js/keystores': 0.2.2 + '@noble/hashes': 1.3.3 + + '@near-js/transactions@1.3.3': + dependencies: + '@near-js/crypto': 1.4.2 + '@near-js/signers': 0.2.2 + '@near-js/types': 0.3.1 + '@near-js/utils': 1.1.0 + '@noble/hashes': 1.7.1 + borsh: 1.0.0 + + '@near-js/types@0.3.1': {} + + '@near-js/utils@1.1.0': + dependencies: + '@near-js/types': 0.3.1 + '@scure/base': 1.2.6 + depd: 2.0.0 + mustache: 4.0.0 + + '@near-js/wallet-account@1.3.3': + dependencies: + '@near-js/accounts': 1.4.1 + '@near-js/crypto': 1.4.2 + '@near-js/keystores': 0.2.2 + '@near-js/providers': 1.0.3 + '@near-js/signers': 0.2.2 + '@near-js/transactions': 1.3.3 + '@near-js/types': 0.3.1 + '@near-js/utils': 1.1.0 + borsh: 1.0.0 + transitivePeerDependencies: + - encoding + + '@near-wallet-selector/core@8.10.2(near-api-js@5.1.1)': + dependencies: + borsh: 1.0.0 + events: 3.3.0 + js-sha256: 0.9.0 + near-api-js: 5.1.1 + rxjs: 7.8.1 + + '@next/env@16.3.1': {} + + '@next/eslint-plugin-next@16.3.1(eslint@9.39.5(jiti@2.7.0))': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.5(jiti@2.7.0)) + fast-glob: 3.3.1 + transitivePeerDependencies: + - eslint + + '@next/swc-darwin-arm64@16.3.1': + optional: true + + '@next/swc-darwin-x64@16.3.1': + optional: true + + '@next/swc-linux-arm64-gnu@16.3.1': + optional: true + + '@next/swc-linux-arm64-musl@16.3.1': + optional: true + + '@next/swc-linux-x64-gnu@16.3.1': + optional: true + + '@next/swc-linux-x64-musl@16.3.1': + optional: true + + '@next/swc-win32-arm64-msvc@16.3.1': + optional: true + + '@next/swc-win32-x64-msvc@16.3.1': + optional: true + + '@ngneat/elf-devtools@1.3.0': {} + + '@ngneat/elf-entities@5.0.2(@ngneat/elf@2.5.1(rxjs@7.8.1))(rxjs@7.8.1)': + dependencies: + '@ngneat/elf': 2.5.1(rxjs@7.8.1) + rxjs: 7.8.1 + + '@ngneat/elf-persist-state@1.2.1(rxjs@7.8.1)': + dependencies: + rxjs: 7.8.1 + + '@ngneat/elf@2.5.1(rxjs@7.8.1)': + dependencies: + rxjs: 7.8.1 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@2.3.0': + dependencies: + '@noble/hashes': 2.3.0 + + '@noble/hashes@1.3.3': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.8.0': {} + + '@noble/hashes@2.3.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.1': {} + + '@protobufjs/fetch@1.1.1': + dependencies: + '@protobufjs/aspromise': 1.1.2 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.2': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.2': {} + + '@rtsao/scc@1.1.0': {} + + '@scure/base@1.2.6': {} + + '@scure/base@2.3.0': {} + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@sinclair/typebox@0.33.24': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + + '@solana-program/stake@0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + + '@solana-program/system@0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + + '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + + '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + + '@solana/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/addresses@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/assertions': 2.3.0(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/assertions@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/buffer-layout@4.0.1': + dependencies: + buffer: 6.0.3 + + '@solana/codecs-core@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-data-structures@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-numbers@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 5.9.3 + + '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/options': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@2.3.0(typescript@5.9.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.3 + typescript: 5.9.3 + + '@solana/fast-stable-stringify@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/functional@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/instructions@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/keys@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/assertions': 2.3.0(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/nominal-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/programs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-parsed-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + ws: 7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + '@solana/rpc-subscriptions-spec@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/rpc-transformers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transport-http@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + undici-types: 7.29.0 + + '@solana/rpc-types@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/rpc-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-transport-http': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/signers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/subscribable@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/transaction-messages@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/wallet-adapter-base@0.9.27(@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6))': + dependencies: + '@solana/wallet-standard-features': 1.4.0 + '@solana/web3.js': 1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6) + '@wallet-standard/base': 1.1.1 + '@wallet-standard/features': 1.1.1 + eventemitter3: 5.0.4 + + '@solana/wallet-standard-features@1.4.0': + dependencies: + '@wallet-standard/base': 1.1.1 + '@wallet-standard/features': 1.1.1 + + '@solana/web3.js@1.98.4(bufferutil@4.1.0)(typescript@5.9.3)(utf-8-validate@6.0.6)': + dependencies: + '@babel/runtime': 7.29.7 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@solana/buffer-layout': 4.0.1 + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + agentkeepalive: 4.6.0 + bn.js: 5.2.5 + borsh: 0.7.0 + bs58: 4.0.1 + buffer: 6.0.3 + fast-stable-stringify: 1.0.0 + jayson: 4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + node-fetch: 2.7.0 + rpc-websockets: 9.3.9 + superstruct: 2.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + + '@stablelib/aead@1.0.1': {} + + '@stablelib/binary@1.0.1': + dependencies: + '@stablelib/int': 1.0.1 + + '@stablelib/bytes@1.0.1': {} + + '@stablelib/chacha20poly1305@1.0.1': + dependencies: + '@stablelib/aead': 1.0.1 + '@stablelib/binary': 1.0.1 + '@stablelib/chacha': 1.0.1 + '@stablelib/constant-time': 1.0.1 + '@stablelib/poly1305': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/chacha@1.0.1': + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/constant-time@1.0.1': {} + + '@stablelib/hash@1.0.1': {} + + '@stablelib/hkdf@1.0.1': + dependencies: + '@stablelib/hash': 1.0.1 + '@stablelib/hmac': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/hmac@1.0.1': + dependencies: + '@stablelib/constant-time': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/int@1.0.1': {} + + '@stablelib/keyagreement@1.0.1': + dependencies: + '@stablelib/bytes': 1.0.1 + + '@stablelib/poly1305@1.0.1': + dependencies: + '@stablelib/constant-time': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/random@1.0.2': + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/sha256@1.0.1': + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + + '@stablelib/wipe@1.0.1': {} + + '@stablelib/x25519@1.0.3': + dependencies: + '@stablelib/keyagreement': 1.0.1 + '@stablelib/random': 1.0.2 + '@stablelib/wipe': 1.0.1 + + '@stellar/freighter-api@5.0.0': + dependencies: + buffer: 6.0.3 + semver: 7.7.1 + + '@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.12 + tweetnacl: 1.0.3 + optionalDependencies: + sodium-native: 4.3.3 + transitivePeerDependencies: + - bare-url + + '@stellar/stellar-base@14.1.0': + dependencies: + '@noble/curves': 1.9.7 + '@stellar/js-xdr': 3.1.2 + base32.js: 0.1.0 + bignumber.js: 9.3.1 + buffer: 6.0.3 + sha.js: 2.4.12 + + '@stellar/stellar-sdk@13.3.0': + dependencies: + '@stellar/stellar-base': 13.1.0 + axios: 1.19.0 + 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 + - supports-color + + '@stellar/stellar-sdk@14.6.1': + dependencies: + '@stellar/stellar-base': 14.1.0 + axios: 1.19.0 + bignumber.js: 9.3.1 + commander: 14.0.3 + eventsource: 2.0.2 + feaxios: 0.0.23 + randombytes: 2.1.0 + toml: 3.0.0 + urijs: 1.19.11 + transitivePeerDependencies: + - debug + - supports-color + + '@swc/helpers@0.5.23': + dependencies: + tslib: 2.8.1 + + '@tailwindcss/node@4.3.3': + dependencies: + '@jridgewell/remapping': 2.3.5 + enhanced-resolve: 5.24.5 + jiti: 2.7.0 + lightningcss: 1.32.0 + magic-string: 0.30.21 + source-map-js: 1.2.1 + tailwindcss: 4.3.3 + + '@tailwindcss/oxide-android-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-arm64@4.3.3': + optional: true + + '@tailwindcss/oxide-darwin-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-freebsd-x64@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm-gnueabihf@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-arm64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-gnu@4.3.3': + optional: true + + '@tailwindcss/oxide-linux-x64-musl@4.3.3': + optional: true + + '@tailwindcss/oxide-wasm32-wasi@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-arm64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide-win32-x64-msvc@4.3.3': + optional: true + + '@tailwindcss/oxide@4.3.3': + optionalDependencies: + '@tailwindcss/oxide-android-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-arm64': 4.3.3 + '@tailwindcss/oxide-darwin-x64': 4.3.3 + '@tailwindcss/oxide-freebsd-x64': 4.3.3 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.3.3 + '@tailwindcss/oxide-linux-arm64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-arm64-musl': 4.3.3 + '@tailwindcss/oxide-linux-x64-gnu': 4.3.3 + '@tailwindcss/oxide-linux-x64-musl': 4.3.3 + '@tailwindcss/oxide-wasm32-wasi': 4.3.3 + '@tailwindcss/oxide-win32-arm64-msvc': 4.3.3 + '@tailwindcss/oxide-win32-x64-msvc': 4.3.3 + + '@tailwindcss/postcss@4.3.3': + dependencies: + '@alloc/quick-lru': 5.2.0 + '@tailwindcss/node': 4.3.3 + '@tailwindcss/oxide': 4.3.3 + postcss: 8.5.26 + tailwindcss: 4.3.3 + + '@trezor/analytics@1.4.2(tslib@2.8.1)': + dependencies: + '@trezor/env-utils': 1.4.2(tslib@2.8.1) + '@trezor/utils': 9.4.2(tslib@2.8.1) + tslib: 2.8.1 + transitivePeerDependencies: + - expo-constants + - expo-localization + - react-native + + '@trezor/blockchain-link-types@1.4.2(tslib@2.8.1)': + dependencies: + '@trezor/utxo-lib': 2.4.2(tslib@2.8.1) + tslib: 2.8.1 + + '@trezor/blockchain-link-utils@1.4.2(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)': + dependencies: + '@mobily/ts-belt': 3.13.1 + '@stellar/stellar-sdk': 13.3.0 + '@trezor/env-utils': 1.4.2(tslib@2.8.1) + '@trezor/utils': 9.4.2(tslib@2.8.1) + tslib: 2.8.1 + xrpl: 4.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bare-url + - bufferutil + - debug + - expo-constants + - expo-localization + - react-native + - supports-color + - utf-8-validate + + '@trezor/blockchain-link@2.5.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@solana-program/stake': 0.2.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))) + '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@stellar/stellar-sdk': 13.3.0 + '@trezor/blockchain-link-types': 1.4.2(tslib@2.8.1) + '@trezor/blockchain-link-utils': 1.4.2(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6) + '@trezor/env-utils': 1.4.2(tslib@2.8.1) + '@trezor/utils': 9.4.2(tslib@2.8.1) + '@trezor/utxo-lib': 2.4.2(tslib@2.8.1) + '@trezor/websocket-client': 1.2.2(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6) + '@types/web': 0.0.197 + events: 3.3.0 + socks-proxy-agent: 8.0.5 + tslib: 2.8.1 + xrpl: 4.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - '@solana/sysvars' + - bare-url + - bufferutil + - debug + - expo-constants + - expo-localization + - fastestsmallesttextencoderdecoder + - react-native + - supports-color + - typescript + - utf-8-validate + - ws + + '@trezor/connect-analytics@1.3.5(tslib@2.8.1)': + dependencies: + '@trezor/analytics': 1.4.2(tslib@2.8.1) + tslib: 2.8.1 + transitivePeerDependencies: + - expo-constants + - expo-localization + - react-native + + '@trezor/connect-common@0.4.2(tslib@2.8.1)': + dependencies: + '@trezor/env-utils': 1.4.2(tslib@2.8.1) + '@trezor/utils': 9.4.2(tslib@2.8.1) + tslib: 2.8.1 + transitivePeerDependencies: + - expo-constants + - expo-localization + - react-native + + '@trezor/connect-plugin-stellar@9.2.1(@stellar/stellar-sdk@14.6.1)(@trezor/connect@9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(tslib@2.8.1)': + dependencies: + '@stellar/stellar-sdk': 14.6.1 + '@trezor/connect': 9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@trezor/utils': 9.4.1(tslib@2.8.1) + tslib: 2.8.1 + + '@trezor/connect-web@9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@trezor/connect': 9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@trezor/connect-common': 0.4.2(tslib@2.8.1) + '@trezor/utils': 9.4.2(tslib@2.8.1) + '@trezor/websocket-client': 1.2.2(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6) + tslib: 2.8.1 + transitivePeerDependencies: + - '@solana/sysvars' + - bare-url + - bufferutil + - debug + - encoding + - expo-constants + - expo-localization + - fastestsmallesttextencoderdecoder + - react-native + - supports-color + - typescript + - utf-8-validate + - ws + + '@trezor/connect@9.6.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))': + dependencies: + '@ethereumjs/common': 10.1.2 + '@ethereumjs/tx': 10.1.2 + '@fivebinaries/coin-selection': 3.0.0 + '@mobily/ts-belt': 3.13.1 + '@noble/hashes': 1.8.0 + '@scure/bip39': 1.6.0 + '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))) + '@solana-program/system': 0.7.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))) + '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6))) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@trezor/blockchain-link': 2.5.2(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(bufferutil@4.1.0)(fastestsmallesttextencoderdecoder@1.0.22)(tslib@2.8.1)(typescript@5.9.3)(utf-8-validate@6.0.6)(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + '@trezor/blockchain-link-types': 1.4.2(tslib@2.8.1) + '@trezor/blockchain-link-utils': 1.4.2(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6) + '@trezor/connect-analytics': 1.3.5(tslib@2.8.1) + '@trezor/connect-common': 0.4.2(tslib@2.8.1) + '@trezor/crypto-utils': 1.1.4(tslib@2.8.1) + '@trezor/device-utils': 1.1.2 + '@trezor/env-utils': 1.5.0(tslib@2.8.1) + '@trezor/protobuf': 1.4.2(tslib@2.8.1) + '@trezor/protocol': 1.2.8(tslib@2.8.1) + '@trezor/schema-utils': 1.3.4(tslib@2.8.1) + '@trezor/transport': 1.5.2(tslib@2.8.1) + '@trezor/type-utils': 1.1.8 + '@trezor/utils': 9.4.2(tslib@2.8.1) + '@trezor/utxo-lib': 2.4.2(tslib@2.8.1) + blakejs: 1.2.1 + bs58: 6.0.0 + bs58check: 4.0.0 + cross-fetch: 4.1.0 + jws: 4.0.1 + tslib: 2.8.1 + transitivePeerDependencies: + - '@solana/sysvars' + - bare-url + - bufferutil + - debug + - encoding + - expo-constants + - expo-localization + - fastestsmallesttextencoderdecoder + - react-native + - supports-color + - typescript + - utf-8-validate + - ws + + '@trezor/crypto-utils@1.1.4(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@trezor/device-utils@1.1.2': {} + + '@trezor/env-utils@1.4.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + ua-parser-js: 2.0.10 + + '@trezor/env-utils@1.5.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + ua-parser-js: 2.0.10 + + '@trezor/protobuf@1.4.2(tslib@2.8.1)': + dependencies: + '@trezor/schema-utils': 1.3.4(tslib@2.8.1) + long: 5.2.5 + protobufjs: 7.4.0 + tslib: 2.8.1 + + '@trezor/protocol@1.2.8(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@trezor/schema-utils@1.3.4(tslib@2.8.1)': + dependencies: + '@sinclair/typebox': 0.33.24 + ts-mixer: 6.0.4 + tslib: 2.8.1 + + '@trezor/transport@1.5.2(tslib@2.8.1)': + dependencies: + '@trezor/protobuf': 1.4.2(tslib@2.8.1) + '@trezor/protocol': 1.2.8(tslib@2.8.1) + '@trezor/type-utils': 1.1.8 + '@trezor/utils': 9.4.2(tslib@2.8.1) + cross-fetch: 4.1.0 + tslib: 2.8.1 + usb: 2.18.0 + transitivePeerDependencies: + - encoding + + '@trezor/type-utils@1.1.8': {} + + '@trezor/utils@9.4.1(tslib@2.8.1)': + dependencies: + bignumber.js: 9.3.1 + tslib: 2.8.1 + + '@trezor/utils@9.4.2(tslib@2.8.1)': + dependencies: + bignumber.js: 9.3.1 + tslib: 2.8.1 + + '@trezor/utxo-lib@2.4.2(tslib@2.8.1)': + dependencies: + '@trezor/utils': 9.4.2(tslib@2.8.1) + bchaddrjs: 0.5.2 + bech32: 2.0.0 + bip66: 2.0.0 + bitcoin-ops: 1.4.1 + blake-hash: 2.0.0 + blakejs: 1.2.1 + bn.js: 5.2.5 + bs58: 6.0.0 + bs58check: 4.0.0 + create-hmac: 1.1.7 + int64-buffer: 1.1.1 + pushdata-bitcoin: 1.0.1 + tiny-secp256k1: 1.1.7 + tslib: 2.8.1 + typeforce: 1.18.0 + varuint-bitcoin: 2.0.0 + wif: 5.0.0 + + '@trezor/websocket-client@1.2.2(bufferutil@4.1.0)(tslib@2.8.1)(utf-8-validate@6.0.6)': + dependencies: + '@trezor/utils': 9.4.2(tslib@2.8.1) + tslib: 2.8.1 + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@tybys/wasm-util@0.10.3': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/connect@3.4.38': + dependencies: + '@types/node': 24.13.3 + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/estree@1.0.9': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} '@types/katex@0.16.8': {} - '@types/ms@2.1.0': {} + '@types/ms@2.1.0': {} + + '@types/node@12.20.55': {} + + '@types/node@24.13.3': + dependencies: + undici-types: 7.18.2 + + '@types/react-dom@19.2.4(@types/react@19.2.18)': + dependencies: + '@types/react': 19.2.18 + + '@types/react@19.2.18': + dependencies: + csstype: 3.2.3 + + '@types/trusted-types@2.0.7': {} + + '@types/unist@2.0.11': {} + + '@types/uuid@10.0.0': {} + + '@types/w3c-web-usb@1.0.14': {} + + '@types/web@0.0.197': {} + + '@types/ws@7.4.7': + dependencies: + '@types/node': 24.13.3 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 24.13.3 + + '@typescript-eslint/eslint-plugin@8.67.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/type-utils': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 + eslint: 9.39.5(jiti@2.7.0) + ignore: 7.0.6 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.67.0 + debug: 4.4.3 + eslint: 9.39.5(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.67.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.67.0': + dependencies: + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 + + '@typescript-eslint/tsconfig-utils@8.67.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.5(jiti@2.7.0) + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@8.67.0': {} + + '@typescript-eslint/typescript-estree@8.67.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.67.0(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.67.0(typescript@5.9.3) + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/visitor-keys': 8.67.0 + debug: 4.4.3 + minimatch: 10.2.6 + semver: 7.8.5 + tinyglobby: 0.2.17 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) + '@typescript-eslint/scope-manager': 8.67.0 + '@typescript-eslint/types': 8.67.0 + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + eslint: 9.39.5(jiti@2.7.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@8.67.0': + dependencies: + '@typescript-eslint/types': 8.67.0 + eslint-visitor-keys: 5.0.1 + + '@unrs/resolver-binding-android-arm-eabi@1.12.2': + optional: true + + '@unrs/resolver-binding-android-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-loong64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.12.2': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.12.2': + optional: true + + '@unrs/resolver-binding-openharmony-arm64@1.12.2': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.12.2': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@napi-rs/wasm-runtime': 1.2.3(@emnapi/core@1.10.0)(@emnapi/runtime@1.10.0) + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.12.2': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.12.2': + optional: true + + '@wallet-standard/base@1.1.1': {} + + '@wallet-standard/features@1.1.1': + dependencies: + '@wallet-standard/base': 1.1.1 + + '@walletconnect/core@2.11.2(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-provider': 1.0.13 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.14(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.3 + '@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.11.2 + '@walletconnect/utils': 2.11.2 + events: 3.3.0 + isomorphic-unfetch: 3.1.0 + lodash.isequal: 4.5.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - uploadthing + - utf-8-validate + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.1': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-provider@1.0.13': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-types@1.0.3': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.14(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.3.0 + unstorage: 1.17.5(idb-keyval@6.3.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@2.1.3': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/modal-core@2.6.2(@types/react@19.2.18)(react@19.2.8)': + dependencies: + valtio: 1.11.2(@types/react@19.2.18)(react@19.2.8) + transitivePeerDependencies: + - '@types/react' + - react + + '@walletconnect/modal-ui@2.6.2(@types/react@19.2.18)(react@19.2.8)': + dependencies: + '@walletconnect/modal-core': 2.6.2(@types/react@19.2.18)(react@19.2.8) + lit: 2.8.0 + motion: 10.16.2 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@types/react' + - react + + '@walletconnect/modal@2.6.2(@types/react@19.2.18)(react@19.2.8)': + dependencies: + '@walletconnect/modal-core': 2.6.2(@types/react@19.2.18)(react@19.2.8) + '@walletconnect/modal-ui': 2.6.2(@types/react@19.2.18)(react@19.2.8) + transitivePeerDependencies: + - '@types/react' + - react + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.3 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.1 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.11.2(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@walletconnect/core': 2.11.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.3 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.11.2 + '@walletconnect/utils': 2.11.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - uploadthing + - utf-8-validate + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.11.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.3 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/utils@2.11.2': + dependencies: + '@stablelib/chacha20poly1305': 1.0.1 + '@stablelib/hkdf': 1.0.1 + '@stablelib/random': 1.0.2 + '@stablelib/sha256': 1.0.1 + '@stablelib/x25519': 1.0.3 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.11.2 + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/window-getters@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/window-metadata@1.0.1': + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + + '@xrplf/isomorphic@1.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@noble/hashes': 2.3.0 + eventemitter3: 5.0.1 + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@xrplf/secret-numbers@2.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6)': + dependencies: + '@xrplf/isomorphic': 1.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ripple-keypairs: 2.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + acorn-jsx@5.3.2(acorn@8.18.0): + dependencies: + acorn: 8.18.0 + + acorn@8.18.0: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + agent-base@7.1.4: {} + + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.3.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + argparse@2.0.1: {} + + aria-query@5.3.2: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + ast-types-flow@0.0.8: {} + + async-function@1.0.0: {} + + asynckit@0.4.0: {} + + atomic-sleep@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.13.0: {} + + axios@1.19.0: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.6 + https-proxy-agent: 5.0.1 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + - supports-color + + axobject-query@4.1.0: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + bare-addon-resolve@1.10.1: + dependencies: + bare-module-resolve: 1.12.4 + bare-semver: 1.1.0 + optional: true + + bare-module-resolve@1.12.4: + dependencies: + bare-semver: 1.1.0 + optional: true + + bare-semver@1.1.0: + optional: true + + base-x@3.0.11: + dependencies: + safe-buffer: 5.2.1 + + base-x@5.0.1: {} + + base32.js@0.1.0: {} + + base64-js@1.5.1: {} + + baseline-browser-mapping@2.11.14: {} + + bchaddrjs@0.5.2: + dependencies: + bs58check: 2.1.2 + buffer: 6.0.3 + cashaddrjs: 0.4.4 + stream-browserify: 3.0.0 + + bech32@2.0.0: {} + + big-integer@1.6.36: {} + + bignumber.js@10.0.2: {} + + bignumber.js@9.3.1: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bip32-path@0.4.2: {} + + bip66@2.0.0: {} + + bitcoin-ops@1.4.1: {} + + blake-hash@2.0.0: + dependencies: + node-addon-api: 3.2.1 + node-gyp-build: 4.8.4 + readable-stream: 3.6.2 + + blakejs@1.2.1: {} + + bn.js@4.12.5: {} + + bn.js@5.2.5: {} + + borsh@0.7.0: + dependencies: + bn.js: 5.2.5 + bs58: 4.0.1 + text-encoding-utf-8: 1.0.2 + + borsh@1.0.0: {} + + borsh@2.0.0: {} + + brace-expansion@1.1.18: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@5.0.9: + dependencies: + balanced-match: 4.0.4 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browserslist@4.28.8: + dependencies: + baseline-browser-mapping: 2.11.14 + caniuse-lite: 1.0.30001809 + electron-to-chromium: 1.5.407 + node-releases: 2.0.53 + update-browserslist-db: 1.3.1(browserslist@4.28.8) + + bs58@4.0.1: + dependencies: + base-x: 3.0.11 + + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + bs58check@4.0.0: + dependencies: + '@noble/hashes': 1.8.0 + bs58: 6.0.0 + + buffer-equal-constant-time@1.0.1: {} + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.1.0: + dependencies: + node-gyp-build: 4.8.4 + optional: true + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + callsites@3.1.0: {} + + camelcase@5.3.1: {} + + caniuse-lite@1.0.30001809: {} + + cashaddrjs@0.4.4: + dependencies: + big-integer: 1.6.36 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@5.6.2: {} + + character-entities-legacy@3.0.0: {} + + character-entities@2.0.2: {} + + character-reference-invalid@2.0.1: {} + + charenc@0.0.2: {} + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + cipher-base@1.0.7: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + client-only@0.0.1: {} + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + clsx@2.1.1: {} + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + commander@14.0.3: {} + + commander@2.20.3: {} + + commander@8.3.0: {} + + concat-map@0.0.1: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.3: {} + + core-util-is@1.0.3: {} + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.7 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.3 + sha.js: 2.4.12 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.7 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + + cross-fetch@4.1.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crypt@0.0.2: {} + + csstype@3.2.3: {} + + damerau-levenshtein@1.0.8: {} + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize@1.2.0: {} + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + defu@6.1.7: {} + + delay@5.0.0: {} + + delayed-stream@1.0.0: {} + + depd@1.1.2: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + + detect-browser@5.3.0: {} + + detect-europe-js@0.1.2: {} + + detect-libc@2.1.2: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + dijkstrajs@1.0.3: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + electron-to-chromium@1.5.407: {} + + elliptic@6.6.1: + dependencies: + bn.js: 4.12.5 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encode-utf8@1.0.3: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + enhanced-resolve@5.24.5: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + entities@4.5.0: {} + + es-abstract-get@1.0.0: + dependencies: + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + is-callable: 1.2.7 + object-inspect: 1.13.4 + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.4 + function.prototype.name: 1.2.0 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.2 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.11 + string.prototype.trimend: 1.0.10 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.8 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.22 + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-iterator-helpers@1.4.0: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.0 + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.4 + + es-to-primitive@1.3.4: + dependencies: + es-abstract-get: 1.0.0 + es-define-property: 1.0.1 + es-errors: 1.3.0 + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 + + escalade@3.2.0: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-next@16.3.1(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 16.3.1(eslint@9.39.5(jiti@2.7.0)) + eslint: 9.39.5(jiti@2.7.0) + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.5(jiti@2.7.0)) + eslint-plugin-react: 7.37.5(eslint@9.39.5(jiti@2.7.0)) + eslint-plugin-react-hooks: 7.1.1(eslint@9.39.5(jiti@2.7.0)) + globals: 16.4.0 + typescript-eslint: 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-import-resolver-node@0.3.10: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.2 + resolve: 2.0.0-next.7 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.5(jiti@2.7.0) + get-tsconfig: 4.14.2 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.17 + unrs-resolver: 1.12.2 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.14.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + eslint: 9.39.5(jiti@2.7.0) + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.5(jiti@2.7.0)) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.5(jiti@2.7.0) + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.14.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.5(jiti@2.7.0)) + hasown: 2.0.4 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.10 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.5(jiti@2.7.0)): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.13.0 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.39.5(jiti@2.7.0) + hasown: 2.0.4 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-react-hooks@7.1.1(eslint@9.39.5(jiti@2.7.0)): + dependencies: + '@babel/core': 7.29.7 + '@babel/parser': 7.29.8 + eslint: 9.39.5(jiti@2.7.0) + hermes-parser: 0.25.1 + zod: 4.4.3 + zod-validation-error: 4.0.2(zod@4.4.3) + transitivePeerDependencies: + - supports-color + + eslint-plugin-react@7.37.5(eslint@9.39.5(jiti@2.7.0)): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.4.0 + eslint: 9.39.5(jiti@2.7.0) + estraverse: 5.3.0 + hasown: 2.0.4 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.7 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@9.39.5(jiti@2.7.0): + dependencies: + '@eslint-community/eslint-utils': 4.10.1(eslint@9.39.5(jiti@2.7.0)) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.6 + '@eslint/js': 9.39.5 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + optionalDependencies: + jiti: 2.7.0 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.18.0 + acorn-jsx: 5.3.2(acorn@8.18.0) + eslint-visitor-keys: 4.2.1 + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + eventemitter3@5.0.1: {} + + eventemitter3@5.0.4: {} + + events@3.3.0: {} + + eventsource@2.0.2: {} + + exponential-backoff@3.1.3: {} + + eyes@0.1.8: {} + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-redact@3.5.0: {} + + fast-stable-stringify@1.0.0: {} + + fastestsmallesttextencoderdecoder@1.0.22: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + + feaxios@0.0.23: + dependencies: + is-retry-allowed: 3.0.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + file-uri-to-path@1.0.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + filter-obj@1.1.0: {} + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.4 + keyv: 4.5.4 + + flatted@3.4.4: {} + + follow-redirects@1.16.0: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + form-data@4.0.6: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.4 + mime-types: 2.1.35 + + function-bind@1.1.2: {} + + function.prototype.name@1.2.0: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + es-define-property: 1.0.1 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + hasown: 2.0.4 + is-callable: 1.2.7 + is-document.all: 1.0.0 + + functions-have-names@1.2.3: {} + + generate-function@2.3.1: + dependencies: + is-property: 1.0.2 + + generate-object-property@1.2.0: + dependencies: + is-property: 1.0.2 + + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.6.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.14.2: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + globals@14.0.0: {} + + globals@16.4.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@16.2.2: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + fast-glob: 3.3.3 + ignore: 7.0.6 + is-path-inside: 4.0.0 + slash: 5.1.0 + unicorn-magic: 0.4.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.5 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + + has-bigints@1.1.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + hash-base@3.1.2: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hermes-estree@0.25.1: {} + + hermes-parser@0.25.1: + dependencies: + hermes-estree: 0.25.1 + + hey-listen@1.0.8: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + http-errors@1.7.2: + dependencies: + depd: 1.1.2 + inherits: 2.0.3 + setprototypeof: 1.1.1 + statuses: 1.5.0 + toidentifier: 1.0.0 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + idb-keyval@6.3.0: {} + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.6: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + int64-buffer@1.1.1: {} + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.4 + side-channel: 1.1.1 + + ip-address@10.5.0: {} + + iron-webcrypto@1.2.1: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-bun-module@2.0.0: + dependencies: + semver: 7.8.5 + + is-callable@1.2.7: {} + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.4 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-decimal@2.0.1: {} + + is-document.all@1.0.0: + dependencies: + call-bound: 1.0.4 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-fullwidth-code-point@3.0.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@2.0.1: {} + + is-map@2.0.3: {} + + is-my-ip-valid@1.0.1: {} + + is-my-json-valid@2.20.6: + dependencies: + generate-function: 2.3.1 + generate-object-property: 1.2.0 + is-my-ip-valid: 1.0.1 + jsonpointer: 5.0.1 + xtend: 4.0.2 + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-path-inside@4.0.0: {} + + is-property@1.0.2: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.4 + + is-retry-allowed@3.0.0: {} + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-standalone-pwa@0.1.1: {} + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.22 + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isomorphic-unfetch@3.1.0: + dependencies: + node-fetch: 2.7.0 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + + isomorphic-ws@4.0.1(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)): + dependencies: + ws: 7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6) + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jayson@4.3.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + dependencies: + '@types/connect': 3.4.38 + '@types/node': 12.20.55 + '@types/ws': 7.4.7 + commander: 2.20.3 + delay: 5.0.0 + es6-promisify: 5.0.0 + eyes: 0.1.8 + isomorphic-ws: 4.0.1(ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6)) + json-stringify-safe: 5.0.1 + stream-json: 1.9.1 + uuid: 8.3.2 + ws: 7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + jiti@2.7.0: {} + + js-sha256@0.11.1: {} + + js-sha256@0.9.0: {} + + js-tokens@4.0.0: {} + + js-yaml@4.3.1: + dependencies: + argparse: 2.0.1 + + js-yaml@5.2.2: + dependencies: + argparse: 2.0.1 + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json-stringify-safe@5.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonc-parser@3.3.1: {} + + jsonpointer@5.0.1: {} + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + katex@0.16.47: + dependencies: + commander: 8.3.0 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + keyvaluestorage-interface@1.0.0: {} + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + + linkify-it@5.0.2: + dependencies: + uc.micro: 2.1.0 + + lit-element@3.3.3: + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + '@lit/reactive-element': 1.6.3 + lit-html: 2.8.0 + + lit-element@4.2.2: + dependencies: + '@lit-labs/ssr-dom-shim': 1.6.0 + '@lit/reactive-element': 2.1.2 + lit-html: 3.3.3 + + lit-html@2.8.0: + dependencies: + '@types/trusted-types': 2.0.7 + + lit-html@3.3.3: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@2.8.0: + dependencies: + '@lit/reactive-element': 1.6.3 + lit-element: 3.3.3 + lit-html: 2.8.0 + + lit@3.2.0: + dependencies: + '@lit/reactive-element': 2.1.2 + lit-element: 4.2.2 + lit-html: 3.3.3 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.isequal@4.5.0: {} + + lodash.merge@4.6.2: {} + + long@5.2.5: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@11.5.2: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru_map@0.4.1: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + markdown-it@14.3.0: + dependencies: + argparse: 2.0.1 + entities: 4.5.0 + linkify-it: 5.0.2 + mdurl: 2.1.0 + punycode.js: 2.3.1 + uc.micro: 2.1.0 + + markdownlint-cli2-formatter-default@0.0.6(markdownlint-cli2@0.23.2): + dependencies: + markdownlint-cli2: 0.23.2 + + markdownlint-cli2@0.23.2: + dependencies: + globby: 16.2.2 + js-yaml: 5.2.2 + jsonc-parser: 3.3.1 + jsonpointer: 5.0.1 + markdown-it: 14.3.0 + markdownlint: 0.41.1 + markdownlint-cli2-formatter-default: 0.0.6(markdownlint-cli2@0.23.2) + micromatch: 4.0.8 + smol-toml: 1.7.0 + transitivePeerDependencies: + - supports-color + + markdownlint@0.41.1: + dependencies: + micromark: 4.0.2 + micromark-core-commonmark: 2.0.3 + micromark-extension-directive: 4.0.0 + micromark-extension-gfm-autolink-literal: 2.1.0 + micromark-extension-gfm-footnote: 2.1.0 + micromark-extension-gfm-table: 2.1.1 + micromark-extension-math: 3.1.0 + micromark-util-types: 2.0.2 + string-width: 8.2.1 + transitivePeerDependencies: + - supports-color + + math-intrinsics@1.1.0: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mdurl@2.1.0: {} + + merge2@1.4.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-directive@4.0.0: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + parse-entities: 4.0.2 + + micromark-extension-gfm-autolink-literal@2.1.0: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-footnote@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-gfm-table@2.1.1: + dependencies: + devlop: 1.1.0 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-extension-math@3.1.0: + dependencies: + '@types/katex': 0.16.8 + devlop: 1.1.0 + katex: 0.16.47 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.9 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.18 + + minimist@1.2.8: {} + + motion@10.16.2: + dependencies: + '@motionone/animation': 10.18.0 + '@motionone/dom': 10.18.0 + '@motionone/svelte': 10.16.4 + '@motionone/types': 10.17.1 + '@motionone/utils': 10.18.0 + '@motionone/vue': 10.16.4 + + ms@2.1.3: {} - '@types/unist@2.0.11': {} + multiformats@9.9.0: {} - ansi-regex@6.3.0: {} + mustache@4.0.0: {} - argparse@2.0.1: {} + nan@2.28.0: {} - braces@3.0.3: + nanoid@3.3.18: {} + + napi-postinstall@0.3.4: {} + + natural-compare@1.4.0: {} + + near-abi@0.2.0: dependencies: - fill-range: 7.1.1 + '@types/json-schema': 7.0.15 - character-entities-legacy@3.0.0: {} + near-api-js@5.1.1: + dependencies: + '@near-js/accounts': 1.4.1 + '@near-js/crypto': 1.4.2 + '@near-js/keystores': 0.2.2 + '@near-js/keystores-browser': 0.2.2 + '@near-js/keystores-node': 0.1.2 + '@near-js/providers': 1.0.3 + '@near-js/signers': 0.2.2 + '@near-js/transactions': 1.3.3 + '@near-js/types': 0.3.1 + '@near-js/utils': 1.1.0 + '@near-js/wallet-account': 1.3.3 + '@noble/curves': 1.8.1 + borsh: 1.0.0 + depd: 2.0.0 + http-errors: 1.7.2 + near-abi: 0.2.0 + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding - character-entities@2.0.2: {} + next@16.3.1(@babel/core@7.29.7)(@types/node@24.13.3)(react-dom@19.2.8(react@19.2.8))(react@19.2.8): + dependencies: + '@next/env': 16.3.1 + '@swc/helpers': 0.5.23 + baseline-browser-mapping: 2.11.14 + caniuse-lite: 1.0.30001809 + postcss: 8.5.23 + react: 19.2.8 + react-dom: 19.2.8(react@19.2.8) + styled-jsx: 5.1.6(@babel/core@7.29.7)(react@19.2.8) + optionalDependencies: + '@next/swc-darwin-arm64': 16.3.1 + '@next/swc-darwin-x64': 16.3.1 + '@next/swc-linux-arm64-gnu': 16.3.1 + '@next/swc-linux-arm64-musl': 16.3.1 + '@next/swc-linux-x64-gnu': 16.3.1 + '@next/swc-linux-x64-musl': 16.3.1 + '@next/swc-win32-arm64-msvc': 16.3.1 + '@next/swc-win32-x64-msvc': 16.3.1 + sharp: 0.35.3(@types/node@24.13.3) + transitivePeerDependencies: + - '@babel/core' + - '@types/node' + - babel-plugin-macros - character-reference-invalid@2.0.1: {} + node-addon-api@3.2.1: {} - commander@8.3.0: {} + node-addon-api@5.1.0: {} - debug@4.4.3: + node-addon-api@8.9.2: {} + + node-exports-info@1.6.2: dependencies: - ms: 2.1.3 + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 - decode-named-character-reference@1.3.0: + node-fetch-native@1.6.7: {} + + node-fetch@2.6.7: dependencies: - character-entities: 2.0.2 + whatwg-url: 5.0.0 - dequal@2.0.3: {} + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 - devlop@1.1.0: + node-gyp-build@4.8.4: {} + + node-mock-http@1.0.5: {} + + node-releases@2.0.53: {} + + normalize-path@3.0.0: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + object-keys@1.1.1: {} + + object.assign@4.1.7: dependencies: - dequal: 2.0.3 + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 - entities@4.5.0: {} + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 - fast-glob@3.3.3: + object.groupby@1.0.3: dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 - fastq@1.20.1: + object.values@1.2.1: dependencies: - reusify: 1.1.0 + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 - fill-range@7.1.1: + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + on-exit-leak-free@0.2.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + own-keys@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-try@2.2.0: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.5: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + + pino-std-serializers@4.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + + pngjs@5.0.0: {} + + possible-typed-array-names@1.1.0: {} + + postcss@8.5.23: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.26: + dependencies: + nanoid: 3.3.18 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + protobufjs@7.4.0: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.1 + '@protobufjs/fetch': 1.1.1 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.2 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.2 + '@types/node': 24.13.3 + long: 5.2.5 + + proxy-compare@2.5.1: {} + + proxy-from-env@2.1.0: {} + + punycode.js@2.3.1: {} + + punycode@2.3.1: {} + + pushdata-bitcoin@1.0.1: + dependencies: + bitcoin-ops: 1.4.1 + + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + radix3@1.1.2: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + react-dom@19.2.8(react@19.2.8): + dependencies: + react: 19.2.8 + scheduler: 0.27.0 + + react-is@16.13.1: {} + + react@19.2.8: {} + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@5.1.1: {} + + real-require@0.1.0: {} + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + require-addon@1.2.0: + dependencies: + bare-addon-resolve: 1.10.1 + transitivePeerDependencies: + - bare-url + optional: true + + require-directory@2.1.1: {} + + require-main-filename@2.0.0: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@2.0.0-next.7: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + node-exports-info: 1.6.2 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.1.0: {} + + ripemd160@2.0.3: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + + ripple-address-codec@5.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6): + dependencies: + '@scure/base': 2.3.0 + '@xrplf/isomorphic': 1.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ripple-binary-codec@2.9.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + dependencies: + '@xrplf/isomorphic': 1.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + bignumber.js: 10.0.2 + ripple-address-codec: 5.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ripple-keypairs@2.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): + dependencies: + '@noble/curves': 1.9.7 + '@xrplf/isomorphic': 1.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ripple-address-codec: 5.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + rpc-websockets@9.3.9: + dependencies: + '@swc/helpers': 0.5.23 + '@types/uuid': 10.0.0 + '@types/ws': 8.18.1 + buffer: 6.0.3 + eventemitter3: 5.0.4 + uuid: 14.0.1 + ws: 8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6) + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.1: + dependencies: + tslib: 2.8.1 + + safe-array-concat@1.1.4: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-stable-stringify@2.5.0: {} + + scheduler@0.27.0: {} + + secp256k1@5.0.1: + dependencies: + elliptic: 6.6.1 + node-addon-api: 5.1.0 + node-gyp-build: 4.8.4 + + semver@6.3.1: {} + + semver@7.7.1: {} + + semver@7.7.3: {} + + semver@7.8.5: {} + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + + setprototypeof@1.1.1: {} + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + sha1@1.1.1: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + + sharp@0.35.3(@types/node@24.13.3): + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.35.3 + '@img/sharp-darwin-x64': 0.35.3 + '@img/sharp-freebsd-wasm32': 0.35.3 + '@img/sharp-libvips-darwin-arm64': 1.3.2 + '@img/sharp-libvips-darwin-x64': 1.3.2 + '@img/sharp-libvips-linux-arm': 1.3.2 + '@img/sharp-libvips-linux-arm64': 1.3.2 + '@img/sharp-libvips-linux-ppc64': 1.3.2 + '@img/sharp-libvips-linux-riscv64': 1.3.2 + '@img/sharp-libvips-linux-s390x': 1.3.2 + '@img/sharp-libvips-linux-x64': 1.3.2 + '@img/sharp-libvips-linuxmusl-arm64': 1.3.2 + '@img/sharp-libvips-linuxmusl-x64': 1.3.2 + '@img/sharp-linux-arm': 0.35.3 + '@img/sharp-linux-arm64': 0.35.3 + '@img/sharp-linux-ppc64': 0.35.3 + '@img/sharp-linux-riscv64': 0.35.3 + '@img/sharp-linux-s390x': 0.35.3 + '@img/sharp-linux-x64': 0.35.3 + '@img/sharp-linuxmusl-arm64': 0.35.3 + '@img/sharp-linuxmusl-x64': 0.35.3 + '@img/sharp-webcontainers-wasm32': 0.35.3 + '@img/sharp-win32-arm64': 0.35.3 + '@img/sharp-win32-ia32': 0.35.3 + '@img/sharp-win32-x64': 0.35.3 + '@types/node': 24.13.3 + optional: true + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + slash@5.1.0: {} + + smart-buffer@4.2.0: {} + + smol-toml@1.7.0: {} + + socks-proxy-agent@8.0.5: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + socks: 2.8.9 + transitivePeerDependencies: + - supports-color + + socks@2.8.9: + dependencies: + ip-address: 10.5.0 + smart-buffer: 4.2.0 + + sodium-native@4.3.3: + dependencies: + require-addon: 1.2.0 + transitivePeerDependencies: + - bare-url + optional: true + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + + source-map-js@1.2.1: {} + + split-on-first@1.1.0: {} + + split2@4.2.0: {} + + stable-hash@0.0.5: {} + + statuses@1.5.0: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + stream-browserify@3.0.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + + stream-chain@2.2.5: {} + + stream-json@1.9.1: + dependencies: + stream-chain: 2.2.5 + + stream-shift@1.0.3: {} + + strict-uri-encode@2.0.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@8.2.1: + dependencies: + get-east-asian-width: 1.6.0 + strip-ansi: 7.2.0 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.1 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.trim@1.2.11: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.2 + has-property-descriptors: 1.0.2 + safe-regex-test: 1.1.0 + + string.prototype.trimend@1.0.10: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-object-atoms: 1.1.2 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.3.0 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + styled-jsx@5.1.6(@babel/core@7.29.7)(react@19.2.8): + dependencies: + client-only: 0.0.1 + react: 19.2.8 + optionalDependencies: + '@babel/core': 7.29.7 + + superstruct@2.0.2: {} + + supports-color@7.2.0: dependencies: - to-regex-range: 5.0.1 + has-flag: 4.0.0 - get-east-asian-width@1.6.0: {} + supports-preserve-symlinks-flag@1.0.0: {} - glob-parent@5.1.2: + tailwind-merge@3.6.0: {} + + tailwindcss@4.3.3: {} + + tapable@2.3.3: {} + + text-encoding-utf-8@1.0.2: {} + + thread-stream@0.15.2: dependencies: - is-glob: 4.0.3 + real-require: 0.1.0 - globby@16.2.2: + tiny-secp256k1@1.1.7: dependencies: - '@sindresorhus/merge-streams': 4.0.0 - fast-glob: 3.3.3 - ignore: 7.0.6 - is-path-inside: 4.0.0 - slash: 5.1.0 - unicorn-magic: 0.4.0 + bindings: 1.5.0 + bn.js: 4.12.5 + create-hmac: 1.1.7 + elliptic: 6.6.1 + nan: 2.28.0 - ignore@7.0.6: {} + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 - is-alphabetical@2.0.1: {} + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 - is-alphanumerical@2.0.1: + to-regex-range@5.0.1: dependencies: - is-alphabetical: 2.0.1 - is-decimal: 2.0.1 + is-number: 7.0.0 - is-decimal@2.0.1: {} + toidentifier@1.0.0: {} - is-extglob@2.1.1: {} + toml@3.0.0: {} - is-glob@4.0.3: + tr46@0.0.3: {} + + ts-api-utils@2.5.0(typescript@5.9.3): dependencies: - is-extglob: 2.1.1 + typescript: 5.9.3 - is-hexadecimal@2.0.1: {} + ts-mixer@6.0.4: {} - is-number@7.0.0: {} + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 - is-path-inside@4.0.0: {} + tslib@1.14.1: {} - js-yaml@5.2.2: - dependencies: - argparse: 2.0.1 + tslib@2.8.1: {} - jsonc-parser@3.3.1: {} + tweetnacl-util@0.15.1: {} - jsonpointer@5.0.1: {} + tweetnacl@1.0.3: {} - katex@0.16.47: + type-check@0.4.0: dependencies: - commander: 8.3.0 + prelude-ls: 1.2.1 - linkify-it@5.0.2: + typed-array-buffer@1.0.3: dependencies: - uc.micro: 2.1.0 + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 - markdown-it@14.3.0: + typed-array-byte-length@1.0.3: dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.2 - mdurl: 2.1.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 - markdownlint-cli2-formatter-default@0.0.6(markdownlint-cli2@0.23.2): + typed-array-byte-offset@1.0.4: dependencies: - markdownlint-cli2: 0.23.2 - - markdownlint-cli2@0.23.2: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.8: dependencies: - globby: 16.2.2 - js-yaml: 5.2.2 - jsonc-parser: 3.3.1 - jsonpointer: 5.0.1 - markdown-it: 14.3.0 - markdownlint: 0.41.1 - markdownlint-cli2-formatter-default: 0.0.6(markdownlint-cli2@0.23.2) - micromatch: 4.0.8 - smol-toml: 1.7.0 - transitivePeerDependencies: - - supports-color + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 - markdownlint@0.41.1: + typeforce@1.18.0: {} + + typescript-eslint@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3): dependencies: - micromark: 4.0.2 - micromark-core-commonmark: 2.0.3 - micromark-extension-directive: 4.0.0 - micromark-extension-gfm-autolink-literal: 2.1.0 - micromark-extension-gfm-footnote: 2.1.0 - micromark-extension-gfm-table: 2.1.1 - micromark-extension-math: 3.1.0 - micromark-util-types: 2.0.2 - string-width: 8.2.1 + '@typescript-eslint/eslint-plugin': 8.67.0(@typescript-eslint/parser@8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3))(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.67.0(typescript@5.9.3) + '@typescript-eslint/utils': 8.67.0(eslint@9.39.5(jiti@2.7.0))(typescript@5.9.3) + eslint: 9.39.5(jiti@2.7.0) + typescript: 5.9.3 transitivePeerDependencies: - supports-color - mdurl@2.1.0: {} + typescript@5.9.3: {} - merge2@1.4.1: {} + ua-is-frozen@0.1.2: {} - micromark-core-commonmark@2.0.3: + ua-parser-js@2.0.10: dependencies: - decode-named-character-reference: 1.3.0 - devlop: 1.1.0 - micromark-factory-destination: 2.0.1 - micromark-factory-label: 2.0.1 - micromark-factory-space: 2.0.1 - micromark-factory-title: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-classify-character: 2.0.1 - micromark-util-html-tag-name: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + detect-europe-js: 0.1.2 + is-standalone-pwa: 0.1.1 + ua-is-frozen: 0.1.2 - micromark-extension-directive@4.0.0: - dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-factory-whitespace: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - parse-entities: 4.0.2 + uc.micro@2.1.0: {} - micromark-extension-gfm-autolink-literal@2.1.0: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + ufo@1.6.4: {} - micromark-extension-gfm-footnote@2.1.0: - dependencies: - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + uint8array-tools@0.0.8: {} - micromark-extension-gfm-table@2.1.1: + uint8arrays@3.1.1: dependencies: - devlop: 1.1.0 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + multiformats: 9.9.0 - micromark-extension-math@3.1.0: + unbox-primitive@1.1.0: dependencies: - '@types/katex': 0.16.8 - devlop: 1.1.0 - katex: 0.16.47 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 - micromark-factory-destination@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + uncrypto@0.1.3: {} - micromark-factory-label@2.0.1: - dependencies: - devlop: 1.1.0 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + undici-types@7.18.2: {} - micromark-factory-space@2.0.1: - dependencies: - micromark-util-character: 2.1.1 - micromark-util-types: 2.0.2 + undici-types@7.29.0: {} - micromark-factory-title@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + unfetch@4.2.0: {} - micromark-factory-whitespace@2.0.1: - dependencies: - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + unicorn-magic@0.4.0: {} - micromark-util-character@2.1.1: + unrs-resolver@1.12.2: dependencies: - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.12.2 + '@unrs/resolver-binding-android-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-arm64': 1.12.2 + '@unrs/resolver-binding-darwin-x64': 1.12.2 + '@unrs/resolver-binding-freebsd-x64': 1.12.2 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.12.2 + '@unrs/resolver-binding-linux-arm64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-arm64-musl': 1.12.2 + '@unrs/resolver-binding-linux-loong64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-loong64-musl': 1.12.2 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-riscv64-musl': 1.12.2 + '@unrs/resolver-binding-linux-s390x-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-gnu': 1.12.2 + '@unrs/resolver-binding-linux-x64-musl': 1.12.2 + '@unrs/resolver-binding-openharmony-arm64': 1.12.2 + '@unrs/resolver-binding-wasm32-wasi': 1.12.2 + '@unrs/resolver-binding-win32-arm64-msvc': 1.12.2 + '@unrs/resolver-binding-win32-ia32-msvc': 1.12.2 + '@unrs/resolver-binding-win32-x64-msvc': 1.12.2 + + unstorage@1.17.5(idb-keyval@6.3.0): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.5.2 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + optionalDependencies: + idb-keyval: 6.3.0 + + update-browserslist-db@1.3.1(browserslist@4.28.8): + dependencies: + browserslist: 4.28.8 + escalade: 3.2.0 + picocolors: 1.1.1 - micromark-util-chunked@2.0.1: + uri-js@4.4.1: dependencies: - micromark-util-symbol: 2.0.1 + punycode: 2.3.1 - micromark-util-classify-character@2.0.1: + urijs@1.19.11: {} + + usb@2.18.0: dependencies: - micromark-util-character: 2.1.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + '@types/w3c-web-usb': 1.0.14 + node-addon-api: 8.9.2 + node-gyp-build: 4.8.4 - micromark-util-combine-extensions@2.0.1: + use-sync-external-store@1.2.0(react@19.2.8): dependencies: - micromark-util-chunked: 2.0.1 - micromark-util-types: 2.0.2 + react: 19.2.8 - micromark-util-decode-numeric-character-reference@2.0.2: + utf-8-validate@6.0.6: dependencies: - micromark-util-symbol: 2.0.1 + node-gyp-build: 4.8.4 + optional: true - micromark-util-encode@2.0.1: {} + util-deprecate@1.0.2: {} - micromark-util-html-tag-name@2.0.1: {} + uuid4@2.0.3: {} - micromark-util-normalize-identifier@2.0.1: + uuid@14.0.1: {} + + uuid@8.3.2: {} + + valtio@1.11.2(@types/react@19.2.18)(react@19.2.8): dependencies: - micromark-util-symbol: 2.0.1 + proxy-compare: 2.5.1 + use-sync-external-store: 1.2.0(react@19.2.8) + optionalDependencies: + '@types/react': 19.2.18 + react: 19.2.8 - micromark-util-resolve-all@2.0.1: + varuint-bitcoin@2.0.0: dependencies: - micromark-util-types: 2.0.2 + uint8array-tools: 0.0.8 - micromark-util-sanitize-uri@2.0.1: + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: dependencies: - micromark-util-character: 2.1.1 - micromark-util-encode: 2.0.1 - micromark-util-symbol: 2.0.1 + tr46: 0.0.3 + webidl-conversions: 3.0.1 - micromark-util-subtokenize@2.1.0: + which-boxed-primitive@1.1.1: dependencies: - devlop: 1.1.0 - micromark-util-chunked: 2.0.1 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 - micromark-util-symbol@2.0.1: {} + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.2.0 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.22 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 - micromark-util-types@2.0.2: {} + which-module@2.0.1: {} - micromark@4.0.2: + which-typed-array@1.1.22: dependencies: - '@types/debug': 4.1.13 - debug: 4.4.3 - decode-named-character-reference: 1.3.0 - devlop: 1.1.0 - micromark-core-commonmark: 2.0.3 - micromark-factory-space: 2.0.1 - micromark-util-character: 2.1.1 - micromark-util-chunked: 2.0.1 - micromark-util-combine-extensions: 2.0.1 - micromark-util-decode-numeric-character-reference: 2.0.2 - micromark-util-encode: 2.0.1 - micromark-util-normalize-identifier: 2.0.1 - micromark-util-resolve-all: 2.0.1 - micromark-util-sanitize-uri: 2.0.1 - micromark-util-subtokenize: 2.1.0 - micromark-util-symbol: 2.0.1 - micromark-util-types: 2.0.2 - transitivePeerDependencies: - - supports-color + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 - micromatch@4.0.8: + wif@5.0.0: dependencies: - braces: 3.0.3 - picomatch: 2.3.2 + bs58check: 4.0.0 - ms@2.1.3: {} + word-wrap@1.2.5: {} - parse-entities@4.0.2: + wrap-ansi@6.2.0: dependencies: - '@types/unist': 2.0.11 - character-entities-legacy: 3.0.0 - character-reference-invalid: 2.0.1 - decode-named-character-reference: 1.3.0 - is-alphanumerical: 2.0.1 - is-decimal: 2.0.1 - is-hexadecimal: 2.0.1 - - picomatch@2.3.2: {} + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 - punycode.js@2.3.1: {} + wrappy@1.0.2: {} - queue-microtask@1.2.3: {} + ws@7.5.13(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 - reusify@1.1.0: {} + ws@8.21.3(bufferutil@4.1.0)(utf-8-validate@6.0.6): + optionalDependencies: + bufferutil: 4.1.0 + utf-8-validate: 6.0.6 - run-parallel@1.2.0: + xrpl@4.6.0(bufferutil@4.1.0)(utf-8-validate@6.0.6): dependencies: - queue-microtask: 1.2.3 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + '@xrplf/isomorphic': 1.0.2(bufferutil@4.1.0)(utf-8-validate@6.0.6) + '@xrplf/secret-numbers': 2.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + bignumber.js: 9.3.1 + eventemitter3: 5.0.4 + fast-json-stable-stringify: 2.1.0 + ripple-address-codec: 5.0.1(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ripple-binary-codec: 2.9.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + ripple-keypairs: 2.0.0(bufferutil@4.1.0)(utf-8-validate@6.0.6) + transitivePeerDependencies: + - bufferutil + - utf-8-validate - slash@5.1.0: {} + xtend@4.0.2: {} - smol-toml@1.7.0: {} + y18n@4.0.3: {} - string-width@8.2.1: - dependencies: - get-east-asian-width: 1.6.0 - strip-ansi: 7.2.0 + yallist@3.1.1: {} - strip-ansi@7.2.0: + yargs-parser@18.1.3: dependencies: - ansi-regex: 6.3.0 + camelcase: 5.3.1 + decamelize: 1.2.0 - to-regex-range@5.0.1: + yargs@15.4.1: dependencies: - is-number: 7.0.0 - - uc.micro@2.1.0: {} + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + yocto-queue@0.1.0: {} + + zod-validation-error@4.0.2(zod@4.4.3): + dependencies: + zod: 4.4.3 - unicorn-magic@0.4.0: {} + zod@4.4.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..3ff5faa --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - "apps/*" + - "packages/*" From 8d066c2f89cee948154ef9f6e0b1f78ef636c683 Mon Sep 17 00:00:00 2001 From: Jethro Irmiya Date: Sun, 16 Aug 2026 19:49:58 +0100 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20docs=20site,=20survey,=20use-case?= =?UTF-8?q?=20pages,=20label=20taxonomy=20=E2=80=94=20closes=20#2=20#3=20#?= =?UTF-8?q?11=20#13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes the remaining open issues and brings every document in line with the fact that the code now exists. #2 — docs/comparison.md. The survey found the README's own claim was half wrong, and it was the convenient half. Both Soroban-native streaming projects were described as "hackathon-scale"; both are actively developed, pushed within a week of the survey, with substantial contributor programmes. Corrected in the README rather than quietly dropped. What did hold up is narrower: none of the four projects surveyed implements approver-gated milestones — Sablier's "tranched" streams unlock on a clock, not a signature. LlamaPay is recorded as a genuinely different model rather than a weaker one: open-ended with debt instead of full escrow, which is strictly better for payroll capital efficiency and strictly worse for the guarantee milestone work needs. Every claim carries a link and a checked-on date. Sablier V2 also turns out to have shipped its core non-upgradeable with an admin that cannot touch user streams — near-identical to #33's decision, reached independently. That resolves the TODO(maintainer) left in upgradeability-and-pause.md with a verified citation instead of a recollection. #3 — three use-case pages with concrete parameters and a required "what can still go wrong" section. The interesting part is that grants and vesting want `on_expiry` pointed in OPPOSITE directions: a grant should resolve to the recipient, because the funder chose the committee and should carry the risk of it failing; a performance-gated vest should resolve to the sender, because a target that pays out when nobody looked is not a target. That is exactly why #38 refused to hardcode a default. #11 — .github/labels.yml with four namespaces, applied to the repo. Every pre-existing ad-hoc label was migrated onto the new taxonomy before the duplicate was deleted, so no issue lost meaning. One difficulty tier above `good first issue`, not three: the boundary between "medium" and "hard" is not one anybody applies consistently. #13 — VitePress over the flattened docs/. Chosen over Docusaurus because it renders the markdown already in this repo, in place; Docusaurus wants frontmatter on every page and its own directory shape. Mermaid renders (verified in-browser). The one link VitePress cannot check — ../README, which resolves correctly on GitHub — is handled in config rather than by bending the markdown, because #13 requires links to work in both places. Pages workflow present and deliberately not enabled: workflow_dispatch only, no push trigger. All six action SHAs verified against the GitHub API. Also in this commit, found while doing the above: - The docs specify `bump_stream` throughout; the contract implemented `touch`. The docs were written first and are the specification, so the code was what was wrong. Renamed and redeployed. - `pnpm bindings` was destroying the workspace on every run: `stellar contract bindings --overwrite` rewrites the package.json to point at an unbuilt ./dist and pin its own stellar-sdk copy. Two SDK copies mean two incompatible sets of u64/i128 aliases, and the failure surfaces somewhere unrelated as "number is not assignable to bigint". Now generated through scripts/generate-bindings.mjs, which rewrites the manifest deterministically. - The README banner needed splitting in two. A README image renders inside an , which has no inherited text colour, so the single currentColor asset resolved to black and vanished on GitHub's dark theme. Also dropped the