From 0116506f54f2e379e051c00073326dfb4f5bdb4f Mon Sep 17 00:00:00 2001 From: JoeX17 Date: Thu, 26 Feb 2026 06:34:13 +0100 Subject: [PATCH] feat(core): add SetOptionsOperation model and explain_set_options() explainer --- packages/core/Cargo.lock | 839 +++++++++++++++++- packages/core/Cargo.toml | 8 +- packages/core/src/explain/operation/mod.rs | 10 + .../core/src/explain/operation/set_options.rs | 380 ++++++++ packages/core/src/explain/transaction.rs | 28 +- packages/core/src/main.rs | 46 +- packages/core/src/models/operation.rs | 372 +++++--- packages/core/src/services/explain.rs | 22 +- packages/core/src/services/horizon.rs | 392 ++++---- packages/core/tests/integration.rs | 3 +- packages/stellar_explain_current2.zip | Bin 0 -> 143077 bytes 11 files changed, 1663 insertions(+), 437 deletions(-) create mode 100644 packages/core/src/explain/operation/set_options.rs create mode 100644 packages/stellar_explain_current2.zip diff --git a/packages/core/Cargo.lock b/packages/core/Cargo.lock index 6fbe3de..c133cd8 100644 --- a/packages/core/Cargo.lock +++ b/packages/core/Cargo.lock @@ -2,6 +2,12 @@ # It is not intended for manual editing. version = 4 +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + [[package]] name = "aho-corasick" version = "1.1.4" @@ -11,6 +17,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + [[package]] name = "ascii-canvas" version = "3.0.0" @@ -251,7 +263,7 @@ dependencies = [ "serde_urlencoded", "sync_wrapper", "tokio", - "tower", + "tower 0.5.3", "tower-layer", "tower-service", "tracing", @@ -322,6 +334,15 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +[[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 = "blocking" version = "1.6.2" @@ -341,6 +362,12 @@ version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "bytes" version = "1.11.0" @@ -394,6 +421,24 @@ 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 = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -406,6 +451,57 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "deadpool" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be2b1d1d6ec8d846f05e137292d0b89133caf95ef33695424c09568bdd39b1b" +dependencies = [ + "deadpool-runtime", + "lazy_static", + "num_cpus", + "tokio", +] + +[[package]] +name = "deadpool-runtime" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "092966b41edc516079bdf31ec78a2e0588d1d0c08f78b91d8307215928642b2b" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + [[package]] name = "dirs-next" version = "2.0.0" @@ -529,12 +625,28 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + [[package]] name = "fnv" version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -559,6 +671,31 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "forwarded-header-value" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" +dependencies = [ + "nonempty", + "thiserror 1.0.69", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + [[package]] name = "futures-channel" version = "0.3.31" @@ -566,6 +703,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] @@ -574,6 +712,17 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + [[package]] name = "futures-io" version = "0.3.31" @@ -616,20 +765,40 @@ version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + [[package]] name = "futures-util" version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", + "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", ] +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + [[package]] name = "getrandom" version = "0.2.17" @@ -657,6 +826,19 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + [[package]] name = "gloo-timers" version = "0.3.0" @@ -669,6 +851,26 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "governor" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" +dependencies = [ + "cfg-if", + "dashmap", + "futures", + "futures-timer", + "no-std-compat", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.8.5", + "smallvec", + "spinning_top", +] + [[package]] name = "h2" version = "0.4.13" @@ -688,12 +890,33 @@ dependencies = [ "tracing", ] +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + [[package]] name = "hashbrown" version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.5.2" @@ -981,6 +1204,12 @@ dependencies = [ "zerovec", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "idna" version = "1.1.0" @@ -1009,7 +1238,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.16.1", + "serde", + "serde_core", ] [[package]] @@ -1099,6 +1330,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "levenshtein" version = "1.0.5" @@ -1157,6 +1394,15 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + [[package]] name = "matchit" version = "0.7.3" @@ -1175,6 +1421,26 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" +dependencies = [ + "mime", + "unicase", +] + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + [[package]] name = "mio" version = "1.1.1" @@ -1209,6 +1475,24 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" +[[package]] +name = "no-std-compat" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b93853da6d84c2e3c7d730d6473e8817692dd89be387eb01b94d7f108ecb5b8c" + +[[package]] +name = "nonempty" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" + +[[package]] +name = "nonzero_ext" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bf9645c8b145698bb0b18a4637dcacbc421ea49bef2317e4fd8065a387cf21" + [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -1218,6 +1502,16 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + [[package]] name = "once_cell" version = "1.21.3" @@ -1328,6 +1622,26 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5be167a7af36ee22fe3115051bc51f6e6c7054c9348e28deb4f49bd6f705a315" +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + [[package]] name = "pin-project-lite" version = "0.2.16" @@ -1371,6 +1685,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "portable-atomic" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" + [[package]] name = "potential_utf" version = "0.1.4" @@ -1395,6 +1715,40 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[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.114", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.105" @@ -1404,6 +1758,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "quanta" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + [[package]] name = "quinn" version = "0.11.9" @@ -1433,7 +1802,7 @@ dependencies = [ "bytes", "getrandom 0.3.4", "lru-slab", - "rand", + "rand 0.9.2", "ring", "rustc-hash", "rustls", @@ -1474,35 +1843,74 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha", - "rand_core", + "rand_chacha 0.9.0", + "rand_core 0.9.5", ] [[package]] name = "rand_chacha" -version = "0.9.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", ] [[package]] -name = "rand_core" -version = "0.9.5" +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.5", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_core" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] +[[package]] +name = "raw-cpuid" +version = "11.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_syscall" version = "0.5.18" @@ -1586,7 +1994,7 @@ dependencies = [ "tokio", "tokio-native-tls", "tokio-rustls", - "tower", + "tower 0.5.3", "tower-http", "tower-service", "url", @@ -1610,6 +2018,40 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rust-embed" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.114", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "8.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" +dependencies = [ + "sha2", + "walkdir", +] + [[package]] name = "rustc-hash" version = "2.1.1" @@ -1723,6 +2165,12 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" + [[package]] name = "serde" version = "1.0.228" @@ -1787,6 +2235,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1799,6 +2256,17 @@ dependencies = [ "serde", ] +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -1824,6 +2292,12 @@ dependencies = [ "libc", ] +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + [[package]] name = "similar" version = "2.7.0" @@ -1868,6 +2342,15 @@ dependencies = [ "windows-sys 0.60.2", ] +[[package]] +name = "spinning_top" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96d2d1d716fb500937168cc09353ffdc7a012be8475ac7308e1bdf0e3923300" +dependencies = [ + "lock_api", +] + [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -1880,15 +2363,23 @@ version = "0.0.1" dependencies = [ "axum", "dotenvy", + "governor", "httpmock", "reqwest", "serde", "serde_json", "thiserror 1.0.69", "tokio", + "toml", + "tower 0.4.13", "tower-http", + "tower_governor", "tracing", "tracing-subscriber", + "utoipa", + "utoipa-swagger-ui", + "uuid", + "wiremock", ] [[package]] @@ -2140,6 +2631,58 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "toml_write", + "winnow", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "tower" version = "0.5.3" @@ -2169,7 +2712,7 @@ dependencies = [ "http-body 1.0.1", "iri-string", "pin-project-lite", - "tower", + "tower 0.5.3", "tower-layer", "tower-service", ] @@ -2186,6 +2729,22 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" +[[package]] +name = "tower_governor" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aea939ea6cfa7c4880f3e7422616624f97a567c16df67b53b11f0d03917a8e46" +dependencies = [ + "axum", + "forwarded-header-value", + "governor", + "http 1.4.0", + "pin-project", + "thiserror 1.0.69", + "tower 0.5.3", + "tracing", +] + [[package]] name = "tracing" version = "0.1.44" @@ -2230,18 +2789,35 @@ dependencies = [ "tracing-core", ] +[[package]] +name = "tracing-serde" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" +dependencies = [ + "serde", + "tracing-core", +] + [[package]] name = "tracing-subscriber" version = "0.3.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2f30143827ddab0d256fd843b7a66d164e9f271cfa0dde49142c5ca0ca291f1e" dependencies = [ + "matchers", "nu-ansi-term", + "once_cell", + "regex-automata", + "serde", + "serde_json", "sharded-slab", "smallvec", "thread_local", + "tracing", "tracing-core", "tracing-log", + "tracing-serde", ] [[package]] @@ -2250,6 +2826,18 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unicase" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc4bc3a9f746d862c45cb89d705aa10f187bb96c76001afab07a0d35ce60142" + [[package]] name = "unicode-ident" version = "1.0.22" @@ -2286,6 +2874,58 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" +[[package]] +name = "utoipa" +version = "4.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5afb1a60e207dca502682537fefcfd9921e71d0b83e9576060f09abc6efab23" +dependencies = [ + "indexmap", + "serde", + "serde_json", + "utoipa-gen", +] + +[[package]] +name = "utoipa-gen" +version = "4.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20c24e8ab68ff9ee746aad22d39b5535601e6416d1b0feeabf78be986a5c4392" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "regex", + "syn 2.0.114", +] + +[[package]] +name = "utoipa-swagger-ui" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b39868d43c011961e04b41623e050aedf2cc93652562ff7935ce0f819aaf2da" +dependencies = [ + "axum", + "mime_guess", + "regex", + "rust-embed", + "serde", + "serde_json", + "utoipa", + "zip", +] + +[[package]] +name = "uuid" +version = "1.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +dependencies = [ + "getrandom 0.4.1", + "js-sys", + "wasm-bindgen", +] + [[package]] name = "valuable" version = "0.1.1" @@ -2304,6 +2944,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + [[package]] name = "walkdir" version = "2.5.0" @@ -2338,6 +2984,15 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasm-bindgen" version = "0.2.108" @@ -2397,6 +3052,40 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + [[package]] name = "web-sys" version = "0.3.85" @@ -2648,11 +3337,125 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "wiremock" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08db1edfb05d9b3c1542e521aea074442088292f00b5f28e435c714a98f85031" +dependencies = [ + "assert-json-diff", + "base64 0.22.1", + "deadpool", + "futures", + "http 1.4.0", + "http-body-util", + "hyper 1.8.1", + "hyper-util", + "log", + "once_cell", + "regex", + "serde", + "serde_json", + "tokio", + "url", +] + [[package]] name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn 2.0.114", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.114", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "writeable" @@ -2763,6 +3566,18 @@ dependencies = [ "syn 2.0.114", ] +[[package]] +name = "zip" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +dependencies = [ + "byteorder", + "crc32fast", + "crossbeam-utils", + "flate2", +] + [[package]] name = "zmij" version = "1.0.16" diff --git a/packages/core/Cargo.toml b/packages/core/Cargo.toml index 4694f83..43ad1f9 100644 --- a/packages/core/Cargo.toml +++ b/packages/core/Cargo.toml @@ -12,14 +12,16 @@ dotenvy = "0.15" reqwest = { version = "0.12", features = ["json", "rustls-tls"] } serde = { version = "1.0", features = ["derive"] } thiserror = "1.0" +tower = "0.4" tower-http = { version = "0.6", features = ["cors"] } -tower-governor = "0.4" +tower_governor = "0.4" +governor = "0.6" utoipa = { version = "4", features = ["axum_extras"] } -utoipa-swagger-ui = "6" +utoipa-swagger-ui = { version = "6", features = ["axum"] } uuid = { version = "1", features = ["v4"] } toml = "0.8" [dev-dependencies] httpmock = "0.7" serde_json = "1" -wiremock = "0.6" +wiremock = "0.6" \ No newline at end of file diff --git a/packages/core/src/explain/operation/mod.rs b/packages/core/src/explain/operation/mod.rs index 81ee5e5..0ff6c6f 100644 --- a/packages/core/src/explain/operation/mod.rs +++ b/packages/core/src/explain/operation/mod.rs @@ -7,3 +7,13 @@ pub mod manage_offer; pub mod path_payment; pub mod change_trust; pub mod create_account; +pub mod set_options; + + + + + + + + + diff --git a/packages/core/src/explain/operation/set_options.rs b/packages/core/src/explain/operation/set_options.rs new file mode 100644 index 0000000..3a0f57c --- /dev/null +++ b/packages/core/src/explain/operation/set_options.rs @@ -0,0 +1,380 @@ +//! Explainer for set_options operations. +//! +//! set_options can change many account settings in one operation. +//! This module enumerates every field that was set and assembles +//! them into a single readable summary. + +use crate::models::operation::SetOptionsOperation; +use serde::{Deserialize, Serialize}; + +/// Human-readable explanation of a set_options operation. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct SetOptionsExplanation { + /// Full natural-language summary of what changed. + /// e.g. "GAAAA updated their account: set home domain to example.com, + /// and added signer GBBB...YYYY with weight 1" + pub summary: String, + + /// The account that submitted the operation. "Unknown" if not present. + pub account: String, + + /// One entry per modified field. + /// e.g. ["set home domain to example.com", "added signer GBBB...YYYY with weight 1"] + pub changes: Vec, +} + +/// Produce a human-readable explanation for a set_options operation. +pub fn explain_set_options(op: &SetOptionsOperation) -> SetOptionsExplanation { + let account = op + .source_account + .clone() + .unwrap_or_else(|| "Unknown".to_string()); + + let mut changes: Vec = Vec::new(); + + // Inflation destination + if let Some(ref dest) = op.inflation_dest { + changes.push(format!("set inflation destination to {}", dest)); + } + + // Master key weight + if let Some(weight) = op.master_weight { + if weight == 0 { + changes.push("disabled the master key".to_string()); + } else { + changes.push(format!("set master key weight to {}", weight)); + } + } + + // Thresholds + if let Some(low) = op.low_threshold { + changes.push(format!("set low threshold to {}", low)); + } + if let Some(med) = op.med_threshold { + changes.push(format!("set medium threshold to {}", med)); + } + if let Some(high) = op.high_threshold { + changes.push(format!("set high threshold to {}", high)); + } + + // Home domain + if let Some(ref domain) = op.home_domain { + if domain.is_empty() { + changes.push("cleared the home domain".to_string()); + } else { + changes.push(format!("set home domain to {}", domain)); + } + } + + // Flags + if let Some(flags) = op.set_flags { + if flags > 0 { + changes.push(format!( + "enabled account flag(s): {}", + describe_flags(flags) + )); + } + } + if let Some(flags) = op.clear_flags { + if flags > 0 { + changes.push(format!( + "disabled account flag(s): {}", + describe_flags(flags) + )); + } + } + + // Signer — weight 0 means remove, anything else means add/modify + if let Some(ref key) = op.signer_key { + let short_key = shorten_key(key); + match op.signer_weight { + Some(0) => { + changes.push(format!("removed signer {}", short_key)); + } + Some(weight) => { + changes.push(format!( + "added signer {} with weight {}", + short_key, weight + )); + } + None => { + changes.push(format!("modified signer {}", short_key)); + } + } + } + + let summary = build_summary(&account, &changes); + + SetOptionsExplanation { + summary, + account, + changes, + } +} + +/// Build the final summary string. +fn build_summary(account: &str, changes: &[String]) -> String { + if changes.is_empty() { + return format!( + "{} submitted a set_options operation with no recognised changes.", + account + ); + } + format!("{} updated their account: {}", account, join_changes(changes)) +} + +/// Join change descriptions into natural English. +/// 1 item → "a" +/// 2 items → "a and b" +/// 3+ → "a, b, and c" +fn join_changes(changes: &[String]) -> String { + match changes.len() { + 0 => String::new(), + 1 => changes[0].clone(), + 2 => format!("{} and {}", changes[0], changes[1]), + _ => { + let all_but_last = changes[..changes.len() - 1].join(", "); + format!("{}, and {}", all_but_last, changes[changes.len() - 1]) + } + } +} + +/// Translate Stellar account flag bitmasks into readable names. +/// AUTH_REQUIRED=1, AUTH_REVOCABLE=2, AUTH_IMMUTABLE=4, CLAWBACK_ENABLED=8 +fn describe_flags(flags: u32) -> String { + let mut names: Vec<&str> = Vec::new(); + if flags & 1 != 0 { names.push("AUTH_REQUIRED"); } + if flags & 2 != 0 { names.push("AUTH_REVOCABLE"); } + if flags & 4 != 0 { names.push("AUTH_IMMUTABLE"); } + if flags & 8 != 0 { names.push("CLAWBACK_ENABLED"); } + if names.is_empty() { + flags.to_string() + } else { + names.join(", ") + } +} + +/// Shorten a long Stellar key for display: "GABC...WXYZ" +fn shorten_key(key: &str) -> String { + if key.len() > 12 { + format!("{}...{}", &key[..4], &key[key.len() - 4..]) + } else { + key.to_string() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::models::operation::SetOptionsOperation; + + fn base_op() -> SetOptionsOperation { + SetOptionsOperation { + id: "op1".to_string(), + source_account: Some("GAAAA...ZZZZ".to_string()), + ..Default::default() + } + } + + // ── Single change ────────────────────────────────────────────────────── + + #[test] + fn test_single_home_domain() { + let op = SetOptionsOperation { + home_domain: Some("example.com".to_string()), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 1); + assert!(result.changes[0].contains("example.com")); + assert!(result.summary.contains("set home domain to example.com")); + assert!(result.summary.contains("updated their account")); + } + + #[test] + fn test_single_inflation_dest() { + let op = SetOptionsOperation { + inflation_dest: Some("GBBBBB...YYYY".to_string()), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 1); + assert!(result.changes[0].contains("inflation destination")); + } + + #[test] + fn test_single_master_weight() { + let op = SetOptionsOperation { + master_weight: Some(5), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 1); + assert!(result.changes[0].contains("master key weight to 5")); + } + + #[test] + fn test_master_weight_zero_disables_key() { + let op = SetOptionsOperation { + master_weight: Some(0), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 1); + assert!(result.changes[0].contains("disabled the master key")); + } + + #[test] + fn test_home_domain_cleared() { + let op = SetOptionsOperation { + home_domain: Some("".to_string()), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 1); + assert!(result.changes[0].contains("cleared the home domain")); + } + + // ── Signer tests ─────────────────────────────────────────────────────── + + #[test] + fn test_signer_added() { + let op = SetOptionsOperation { + signer_key: Some("GBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB".to_string()), + signer_weight: Some(1), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 1); + assert!(result.changes[0].contains("added signer")); + assert!(result.changes[0].contains("weight 1")); + } + + #[test] + fn test_signer_removed_weight_zero() { + let op = SetOptionsOperation { + signer_key: Some("GCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC".to_string()), + signer_weight: Some(0), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 1); + assert!(result.changes[0].contains("removed signer")); + } + + // ── Multiple changes ─────────────────────────────────────────────────── + + #[test] + fn test_two_changes_joined_with_and() { + let op = SetOptionsOperation { + home_domain: Some("stellar.org".to_string()), + low_threshold: Some(1), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 2); + assert!(result.summary.contains(" and ")); + } + + #[test] + fn test_three_changes_uses_oxford_comma() { + let op = SetOptionsOperation { + home_domain: Some("example.com".to_string()), + low_threshold: Some(1), + med_threshold: Some(2), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 3); + assert!(result.summary.contains(", and ")); + } + + #[test] + fn test_signer_add_plus_home_domain() { + let op = SetOptionsOperation { + home_domain: Some("example.com".to_string()), + signer_key: Some("GBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB".to_string()), + signer_weight: Some(1), + ..base_op() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 2); + assert!(result.summary.contains("set home domain to example.com")); + assert!(result.summary.contains("added signer")); + } + + // ── Edge cases ───────────────────────────────────────────────────────── + + #[test] + fn test_empty_set_options() { + let op = SetOptionsOperation { + id: "op1".to_string(), + source_account: Some("GAAAA".to_string()), + ..Default::default() + }; + let result = explain_set_options(&op); + + assert_eq!(result.changes.len(), 0); + assert!(result.summary.contains("no recognised changes")); + } + + #[test] + fn test_set_flags_auth_required() { + let op = SetOptionsOperation { + set_flags: Some(1), + ..base_op() + }; + let result = explain_set_options(&op); + + assert!(result.changes[0].contains("AUTH_REQUIRED")); + assert!(result.changes[0].contains("enabled")); + } + + #[test] + fn test_clear_flags_auth_revocable() { + let op = SetOptionsOperation { + clear_flags: Some(2), + ..base_op() + }; + let result = explain_set_options(&op); + + assert!(result.changes[0].contains("AUTH_REVOCABLE")); + assert!(result.changes[0].contains("disabled")); + } + + #[test] + fn test_unknown_account_fallback() { + let op = SetOptionsOperation { + source_account: None, + home_domain: Some("test.com".to_string()), + ..Default::default() + }; + let result = explain_set_options(&op); + + assert_eq!(result.account, "Unknown"); + assert!(result.summary.starts_with("Unknown")); + } + + #[test] + fn test_account_field_in_result() { + let op = SetOptionsOperation { + source_account: Some("GSPECIFIC".to_string()), + home_domain: Some("test.com".to_string()), + ..Default::default() + }; + let result = explain_set_options(&op); + + assert_eq!(result.account, "GSPECIFIC"); + assert!(result.summary.starts_with("GSPECIFIC")); + } +} \ No newline at end of file diff --git a/packages/core/src/explain/transaction.rs b/packages/core/src/explain/transaction.rs index c89586c..a30fa3d 100644 --- a/packages/core/src/explain/transaction.rs +++ b/packages/core/src/explain/transaction.rs @@ -1,6 +1,4 @@ //! Transaction explanation orchestration. -//! -//! Accepts an internal transaction model and produces structured explanations. use serde::{Deserialize, Serialize}; @@ -8,11 +6,7 @@ use crate::explain::memo::explain_memo; use crate::models::fee::FeeStats; use crate::models::transaction::Transaction; -use super::operation::payment::{ - explain_payment, - explain_payment_with_fee, - PaymentExplanation, -}; +use super::operation::payment::{explain_payment, explain_payment_with_fee, PaymentExplanation}; /// Complete explanation of a transaction. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] @@ -22,20 +16,14 @@ pub struct TransactionExplanation { pub summary: String, pub payment_explanations: Vec, pub skipped_operations: usize, - /// Human-readable explanation of the transaction memo. - /// None if the transaction has no memo. pub memo_explanation: Option, - /// Human-readable explanation of transaction fee context. pub fee_explanation: Option, } -/// Result type for transaction explanation. pub type ExplainResult = Result; -/// Errors that can occur during explanation. #[derive(Debug, Clone, PartialEq)] pub enum ExplainError { - /// The transaction has zero operations (truly empty). EmptyTransaction, } @@ -52,12 +40,8 @@ impl std::fmt::Display for ExplainError { impl std::error::Error for ExplainError {} /// Produce a plain-English fee explanation. -/// -/// Uses FeeStats to contextualise whether the fee is standard or elevated. -/// Falls back to a simple message if fee_stats is None. pub fn explain_fee(fee_charged: u64, fee_stats: Option<&FeeStats>) -> String { let xlm = FeeStats::stroops_to_xlm(fee_charged); - match fee_stats { None => format!("A fee of {} XLM was charged.", xlm), Some(stats) => { @@ -192,14 +176,10 @@ mod tests { operations: vec![create_payment_operation("1", "50.0")], memo: Some(Memo::text("Invoice #12345").unwrap()), }; - let explanation = explain_transaction(&tx, None).unwrap(); assert_eq!(explanation.transaction_hash, "abc123"); assert!(explanation.memo_explanation.is_some()); - assert!(explanation - .memo_explanation - .unwrap() - .contains("Invoice #12345")); + assert!(explanation.memo_explanation.unwrap().contains("Invoice #12345")); assert!(explanation.fee_explanation.is_some()); } @@ -212,7 +192,6 @@ mod tests { operations: vec![create_other_operation("1"), create_other_operation("2")], memo: None, }; - let result = explain_transaction(&tx, None); assert!(result.is_ok()); let explanation = result.unwrap(); @@ -229,7 +208,6 @@ mod tests { operations: vec![], memo: None, }; - assert!(explain_transaction(&tx, None).is_err()); } @@ -238,4 +216,4 @@ mod tests { let summary = build_transaction_summary(false, 1, 0); assert_eq!(summary, "This failed transaction contains 1 payment."); } -} +} \ No newline at end of file diff --git a/packages/core/src/main.rs b/packages/core/src/main.rs index 44bea61..e7d9de1 100644 --- a/packages/core/src/main.rs +++ b/packages/core/src/main.rs @@ -5,9 +5,10 @@ mod explain; mod routes; mod config; mod middleware; +mod state; use axum::{ - middleware, + middleware as axum_middleware, Router, routing::get, response::{IntoResponse, Response}, @@ -23,7 +24,10 @@ use tower_http::cors::{CorsLayer, AllowOrigin}; use tower_governor::{ governor::GovernorConfigBuilder, GovernorLayer, + key_extractor::PeerIpKeyExtractor, }; +use governor::middleware::NoOpMiddleware; +use utoipa::OpenApi; use utoipa_swagger_ui::SwaggerUi; use tracing_subscriber::EnvFilter; @@ -33,26 +37,16 @@ use crate::services::horizon::HorizonClient; use crate::middleware::request_id::request_id_middleware; -fn rate_limit_layer() -> GovernorLayer { - let governor_conf = GovernorConfigBuilder::default() - .per_minute(60) - .burst_size(60) - .use_headers() - .finish() - .expect("failed to build rate limit config"); - - GovernorLayer { - config: std::sync::Arc::new(governor_conf), - error_handler: Some(Box::new(|_| { - Box::pin(async { - RateLimitError { - error: "rate_limited", - message: "Too many requests. Please retry later.", - } - .into_response() - }) - })), - } +fn rate_limit_layer() -> GovernorLayer { + let governor_conf = Arc::new( + GovernorConfigBuilder::default() + .per_second(1) + .burst_size(60) + .finish() + .expect("failed to build rate limit config"), + ); + + GovernorLayer { config: governor_conf } } #[derive(Serialize)] @@ -63,11 +57,7 @@ struct RateLimitError { impl IntoResponse for RateLimitError { fn into_response(self) -> Response { - ( - StatusCode::TOO_MANY_REQUESTS, - Json(self), - ) - .into_response() + (StatusCode::TOO_MANY_REQUESTS, Json(self)).into_response() } } @@ -151,7 +141,7 @@ async fn main() { .layer(cors) .layer( ServiceBuilder::new() - .layer(middleware::from_fn(request_id_middleware)) + .layer(axum_middleware::from_fn(request_id_middleware)) .layer(rate_limit_layer()) ); @@ -160,4 +150,4 @@ async fn main() { let listener = TcpListener::bind(addr).await.unwrap(); axum::serve(listener, app).await.unwrap(); -} +} \ No newline at end of file diff --git a/packages/core/src/models/operation.rs b/packages/core/src/models/operation.rs index 121af62..87da76c 100644 --- a/packages/core/src/models/operation.rs +++ b/packages/core/src/models/operation.rs @@ -2,21 +2,28 @@ //! //! Internal representation of Stellar operations, independent of Horizon JSON. +use crate::models::memo::Memo; use serde::{Deserialize, Serialize}; -use crate::services::horizon::{HorizonOperation, HorizonPathAsset}; +#[derive(Debug, Clone)] +pub struct Transaction { + pub hash: String, + pub successful: bool, + pub fee_charged: u64, + pub operations: Vec, + pub memo: Memo, +} /// Represents a Stellar operation. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] #[serde(tag = "type", rename_all = "snake_case")] pub enum Operation { Payment(PaymentOperation), - ManageSellOffer(ManageOfferOperation), - ManageBuyOffer(ManageOfferOperation), - PathPaymentStrictSend(PathPaymentOperation), - PathPaymentStrictReceive(PathPaymentOperation), - ChangeTrust(ChangeTrustOperation), + SetOptions(SetOptionsOperation), CreateAccount(CreateAccountOperation), + ChangeTrust(ChangeTrustOperation), + ManageOffer(ManageOfferOperation), + PathPayment(PathPaymentOperation), Other(OtherOperation), } @@ -32,12 +39,57 @@ pub struct PaymentOperation { pub amount: String, } +/// A set_options operation that configures account settings. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Default)] +pub struct SetOptionsOperation { + pub id: String, + pub source_account: Option, + pub inflation_dest: Option, + pub clear_flags: Option, + pub set_flags: Option, + pub master_weight: Option, + pub low_threshold: Option, + pub med_threshold: Option, + pub high_threshold: Option, + pub home_domain: Option, + pub signer_key: Option, + pub signer_weight: Option, +} + +/// A create_account operation that funds and activates a new Stellar account. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct CreateAccountOperation { + pub id: String, + /// The account that funds the new account. + pub funder: String, + /// The newly created account address. + pub new_account: String, + /// Starting XLM balance sent to the new account. + pub starting_balance: String, +} + +/// A change_trust operation that adds, updates, or removes a trust line. +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +pub struct ChangeTrustOperation { + pub id: String, + /// The account opting in or out of holding the asset. + pub trustor: String, + pub asset_code: String, + pub asset_issuer: String, + /// Trust limit. "0" means remove the trust line. + pub limit: String, +} + +/// Whether the offer intends to sell or buy the named asset. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "snake_case")] pub enum OfferType { Sell, Buy, } +/// A manage_offer (or manage_buy_offer) operation that creates, updates, or +/// cancels an order on the Stellar DEX. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct ManageOfferOperation { pub id: String, @@ -46,16 +98,20 @@ pub struct ManageOfferOperation { pub buying_asset: String, pub amount: String, pub price: String, + /// 0 = new offer, non-zero = update or cancel. pub offer_id: u64, pub offer_type: OfferType, } +/// Whether the path payment fixes the send amount or the receive amount. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] +#[serde(rename_all = "snake_case")] pub enum PathPaymentType { StrictSend, StrictReceive, } +/// A path_payment_strict_send or path_payment_strict_receive operation. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct PathPaymentOperation { pub id: String, @@ -65,30 +121,12 @@ pub struct PathPaymentOperation { pub send_amount: String, pub dest_asset: String, pub dest_amount: String, + /// Intermediate assets in the conversion path. pub path: Vec, pub payment_type: PathPaymentType, } -/// A create_account operation that funds and activates a new Stellar account. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct CreateAccountOperation { - pub id: String, - pub funder: String, - pub new_account: String, - pub starting_balance: String, -} - -/// A change_trust operation that opts an account in or out of holding a non-native asset. -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct ChangeTrustOperation { - pub id: String, - pub trustor: String, - pub asset_code: String, - pub asset_issuer: String, - pub limit: String, -} - -/// Placeholder for non-supported operation types. +/// Placeholder for operation types we do not yet explain. #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] pub struct OtherOperation { pub id: String, @@ -96,156 +134,174 @@ pub struct OtherOperation { } impl Operation { - /// Returns true if this operation is a payment. pub fn is_payment(&self) -> bool { matches!(self, Operation::Payment(_)) } - /// Returns true if this operation is a change_trust. - pub fn is_change_trust(&self) -> bool { - matches!(self, Operation::ChangeTrust(_)) - } - - /// Returns true if this operation is a create_account. - pub fn is_create_account(&self) -> bool { - matches!(self, Operation::CreateAccount(_)) + pub fn is_set_options(&self) -> bool { + matches!(self, Operation::SetOptions(_)) } - /// Returns the operation ID. pub fn id(&self) -> &str { match self { Operation::Payment(p) => &p.id, - Operation::ManageSellOffer(o) => &o.id, - Operation::ManageBuyOffer(o) => &o.id, - Operation::PathPaymentStrictSend(p) => &p.id, - Operation::PathPaymentStrictReceive(p) => &p.id, + Operation::SetOptions(s) => &s.id, + Operation::CreateAccount(c) => &c.id, Operation::ChangeTrust(c) => &c.id, - Operation::CreateAccount(ca) => &ca.id, + Operation::ManageOffer(m) => &m.id, + Operation::PathPayment(p) => &p.id, Operation::Other(o) => &o.id, } } } -fn format_asset( - asset_type: Option, - asset_code: Option, - asset_issuer: Option, -) -> String { - match asset_type.as_deref() { - Some("native") => "XLM (native)".to_string(), +use crate::services::horizon::HorizonOperation; + +/// Format an asset from Horizon's separate code/issuer/type fields into +/// a single display string: "XLM (native)" or "USDC (GISSUER...)". +fn format_asset(asset_type: Option<&str>, asset_code: Option<&str>, asset_issuer: Option<&str>) -> String { + match asset_type { + Some("native") | None => "XLM (native)".to_string(), _ => match (asset_code, asset_issuer) { (Some(code), Some(issuer)) => format!("{} ({})", code, issuer), - (Some(code), None) => code, + (Some(code), None) => code.to_string(), _ => "Unknown".to_string(), }, } } -fn format_offer_asset( - asset_type: Option, - asset_code: Option, - asset_issuer: Option, -) -> String { - format_asset(asset_type, asset_code, asset_issuer) -} - -fn format_path(path: Option>) -> Vec { - path.unwrap_or_default() - .into_iter() - .map(|asset| format_asset(Some(asset.asset_type), asset.asset_code, asset.asset_issuer)) - .collect() -} - impl From for Operation { fn from(op: HorizonOperation) -> Self { - let op_type = op.type_i.clone(); - - match op_type.as_str() { + match op.type_i.as_str() { "payment" => Operation::Payment(PaymentOperation { id: op.id, - source_account: op.from.or(op.source_account), + source_account: op.from.clone().or(op.source_account.clone()), destination: op.to.unwrap_or_default(), asset_type: op.asset_type.unwrap_or_else(|| "native".to_string()), asset_code: op.asset_code, asset_issuer: op.asset_issuer, amount: op.amount.unwrap_or_else(|| "0".to_string()), }), - "manage_sell_offer" => Operation::ManageSellOffer(ManageOfferOperation { + "set_options" => Operation::SetOptions(SetOptionsOperation { id: op.id, - seller: op.source_account.unwrap_or_default(), - selling_asset: format_offer_asset( - op.selling_asset_type, - op.selling_asset_code, - op.selling_asset_issuer, - ), - buying_asset: format_offer_asset( - op.buying_asset_type, - op.buying_asset_code, - op.buying_asset_issuer, - ), - amount: op.amount.unwrap_or_else(|| "0".to_string()), - price: op.price.unwrap_or_default(), - offer_id: op.offer_id.unwrap_or(0), - offer_type: OfferType::Sell, + source_account: op.source_account, + inflation_dest: op.inflation_dest, + clear_flags: op.clear_flags, + set_flags: op.set_flags, + master_weight: op.master_weight, + low_threshold: op.low_threshold, + med_threshold: op.med_threshold, + high_threshold: op.high_threshold, + home_domain: op.home_domain, + signer_key: op.signer_key, + signer_weight: op.signer_weight, }), - "manage_buy_offer" => Operation::ManageBuyOffer(ManageOfferOperation { + "create_account" => Operation::CreateAccount(CreateAccountOperation { id: op.id, - seller: op.source_account.unwrap_or_default(), - selling_asset: format_offer_asset( - op.selling_asset_type, - op.selling_asset_code, - op.selling_asset_issuer, - ), - buying_asset: format_offer_asset( - op.buying_asset_type, - op.buying_asset_code, - op.buying_asset_issuer, - ), - amount: op.amount.unwrap_or_else(|| "0".to_string()), - price: op.price.unwrap_or_default(), - offer_id: op.offer_id.unwrap_or(0), - offer_type: OfferType::Buy, + funder: op.funder.unwrap_or_else(|| "Unknown".to_string()), + new_account: op.account.unwrap_or_default(), + starting_balance: op.starting_balance.unwrap_or_else(|| "0".to_string()), }), - "path_payment_strict_send" => Operation::PathPaymentStrictSend(PathPaymentOperation { + "change_trust" => Operation::ChangeTrust(ChangeTrustOperation { id: op.id, - source_account: op.from.or(op.source_account), - destination: op.to.unwrap_or_default(), - send_asset: format_asset(op.source_asset_type, op.source_asset_code, op.source_asset_issuer), - send_amount: op.source_amount.unwrap_or_else(|| "0".to_string()), - dest_asset: format_asset(op.asset_type, op.asset_code, op.asset_issuer), - dest_amount: op.amount.unwrap_or_else(|| "0".to_string()), - path: format_path(op.path), - payment_type: PathPaymentType::StrictSend, + trustor: op.source_account.unwrap_or_else(|| "Unknown".to_string()), + asset_code: op.asset_code.unwrap_or_default(), + asset_issuer: op.asset_issuer.unwrap_or_default(), + limit: op.limit.unwrap_or_else(|| "0".to_string()), }), + "manage_offer" | "manage_sell_offer" => { + let selling = format_asset( + op.selling_asset_type.as_deref(), + op.selling_asset_code.as_deref(), + op.selling_asset_issuer.as_deref(), + ); + let buying = format_asset( + op.buying_asset_type.as_deref(), + op.buying_asset_code.as_deref(), + op.buying_asset_issuer.as_deref(), + ); + Operation::ManageOffer(ManageOfferOperation { + id: op.id, + seller: op.source_account.unwrap_or_else(|| "Unknown".to_string()), + selling_asset: selling, + buying_asset: buying, + amount: op.amount.unwrap_or_else(|| "0".to_string()), + price: op.price.unwrap_or_default(), + offer_id: op.offer_id.unwrap_or(0), + offer_type: OfferType::Sell, + }) + } + "manage_buy_offer" => { + let selling = format_asset( + op.selling_asset_type.as_deref(), + op.selling_asset_code.as_deref(), + op.selling_asset_issuer.as_deref(), + ); + let buying = format_asset( + op.buying_asset_type.as_deref(), + op.buying_asset_code.as_deref(), + op.buying_asset_issuer.as_deref(), + ); + Operation::ManageOffer(ManageOfferOperation { + id: op.id, + seller: op.source_account.unwrap_or_else(|| "Unknown".to_string()), + selling_asset: selling, + buying_asset: buying, + amount: op.amount.unwrap_or_else(|| "0".to_string()), + price: op.price.unwrap_or_default(), + offer_id: op.offer_id.unwrap_or(0), + offer_type: OfferType::Buy, + }) + } + "path_payment_strict_send" => { + let send_asset = format_asset( + op.source_asset_type.as_deref(), + op.source_asset_code.as_deref(), + op.source_asset_issuer.as_deref(), + ); + let dest_asset = format_asset( + op.asset_type.as_deref(), + op.asset_code.as_deref(), + op.asset_issuer.as_deref(), + ); + Operation::PathPayment(PathPaymentOperation { + id: op.id, + source_account: op.from.clone().or(op.source_account.clone()), + destination: op.to.unwrap_or_default(), + send_asset, + send_amount: op.source_amount.unwrap_or_else(|| "0".to_string()), + dest_asset, + dest_amount: op.amount.unwrap_or_else(|| "0".to_string()), + path: op.path.unwrap_or_default(), + payment_type: PathPaymentType::StrictSend, + }) + } "path_payment_strict_receive" => { - Operation::PathPaymentStrictReceive(PathPaymentOperation { + let send_asset = format_asset( + op.source_asset_type.as_deref(), + op.source_asset_code.as_deref(), + op.source_asset_issuer.as_deref(), + ); + let dest_asset = format_asset( + op.asset_type.as_deref(), + op.asset_code.as_deref(), + op.asset_issuer.as_deref(), + ); + Operation::PathPayment(PathPaymentOperation { id: op.id, - source_account: op.from.or(op.source_account), + source_account: op.from.clone().or(op.source_account.clone()), destination: op.to.unwrap_or_default(), - send_asset: format_asset(op.source_asset_type, op.source_asset_code, op.source_asset_issuer), + send_asset, send_amount: op.source_amount.unwrap_or_else(|| "0".to_string()), - dest_asset: format_asset(op.asset_type, op.asset_code, op.asset_issuer), + dest_asset, dest_amount: op.amount.unwrap_or_else(|| "0".to_string()), - path: format_path(op.path), + path: op.path.unwrap_or_default(), payment_type: PathPaymentType::StrictReceive, }) } - "change_trust" => Operation::ChangeTrust(ChangeTrustOperation { - id: op.id, - trustor: op.trustor.unwrap_or_default(), - asset_code: op.asset_code.unwrap_or_default(), - asset_issuer: op.asset_issuer.unwrap_or_default(), - limit: op.limit.unwrap_or_else(|| "0".to_string()), - }), - "create_account" => Operation::CreateAccount(CreateAccountOperation { - id: op.id, - funder: op.funder.unwrap_or_default(), - new_account: op.account.unwrap_or_default(), - starting_balance: op.starting_balance.unwrap_or_else(|| "0".to_string()), - }), _ => Operation::Other(OtherOperation { id: op.id, - operation_type: op_type, + operation_type: op.type_i, }), } } @@ -266,16 +322,25 @@ mod tests { asset_issuer: None, amount: "100.0".to_string(), }); - let other = Operation::Other(OtherOperation { id: "67890".to_string(), operation_type: "create_account".to_string(), }); - assert!(payment.is_payment()); assert!(!other.is_payment()); } + #[test] + fn test_is_set_options() { + let set_opts = Operation::SetOptions(SetOptionsOperation { + id: "op1".to_string(), + home_domain: Some("example.com".to_string()), + ..Default::default() + }); + assert!(set_opts.is_set_options()); + assert!(!set_opts.is_payment()); + } + #[test] fn test_operation_id() { let payment = Operation::Payment(PaymentOperation { @@ -287,7 +352,50 @@ mod tests { asset_issuer: None, amount: "100.0".to_string(), }); - assert_eq!(payment.id(), "12345"); } -} + + #[test] + fn test_set_options_id() { + let op = Operation::SetOptions(SetOptionsOperation { + id: "set-op-99".to_string(), + ..Default::default() + }); + assert_eq!(op.id(), "set-op-99"); + } + + #[test] + fn test_create_account_id() { + let op = Operation::CreateAccount(CreateAccountOperation { + id: "ca-1".to_string(), + funder: "GFUNDER".to_string(), + new_account: "GNEW".to_string(), + starting_balance: "100".to_string(), + }); + assert_eq!(op.id(), "ca-1"); + } + + #[test] + fn test_change_trust_id() { + let op = Operation::ChangeTrust(ChangeTrustOperation { + id: "ct-1".to_string(), + trustor: "GTRUSTEE".to_string(), + asset_code: "USDC".to_string(), + asset_issuer: "GISSUER".to_string(), + limit: "1000".to_string(), + }); + assert_eq!(op.id(), "ct-1"); + } + + #[test] + fn test_format_asset_native() { + let result = format_asset(Some("native"), None, None); + assert_eq!(result, "XLM (native)"); + } + + #[test] + fn test_format_asset_credit() { + let result = format_asset(Some("credit_alphanum4"), Some("USDC"), Some("GISSUER")); + assert_eq!(result, "USDC (GISSUER)"); + } +} \ No newline at end of file diff --git a/packages/core/src/services/explain.rs b/packages/core/src/services/explain.rs index b668d2d..cd893e9 100644 --- a/packages/core/src/services/explain.rs +++ b/packages/core/src/services/explain.rs @@ -23,21 +23,12 @@ pub fn map_transaction_to_domain( fn map_memo(memo_type: Option<&str>, memo_value: Option<&str>) -> Option { match memo_type { None | Some("none") => None, - Some("text") => { - memo_value.and_then(|v| Memo::text(v)) - } - Some("id") => { - memo_value - .and_then(|v| v.parse::().ok()) - .map(Memo::id) - } - Some("hash") => { - memo_value.map(|v| Memo::hash(v)) - } - Some("return") => { - memo_value.map(|v| Memo::return_hash(v)) - } - // Unknown memo type — treat as no memo rather than crashing + Some("text") => memo_value.and_then(|v| Memo::text(v)), + Some("id") => memo_value + .and_then(|v| v.parse::().ok()) + .map(Memo::id), + Some("hash") => memo_value.map(|v| Memo::hash(v)), + Some("return") => memo_value.map(|v| Memo::return_hash(v)), Some(_) => None, } } @@ -86,7 +77,6 @@ mod tests { #[test] fn test_map_memo_unknown_type() { - // Unknown types should degrade gracefully, not crash assert_eq!(map_memo(Some("unknown_future_type"), Some("value")), None); } } \ No newline at end of file diff --git a/packages/core/src/services/horizon.rs b/packages/core/src/services/horizon.rs index 50d6eae..e2b2c17 100644 --- a/packages/core/src/services/horizon.rs +++ b/packages/core/src/services/horizon.rs @@ -1,16 +1,12 @@ use reqwest::Client; use serde::Deserialize; -use std::{ - collections::HashMap, - sync::{Mutex, OnceLock}, - time::Duration, -}; +use std::collections::HashMap; +use std::sync::{Arc, RwLock}; +use std::time::{Duration, Instant}; use crate::errors::HorizonError; use crate::models::fee::FeeStats; -use crate::services::transaction_cache::{CacheKey, Network, TransactionCache}; -/// Raw transaction response from the Horizon API. #[derive(Debug, Deserialize, Clone)] pub struct HorizonTransaction { pub hash: String, @@ -20,29 +16,23 @@ pub struct HorizonTransaction { pub memo: Option, } -/// Raw fee_stats response from Horizon. -/// https://developers.stellar.org/api/horizon/aggregations/fee-stats -#[derive(Debug, Deserialize)] -struct HorizonFeeStats { - last_ledger_base_fee: String, - fee_charged: HorizonFeeCharged, -} - -#[derive(Debug, Deserialize)] -struct HorizonFeeCharged { - min: String, - max: String, - mode: String, - p90: String, +#[derive(Debug, Deserialize, Clone)] +pub struct HorizonAccountTransaction { + pub hash: String, + pub successful: bool, + pub created_at: String, + pub source_account: Option, + pub operation_count: u32, + pub memo_type: Option, + pub memo: Option, } -static STELLAR_TOML_ORG_CACHE: OnceLock>>> = OnceLock::new(); - #[derive(Clone)] pub struct HorizonClient { client: Client, base_url: String, - cache: TransactionCache, + /// Simple in-memory cache for stellar.toml lookups keyed by domain. + toml_cache: Arc, Instant)>>>, } impl HorizonClient { @@ -50,7 +40,7 @@ impl HorizonClient { Self { client: Client::new(), base_url: base_url.into(), - cache: TransactionCache::with_default_ttl(), + toml_cache: Arc::new(RwLock::new(HashMap::new())), } } @@ -58,12 +48,6 @@ impl HorizonClient { &self, hash: &str, ) -> Result { - let cache_key = CacheKey::new(hash.to_string(), Network::Testnet); - - if let Some(cached) = self.cache.get(&cache_key) { - return Ok(cached); - } - let url = format!("{}/transactions/{}", self.base_url, hash); let res = self @@ -73,18 +57,14 @@ impl HorizonClient { .await .map_err(|_| HorizonError::NetworkError)?; - let tx = match res.status().as_u16() { + match res.status().as_u16() { 200 => res .json::() .await - .map_err(|_| HorizonError::InvalidResponse)?, - 404 => return Err(HorizonError::TransactionNotFound), - _ => return Err(HorizonError::InvalidResponse), - }; - - self.cache.insert(cache_key, tx.clone()); - - Ok(tx) + .map_err(|_| HorizonError::InvalidResponse), + 404 => Err(HorizonError::TransactionNotFound), + _ => Err(HorizonError::InvalidResponse), + } } pub async fn fetch_operations( @@ -113,6 +93,43 @@ impl HorizonClient { } } + /// Fetch the current network fee stats from Horizon. + /// Returns None if the request fails — callers degrade gracefully. + pub async fn fetch_fee_stats(&self) -> Option { + let url = format!("{}/fee_stats", self.base_url); + + let res = self.client.get(url).send().await.ok()?; + + if res.status().as_u16() != 200 { + return None; + } + + let raw: HorizonFeeStats = res.json().await.ok()?; + + let base_fee = raw.last_ledger_base_fee.parse::().ok()?; + let min_fee = raw.fee_charged.min.parse::().unwrap_or(base_fee); + let max_fee = raw.fee_charged.max.parse::().unwrap_or(base_fee); + let mode_fee = raw.fee_charged.mode.parse::().unwrap_or(base_fee); + let p90_fee = raw.fee_charged.p90.parse::().unwrap_or(base_fee); + + Some(FeeStats::new(base_fee, min_fee, max_fee, mode_fee, p90_fee)) + } + + /// Check whether Horizon is reachable by hitting the root endpoint. + pub async fn is_reachable(&self) -> bool { + let url = format!("{}/", self.base_url); + self.client + .get(url) + .timeout(Duration::from_secs(5)) + .send() + .await + .map(|r| r.status().as_u16() < 500) + .unwrap_or(false) + } + + /// Fetch paginated transactions for an account. + /// + /// Returns `(records, next_cursor, prev_cursor)`. pub async fn fetch_account_transactions( &self, address: &str, @@ -137,161 +154,135 @@ impl HorizonClient { match res.status().as_u16() { 200 => { - let wrapper: HorizonAccountTransactionsResponse = - res.json().await.map_err(|_| HorizonError::InvalidResponse)?; - let next_cursor = wrapper.links.next.as_ref().and_then(|l| extract_cursor(&l.href)); - let prev_cursor = wrapper.links.prev.as_ref().and_then(|l| extract_cursor(&l.href)); - Ok((wrapper.embedded.records, next_cursor, prev_cursor)) + let wrapper: HorizonAccountTransactionsResponse = res + .json() + .await + .map_err(|_| HorizonError::InvalidResponse)?; + + let next_cursor = extract_cursor( + wrapper._links.next.as_ref().and_then(|l| l.href.as_deref()), + ); + let prev_cursor = extract_cursor( + wrapper._links.prev.as_ref().and_then(|l| l.href.as_deref()), + ); + + Ok((wrapper._embedded.records, next_cursor, prev_cursor)) } 404 => Err(HorizonError::AccountNotFound), _ => Err(HorizonError::InvalidResponse), } } - /// Resolve ORG_NAME from a domain's stellar.toml file. - /// - /// Uses an in-memory cache for the process lifetime and applies a hard timeout - /// so this call never blocks explanation responses for long. - pub async fn fetch_stellar_toml_org_name(&self, home_domain: &str) -> Option { - let cache_key = normalize_cache_key(home_domain)?; - - if let Some(cached) = lookup_stellar_toml_cache(&cache_key) { - return cached; + /// Fetch ORG_NAME from a domain's stellar.toml. + /// Results are cached in memory for 10 minutes per domain. + pub async fn fetch_stellar_toml_org_name(&self, domain: &str) -> Option { + // Check cache first + { + let cache = self.toml_cache.read().unwrap(); + if let Some((cached_value, cached_at)) = cache.get(domain) { + if cached_at.elapsed() < Duration::from_secs(600) { + return cached_value.clone(); + } + } } - let url = match build_stellar_toml_url(home_domain) { - Some(url) => url, - None => { - store_stellar_toml_cache(cache_key, None); - return None; - } - }; + // Fetch from domain + let url = format!("{}/.well-known/stellar.toml", domain); + let result = self.client.get(&url).send().await.ok(); - let response = match self - .client - .get(url) - .timeout(Duration::from_secs(3)) - .send() - .await - { - Ok(response) => response, - Err(_) => { - store_stellar_toml_cache(cache_key, None); - return None; + let org_name = if let Some(res) = result { + if res.status().as_u16() == 200 { + let body = res.text().await.ok().unwrap_or_default(); + parse_org_name(&body) + } else { + None } + } else { + None }; - if !response.status().is_success() { - store_stellar_toml_cache(cache_key, None); - return None; + // Store in cache + { + let mut cache = self.toml_cache.write().unwrap(); + cache.insert(domain.to_string(), (org_name.clone(), Instant::now())); } - let body = match response.text().await { - Ok(body) => body, - Err(_) => { - store_stellar_toml_cache(cache_key, None); - return None; - } - }; - let org_name = parse_org_name_from_stellar_toml(&body); - store_stellar_toml_cache(cache_key, org_name.clone()); - org_name } +} - /// Fetch current network fee statistics from Horizon. - /// Returns None if the request fails — callers should degrade gracefully. - pub async fn fetch_fee_stats(&self) -> Option { - let url = format!("{}/fee_stats", self.base_url); - - let res = self.client.get(url).send().await.ok()?; +/// Extract `cursor` query param value from a Horizon pagination href. +fn extract_cursor(href: Option<&str>) -> Option { + let href = href?; + let url = reqwest::Url::parse(href).ok()?; + url.query_pairs() + .find(|(k, _)| k == "cursor") + .map(|(_, v)| v.into_owned()) +} - if res.status().as_u16() != 200 { - return None; +/// Parse ORG_NAME from a stellar.toml body. +/// Handles both `ORG_NAME="Foo"` and `ORG_NAME = "Foo"` formats. +fn parse_org_name(toml: &str) -> Option { + for line in toml.lines() { + let trimmed = line.trim(); + if trimmed.starts_with("ORG_NAME") { + if let Some(pos) = trimmed.find('=') { + let value = trimmed[pos + 1..].trim().trim_matches('"').to_string(); + if !value.is_empty() { + return Some(value); + } + } } - - let raw: HorizonFeeStats = res.json().await.ok()?; - - // Horizon returns fees as string stroops — parse each field - let base_fee = raw.last_ledger_base_fee.parse::().ok()?; - let min_fee = raw.fee_charged.min.parse::().ok()?; - let max_fee = raw.fee_charged.max.parse::().ok()?; - let mode_fee = raw.fee_charged.mode.parse::().ok()?; - let p90_fee = raw.fee_charged.p90.parse::().ok()?; - - Some(FeeStats { - base_fee, - min_fee, - max_fee, - mode_fee, - p90_fee, - }) - } - - /// Lightweight connectivity check for health endpoint - pub async fn is_reachable(&self) -> bool { - let res = self - .client - .head(&self.base_url) - .timeout(Duration::from_secs(2)) - .send() - .await; - - matches!(res, Ok(r) if r.status().is_success()) } + None } +// ── Horizon JSON shapes ──────────────────────────────────────────────────── + #[derive(Debug, Deserialize)] -struct HorizonTransactionLink { - href: String, +struct HorizonOperationsResponse { + _embedded: HorizonEmbeddedOperations, } #[derive(Debug, Deserialize)] -struct HorizonTransactionLinks { - next: Option, - prev: Option, +struct HorizonEmbeddedOperations { + records: Vec, } #[derive(Debug, Deserialize)] struct HorizonAccountTransactionsResponse { - #[serde(rename = "_links")] - links: HorizonTransactionLinks, - #[serde(rename = "_embedded")] - embedded: HorizonAccountTransactionsEmbedded, + _links: HorizonLinks, + _embedded: HorizonEmbeddedAccountTransactions, } #[derive(Debug, Deserialize)] -struct HorizonAccountTransactionsEmbedded { - records: Vec, +struct HorizonLinks { + next: Option, + prev: Option, } -#[derive(Debug, Deserialize, Clone)] -pub struct HorizonAccountTransaction { - pub hash: String, - pub successful: bool, - pub created_at: String, - pub source_account: String, - pub operation_count: u32, - pub memo_type: Option, - pub memo: Option, +#[derive(Debug, Deserialize)] +struct HorizonLink { + href: Option, } #[derive(Debug, Deserialize)] -struct HorizonOperationsResponse { - _embedded: HorizonEmbeddedOperations, +struct HorizonEmbeddedAccountTransactions { + records: Vec, } #[derive(Debug, Deserialize)] -struct HorizonEmbeddedOperations { - records: Vec, +struct HorizonFeeStats { + last_ledger_base_fee: String, + fee_charged: HorizonFeeCharged, } -#[derive(Debug, Deserialize, Clone)] -pub struct HorizonPathAsset { - #[serde(rename = "asset_type")] - pub asset_type: String, - pub asset_code: Option, - pub asset_issuer: Option, +#[derive(Debug, Deserialize)] +struct HorizonFeeCharged { + min: String, + max: String, + mode: String, + p90: String, } #[derive(Debug, Deserialize)] @@ -300,13 +291,37 @@ pub struct HorizonOperation { pub transaction_hash: String, #[serde(rename = "type")] pub type_i: String, - pub source_account: Option, + + // Shared / payment pub from: Option, pub to: Option, pub asset_type: Option, pub asset_code: Option, pub asset_issuer: Option, pub amount: Option, + pub source_account: Option, + + // set_options + pub inflation_dest: Option, + pub clear_flags: Option, + pub set_flags: Option, + pub master_weight: Option, + pub low_threshold: Option, + pub med_threshold: Option, + pub high_threshold: Option, + pub home_domain: Option, + pub signer_key: Option, + pub signer_weight: Option, + + // create_account + pub funder: Option, + pub account: Option, + pub starting_balance: Option, + + // change_trust + pub limit: Option, + + // manage_offer / manage_buy_offer pub selling_asset_type: Option, pub selling_asset_code: Option, pub selling_asset_issuer: Option, @@ -315,74 +330,11 @@ pub struct HorizonOperation { pub buying_asset_issuer: Option, pub price: Option, pub offer_id: Option, + + // path_payment pub source_asset_type: Option, pub source_asset_code: Option, pub source_asset_issuer: Option, pub source_amount: Option, - pub path: Option>, - pub trustor: Option, - pub limit: Option, - pub funder: Option, - pub account: Option, - pub starting_balance: Option, -} - -fn extract_cursor(href: &str) -> Option { - href.split('?') - .nth(1)? - .split('&') - .find_map(|pair| { - let mut parts = pair.splitn(2, '='); - if parts.next()? == "cursor" { - parts.next().map(|v| v.to_string()) - } else { - None - } - }) -} - -fn stellar_toml_cache() -> &'static Mutex>> { - STELLAR_TOML_ORG_CACHE.get_or_init(|| Mutex::new(HashMap::new())) -} - -fn lookup_stellar_toml_cache(cache_key: &str) -> Option> { - let cache = stellar_toml_cache().lock().ok()?; - cache.get(cache_key).cloned() -} - -fn store_stellar_toml_cache(cache_key: String, org_name: Option) { - if let Ok(mut cache) = stellar_toml_cache().lock() { - cache.insert(cache_key, org_name); - } -} - -fn normalize_cache_key(home_domain: &str) -> Option { - let key = home_domain.trim().trim_end_matches('/').to_lowercase(); - if key.is_empty() { - None - } else { - Some(key) - } -} - -fn build_stellar_toml_url(home_domain: &str) -> Option { - let domain = home_domain.trim().trim_end_matches('/'); - if domain.is_empty() { - return None; - } - - if domain.starts_with("https://") || domain.starts_with("http://") { - Some(format!("{domain}/.well-known/stellar.toml")) - } else { - Some(format!("https://{domain}/.well-known/stellar.toml")) - } -} - -fn parse_org_name_from_stellar_toml(content: &str) -> Option { - let parsed: toml::Value = toml::from_str(content).ok()?; - parsed - .get("ORG_NAME") - .and_then(|value| value.as_str()) - .map(|value| value.trim().to_string()) - .filter(|value| !value.is_empty()) -} + pub path: Option>, +} \ No newline at end of file diff --git a/packages/core/tests/integration.rs b/packages/core/tests/integration.rs index 6d3bbe6..0f00376 100644 --- a/packages/core/tests/integration.rs +++ b/packages/core/tests/integration.rs @@ -1 +1,2 @@ -mod integration; +// Integration tests live in tests/integration/mod.rs +// This file intentionally left empty to avoid module ambiguity. \ No newline at end of file diff --git a/packages/stellar_explain_current2.zip b/packages/stellar_explain_current2.zip new file mode 100644 index 0000000000000000000000000000000000000000..055eaa260328277e177a3e1d9f7ceb8c47ed09f4 GIT binary patch literal 143077 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 literal 0 HcmV?d00001