From a1ddf6a75cb55b2ad60a340651edafb0f0248e4d Mon Sep 17 00:00:00 2001 From: yunusabdul38 Date: Mon, 6 Oct 2025 21:56:03 +0100 Subject: [PATCH 1/8] feat: ekubo manual swap --- Cargo.lock | 433 +++++++++-------------------------------- Cargo.toml | 12 +- src/client.rs | 8 +- src/constant/mod.rs | 86 ++++---- src/constant/util.rs | 8 + src/lib.rs | 18 +- src/swappr.rs | 186 ++++++++++++++++++ src/types/connector.rs | 114 ++++++++--- 8 files changed, 430 insertions(+), 435 deletions(-) create mode 100644 src/constant/util.rs create mode 100644 src/swappr.rs diff --git a/Cargo.lock b/Cargo.lock index 6e28aab..aff5600 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -85,10 +85,10 @@ dependencies = [ "reqwest", "serde", "starknet", - "starknet-accounts 0.15.0", - "starknet-contract 0.15.0", - "starknet-core 0.15.0", - "starknet-providers 0.15.0", + "starknet-accounts", + "starknet-contract", + "starknet-core", + "starknet-providers", "thiserror 2.0.16", "tokio", "url", @@ -106,7 +106,7 @@ dependencies = [ "miniz_oxide", "object", "rustc-demangle", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -227,9 +227,9 @@ dependencies = [ [[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] @@ -317,9 +317,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" dependencies = [ "darling_core", "darling_macro", @@ -327,9 +327,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" dependencies = [ "fnv", "ident_case", @@ -341,9 +341,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.11" +version = "0.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" dependencies = [ "darling_core", "quote", @@ -352,12 +352,12 @@ dependencies = [ [[package]] name = "deranged" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d630bccd429a5bb5a64b5e94f693bfc48c9f8566418fda4c494cc94f911f87cc" +checksum = "a41953f86f8a05768a6cda24def994fd2f424b04ec5c719cf89989779f199071" dependencies = [ "powerfmt", - "serde", + "serde_core", ] [[package]] @@ -488,9 +488,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" +checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" dependencies = [ "crc32fast", "miniz_oxide", @@ -1046,25 +1046,13 @@ dependencies = [ "cpufeatures", ] -[[package]] -name = "lambdaworks-crypto" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbc2a4da0d9e52ccfe6306801a112e81a8fc0c76aa3e4449fefeda7fef72bb34" -dependencies = [ - "lambdaworks-math 0.10.0", - "serde", - "sha2", - "sha3", -] - [[package]] name = "lambdaworks-crypto" version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fce8f59622ed408c318c9b5eca17f1a1154159e3738b5c4d5a22a0dd3700c906" dependencies = [ - "lambdaworks-math 0.12.0", + "lambdaworks-math", "rand 0.8.5", "rand_chacha 0.3.1", "serde", @@ -1072,16 +1060,6 @@ dependencies = [ "sha3", ] -[[package]] -name = "lambdaworks-math" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1bd2632acbd9957afc5aeec07ad39f078ae38656654043bf16e046fa2730e23" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "lambdaworks-math" version = "0.12.0" @@ -1153,6 +1131,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", + "simd-adler32", ] [[package]] @@ -1324,7 +1303,7 @@ dependencies = [ "libc", "redox_syscall", "smallvec", - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -1467,7 +1446,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] @@ -1561,18 +1540,18 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.24" +version = "1.0.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" dependencies = [ "proc-macro2", "quote", @@ -1886,9 +1865,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5" +checksum = "6093cd8c01b25262b84927e0f7151692158fab02d961e04c979d3903eba7ecc5" dependencies = [ "base64 0.22.1", "chrono", @@ -1897,8 +1876,7 @@ dependencies = [ "indexmap 2.11.4", "schemars 0.9.0", "schemars 1.0.4", - "serde", - "serde_derive", + "serde_core", "serde_json", "serde_with_macros", "time", @@ -1906,9 +1884,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.14.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f" +checksum = "a7e6c180db0816026a61afa1cff5344fb7ebded7e4d3062772179f2501481c27" dependencies = [ "darling", "proc-macro2", @@ -1953,10 +1931,10 @@ dependencies = [ ] [[package]] -name = "size-of" -version = "0.1.5" +name = "simd-adler32" +version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4e36eca171fddeda53901b0a436573b3f2391eaa9189d439b2bd8ea8cebd7e3" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" [[package]] name = "slab" @@ -1988,126 +1966,50 @@ checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "starknet" -version = "0.15.1" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21ec983c56ce05b2d7679fa860b37b2ade21004c343ff49374a591b40ee8ee1d" +checksum = "f5ed01c14136e56dcdf21385d20c4a6fdd3509947cb56cca45fc765ef5809add" dependencies = [ - "starknet-accounts 0.14.0", - "starknet-contract 0.14.0", - "starknet-core 0.14.0", + "starknet-accounts", + "starknet-contract", + "starknet-core", "starknet-core-derive", - "starknet-crypto 0.7.4", + "starknet-crypto", "starknet-macros", - "starknet-providers 0.14.1", - "starknet-signers 0.12.0", + "starknet-providers", + "starknet-signers", ] [[package]] name = "starknet-accounts" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7adf55fa08ffed413614df3171632e45dcba72cc53706b147ba08e5b7b4e4fb" -dependencies = [ - "async-trait", - "auto_impl", - "starknet-core 0.14.0", - "starknet-crypto 0.7.4", - "starknet-providers 0.14.1", - "starknet-signers 0.12.0", - "thiserror 1.0.69", -] - -[[package]] -name = "starknet-accounts" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7961299fe73e642f1c2c6b8297cc5702740b000ce2b3956c1ab349f53654107e" +checksum = "4f7c118729bcdcfa1610844047cbdb23090fb1d4172a36bb97a663be8d022d1a" dependencies = [ "async-trait", "auto_impl", - "starknet-core 0.15.0", - "starknet-crypto 0.7.4", - "starknet-providers 0.15.0", - "starknet-signers 0.13.0", + "starknet-core", + "starknet-crypto", + "starknet-providers", + "starknet-signers", "thiserror 1.0.69", ] [[package]] name = "starknet-contract" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72746fa496e352ef16b4a8fd11e415ada6b7b5a9107fc6e845eeb921b8bb2a69" -dependencies = [ - "serde", - "serde_json", - "serde_with", - "starknet-accounts 0.14.0", - "starknet-core 0.14.0", - "starknet-providers 0.14.1", - "thiserror 1.0.69", -] - -[[package]] -name = "starknet-contract" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94e91bb0ec9b25b8cd0579540f66fb3eb965b43fbf65789a4bda65073aa43662" +checksum = "ccb64331b72caf51c0d8b684b62012f9a771015b4cf5e52cba9bf61be8384ad3" dependencies = [ "serde", "serde_json", "serde_with", - "starknet-accounts 0.15.0", - "starknet-core 0.15.0", - "starknet-providers 0.15.0", + "starknet-accounts", + "starknet-core", + "starknet-providers", "thiserror 1.0.69", ] -[[package]] -name = "starknet-core" -version = "0.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc2091a08ebfc65c5a6b8bd2c66e32780739854b813af0b4348b6dbf3a887865" -dependencies = [ - "base64 0.21.7", - "crypto-bigint", - "flate2", - "foldhash", - "hex", - "indexmap 2.11.4", - "num-traits", - "serde", - "serde_json", - "serde_json_pythonic", - "serde_with", - "sha3", - "starknet-core-derive", - "starknet-crypto 0.7.4", - "starknet-types-core 0.1.9", -] - -[[package]] -name = "starknet-core" -version = "0.15.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ebd248c1503f89d74f98bfb38119f6421ffb81b23f3404f33b268539d0c4cb6" -dependencies = [ - "base64 0.21.7", - "crypto-bigint", - "flate2", - "foldhash", - "hex", - "indexmap 2.11.4", - "num-traits", - "serde", - "serde_json", - "serde_json_pythonic", - "serde_with", - "sha3", - "starknet-core-derive", - "starknet-crypto 0.7.4", - "starknet-types-core 0.1.9", -] - [[package]] name = "starknet-core" version = "0.16.0" @@ -2127,8 +2029,8 @@ dependencies = [ "serde_with", "sha3", "starknet-core-derive", - "starknet-crypto 0.8.1", - "starknet-types-core 0.2.1", + "starknet-crypto", + "starknet-types-core", ] [[package]] @@ -2142,25 +2044,6 @@ dependencies = [ "syn", ] -[[package]] -name = "starknet-crypto" -version = "0.7.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "039a3bad70806b494c9e6b21c5238a6c8a373d66a26071859deb0ccca6f93634" -dependencies = [ - "crypto-bigint", - "hex", - "hmac", - "num-bigint", - "num-integer", - "num-traits", - "rfc6979", - "sha2", - "starknet-curve 0.5.1", - "starknet-types-core 0.1.9", - "zeroize", -] - [[package]] name = "starknet-crypto" version = "0.8.1" @@ -2175,27 +2058,18 @@ dependencies = [ "num-traits", "rfc6979", "sha2", - "starknet-curve 0.6.0", - "starknet-types-core 0.2.1", + "starknet-curve", + "starknet-types-core", "zeroize", ] -[[package]] -name = "starknet-curve" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcde6bd74269b8161948190ace6cf069ef20ac6e79cd2ba09b320efa7500b6de" -dependencies = [ - "starknet-types-core 0.1.9", -] - [[package]] name = "starknet-curve" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "22c898ae81b6409532374cf237f1bd752d068b96c6ad500af9ebbd0d9bb712f6" dependencies = [ - "starknet-types-core 0.2.1", + "starknet-types-core", ] [[package]] @@ -2204,36 +2078,15 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6d59e1eb22f4366385b132ba7016faa5a6457f1f23f896f737a06da626455e7b" dependencies = [ - "starknet-core 0.16.0", + "starknet-core", "syn", ] [[package]] name = "starknet-providers" -version = "0.14.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ce77bf215b70673264bc875d59c45fb7da500e7e6f71d2608ad25a1f7280671" -dependencies = [ - "async-trait", - "auto_impl", - "ethereum-types", - "flate2", - "getrandom 0.2.16", - "log", - "reqwest", - "serde", - "serde_json", - "serde_with", - "starknet-core 0.14.0", - "thiserror 1.0.69", - "url", -] - -[[package]] -name = "starknet-providers" -version = "0.15.0" +version = "0.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a11aa3094e646d6fe49d2cfdc49b99b42b280b170518eeb50f759d62cccbf4ae" +checksum = "15fc3d94cc008cea64e291b261e8349065424ee7491e5dd0fa9bd688818bece1" dependencies = [ "async-trait", "auto_impl", @@ -2245,33 +2098,16 @@ dependencies = [ "serde", "serde_json", "serde_with", - "starknet-core 0.15.0", + "starknet-core", "thiserror 1.0.69", "url", ] [[package]] name = "starknet-signers" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defd831176f8a217694895fd69be17f985e5e28f00bc8044eb54b55656f3a7f1" -dependencies = [ - "async-trait", - "auto_impl", - "crypto-bigint", - "eth-keystore", - "getrandom 0.2.16", - "rand 0.8.5", - "starknet-core 0.14.0", - "starknet-crypto 0.7.4", - "thiserror 1.0.69", -] - -[[package]] -name = "starknet-signers" -version = "0.13.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e60350b8a56451cd937bdea01bee50519a38611f277c06bc2bdc7eaf103a6a" +checksum = "d839b06d899ef3a0de11b1e9a91a14c118b1ed36830ec8e59d9fbc9a1e51976b" dependencies = [ "async-trait", "auto_impl", @@ -2279,45 +2115,26 @@ dependencies = [ "eth-keystore", "getrandom 0.2.16", "rand 0.8.5", - "starknet-core 0.15.0", - "starknet-crypto 0.7.4", + "starknet-core", + "starknet-crypto", "thiserror 1.0.69", ] [[package]] name = "starknet-types-core" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87af771d7f577931913089f9ca9a9f85d8a6238d59b2977f4c383d133c8abd3b" -dependencies = [ - "blake2", - "digest", - "lambdaworks-crypto 0.10.0", - "lambdaworks-math 0.10.0", - "num-bigint", - "num-integer", - "num-traits", - "serde", - "size-of", - "zeroize", -] - -[[package]] -name = "starknet-types-core" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c043ab183b1cb1daab10d592719d27f283e7ef7e7ac8accd243b4e70b4e1c0d8" +checksum = "92eb6db1a763c350ffa50ed65ea3a92de9888239357cfbcb633e29a4da77f122" dependencies = [ "blake2", "digest", - "lambdaworks-crypto 0.12.0", - "lambdaworks-math 0.12.0", + "lambdaworks-crypto", + "lambdaworks-math", "num-bigint", "num-integer", "num-traits", "rand 0.9.2", "serde", - "size-of", "zeroize", ] @@ -2681,9 +2498,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.18.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "uint" @@ -2891,9 +2708,9 @@ dependencies = [ [[package]] name = "windows-core" -version = "0.62.0" +version = "0.62.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57fe7168f7de578d2d8a05b07fd61870d2e73b4020e9f49aa00da8471723497c" +checksum = "6844ee5416b285084d3d3fffd743b925a6c9385455f64f6d4fa3031c4c2749a9" dependencies = [ "windows-implement", "windows-interface", @@ -2904,9 +2721,9 @@ dependencies = [ [[package]] name = "windows-implement" -version = "0.60.0" +version = "0.60.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +checksum = "edb307e42a74fb6de9bf3a02d9712678b22399c87e6fa869d6dfcd8c1b7754e0" dependencies = [ "proc-macro2", "quote", @@ -2915,9 +2732,9 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.59.1" +version = "0.59.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +checksum = "c0abd1ddbc6964ac14db11c7213d6532ef34bd9aa042c2e5935f59d7908b46a5" dependencies = [ "proc-macro2", "quote", @@ -2989,7 +2806,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.6", + "windows-targets", ] [[package]] @@ -2998,16 +2815,7 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-sys" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" -dependencies = [ - "windows-targets 0.53.3", + "windows-targets", ] [[package]] @@ -3025,31 +2833,14 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.6", - "windows_aarch64_msvc 0.52.6", - "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm 0.52.6", - "windows_i686_msvc 0.52.6", - "windows_x86_64_gnu 0.52.6", - "windows_x86_64_gnullvm 0.52.6", - "windows_x86_64_msvc 0.52.6", -] - -[[package]] -name = "windows-targets" -version = "0.53.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" -dependencies = [ - "windows-link 0.1.3", - "windows_aarch64_gnullvm 0.53.0", - "windows_aarch64_msvc 0.53.0", - "windows_i686_gnu 0.53.0", - "windows_i686_gnullvm 0.53.0", - "windows_i686_msvc 0.53.0", - "windows_x86_64_gnu 0.53.0", - "windows_x86_64_gnullvm 0.53.0", - "windows_x86_64_msvc 0.53.0", + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", ] [[package]] @@ -3058,96 +2849,48 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" -[[package]] -name = "windows_aarch64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" - [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" -[[package]] -name = "windows_i686_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" - [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" -[[package]] -name = "windows_i686_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" - [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" -[[package]] -name = "windows_i686_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" -[[package]] -name = "windows_x86_64_gnu" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" -[[package]] -name = "windows_x86_64_msvc" -version = "0.53.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" - [[package]] name = "winnow" version = "0.7.13" diff --git a/Cargo.toml b/Cargo.toml index ad1178f..50a4f3c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,12 +21,12 @@ edition = "2024" [dependencies] thiserror = "2.0.16" serde = {version="1.0.219", features=["derive"]} -starknet = "0.15.0" -starknet-contract = "0.15.0" -starknet-accounts = "0.15.0" -starknet-providers = "0.15.0" -starknet-core = "0.15.0" tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } url = "2.5" -hex = "0.4" \ No newline at end of file +hex = "0.4" +starknet = "0.17.0" +starknet-contract = "0.16.0" +starknet-accounts = "0.16.0" +starknet-providers = "0.16.0" +starknet-core = "0.16.0" diff --git a/src/client.rs b/src/client.rs index 430986f..88b26df 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,6 +1,6 @@ use crate::{ contracts::{AutoSwapprContract, Erc20Contract}, - types::connector::{AutoSwapprConfig, AutoSwapprError, ContractInfo, SwapData, Uint256}, + types::connector::{AutoSwappr, AutoSwapprError, ContractInfo, SwapData, Uint256}, }; use starknet::{ accounts::{Account, ExecutionEncoding, SingleOwnerAccount}, @@ -18,12 +18,12 @@ pub struct AutoSwapprClient { provider: Arc>, autoswappr_contract: AutoSwapprContract, account: SingleOwnerAccount, LocalWallet>, - config: AutoSwapprConfig, + config: AutoSwappr, } impl AutoSwapprClient { /// Create a new AutoSwappr client with real Starknet integration - pub async fn new(config: AutoSwapprConfig) -> Result { + pub async fn new(config: AutoSwappr) -> Result { // Parse RPC URL let rpc_url = Url::parse(&config.rpc_url).map_err(|e| AutoSwapprError::InvalidInput { details: format!("Invalid RPC URL: {}", e), @@ -430,7 +430,7 @@ impl AutoSwapprClient { mod tests { use super::*; use crate::types::connector::{ - Amount, AutoSwapprConfig, PoolKey, SwapData, SwapParameters, Uint256, + Amount, AutoSwappr, PoolKey, SwapData, SwapParameters, Uint256, }; fn create_test_config() -> AutoSwapprConfig { diff --git a/src/constant/mod.rs b/src/constant/mod.rs index f1076af..e166ac1 100644 --- a/src/constant/mod.rs +++ b/src/constant/mod.rs @@ -1,14 +1,25 @@ +mod util; +use std::sync::LazyLock; + +use starknet::core::types::Felt; +pub use util::u128_to_uint256; //Token addresses for common tokens -#[allow(dead_code)] -const STRK: &str = "0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d"; -#[allow(dead_code)] -const ETH: &str = "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"; -#[allow(dead_code)] -const USDC: &str = "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8"; -#[allow(dead_code)] -const USDT: &str = "0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8"; -#[allow(dead_code)] -const WBTC: &str = "0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac"; + +pub static STRK: LazyLock = LazyLock::new(|| { + Felt::from_hex("0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d").unwrap() +}); +pub static ETH: LazyLock = LazyLock::new(|| { + Felt::from_hex("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap() +}); +pub static USDC: LazyLock = LazyLock::new(|| { + Felt::from_hex("0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8").unwrap() +}); +pub static USDT: LazyLock = LazyLock::new(|| { + Felt::from_hex("0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8").unwrap() +}); +pub static WBTC: LazyLock = LazyLock::new(|| { + Felt::from_hex("0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac").unwrap() +}); #[allow(dead_code)] #[derive(Clone)] @@ -17,12 +28,12 @@ pub struct TokenAddress<'a> { } #[allow(dead_code)] -#[derive(Clone)] +#[derive(Clone, Debug)] /// Token information for supported tokens pub struct TokenInfo<'a> { - address: &'a str, - symbol: &'a str, - decimals: u8, + pub address: Felt, + pub symbol: &'a str, + pub decimals: u8, name: &'a str, } #[allow(dead_code)] @@ -30,31 +41,31 @@ impl TokenAddress<'static> { pub fn new() -> Self { let tokens: Vec = vec![ TokenInfo { - address: ETH, + address: *ETH, symbol: "ETH", decimals: 18, name: "Ether", }, TokenInfo { - address: USDC, + address: *USDC, symbol: "USDC", decimals: 6, name: "USD Coin", }, TokenInfo { - address: USDT, + address: *USDT, symbol: "USDT", decimals: 6, name: "Tether USD", }, TokenInfo { - address: WBTC, + address: *WBTC, symbol: "WBTC", decimals: 8, name: "Wrapped BTC", }, TokenInfo { - address: STRK, + address: *STRK, symbol: "STRK", decimals: 18, name: "Starknet Token", @@ -73,14 +84,10 @@ impl TokenAddress<'static> { None => Err("TOKEN IS NOT AVAILABLE".to_string()), } } - pub fn get_token_address(&self, address: &'static str) -> Result<&'static str, String> { - let token = self - .tokens - .iter() - .find(|x| x.symbol.to_lowercase() == address.to_lowercase()) - .cloned(); + pub fn get_token_info_by_address(&self, address: Felt) -> Result, String> { + let token = self.tokens.iter().find(|x| x.address == address).cloned(); match token { - Some(x) => Ok(x.address), + Some(x) => Ok(x), None => Err("TOKEN IS NOT AVAILABLE".to_string()), } } @@ -92,19 +99,20 @@ mod tests { #[test] fn is_success() { - let strk = TokenAddress::new().get_token_info("strk"); - assert_eq!(strk.unwrap().address, STRK); - let usdc = TokenAddress::new().get_token_info("usdc"); - assert_eq!(usdc.unwrap().address, USDC); - let usdt = TokenAddress::new().get_token_info("usdt"); - assert_eq!(usdt.unwrap().address, USDT); - let eth = TokenAddress::new().get_token_info("eth"); - assert_eq!(eth.unwrap().address, ETH); - let eth = TokenAddress::new().get_token_info("eth"); + let strk = TokenAddress::new().get_token_info_by_address(*STRK); + assert_eq!(strk.clone().unwrap().address, *STRK); + println!("strk {:?} ", strk); + let usdc = TokenAddress::new().get_token_info_by_address(*USDC); + assert_eq!(usdc.unwrap().address, *USDC); + let usdt = TokenAddress::new().get_token_info_by_address(*USDT); + assert_eq!(usdt.unwrap().address, *USDT); + let eth = TokenAddress::new().get_token_info_by_address(*ETH); + assert_eq!(eth.unwrap().address, *ETH); + let eth = TokenAddress::new().get_token_info_by_address(*ETH); assert_eq!(eth.unwrap().name, "Ether"); - let wbtc = TokenAddress::new().get_token_info("wbtc"); - assert_eq!(wbtc.unwrap().address, WBTC); - let wbtc = TokenAddress::new().get_token_info("wbtc"); + let wbtc = TokenAddress::new().get_token_info_by_address(*WBTC); + assert_eq!(wbtc.unwrap().address, *WBTC); + let wbtc = TokenAddress::new().get_token_info_by_address(*WBTC); assert_eq!(wbtc.unwrap().decimals, 8); } @@ -112,6 +120,6 @@ mod tests { #[should_panic(expected = "TOKEN IS NOT AVAILABLE")] fn should_panic() { let strk = TokenAddress::new().get_token_info("sol"); - assert_eq!(strk.unwrap().address, STRK); + assert_eq!(strk.unwrap().address, *STRK); } } diff --git a/src/constant/util.rs b/src/constant/util.rs new file mode 100644 index 0000000..d6c0f1c --- /dev/null +++ b/src/constant/util.rs @@ -0,0 +1,8 @@ +use starknet::core::types::Felt; + +// Helper function to convert u128 to (low, high) felts for uint256 +pub fn u128_to_uint256(amount: u128) -> (Felt, Felt) { + let amount_low = Felt::from(amount & 0xFFFFFFFFFFFFFFFF); // Lower 64 bits (NOT 128!) + let amount_high = Felt::from(amount >> 64); // Upper 64 bits + (amount_low, amount_high) +} diff --git a/src/lib.rs b/src/lib.rs index 53b7402..8edbf5f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,21 +1,21 @@ -pub mod client; +// pub mod client; pub mod constant; -pub mod contracts; +// pub mod contracts; pub mod provider; pub mod simple_client; +pub mod swappr; pub mod types; - -#[cfg(test)] -mod contracts_test; +// #[cfg(test)] +// mod contracts_test; // Re-export main types and clients for easy access -pub use client::AutoSwapprClient; -pub use contracts::{AutoSwapprContract, Erc20Contract, addresses}; +// pub use client::AutoSwapprClient; +// pub use contracts::{AutoSwapprContract, Erc20Contract, addresses,conversions::u128_to_uint256}; pub use provider::{Network, StarknetProvider}; pub use simple_client::{ SimpleAutoSwapprClient, SimpleConfig, SimpleError, SwapData as SimpleSwapData, }; pub use types::connector::{ - Amount, AutoSwapprConfig, AutoSwapprError, ContractInfo, Delta, FeeType, I129, PoolKey, Route, - RouteParams, SwapData, SwapOptions, SwapParameters, SwapParams, SwapResult, TokenInfo, Uint256, + AutoSwappr, AutoSwapprError, ContractInfo, Delta, FeeType, I129, PoolKey, Route, RouteParams, + SwapData, SwapOptions, SwapParameters, SwapParams, SwapResult, TokenInfo, Uint256, }; diff --git a/src/swappr.rs b/src/swappr.rs new file mode 100644 index 0000000..a1a00aa --- /dev/null +++ b/src/swappr.rs @@ -0,0 +1,186 @@ +use starknet::{ + accounts::{Account, ExecutionEncoding, SingleOwnerAccount}, + core::{ + chain_id, + codec::Encode, + types::{BlockId, BlockTag, Call, Felt}, + }, + macros::selector, + providers::{JsonRpcClient, Url, jsonrpc::HttpTransport}, + signers::{LocalWallet, SigningKey}, +}; + +use crate::{ + I129, PoolKey, SwapData, SwapParameters, + constant::{TokenAddress, u128_to_uint256}, + types::connector::AutoSwappr, +}; +#[allow(dead_code)] +type EkuboResponse = Result< + starknet::core::types::InvokeTransactionResult, + starknet::accounts::AccountError< + starknet::accounts::single_owner::SignError, + >, +>; +impl AutoSwappr { + // wallet configuration + pub fn config(rpc_url: String, account_address: String, private_key: String) -> AutoSwappr { + let signer = LocalWallet::from(SigningKey::from_secret_scalar( + Felt::from_hex(&private_key).unwrap(), + )); + let contract_address = + Felt::from_hex("0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b") + .unwrap(); + let address = Felt::from_hex(&account_address).unwrap(); + let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); + + let account = SingleOwnerAccount::new( + provider, + signer, + address, + chain_id::MAINNET, + ExecutionEncoding::New, + ); + AutoSwappr { + rpc_url, + account_address, + private_key, + account, + contract_address, + } + } + + // to do this function need a proper error handling + // ekubo manual swap + pub async fn ekubo_manual_swap( + &mut self, + token0: Felt, + token1: Felt, + swap_amount: u128, + ) -> Result { + if swap_amount == 0 { + return Err("ZERO SWAP AMOUNT".to_string()); + } + + let token_decimal = TokenAddress::new() + .get_token_info_by_address(token0) + .unwrap() + .decimals; + let actual_amount = swap_amount * 10_u128.pow(token_decimal as u32); + let (amount_low, amount_high) = u128_to_uint256(actual_amount); + + let pool_key = PoolKey::new(token0, token1); + let swap_parameters = SwapParameters::new(I129::new(actual_amount, false), false); + let swap_data = SwapData::new(swap_parameters, pool_key, self.account.address()); + // let mut account = self.account; + self.account + .set_block_id(BlockId::Tag(BlockTag::PreConfirmed)); + + let mut serialized = vec![]; + swap_data.encode(&mut serialized).unwrap(); + + let approve_call = Call { + to: token0, + selector: selector!("approve"), + calldata: vec![self.contract_address, amount_low, amount_high], + }; + println!("Calldata: {:?}", serialized); + + let swap_call = Call { + to: self.contract_address, + selector: selector!("ekubo_manual_swap"), + calldata: serialized, + }; + + let result = self + .account + .execute_v3(vec![approve_call, swap_call]) + .send() + .await; + match result { + Ok(x) => { + println!("txt is succesful {:?}", x); + return Ok("SUCCESSFUL".to_string()); + } + Err(x) => { + println!("error message {}", x); + Err("error ".to_string()) + } + } + } + + // pub async fn ekubo_auto_swap(){ + // // todo steph + // // approve contract to spend + // // sent a post request to auto swapper backend + // // post request arg will look like this + // // ====== wallet_address, user address + // // ======= to_token, + // // ======= from_token, + // // ======= swap_amount, + + // // below is how the approval fall will look + // // handle error + + // // let account = approver_signer_account(); + + // // if !is_valid_address(token) { + // // return Err("INVALID TOKEN ADDRESS".to_string()); + // // } + + // // let spender = contract_address_felt(); + + // // let token = Felt::from_hex(token).expect("TOKEN ADDRESS NOT PROVIDED"); + + // // // Convert amount to uint256 (split into low and high parts) + // // let (amount_low, amount_high) = u128_to_uint256(amount); + + // // // Prepare the calldata: [spender, amount_low, amount_high] + // // let calldata = vec![spender, amount_low, amount_high]; + + // // let call = Call { + // // to: token, + // // selector: get_selector_from_name("approve").unwrap(), + // // calldata, + // // }; + // // let execution = account + // // .execute_v3(vec![call]) + // // .send() + // // .await + // // .map_err(|e| e.to_string())?; + // // Ok(execution.transaction_hash) + // } +} + +#[cfg(test)] +mod tests { + use crate::constant::{STRK, USDC}; + + use super::*; + + #[tokio::test] + #[ignore = "owner address and private key is required to run the test"] + async fn it_works_bravoos() { + let rpc_url = "YOUR MAINNET RPC".to_string(); + let account_address = "YOUR WALLET ADDRESS".to_string(); + let private_key = "YOUR WALLET PRIVATE KEY".to_string(); + let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key); + let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); + + // assert!(result.await.clone().is_ok()); + println!("test complete {:?}", result.await.ok()); + } + + #[tokio::test] + #[ignore = "owner address and private key is required to run the test"] + async fn it_works_argent() { // currently having issue with argent wallet () + let rpc_url = "YOUR MAINNET RPC".to_string(); + let account_address = "YOUR WALLET ADDRESS".to_string(); + let private_key = "YOUR WALLET PRIVATE KEY".to_string(); + let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key); + let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); + + // assert!(result.await.clone().is_ok()); + println!("test complete {:?}", result.await.ok()); + } +} diff --git a/src/types/connector.rs b/src/types/connector.rs index 1cc7018..53c9a36 100644 --- a/src/types/connector.rs +++ b/src/types/connector.rs @@ -1,12 +1,25 @@ use serde::{Deserialize, Serialize}; +use starknet::{ + accounts::SingleOwnerAccount, + core::{ + codec::{Decode, Encode}, + types::{Felt, U256}, + }, + providers::{JsonRpcClient, jsonrpc::HttpTransport}, + signers::LocalWallet, +}; use thiserror::Error; + +use crate::constant::{USDC, USDT}; + /// Configuration for the AutoSwappr SDK -#[derive(Debug, Serialize, Deserialize)] -pub struct AutoSwapprConfig { - pub contract_address: String, +#[derive(Debug)] +pub struct AutoSwappr { pub rpc_url: String, pub account_address: String, pub private_key: String, + pub account: SingleOwnerAccount, LocalWallet>, + pub contract_address: Felt, } /// Uint256 representation for Starknet @@ -36,47 +49,71 @@ impl Uint256 { } /// Ekubo pool key structure -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Serialize, Deserialize, Clone, Encode, Decode)] pub struct PoolKey { - pub token0: String, // First token in the pool - pub token1: String, // Second token in the pool - pub fee: u128, // Pool fee in basis points (u128) - pub tick_spacing: u32, // Pool extension parameter (felt252) - pub extension: String, // Pool extension parameter + pub token0: Felt, // First token in the pool + pub token1: Felt, // Second token in the pool + pub fee: u128, // Pool fee in basis points (u128) + pub tick_spacing: u128, // Pool extension parameter (felt252) + pub extension: Felt, // Pool extension parameter } - /// Amount to swap with magnitude and sign -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Amount { - pub mag: Uint256, // Uint256 magnitude - pub sign: bool, // Always positive for swaps +#[derive(Debug, Serialize, Deserialize, Clone, Encode, Decode)] +pub struct I129 { + pub mag: u128, // u128 magnitude + pub sign: bool, // Always positive for swaps +} + +impl I129 { + pub fn new(mag: u128, sign: bool) -> Self { + I129 { mag, sign } + } } /// Ekubo swap parameters -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Clone, Encode, Decode)] pub struct SwapParameters { - pub amount: Amount, // Amount to swap with magnitude and sign - pub sqrt_ratio_limit: Uint256, // Price limit for the swap (Uint256) - pub is_token1: bool, // Whether the input token is token1 - pub skip_ahead: u32, // Skip ahead parameter (u32) + pub amount: I129, // Amount to swap with magnitude and sign + pub is_token1: bool, // Whether the input token is token1 + pub sqrt_ratio_limit: U256, // Price limit for the swap (U256) + pub skip_ahead: u32, // Skip ahead parameter (u32) } +impl SwapParameters { + pub fn new(amount: I129, is_token1: bool) -> Self { + SwapParameters { + amount, + is_token1, + sqrt_ratio_limit: U256::from(18446748437148339061u128), + skip_ahead: 0, + } + } +} /// Swap data structure for ekubo_manual_swap function -#[derive(Debug, Serialize, Deserialize, Clone)] +#[derive(Debug, Clone, Encode, Decode)] pub struct SwapData { pub params: SwapParameters, pub pool_key: PoolKey, - pub caller: String, + pub caller: Felt, } +impl SwapData { + pub fn new(params: SwapParameters, pool_key: PoolKey, caller: Felt) -> Self { + SwapData { + params, + pool_key, + caller, + } + } +} /// Route structure for AVNU swaps #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Route { - pub token_from: String, - pub token_to: String, - pub exchange_address: String, + pub token_from: Felt, + pub token_to: Felt, + pub exchange_address: Felt, pub percent: u128, - pub additional_swap_params: Vec, + pub additional_swap_params: Vec, } /// Route parameters for Fibrous swaps @@ -113,13 +150,6 @@ pub struct Delta { pub amount1: I129, } -/// I129 structure for Ekubo amounts -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct I129 { - pub mag: u128, - pub sign: bool, -} - /// Fee type enum #[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] pub enum FeeType { @@ -184,6 +214,26 @@ pub struct SwapOptions { pub sqrt_ratio_limit: Option, // Custom sqrt ratio limit } +impl PoolKey { + pub fn new(token0: Felt, token1: Felt) -> Self { + let (fee, tick_spacing) = if token1 == *USDC { + (170141183460469235273462165868118016, 1000) + } else if token1 == *USDT { + (3402823669209384634633746074317682114, 19802) + } else { + (0, 0) + }; + + PoolKey { + token0, + token1, + fee, + tick_spacing, + extension: Felt::ZERO, + } + } +} + /// Error types for the AutoSwappr SDK #[derive(Error, Debug)] pub enum AutoSwapprError { From 07ef3fb5b22fd739739f0582ccdc0949533be1c4 Mon Sep 17 00:00:00 2001 From: yunusabdul38 Date: Mon, 6 Oct 2025 21:56:31 +0100 Subject: [PATCH 2/8] fix: format --- src/swappr.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/swappr.rs b/src/swappr.rs index a1a00aa..29cbfb4 100644 --- a/src/swappr.rs +++ b/src/swappr.rs @@ -173,7 +173,8 @@ mod tests { #[tokio::test] #[ignore = "owner address and private key is required to run the test"] - async fn it_works_argent() { // currently having issue with argent wallet () + async fn it_works_argent() { + // currently having issue with argent wallet () let rpc_url = "YOUR MAINNET RPC".to_string(); let account_address = "YOUR WALLET ADDRESS".to_string(); let private_key = "YOUR WALLET PRIVATE KEY".to_string(); From be8c617548ec33e769c2f3e2197ec39132fac017 Mon Sep 17 00:00:00 2001 From: Stephanie Nwankwo Date: Tue, 7 Oct 2025 17:57:27 +0100 Subject: [PATCH 3/8] feat: create auto ekubo swap --- Cargo.lock | 1 + Cargo.toml | 1 + src/swappr.rs | 132 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 94 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aff5600..190edb3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,6 +84,7 @@ dependencies = [ "hex", "reqwest", "serde", + "serde_json", "starknet", "starknet-accounts", "starknet-contract", diff --git a/Cargo.toml b/Cargo.toml index 50a4f3c..208d14d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ thiserror = "2.0.16" serde = {version="1.0.219", features=["derive"]} tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } +serde_json = "1.0" url = "2.5" hex = "0.4" starknet = "0.17.0" diff --git a/src/swappr.rs b/src/swappr.rs index 29cbfb4..84c4c92 100644 --- a/src/swappr.rs +++ b/src/swappr.rs @@ -15,6 +15,8 @@ use crate::{ constant::{TokenAddress, u128_to_uint256}, types::connector::AutoSwappr, }; +use serde_json::json; +use reqwest::Client; #[allow(dead_code)] type EkuboResponse = Result< starknet::core::types::InvokeTransactionResult, @@ -110,46 +112,76 @@ impl AutoSwappr { } // pub async fn ekubo_auto_swap(){ - // // todo steph - // // approve contract to spend - // // sent a post request to auto swapper backend - // // post request arg will look like this - // // ====== wallet_address, user address - // // ======= to_token, - // // ======= from_token, - // // ======= swap_amount, - - // // below is how the approval fall will look - // // handle error - - // // let account = approver_signer_account(); - - // // if !is_valid_address(token) { - // // return Err("INVALID TOKEN ADDRESS".to_string()); - // // } - - // // let spender = contract_address_felt(); - - // // let token = Felt::from_hex(token).expect("TOKEN ADDRESS NOT PROVIDED"); - - // // // Convert amount to uint256 (split into low and high parts) - // // let (amount_low, amount_high) = u128_to_uint256(amount); - - // // // Prepare the calldata: [spender, amount_low, amount_high] - // // let calldata = vec![spender, amount_low, amount_high]; - - // // let call = Call { - // // to: token, - // // selector: get_selector_from_name("approve").unwrap(), - // // calldata, - // // }; - // // let execution = account - // // .execute_v3(vec![call]) - // // .send() - // // .await - // // .map_err(|e| e.to_string())?; - // // Ok(execution.transaction_hash) - // } + // Implemented: approve token and notify backend for auto-swap + pub async fn ekubo_auto_swap( + &mut self, + token_from: Felt, + token_to: Felt, + amount: u128, + backend_url: &str, + ) -> Result { + if amount == 0 { + return Err("ZERO SWAP AMOUNT".to_string()); + } + + // ensure token is supported to derive decimals + let token_decimal = TokenAddress::new() + .get_token_info_by_address(token_from) + .map_err(|e| e.to_string())? + .decimals; + + let actual_amount = amount * 10_u128.pow(token_decimal as u32); + let (amount_low, amount_high) = u128_to_uint256(actual_amount); + + // Prepare approve call to allow contract to spend `token_from` + let approve_call = Call { + to: token_from, + selector: selector!("approve"), + calldata: vec![self.contract_address, amount_low, amount_high], + }; + + // set preconfirmed block for querying + self.account + .set_block_id(BlockId::Tag(BlockTag::PreConfirmed)); + + // send approve transaction + let approve_result = self + .account + .execute_v3(vec![approve_call]) + .send() + .await + .map_err(|e| format!("approve failed: {}", e))?; + + // Prepare payload for backend + let payload = json!({ + "wallet_address": format!("0x{:x}", self.account.address()), + "user_address": format!("0x{:x}", self.account.address()), + "to_token": format!("0x{:x}", token_to), + "from_token": format!("0x{:x}", token_from), + "swap_amount": actual_amount.to_string(), + "approve_tx_hash": format!("0x{:x}", approve_result.transaction_hash), + }); + + let client = Client::new(); + let resp = client + .post(backend_url) + .json(&payload) + .send() + .await + .map_err(|e| format!("network error: {}", e))?; + + let status = resp.status(); + let text = resp + .text() + .await + .map_err(|e| format!("response read error: {}", e))?; + + if status.is_success() { + Ok(text) + } else { + Err(format!("backend error: {} - {}", status, text)) + } + } } #[cfg(test)] @@ -184,4 +216,24 @@ mod tests { // assert!(result.await.clone().is_ok()); println!("test complete {:?}", result.await.ok()); } + + #[tokio::test] + #[ignore = "owner address, private key and backend required to run the test"] + async fn it_works_auto() { + // This test exercises `ekubo_auto_swap` flow: approve + notify backend. + // It is ignored by default because it requires a funded wallet and a reachable backend. + let rpc_url = "YOUR MAINNET RPC".to_string(); + let account_address = "YOUR WALLET ADDRESS".to_string(); + let private_key = "YOUR WALLET PRIVATE KEY".to_string(); + let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key); + + // Use STRK -> USDC for a tiny amount (1 unit). Backend URL is a placeholder and + // should be replaced with a real auto-swapper endpoint when running the test. + let backend_url = "https://example.com/api/auto-swap"; + let result = swapper.ekubo_auto_swap(*STRK, *USDC, 1, backend_url); + + // Print the result (Ok response body or Err description). The test is ignored + // so it won't run in CI unless explicitly enabled. + println!("auto swap test result: {:?}", result.await); + } } From 25ca30f433c52f6d194fd1424916bbf60d020eef Mon Sep 17 00:00:00 2001 From: Stephanie Nwankwo Date: Thu, 9 Oct 2025 15:44:22 +0100 Subject: [PATCH 4/8] fix: cargo fmt --- src/swappr.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/swappr.rs b/src/swappr.rs index 84c4c92..0bf796b 100644 --- a/src/swappr.rs +++ b/src/swappr.rs @@ -15,8 +15,8 @@ use crate::{ constant::{TokenAddress, u128_to_uint256}, types::connector::AutoSwappr, }; -use serde_json::json; use reqwest::Client; +use serde_json::json; #[allow(dead_code)] type EkuboResponse = Result< starknet::core::types::InvokeTransactionResult, @@ -112,7 +112,7 @@ impl AutoSwappr { } // pub async fn ekubo_auto_swap(){ - // Implemented: approve token and notify backend for auto-swap + // Implemented: approve token and notify backend for auto-swap pub async fn ekubo_auto_swap( &mut self, token_from: Felt, From ea38648651a3becbe6d062f50a0f3c264b594504 Mon Sep 17 00:00:00 2001 From: yunusabdul38 Date: Thu, 9 Oct 2025 16:42:31 +0100 Subject: [PATCH 5/8] feat: error handling + doc --- Cargo.lock | 91 ++++++++++++++++ Cargo.toml | 1 + src/swappr.rs | 233 ++++++++++++++++++++++++++++++++++------- src/types/connector.rs | 12 +++ 4 files changed, 301 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aff5600..b1ed89d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -81,6 +81,7 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" name = "autoswap-rust-sdk" version = "0.1.0" dependencies = [ + "axum", "hex", "reqwest", "serde", @@ -94,6 +95,70 @@ dependencies = [ "url", ] +[[package]] +name = "axum" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871" +dependencies = [ + "axum-core", + "axum-macros", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-macros" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "backtrace" version = "0.3.75" @@ -706,6 +771,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "hyper" version = "1.7.0" @@ -720,6 +791,7 @@ dependencies = [ "http", "http-body", "httparse", + "httpdate", "itoa", "pin-project-lite", "pin-utils", @@ -1112,6 +1184,12 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "memchr" version = "2.7.5" @@ -1851,6 +1929,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -2439,6 +2528,7 @@ dependencies = [ "tokio", "tower-layer", "tower-service", + "tracing", ] [[package]] @@ -2477,6 +2567,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-core", ] diff --git a/Cargo.toml b/Cargo.toml index 50a4f3c..cbba4cb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,3 +30,4 @@ starknet-contract = "0.16.0" starknet-accounts = "0.16.0" starknet-providers = "0.16.0" starknet-core = "0.16.0" +axum ={ version = "0.8.6", features = ["macros"] } diff --git a/src/swappr.rs b/src/swappr.rs index 29cbfb4..86f0d1d 100644 --- a/src/swappr.rs +++ b/src/swappr.rs @@ -13,18 +13,88 @@ use starknet::{ use crate::{ I129, PoolKey, SwapData, SwapParameters, constant::{TokenAddress, u128_to_uint256}, - types::connector::AutoSwappr, + types::connector::{AutoSwappr, ErrorResponse, SuccessResponse}, }; -#[allow(dead_code)] -type EkuboResponse = Result< - starknet::core::types::InvokeTransactionResult, - starknet::accounts::AccountError< - starknet::accounts::single_owner::SignError, - >, ->; +use axum::Json; + impl AutoSwappr { - // wallet configuration - pub fn config(rpc_url: String, account_address: String, private_key: String) -> AutoSwappr { + /// Configure a new AutoSwappr instance with wallet credentials. + /// + /// This function initializes the connection to Starknet and sets up the account + /// for executing swaps through the AutoSwappr contract. + /// + /// # Arguments + /// + /// * `rpc_url` - The RPC endpoint URL for Starknet (e.g., Alchemy, Infura) + /// * `account_address` - Your wallet address on Starknet + /// * `private_key` - Your wallet's private key (keep this secure!) + /// + /// # Returns + /// + /// Returns `Ok(AutoSwappr)` if configuration is successful, or an `Err(Json)` + /// if any of the inputs are invalid or empty. + /// + /// # Errors + /// + /// This function will return an error if: + /// - `rpc_url` is an empty string + /// - `account_address` is an empty string + /// - `private_key` is an empty string + /// - The RPC URL format is invalid + /// - The account address or private key cannot be parsed as valid Felt values + /// + /// # Examples + /// + /// ```no_run + /// use auto_swappr::types::connector::AutoSwappr; + /// + /// let rpc_url = "https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_9/YOUR_API_KEY".to_string(); + /// let account_address = "0x05362484eb9b91ae4365963dad33794cb50a5f93eb7a08b0280cf0f0c0129e4f".to_string(); + /// let private_key = "0x062e0c4dc96f3d877af48285a5442ce69860a50b11a1d91eae1e3f128df1c454".to_string(); + /// + /// let swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + /// ``` + /// + /// # Example with Error Handling + /// + /// ``` + /// use auto_swappr::types::connector::AutoSwappr; + /// + /// // This will fail due to empty RPC URL + /// let result = AutoSwappr::config( + /// "".to_string(), + /// "0x123".to_string(), + /// "0x456".to_string() + /// ); + /// + /// assert!(result.is_err()); + /// ``` + + pub fn config( + rpc_url: String, + account_address: String, + private_key: String, + ) -> Result> { + if rpc_url.is_empty() { + return Err(Json(ErrorResponse { + success: false, + message: "EMPTY RPC STRING".to_string(), + })); + } + + if account_address.is_empty() { + return Err(Json(ErrorResponse { + success: false, + message: "EMPTY ACCOUNT ADDRESS STRING".to_string(), + })); + } + + if private_key.is_empty() { + return Err(Json(ErrorResponse { + success: false, + message: "EMPTY PRIVATE KEY STRING".to_string(), + })); + } let signer = LocalWallet::from(SigningKey::from_secret_scalar( Felt::from_hex(&private_key).unwrap(), )); @@ -41,27 +111,102 @@ impl AutoSwappr { chain_id::MAINNET, ExecutionEncoding::New, ); - AutoSwappr { + Ok(AutoSwappr { rpc_url, account_address, private_key, account, contract_address, - } + }) } - // to do this function need a proper error handling - // ekubo manual swap + /// Execute a manual token swap. + /// + /// # Arguments + /// + /// * `token0` - The address of the token to swap from (as Felt) + /// * `token1` - The address of the token to swap to (as Felt) + /// * `swap_amount` - The amount to swap in the smallest unit (e.g., wei for ETH) + /// + /// # Returns + /// + /// Returns `Ok(Json)` with the transaction hash on success, + /// or `Err(Json)` if the swap fails. + /// + /// # Errors + /// + /// This function will return an error if: + /// - `swap_amount` is zero + /// - Token information cannot be retrieved + /// - The transaction execution fails + /// - Insufficient balance or allowance + /// + /// # Examples + /// + /// ## Basic Swap Example + /// + /// ```no_run + /// use auto_swappr::types::connector::AutoSwappr; + /// use auto_swappr::constant::{STRK, USDC}; + /// + /// # #[tokio::main] + /// # async fn main() { + /// let rpc_url = "https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_9/YOUR_API_KEY".to_string(); + /// let account_address = "0x053620000000000000000000000000000000000000000000000000000000".to_string(); + /// let private_key = "0x000000000000000000000000000000000000000000000000000000000000".to_string(); + /// + /// let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + /// + /// // Swap 1 STRK token (amount is in base units without decimals) + /// let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1).await; + /// + /// match result { + /// Ok(response) => println!("Swap successful! TX: {:?}", response.tx_hash), + /// Err(error) => println!("Swap failed: {}", error.message), + /// } + /// # } + /// ``` + /// + /// ## Error Handling Example + /// + /// ```no_run + /// use auto_swappr::types::connector::AutoSwappr; + /// use auto_swappr::constant::{STRK, USDC}; + /// + /// # #[tokio::main] + /// # async fn main() { + /// # let rpc_url = "https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_9/YOUR_API_KEY".to_string(); + /// # let account_address = "0x05362484eb9b91ae4365963dad33794cb50a5f93eb7a08b0280cf0f0c0129e4f".to_string(); + /// # let private_key = "0x062e0c4dc96f3d877af48285a5442ce69860a50b11a1d91eae1e3f128df1c454".to_string(); + /// let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + /// + /// // This will fail because swap_amount is zero + /// let result = swapper.ekubo_manual_swap(*STRK, *USDC, 0).await; + /// + /// assert!(result.is_err()); + /// if let Err(error) = result { + /// assert_eq!(error.err().message, "SWAP AMOUNT IS ZERO"); + /// } + /// # } + /// ``` + /// # Notes + /// + /// - The `swap_amount` should be specified in base units (without decimal adjustment) + /// - The function automatically handles decimal conversion based on the token + /// - Both approval and swap are executed in a single transaction + /// - Make sure your account has sufficient balance of `token0` pub async fn ekubo_manual_swap( &mut self, token0: Felt, token1: Felt, swap_amount: u128, - ) -> Result { + ) -> Result, Json> { if swap_amount == 0 { - return Err("ZERO SWAP AMOUNT".to_string()); + return Err(Json(ErrorResponse { + success: false, + message: "SWAP AMOUNT IS ZERO".to_string(), + })); } - let token_decimal = TokenAddress::new() .get_token_info_by_address(token0) .unwrap() @@ -84,7 +229,6 @@ impl AutoSwappr { selector: selector!("approve"), calldata: vec![self.contract_address, amount_low, amount_high], }; - println!("Calldata: {:?}", serialized); let swap_call = Call { to: self.contract_address, @@ -98,13 +242,16 @@ impl AutoSwappr { .send() .await; match result { - Ok(x) => { - println!("txt is succesful {:?}", x); - return Ok("SUCCESSFUL".to_string()); - } + Ok(x) => Ok(Json(SuccessResponse { + success: true, + tx_hash: x.transaction_hash, + })), Err(x) => { - println!("error message {}", x); - Err("error ".to_string()) + println!("error message {}", x.to_string()); + Err(Json(ErrorResponse { + success: false, + message: "FAILED TO SWAP".to_string(), + })) } } } @@ -159,29 +306,43 @@ mod tests { use super::*; #[tokio::test] - #[ignore = "owner address and private key is required to run the test"] + // #[ignore = "owner address and private key is required to run the test"] async fn it_works_bravoos() { let rpc_url = "YOUR MAINNET RPC".to_string(); - let account_address = "YOUR WALLET ADDRESS".to_string(); - let private_key = "YOUR WALLET PRIVATE KEY".to_string(); - let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key); + let account_address = + "YOUR WALLET ADDRESS".to_string(); + let private_key = + "YOUR WALLET PRIVATE KEY".to_string(); + let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); + assert!(result.await.is_ok()) + } + #[tokio::test] + #[ignore = "owner address and private key is required to run the test"] + async fn swap_with_zero_amount() { + let rpc_url = "YOUR MAINNET RPC".to_string(); + let account_address = + "YOUR WALLET ADDRESS".to_string(); + let private_key = + "YOUR WALLET PRIVATE KEY".to_string(); + let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + let result = swapper.ekubo_manual_swap(*STRK, *USDC, 0); - // assert!(result.await.clone().is_ok()); - println!("test complete {:?}", result.await.ok()); + assert!(result.await.is_err()) } #[tokio::test] #[ignore = "owner address and private key is required to run the test"] async fn it_works_argent() { - // currently having issue with argent wallet () let rpc_url = "YOUR MAINNET RPC".to_string(); - let account_address = "YOUR WALLET ADDRESS".to_string(); - let private_key = "YOUR WALLET PRIVATE KEY".to_string(); - let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key); + let account_address = + "YOUR WALLET ADDRESS".to_string(); + let private_key = + "YOUR WALLET PRIVATE KEY".to_string(); + let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); - // assert!(result.await.clone().is_ok()); - println!("test complete {:?}", result.await.ok()); + assert!(result.await.is_ok()); + // println!("test complete {:?}", result.await.err().unwrap().message); } } diff --git a/src/types/connector.rs b/src/types/connector.rs index 53c9a36..c9d4c3b 100644 --- a/src/types/connector.rs +++ b/src/types/connector.rs @@ -234,6 +234,18 @@ impl PoolKey { } } +#[derive(Debug, Serialize)] +pub struct SuccessResponse { + pub success: bool, + pub tx_hash: Felt, +} + +#[derive(Debug, Serialize)] +pub struct ErrorResponse { + pub success: bool, + pub message: String, +} + /// Error types for the AutoSwappr SDK #[derive(Error, Debug)] pub enum AutoSwapprError { From 67686f9e10b5a8e20687939baf5e215232905dca Mon Sep 17 00:00:00 2001 From: yunusabdul38 Date: Thu, 9 Oct 2025 16:54:00 +0100 Subject: [PATCH 6/8] fix: _ekubo_auto_swap to private fn --- src/swappr.rs | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/swappr.rs b/src/swappr.rs index 9d644bb..0ead2bb 100644 --- a/src/swappr.rs +++ b/src/swappr.rs @@ -13,20 +13,11 @@ use starknet::{ use crate::{ I129, PoolKey, SwapData, SwapParameters, constant::{TokenAddress, u128_to_uint256}, - types::connector::AutoSwappr, -}; -use reqwest::Client; -use serde_json::json; -#[allow(dead_code)] -type EkuboResponse = Result< - starknet::core::types::InvokeTransactionResult, - starknet::accounts::AccountError< - starknet::accounts::single_owner::SignError, - >, ->; types::connector::{AutoSwappr, ErrorResponse, SuccessResponse}, }; use axum::Json; +use reqwest::Client; +use serde_json::json; impl AutoSwappr { /// Configure a new AutoSwappr instance with wallet credentials. @@ -269,7 +260,7 @@ impl AutoSwappr { // pub async fn ekubo_auto_swap(){ // Implemented: approve token and notify backend for auto-swap - pub async fn ekubo_auto_swap( + async fn _ekubo_auto_swap( &mut self, token_from: Felt, token_to: Felt, @@ -350,10 +341,8 @@ mod tests { // #[ignore = "owner address and private key is required to run the test"] async fn it_works_bravoos() { let rpc_url = "YOUR MAINNET RPC".to_string(); - let account_address = - "YOUR WALLET ADDRESS".to_string(); - let private_key = - "YOUR WALLET PRIVATE KEY".to_string(); + let account_address = "YOUR WALLET ADDRESS".to_string(); + let private_key = "YOUR WALLET PRIVATE KEY".to_string(); let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); assert!(result.await.is_ok()) @@ -362,10 +351,8 @@ mod tests { #[ignore = "owner address and private key is required to run the test"] async fn swap_with_zero_amount() { let rpc_url = "YOUR MAINNET RPC".to_string(); - let account_address = - "YOUR WALLET ADDRESS".to_string(); - let private_key = - "YOUR WALLET PRIVATE KEY".to_string(); + let account_address = "YOUR WALLET ADDRESS".to_string(); + let private_key = "YOUR WALLET PRIVATE KEY".to_string(); let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 0); @@ -376,10 +363,8 @@ mod tests { #[ignore = "owner address and private key is required to run the test"] async fn it_works_argent() { let rpc_url = "YOUR MAINNET RPC".to_string(); - let account_address = - "YOUR WALLET ADDRESS".to_string(); - let private_key = - "YOUR WALLET PRIVATE KEY".to_string(); + let account_address = "YOUR WALLET ADDRESS".to_string(); + let private_key = "YOUR WALLET PRIVATE KEY".to_string(); let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); @@ -395,12 +380,12 @@ mod tests { let rpc_url = "YOUR MAINNET RPC".to_string(); let account_address = "YOUR WALLET ADDRESS".to_string(); let private_key = "YOUR WALLET PRIVATE KEY".to_string(); - let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key); + let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); // Use STRK -> USDC for a tiny amount (1 unit). Backend URL is a placeholder and // should be replaced with a real auto-swapper endpoint when running the test. let backend_url = "https://example.com/api/auto-swap"; - let result = swapper.ekubo_auto_swap(*STRK, *USDC, 1, backend_url); + let result = swapper._ekubo_auto_swap(*STRK, *USDC, 1, backend_url); // Print the result (Ok response body or Err description). The test is ignored // so it won't run in CI unless explicitly enabled. From 247b401a258be348f003ff33934162c1a1eb4e09 Mon Sep 17 00:00:00 2001 From: yunusabdul38 Date: Fri, 10 Oct 2025 11:40:33 +0100 Subject: [PATCH 7/8] chore: code structure + readme --- Cargo.lock | 6 -- Cargo.toml | 12 +-- README.md | 196 +++++++++++++++++++---------------------- src/lib.rs | 18 +--- src/swappr.rs | 119 ++++++------------------- src/types/connector.rs | 53 +++-------- 6 files changed, 135 insertions(+), 269 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7799ddf..7269f07 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -82,18 +82,12 @@ name = "autoswap-rust-sdk" version = "0.1.0" dependencies = [ "axum", - "hex", "reqwest", "serde", "serde_json", "starknet", - "starknet-accounts", - "starknet-contract", - "starknet-core", - "starknet-providers", "thiserror 2.0.16", "tokio", - "url", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c97172f..62a094f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,21 +14,17 @@ keywords = [ "swap" ] documentation = "" -exclude = [".github/**"] +exclude = [".github/**", "examples/",] version = "0.1.0" edition = "2024" +autoexamples = false + [dependencies] thiserror = "2.0.16" serde = {version="1.0.219", features=["derive"]} tokio = { version = "1.0", features = ["full"] } reqwest = { version = "0.12", features = ["json"] } serde_json = "1.0" -url = "2.5" -hex = "0.4" starknet = "0.17.0" -starknet-contract = "0.16.0" -starknet-accounts = "0.16.0" -starknet-providers = "0.16.0" -starknet-core = "0.16.0" -axum ={ version = "0.8.6", features = ["macros"] } +axum ={ version = "0.8.6", features = ["macros"] } \ No newline at end of file diff --git a/README.md b/README.md index 29748f5..07a4591 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,12 @@ # AutoSwappr Rust SDK -A Rust implementation of the AutoSwappr SDK for interacting with the AutoSwappr smart contract on Starknet. - -## Status - - **Real Implementation** - This is a complete implementation with actual Starknet integration, real contract ABI, and full functionality. +A Rust SDK for interacting with the AutoSwappr contract on Starknet. ## Features -### Fully Implemented (Issues #1, #2, #3, #4) - -- **Project Setup**: Complete Cargo configuration with proper metadata -- **Core Type Definitions**: All essential data structures and types -- **Real Starknet Integration**: Full blockchain integration with actual contract calls -- **Contract ABI**: Complete AutoSwappr contract ABI implementation -- **ERC20 Integration**: Full ERC20 token contract integration -- **Multi-Protocol Support**: Ekubo, AVNU, and Fibrous protocol support -- **Real Token Addresses**: Actual mainnet token addresses (STRK, ETH, USDC, USDT, WBTC) -- **Real Contract Address**: Actual AutoSwappr contract address -- **Error Handling**: Comprehensive error types and handling -- **Testing**: Unit tests for all core functionality -- **Documentation**: Complete API documentation and examples +- 🔄 Execute manual token swaps on Ekubo +- 🦀 Full Rust type safety +- ⚡ Async/await support with Tokio ## Installation @@ -28,133 +14,133 @@ Add this to your `Cargo.toml`: ```toml [dependencies] -autoswap-rust-sdk = "0.1.0" +autoswappr-sdk = "0.1.0" +tokio = { version = "1", features = ["full"] } +``` + +All other dependencies (like `starknet`, `axum`, etc.) are automatically included. + +## AutoSwappr Contract Address + +``` +0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b ``` ## Quick Start ```rust -use autoswap_rust_sdk::{SimpleAutoSwapprClient, SimpleConfig}; +use autoswappr_sdk::{AutoSwappr, constant::{STRK, USDC}}; #[tokio::main] -async fn main() -> Result<(), Box> { - // Create configuration - let config = SimpleConfig { - contract_address: "0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b".to_string(), - rpc_url: "https://starknet-mainnet.public.blastapi.io/rpc/v0_7".to_string(), - account_address: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef".to_string(), - private_key: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef".to_string(), - }; - - // Create client - let client = SimpleAutoSwapprClient::new(config); - - // Validate configuration - client.validate_config()?; - - // Create swap data - let swap_data = client.create_swap_data( - "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", // ETH - "0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8", // USDC - "1000000000000000000" // 1 ETH in wei - )?; - - // Simulate swap (placeholder for actual execution) - let result = client.simulate_swap(&swap_data).await?; - println!("Swap result: {}", result); - - Ok(()) +async fn main() { + // Initialize the SDK + let mut swapper = AutoSwappr::config( + "https://starknet-mainnet.public.blastapi.io".to_string(), + "YOUR_ACCOUNT_ADDRESS".to_string(), + "YOUR_PRIVATE_KEY".to_string(), + "0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b".to_string(), + ).unwrap(); + + // Execute swap (1 STRK to USDC) + let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1).await; + + match result { + Ok(response) => println!("Swap successful! Tx: {:?}", response.tx_hash), + Err(error) => println!("Swap failed: {}", error.message), + } } ``` ## API Reference -### SimpleAutoSwapprClient - -The main client for interacting with AutoSwappr functionality. - -#### Methods - -- `new(config: SimpleConfig) -> Self` - Create a new client -- `validate_config() -> Result<(), SimpleError>` - Validate client configuration -- `create_swap_data(token_in: &str, token_out: &str, amount: &str) -> Result` - Create swap data -- `simulate_swap(swap_data: &SwapData) -> Result` - Simulate a swap +### `AutoSwappr::config` -### SimpleConfig - -Configuration for the AutoSwappr client. +Configure a new AutoSwappr instance. ```rust -pub struct SimpleConfig { - pub contract_address: String, // AutoSwappr contract address - pub rpc_url: String, // Starknet RPC URL - pub account_address: String, // Your account address - pub private_key: String, // Your private key -} +pub fn config( + rpc_url: String, + account_address: String, + private_key: String, + contract_address: String, +) -> Result> ``` -### SwapData +### `ekubo_manual_swap` -Swap data structure containing all necessary information for a swap. +Execute a manual token swap. ```rust -pub struct SwapData { - pub token_in: String, // Input token address - pub token_out: String, // Output token address - pub amount: String, // Amount to swap (in wei) - pub caller: String, // Caller address -} +pub async fn ekubo_manual_swap( + &mut self, + token0: Felt, + token1: Felt, + swap_amount: u128, +) -> Result, Json> ``` -## Token Addresses +**Parameters:** -Common Starknet token addresses: +- `token0`: Source token address +- `token1`: Destination token address +- `swap_amount`: Amount to swap (in token units, not smallest denomination) -- **ETH**: `0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7` -- **USDC**: `0x053c91253bc9682c04929ca02ed00b3e423f6710d2ee7e0d5ebb06f3ecf368a8` -- **USDT**: `0x068f5c6a61780768455de69077e07e89787839bf8166decfbf92b645209c0fb8` -- **STRK**: `0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d` -- **WBTC**: `0x03fe2b97c1fd336e750087d68b9b867997fd64a2661ff3ca5a7c771641e8e7ac` +**Returns:** -## Error Handling +- `Ok(SuccessResponse)`: Contains transaction hash on success +- `Err(ErrorResponse)`: Contains error message on failure -The SDK provides comprehensive error handling through the `SimpleError` enum: +## Available Token Addresses ```rust -pub enum SimpleError { - InvalidInput { details: String }, - NetworkError { message: String }, - ContractError { message: String }, - Other { message: String }, -} -``` +use autoswappr_sdk::constant::{STRK, USDC, ETH}; -## Testing +// STRK token +*STRK -Run the test suite: +// USDC token +*USDC -```bash -cargo test +// ETH token +*ETH ``` -Run the example: +## Security Considerations -```bash -cargo run --example basic_usage -``` +⚠️ **Never expose private keys in your code or version control** -## Development Status +1. Use environment variables for sensitive data +2. Keep private keys secure and encrypted +3. Test with small amounts first -This implementation covers the foundational aspects of Issues #1-#4 from the original roadmap: +## Example with Environment Variables -- **Issue #1**: Project setup and Cargo configuration -- **Issue #2**: Core type definitions and data structures -- **Issue #3**: Starknet integration (basic structure implemented, full integration pending) -- **Issue #4**: Contract ABI and interface implementation (structure ready, needs Starknet integration) +```rust +use std::env; + +let rpc_url = env::var("STARKNET_RPC_URL").expect("STARKNET_RPC_URL not set"); +let account_address = env::var("ACCOUNT_ADDRESS").expect("ACCOUNT_ADDRESS not set"); +let private_key = env::var("PRIVATE_KEY").expect("PRIVATE_KEY not set"); + +let mut swapper = AutoSwappr::config( + rpc_url, + account_address, + private_key, + "0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b".to_string(), +).unwrap(); +``` ## Contributing -Contributions are welcome! Please see the [Issues](https://github.com/BlockheaderWeb3-Community/autoswap-rust-sdk/issues) for current development priorities. +1. Fork the repository +2. Create a feature branch +3. Make your changes +4. Add tests +5. Submit a pull request + +## Support + +For support and questions, please open an issue on GitHub. ## License diff --git a/src/lib.rs b/src/lib.rs index 8edbf5f..e3048fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,21 +1,11 @@ -// pub mod client; pub mod constant; -// pub mod contracts; -pub mod provider; -pub mod simple_client; pub mod swappr; pub mod types; -// #[cfg(test)] -// mod contracts_test; // Re-export main types and clients for easy access -// pub use client::AutoSwapprClient; -// pub use contracts::{AutoSwapprContract, Erc20Contract, addresses,conversions::u128_to_uint256}; -pub use provider::{Network, StarknetProvider}; -pub use simple_client::{ - SimpleAutoSwapprClient, SimpleConfig, SimpleError, SwapData as SimpleSwapData, -}; pub use types::connector::{ - AutoSwappr, AutoSwapprError, ContractInfo, Delta, FeeType, I129, PoolKey, Route, RouteParams, - SwapData, SwapOptions, SwapParameters, SwapParams, SwapResult, TokenInfo, Uint256, + AutoSwappr, AutoSwapprError, ContractInfo, Delta, FeeType, I129, PoolKey, Route, SwapData, + SwapOptions, SwapParameters, SwapParams, SwapResult, }; + +pub use constant::{ETH, STRK, TokenAddress, TokenInfo, USDC, USDT, WBTC}; diff --git a/src/swappr.rs b/src/swappr.rs index 0ead2bb..c18168c 100644 --- a/src/swappr.rs +++ b/src/swappr.rs @@ -11,8 +11,8 @@ use starknet::{ }; use crate::{ - I129, PoolKey, SwapData, SwapParameters, - constant::{TokenAddress, u128_to_uint256}, + I129, PoolKey, SwapData, SwapParameters, TokenAddress, + constant::u128_to_uint256, types::connector::{AutoSwappr, ErrorResponse, SuccessResponse}, }; use axum::Json; @@ -30,6 +30,7 @@ impl AutoSwappr { /// * `rpc_url` - The RPC endpoint URL for Starknet (e.g., Alchemy, Infura) /// * `account_address` - Your wallet address on Starknet /// * `private_key` - Your wallet's private key (keep this secure!) + /// * `contract_address` - AutoSwappr contract address /// /// # Returns /// @@ -44,38 +45,11 @@ impl AutoSwappr { /// - `private_key` is an empty string /// - The RPC URL format is invalid /// - The account address or private key cannot be parsed as valid Felt values - /// - /// # Examples - /// - /// ```no_run - /// use auto_swappr::types::connector::AutoSwappr; - /// - /// let rpc_url = "https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_9/YOUR_API_KEY".to_string(); - /// let account_address = "0x05362484eb9b91ae4365963dad33794cb50a5f93eb7a08b0280cf0f0c0129e4f".to_string(); - /// let private_key = "0x062e0c4dc96f3d877af48285a5442ce69860a50b11a1d91eae1e3f128df1c454".to_string(); - /// - /// let swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); - /// ``` - /// - /// # Example with Error Handling - /// - /// ``` - /// use auto_swappr::types::connector::AutoSwappr; - /// - /// // This will fail due to empty RPC URL - /// let result = AutoSwappr::config( - /// "".to_string(), - /// "0x123".to_string(), - /// "0x456".to_string() - /// ); - /// - /// assert!(result.is_err()); - /// ``` - pub fn config( rpc_url: String, account_address: String, private_key: String, + contract_address: String, ) -> Result> { if rpc_url.is_empty() { return Err(Json(ErrorResponse { @@ -100,9 +74,7 @@ impl AutoSwappr { let signer = LocalWallet::from(SigningKey::from_secret_scalar( Felt::from_hex(&private_key).unwrap(), )); - let contract_address = - Felt::from_hex("0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b") - .unwrap(); + let contract_address = Felt::from_hex(&contract_address).unwrap(); let address = Felt::from_hex(&account_address).unwrap(); let provider = JsonRpcClient::new(HttpTransport::new(Url::parse(&rpc_url).unwrap())); @@ -142,61 +114,6 @@ impl AutoSwappr { /// - Token information cannot be retrieved /// - The transaction execution fails /// - Insufficient balance or allowance - /// - /// # Examples - /// - /// ## Basic Swap Example - /// - /// ```no_run - /// use auto_swappr::types::connector::AutoSwappr; - /// use auto_swappr::constant::{STRK, USDC}; - /// - /// # #[tokio::main] - /// # async fn main() { - /// let rpc_url = "https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_9/YOUR_API_KEY".to_string(); - /// let account_address = "0x053620000000000000000000000000000000000000000000000000000000".to_string(); - /// let private_key = "0x000000000000000000000000000000000000000000000000000000000000".to_string(); - /// - /// let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); - /// - /// // Swap 1 STRK token (amount is in base units without decimals) - /// let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1).await; - /// - /// match result { - /// Ok(response) => println!("Swap successful! TX: {:?}", response.tx_hash), - /// Err(error) => println!("Swap failed: {}", error.message), - /// } - /// # } - /// ``` - /// - /// ## Error Handling Example - /// - /// ```no_run - /// use auto_swappr::types::connector::AutoSwappr; - /// use auto_swappr::constant::{STRK, USDC}; - /// - /// # #[tokio::main] - /// # async fn main() { - /// # let rpc_url = "https://starknet-mainnet.g.alchemy.com/starknet/version/rpc/v0_9/YOUR_API_KEY".to_string(); - /// # let account_address = "0x05362484eb9b91ae4365963dad33794cb50a5f93eb7a08b0280cf0f0c0129e4f".to_string(); - /// # let private_key = "0x062e0c4dc96f3d877af48285a5442ce69860a50b11a1d91eae1e3f128df1c454".to_string(); - /// let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); - /// - /// // This will fail because swap_amount is zero - /// let result = swapper.ekubo_manual_swap(*STRK, *USDC, 0).await; - /// - /// assert!(result.is_err()); - /// if let Err(error) = result { - /// assert_eq!(error.err().message, "SWAP AMOUNT IS ZERO"); - /// } - /// # } - /// ``` - /// # Notes - /// - /// - The `swap_amount` should be specified in base units (without decimal adjustment) - /// - The function automatically handles decimal conversion based on the token - /// - Both approval and swap are executed in a single transaction - /// - Make sure your account has sufficient balance of `token0` pub async fn ekubo_manual_swap( &mut self, token0: Felt, @@ -338,12 +255,16 @@ mod tests { use super::*; #[tokio::test] - // #[ignore = "owner address and private key is required to run the test"] + #[ignore = "owner address and private key is required to run the test"] async fn it_works_bravoos() { let rpc_url = "YOUR MAINNET RPC".to_string(); let account_address = "YOUR WALLET ADDRESS".to_string(); let private_key = "YOUR WALLET PRIVATE KEY".to_string(); - let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + let auto_swapper_address = + "0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b".to_string(); + let mut swapper = + AutoSwappr::config(rpc_url, account_address, private_key, auto_swapper_address) + .unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); assert!(result.await.is_ok()) } @@ -353,7 +274,11 @@ mod tests { let rpc_url = "YOUR MAINNET RPC".to_string(); let account_address = "YOUR WALLET ADDRESS".to_string(); let private_key = "YOUR WALLET PRIVATE KEY".to_string(); - let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + let auto_swapper_address = + "0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b".to_string(); + let mut swapper = + AutoSwappr::config(rpc_url, account_address, private_key, auto_swapper_address) + .unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 0); assert!(result.await.is_err()) @@ -365,7 +290,11 @@ mod tests { let rpc_url = "YOUR MAINNET RPC".to_string(); let account_address = "YOUR WALLET ADDRESS".to_string(); let private_key = "YOUR WALLET PRIVATE KEY".to_string(); - let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + let auto_swapper_address = + "0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b".to_string(); + let mut swapper = + AutoSwappr::config(rpc_url, account_address, private_key, auto_swapper_address) + .unwrap(); let result = swapper.ekubo_manual_swap(*STRK, *USDC, 1); assert!(result.await.is_ok()); @@ -380,7 +309,11 @@ mod tests { let rpc_url = "YOUR MAINNET RPC".to_string(); let account_address = "YOUR WALLET ADDRESS".to_string(); let private_key = "YOUR WALLET PRIVATE KEY".to_string(); - let mut swapper = AutoSwappr::config(rpc_url, account_address, private_key).unwrap(); + let auto_swapper_address = + "0x05582ad635c43b4c14dbfa53cbde0df32266164a0d1b36e5b510e5b34aeb364b".to_string(); + let mut swapper = + AutoSwappr::config(rpc_url, account_address, private_key, auto_swapper_address) + .unwrap(); // Use STRK -> USDC for a tiny amount (1 unit). Backend URL is a placeholder and // should be replaced with a real auto-swapper endpoint when running the test. diff --git a/src/types/connector.rs b/src/types/connector.rs index c9d4c3b..e09eb51 100644 --- a/src/types/connector.rs +++ b/src/types/connector.rs @@ -10,7 +10,7 @@ use starknet::{ }; use thiserror::Error; -use crate::constant::{USDC, USDT}; +use crate::{USDC, USDT}; /// Configuration for the AutoSwappr SDK #[derive(Debug)] @@ -22,32 +22,6 @@ pub struct AutoSwappr { pub contract_address: Felt, } -/// Uint256 representation for Starknet -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct Uint256 { - pub low: u128, - pub high: u128, -} - -impl Uint256 { - pub fn from_u128(value: u128) -> Self { - Self { - low: value, - high: 0, - } - } - - pub fn from_string(value: &str) -> Result { - let parsed = value.parse::().map_err(|_| "Invalid number format")?; - Ok(Self::from_u128(parsed)) - } - - pub fn to_hex_string(&self) -> String { - // Convert Uint256 to hex string - format!("0x{:032x}{:032x}", self.high, self.low) - } -} - /// Ekubo pool key structure #[derive(Debug, Serialize, Deserialize, Clone, Encode, Decode)] pub struct PoolKey { @@ -116,15 +90,15 @@ pub struct Route { pub additional_swap_params: Vec, } -/// Route parameters for Fibrous swaps -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct RouteParams { - pub token_in: String, - pub token_out: String, - pub amount_in: Uint256, - pub min_received: Uint256, - pub destination: String, -} +// /// Route parameters for Fibrous swaps +// #[derive(Debug, Serialize, Deserialize, Clone)] +// pub struct RouteParams { +// pub token_in: String, +// pub token_out: String, +// pub amount_in: Uint256, +// pub min_received: Uint256, +// pub destination: String, +// } /// Swap parameters for Fibrous swaps #[derive(Debug, Serialize, Deserialize, Clone)] @@ -186,13 +160,6 @@ pub struct ContractInfo { } /// Token information for supported tokens -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct TokenInfo { - pub address: String, - pub symbol: String, - pub decimals: u8, - pub name: String, -} /// Pool configuration for different token pairs #[derive(Debug, Serialize, Deserialize, Clone)] From 15659e4a2c4440542a12bfc602d58182506d7094 Mon Sep 17 00:00:00 2001 From: yunusabdul38 Date: Fri, 10 Oct 2025 14:45:48 +0100 Subject: [PATCH 8/8] fix: clippy warnings --- src/constant/mod.rs | 8 +++++++- src/swappr.rs | 11 ++++------- src/types/connector.rs | 2 -- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/constant/mod.rs b/src/constant/mod.rs index e166ac1..604c056 100644 --- a/src/constant/mod.rs +++ b/src/constant/mod.rs @@ -36,7 +36,13 @@ pub struct TokenInfo<'a> { pub decimals: u8, name: &'a str, } -#[allow(dead_code)] + +impl Default for TokenAddress<'static> { + fn default() -> Self { + Self::new() + } +} + impl TokenAddress<'static> { pub fn new() -> Self { let tokens: Vec = vec![ diff --git a/src/swappr.rs b/src/swappr.rs index c18168c..07cb681 100644 --- a/src/swappr.rs +++ b/src/swappr.rs @@ -165,13 +165,10 @@ impl AutoSwappr { success: true, tx_hash: x.transaction_hash, })), - Err(x) => { - println!("error message {}", x.to_string()); - Err(Json(ErrorResponse { - success: false, - message: "FAILED TO SWAP".to_string(), - })) - } + Err(_) => Err(Json(ErrorResponse { + success: false, + message: "FAILED TO SWAP".to_string(), + })), } } diff --git a/src/types/connector.rs b/src/types/connector.rs index e09eb51..ff19b9c 100644 --- a/src/types/connector.rs +++ b/src/types/connector.rs @@ -159,8 +159,6 @@ pub struct ContractInfo { pub percentage_fee: u16, } -/// Token information for supported tokens - /// Pool configuration for different token pairs #[derive(Debug, Serialize, Deserialize, Clone)] pub struct PoolConfig {