diff --git a/Cargo.lock b/Cargo.lock index b823b9321..1850fb55e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -63,6 +63,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.15", + "once_cell", + "version_check", +] + [[package]] name = "ahash" version = "0.8.11" @@ -669,11 +680,14 @@ dependencies = [ "bincode", "borsh 1.5.5", "clap", + "dashmap 6.1.0", "email_address", "express-relay", "express-relay-api-types", "express-relay-client", "futures", + "governor 0.10.0", + "jupiter-swap-api-client", "litesvm", "mockall", "mockall_double", @@ -980,6 +994,18 @@ dependencies = [ "serde", ] +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "blake3" version = "1.5.5" @@ -1126,6 +1152,28 @@ dependencies = [ "serde", ] +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "bytemuck" version = "1.21.0" @@ -1580,6 +1628,20 @@ dependencies = [ "parking_lot_core", ] +[[package]] +name = "dashmap" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" +dependencies = [ + "cfg-if", + "crossbeam-utils", + "hashbrown 0.14.5", + "lock_api", + "once_cell", + "parking_lot_core", +] + [[package]] name = "data-encoding" version = "2.6.0" @@ -1990,6 +2052,12 @@ 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" @@ -2020,6 +2088,12 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "futures" version = "0.3.31" @@ -2172,6 +2246,20 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", +] + [[package]] name = "gimli" version = "0.31.1" @@ -2191,7 +2279,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68a7f542ee6b35af73b06abc0dad1c1bae89964e4e253bc4b587b91c9637867b" dependencies = [ "cfg-if", - "dashmap", + "dashmap 5.5.3", "futures", "futures-timer", "no-std-compat", @@ -2204,6 +2292,29 @@ dependencies = [ "spinning_top", ] +[[package]] +name = "governor" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cbe789d04bf14543f03c4b60cd494148aa79438c8440ae7d81a7778147745c3" +dependencies = [ + "cfg-if", + "dashmap 6.1.0", + "futures-sink", + "futures-timer", + "futures-util", + "getrandom 0.3.2", + "hashbrown 0.15.2", + "nonzero_ext", + "parking_lot", + "portable-atomic", + "quanta", + "rand 0.9.1", + "smallvec", + "spinning_top", + "web-time", +] + [[package]] name = "h2" version = "0.3.26" @@ -2256,6 +2367,9 @@ name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.8", +] [[package]] name = "hashbrown" @@ -2263,7 +2377,7 @@ version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" dependencies = [ - "ahash", + "ahash 0.8.11", ] [[package]] @@ -2272,7 +2386,7 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" dependencies = [ - "ahash", + "ahash 0.8.11", "allocator-api2", ] @@ -2281,6 +2395,11 @@ name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "hashlink" @@ -2935,6 +3054,24 @@ dependencies = [ "serde_json", ] +[[package]] +name = "jupiter-swap-api-client" +version = "0.1.0" +source = "git+https://github.com/anihamde/jupiter-swap-api-client.git#16effd16ed39af3bb7bf56d8048d6ce0433d81b7" +dependencies = [ + "anyhow", + "base64 0.22.1", + "bincode", + "reqwest 0.12.9", + "rust_decimal", + "serde", + "serde_json", + "serde_qs", + "solana-account-decoder", + "solana-sdk", + "thiserror 2.0.12", +] + [[package]] name = "kaigan" version = "0.2.6" @@ -3202,7 +3339,7 @@ version = "0.22.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2be3cbd384d4e955b231c895ce10685e3d8260c5ccffae898c96c723b0772835" dependencies = [ - "ahash", + "ahash 0.8.11", "portable-atomic", ] @@ -3955,6 +4092,26 @@ dependencies = [ "syn 2.0.90", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "qstring" version = "0.7.2" @@ -4052,6 +4209,18 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "rand" version = "0.7.3" @@ -4076,6 +4245,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -4096,6 +4275,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -4114,6 +4303,15 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.2", +] + [[package]] name = "rand_hc" version = "0.2.0" @@ -4205,6 +4403,15 @@ version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + [[package]] name = "reqwest" version = "0.11.27" @@ -4325,6 +4532,35 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rkyv" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9008cd6385b9e161d8229e1f6549dd23c3d022f132a2ea37ac3a10ac4935779b" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503d1d27590a2b0a3a4ca4c94755aa2875657196ecbf401a42eff41d7de532c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "rsa" version = "0.9.7" @@ -4345,6 +4581,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rust_decimal" +version = "1.37.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faa7de2ba56ac291bd90c6b9bece784a52ae1411f9506544b3eae36dd2356d50" +dependencies = [ + "arrayvec", + "borsh 1.5.5", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + [[package]] name = "rustc-demangle" version = "0.1.24" @@ -4548,6 +4800,12 @@ dependencies = [ "untrusted", ] +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + [[package]] name = "security-framework" version = "2.11.1" @@ -4638,6 +4896,17 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_qs" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd34f36fe4c5ba9654417139a9b3a20d2e1de6012ee678ad14d240c22c78d8d6" +dependencies = [ + "percent-encoding", + "serde", + "thiserror 1.0.69", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -4788,6 +5057,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "0.3.11" @@ -5098,7 +5373,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4ee734c35b736e632aa3b1367f933d93ee7b4129dd1e20ca942205d4834054e" dependencies = [ - "ahash", + "ahash 0.8.11", "lazy_static", "log", "qualifier_attr", @@ -5123,7 +5398,7 @@ checksum = "1e25b7073890561a6b7875a921572fc4a9a2c78b3e60fb8e0a7ee4911961f8bd" dependencies = [ "async-trait", "bincode", - "dashmap", + "dashmap 5.5.3", "futures", "futures-util", "indexmap 2.8.0", @@ -5481,7 +5756,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89e1d3b52b4a014efeaaab67f14e40af3972a4be61c523d612860db8e3145529" dependencies = [ - "ahash", + "ahash 0.8.11", "lazy_static", "solana-epoch-schedule", "solana-hash", @@ -5919,7 +6194,7 @@ version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f0962d3818fc942a888f7c2d530896aeaf6f2da2187592a67bbdc8cf8a54192" dependencies = [ - "ahash", + "ahash 0.8.11", "bincode", "bv", "caps", @@ -6797,10 +7072,10 @@ dependencies = [ "async-channel", "bytes", "crossbeam-channel", - "dashmap", + "dashmap 5.5.3", "futures", "futures-util", - "governor", + "governor 0.6.3", "histogram", "indexmap 2.8.0", "itertools 0.12.1", @@ -7822,7 +8097,7 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" dependencies = [ - "ahash", + "ahash 0.8.11", "atoi", "bigdecimal", "byteorder", @@ -8163,6 +8438,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "task-local-extensions" version = "0.1.4" @@ -8950,6 +9231,15 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasite" version = "0.1.0" @@ -9324,6 +9614,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.0", +] + [[package]] name = "write16" version = "1.0.0" @@ -9336,6 +9635,15 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + [[package]] name = "x509-parser" version = "0.14.0" diff --git a/auction-server/.sqlx/query-12869f012538d108ee2a3e9c98ad91daf52246ba0ebad020330288d05ac5b3c9.json b/auction-server/.sqlx/query-12869f012538d108ee2a3e9c98ad91daf52246ba0ebad020330288d05ac5b3c9.json index 76a5281d6..e8319e32a 100644 --- a/auction-server/.sqlx/query-12869f012538d108ee2a3e9c98ad91daf52246ba0ebad020330288d05ac5b3c9.json +++ b/auction-server/.sqlx/query-12869f012538d108ee2a3e9c98ad91daf52246ba0ebad020330288d05ac5b3c9.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -39,8 +39,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-5143a4ff9e62fdfc64d652d778485aa5e1962ad3aa9c70bd34472f24cef77306.json b/auction-server/.sqlx/query-5143a4ff9e62fdfc64d652d778485aa5e1962ad3aa9c70bd34472f24cef77306.json deleted file mode 100644 index bdd6bed2c..000000000 --- a/auction-server/.sqlx/query-5143a4ff9e62fdfc64d652d778485aa5e1962ad3aa9c70bd34472f24cef77306.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE bid SET status = $1, metadata = jsonb_set(metadata, '{bundle_index}', $2) WHERE id = $3 AND status = $4", - "describe": { - "columns": [], - "parameters": { - "Left": [ - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - }, - "Jsonb", - "Uuid", - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - } - ] - }, - "nullable": [] - }, - "hash": "5143a4ff9e62fdfc64d652d778485aa5e1962ad3aa9c70bd34472f24cef77306" -} diff --git a/auction-server/.sqlx/query-71a59d9696f9bac1b6d31ce4926b497337c599c11c9cf3d29c58fbbf7501779d.json b/auction-server/.sqlx/query-71a59d9696f9bac1b6d31ce4926b497337c599c11c9cf3d29c58fbbf7501779d.json deleted file mode 100644 index 13864b25c..000000000 --- a/auction-server/.sqlx/query-71a59d9696f9bac1b6d31ce4926b497337c599c11c9cf3d29c58fbbf7501779d.json +++ /dev/null @@ -1,54 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE bid SET status = $1 WHERE id = $2 AND status = $3", - "describe": { - "columns": [], - "parameters": { - "Left": [ - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - }, - "Uuid", - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - } - ] - }, - "nullable": [] - }, - "hash": "71a59d9696f9bac1b6d31ce4926b497337c599c11c9cf3d29c58fbbf7501779d" -} diff --git a/auction-server/.sqlx/query-756fe3557caee2202d61430982956109d0a3ba60cce3536dc5ac2e4eb3682a23.json b/auction-server/.sqlx/query-756fe3557caee2202d61430982956109d0a3ba60cce3536dc5ac2e4eb3682a23.json deleted file mode 100644 index 363a17981..000000000 --- a/auction-server/.sqlx/query-756fe3557caee2202d61430982956109d0a3ba60cce3536dc5ac2e4eb3682a23.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE bid SET status = $1, auction_id = $2, metadata = jsonb_set(metadata, '{bundle_index}', $3) WHERE id = $4 AND status = $5", - "describe": { - "columns": [], - "parameters": { - "Left": [ - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - }, - "Uuid", - "Jsonb", - "Uuid", - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - } - ] - }, - "nullable": [] - }, - "hash": "756fe3557caee2202d61430982956109d0a3ba60cce3536dc5ac2e4eb3682a23" -} diff --git a/auction-server/.sqlx/query-82192571d3edf3a46265ac00702402fe80ecee20caf9001b88bf8d885b0524e2.json b/auction-server/.sqlx/query-82192571d3edf3a46265ac00702402fe80ecee20caf9001b88bf8d885b0524e2.json deleted file mode 100644 index 61c6b1b32..000000000 --- a/auction-server/.sqlx/query-82192571d3edf3a46265ac00702402fe80ecee20caf9001b88bf8d885b0524e2.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE bid SET status = $1, metadata = jsonb_set(metadata, '{bundle_index}', $2), auction_id = $3 WHERE id = $4 AND status = $5", - "describe": { - "columns": [], - "parameters": { - "Left": [ - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - }, - "Jsonb", - "Uuid", - "Uuid", - { - "Custom": { - "name": "bid_status", - "kind": { - "Enum": [ - "pending", - "lost", - "submitted", - "won", - "expired", - "failed", - "cancelled", - "awaiting_signature", - "sent_to_user_for_submission", - "submission_failed_cancelled", - "submission_failed_deadline_passed" - ] - } - } - } - ] - }, - "nullable": [] - }, - "hash": "82192571d3edf3a46265ac00702402fe80ecee20caf9001b88bf8d885b0524e2" -} diff --git a/auction-server/.sqlx/query-8a16817295ec17dda1e25c36141b51f4ac67966f57636e9df36222263552c10f.json b/auction-server/.sqlx/query-8a16817295ec17dda1e25c36141b51f4ac67966f57636e9df36222263552c10f.json index a8a831caa..40d24e75b 100644 --- a/auction-server/.sqlx/query-8a16817295ec17dda1e25c36141b51f4ac67966f57636e9df36222263552c10f.json +++ b/auction-server/.sqlx/query-8a16817295ec17dda1e25c36141b51f4ac67966f57636e9df36222263552c10f.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -39,8 +39,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -59,8 +59,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -79,8 +79,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-9526c7c80829a0dbeea7763b3381467782c8bec86f6f8b52fe11325b96edbdb4.json b/auction-server/.sqlx/query-9526c7c80829a0dbeea7763b3381467782c8bec86f6f8b52fe11325b96edbdb4.json index bdeded384..09247e502 100644 --- a/auction-server/.sqlx/query-9526c7c80829a0dbeea7763b3381467782c8bec86f6f8b52fe11325b96edbdb4.json +++ b/auction-server/.sqlx/query-9526c7c80829a0dbeea7763b3381467782c8bec86f6f8b52fe11325b96edbdb4.json @@ -32,8 +32,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-a25adc19c687c4988ca108b2ef7dedeafe298047458c91bf3bf0540274c4c508.json b/auction-server/.sqlx/query-a25adc19c687c4988ca108b2ef7dedeafe298047458c91bf3bf0540274c4c508.json index 4620a55c9..f2f828b99 100644 --- a/auction-server/.sqlx/query-a25adc19c687c4988ca108b2ef7dedeafe298047458c91bf3bf0540274c4c508.json +++ b/auction-server/.sqlx/query-a25adc19c687c4988ca108b2ef7dedeafe298047458c91bf3bf0540274c4c508.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -39,8 +39,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-b54b6d2c1d4d7957fb7188eec17ec8a0b4e7ab51c728bac77f79ffbd896d8c27.json b/auction-server/.sqlx/query-b54b6d2c1d4d7957fb7188eec17ec8a0b4e7ab51c728bac77f79ffbd896d8c27.json index 2029c9bb0..5968de1ec 100644 --- a/auction-server/.sqlx/query-b54b6d2c1d4d7957fb7188eec17ec8a0b4e7ab51c728bac77f79ffbd896d8c27.json +++ b/auction-server/.sqlx/query-b54b6d2c1d4d7957fb7188eec17ec8a0b4e7ab51c728bac77f79ffbd896d8c27.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -38,8 +38,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-b9ce3a739e775f73af93da31d45044493fd2b8c67e85dea6331bef2621a558be.json b/auction-server/.sqlx/query-b9ce3a739e775f73af93da31d45044493fd2b8c67e85dea6331bef2621a558be.json index cb236a923..7ca3b23bd 100644 --- a/auction-server/.sqlx/query-b9ce3a739e775f73af93da31d45044493fd2b8c67e85dea6331bef2621a558be.json +++ b/auction-server/.sqlx/query-b9ce3a739e775f73af93da31d45044493fd2b8c67e85dea6331bef2621a558be.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -38,8 +38,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -58,8 +58,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -78,8 +78,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -98,8 +98,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-d8d976f022e66635ab32c56b9fda9ac97b4e7ef55ec3dc11bde044fc248998be.json b/auction-server/.sqlx/query-d8d976f022e66635ab32c56b9fda9ac97b4e7ef55ec3dc11bde044fc248998be.json index 0aad03a08..0b636e89e 100644 --- a/auction-server/.sqlx/query-d8d976f022e66635ab32c56b9fda9ac97b4e7ef55ec3dc11bde044fc248998be.json +++ b/auction-server/.sqlx/query-d8d976f022e66635ab32c56b9fda9ac97b4e7ef55ec3dc11bde044fc248998be.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -38,8 +38,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -58,8 +58,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -78,8 +78,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-e57e8bee9fbc6c2c16396d0900f44a734f7cfc94637ff3a8f1b52a329a704522.json b/auction-server/.sqlx/query-e57e8bee9fbc6c2c16396d0900f44a734f7cfc94637ff3a8f1b52a329a704522.json index aa02ab0f3..4ec0c0b8d 100644 --- a/auction-server/.sqlx/query-e57e8bee9fbc6c2c16396d0900f44a734f7cfc94637ff3a8f1b52a329a704522.json +++ b/auction-server/.sqlx/query-e57e8bee9fbc6c2c16396d0900f44a734f7cfc94637ff3a8f1b52a329a704522.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -38,8 +38,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-fa6d4023356c380d05db09464366e432a314051f152854620bd2dfcbd66434e2.json b/auction-server/.sqlx/query-fa6d4023356c380d05db09464366e432a314051f152854620bd2dfcbd66434e2.json index 348635fad..8052035bf 100644 --- a/auction-server/.sqlx/query-fa6d4023356c380d05db09464366e432a314051f152854620bd2dfcbd66434e2.json +++ b/auction-server/.sqlx/query-fa6d4023356c380d05db09464366e432a314051f152854620bd2dfcbd66434e2.json @@ -16,8 +16,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -38,8 +38,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" @@ -58,8 +58,8 @@ "won", "expired", "failed", - "cancelled", "awaiting_signature", + "cancelled", "sent_to_user_for_submission", "submission_failed_cancelled", "submission_failed_deadline_passed" diff --git a/auction-server/.sqlx/query-fde34e23ad414f690193010b69b8ef33d8a914eda185b0ea7daf321edcf69413.json b/auction-server/.sqlx/query-fde34e23ad414f690193010b69b8ef33d8a914eda185b0ea7daf321edcf69413.json new file mode 100644 index 000000000..100c89b5a --- /dev/null +++ b/auction-server/.sqlx/query-fde34e23ad414f690193010b69b8ef33d8a914eda185b0ea7daf321edcf69413.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE opportunity SET metadata = jsonb_set(metadata, '{other_quotes}', $1::jsonb, false) WHERE id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Jsonb", + "Uuid" + ] + }, + "nullable": [] + }, + "hash": "fde34e23ad414f690193010b69b8ef33d8a914eda185b0ea7daf321edcf69413" +} diff --git a/auction-server/Cargo.toml b/auction-server/Cargo.toml index d6433166d..19d1584dd 100644 --- a/auction-server/Cargo.toml +++ b/auction-server/Cargo.toml @@ -58,6 +58,9 @@ spl-token = { workspace = true } mockall_double = "0.3.1" spl-memo-client = { workspace = true } spl-token-2022 = { workspace = true } +jupiter-swap-api-client = { git = "https://github.com/anihamde/jupiter-swap-api-client.git", package = "jupiter-swap-api-client" } +dashmap = "6.1.0" +governor = "0.10.0" [dev-dependencies] mockall = "0.13.1" diff --git a/auction-server/config.sample.yaml b/auction-server/config.sample.yaml index c1844b9a4..d03485a23 100644 --- a/auction-server/config.sample.yaml +++ b/auction-server/config.sample.yaml @@ -1,15 +1,4 @@ chains: - development: - geth_rpc_addr: http://localhost:8545 - geth_ws_addr: ws://127.0.0.1:9545 - rpc_timeout: 5 - express_relay_contract: 0xa513E6E4b8f2a923D98304ec87F64353C4D5C853 - adapter_factory_contract: 0xB7f8BC63BbcaD18155201308C8f3540b07f84F5e - legacy_tx: false - poll_interval: 1 - subwallets: - - 0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef - - 0xdecafdecafdecafdecafdecafdecafdecafdecaf development-solana: express_relay_program_id: PytERJFhAKuNNuaiXkApLfWzwNwSNDACpigT3LwQfou rpc_read_url: http://localhost:8899 @@ -23,3 +12,4 @@ chains: - EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v - Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB - So11111111111111111111111111111111111111112 + jupiter_ultra_url: https://ultra-api.jup.ag diff --git a/auction-server/src/auction/service/verification.rs b/auction-server/src/auction/service/verification.rs index 4a098bc5d..5a1fce4bd 100644 --- a/auction-server/src/auction/service/verification.rs +++ b/auction-server/src/auction/service/verification.rs @@ -1667,6 +1667,7 @@ mod tests { BID_MINIMUM_LIFE_TIME_SVM_OTHER, ), cancellable: true, + other_quotes: vec![], } } } diff --git a/auction-server/src/config.rs b/auction-server/src/config.rs index 41fffd88c..d304cf156 100644 --- a/auction-server/src/config.rs +++ b/auction-server/src/config.rs @@ -137,4 +137,6 @@ pub struct ConfigSvm { /// Ordered list of fee tokens, with first being the most preferred. #[serde_as(as = "Vec")] pub ordered_fee_tokens: Vec, + /// URL for Jupiter Ultra API. + pub jupiter_ultra_url: Option, } diff --git a/auction-server/src/opportunity/entities/opportunity.rs b/auction-server/src/opportunity/entities/opportunity.rs index 08ef30943..d35f210a2 100644 --- a/auction-server/src/opportunity/entities/opportunity.rs +++ b/auction-server/src/opportunity/entities/opportunity.rs @@ -30,11 +30,16 @@ use { Deserialize, Serialize, }, + serde_with::{ + serde_as, + DisplayFromStr, + }, solana_sdk::{ clock::Slot, program_pack::Pack, pubkey::Pubkey, rent::Rent, + transaction::VersionedTransaction, }, spl_token_2022::state::Account as TokenAccount, std::{ @@ -135,6 +140,21 @@ impl TokenAccountInitializationConfigs { } } +#[serde_as] +#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)] +pub struct OtherQuote { + pub quoter: String, + pub amount_quoted: u64, + pub slippage_bps: Option, + #[serde_as(as = "Option")] + pub fee_mint: Option, + pub fee_bps: Option, + pub deadline: Option, + #[serde(with = "express_relay_api_types::serde::nullable_transaction_svm")] + pub transaction: Option, + pub swap_details: String, +} + #[derive(Debug, Clone, PartialEq)] pub struct OpportunitySvmProgramSwap { pub user_wallet_address: Pubkey, @@ -150,6 +170,7 @@ pub struct OpportunitySvmProgramSwap { pub cancellable: bool, pub minimum_lifetime: Option, pub minimum_deadline: OffsetDateTime, + pub other_quotes: Vec, } #[derive(Debug, Clone, PartialEq)] @@ -238,6 +259,7 @@ impl OpportunitySvm { memo: program.memo, cancellable: program.cancellable, minimum_lifetime: program.minimum_lifetime, + other_quotes: program.other_quotes, }, ) } @@ -512,6 +534,7 @@ impl TryFrom> for Op .map(|lifetime| Duration::from_secs(lifetime as u64)) .unwrap_or(BID_MINIMUM_LIFE_TIME_SVM_OTHER), ), + other_quotes: program.other_quotes, }) } }; diff --git a/auction-server/src/opportunity/repository/add_other_quotes.rs b/auction-server/src/opportunity/repository/add_other_quotes.rs new file mode 100644 index 000000000..c7605887f --- /dev/null +++ b/auction-server/src/opportunity/repository/add_other_quotes.rs @@ -0,0 +1,117 @@ +use { + super::Repository, + crate::{ + api::RestError, + opportunity::entities::{ + OtherQuote, + QuoteCreate, + QuoteTokens, + }, + }, + governor::RateLimiter, + jupiter_swap_api_client::{ + quote::{ + ParamsMode, + SwapMode as UltraSwapMode, + SwapType, + UltraQuoteRequest, + }, + JupiterUltraSwapApiClient, + }, + std::sync::Arc, + uuid::Uuid, +}; + +pub const QUOTER_ULTRA: &str = "JupiterUltra"; +pub const RATE_LIMIT_ULTRA_PER_SECOND: u32 = 1; + +impl Repository { + pub async fn add_other_quotes( + &self, + opportunity_id: Uuid, + jupiter_ultra_client: Option, + quote_create: QuoteCreate, + ) -> Result<(), RestError> { + let other_quotes = self + .get_other_quotes(jupiter_ultra_client, quote_create) + .await; + if !other_quotes.is_empty() { + self.db + .add_other_quotes(opportunity_id, other_quotes) + .await?; + } + Ok(()) + } + + async fn get_other_quotes( + &self, + jupiter_ultra_client: Option, + quote_create: QuoteCreate, + ) -> Vec { + let (input_mint, output_mint, amount, swap_mode) = match quote_create.tokens { + QuoteTokens::UserTokenSpecified { + user_token, + searcher_token, + } => ( + user_token.token, + searcher_token, + user_token.amount, + Some(UltraSwapMode::ExactIn), + ), + QuoteTokens::SearcherTokenSpecified { + user_token, + searcher_token, + } => ( + user_token, + searcher_token.token, + searcher_token.amount, + Some(UltraSwapMode::ExactOut), + ), + }; + let mut other_quotes = vec![]; + + if let Some(jupiter_ultra_client) = jupiter_ultra_client { + let limiter = self + .last_other_quotes_call + .entry(QUOTER_ULTRA.to_string()) + .or_insert_with(|| { + Arc::new(RateLimiter::direct(governor::Quota::per_second( + std::num::NonZeroU32::new(RATE_LIMIT_ULTRA_PER_SECOND).unwrap(), + ))) + }) + .clone(); + if limiter.check().is_ok() { + let ultra_response = jupiter_ultra_client + .quote(&UltraQuoteRequest { + input_mint, + output_mint, + amount, + swap_mode: swap_mode.clone(), + mode: ParamsMode::Ultra, + taker: quote_create.user_wallet_address, + }) + .await; + if let Ok(ultra_response) = ultra_response { + other_quotes.push(OtherQuote { + quoter: "JupiterUltra".to_string(), + amount_quoted: match swap_mode { + None | Some(UltraSwapMode::ExactIn) => ultra_response.out_amount, + Some(UltraSwapMode::ExactOut) => ultra_response.in_amount, + }, + slippage_bps: Some(ultra_response.slippage_bps), + fee_mint: ultra_response.fee_mint, + fee_bps: Some(ultra_response.fee_bps), + deadline: ultra_response.expire_at, + transaction: ultra_response.transaction.clone(), + swap_details: match ultra_response.swap_type { + SwapType::Aggregator => "aggregator".to_string(), + SwapType::Rfq => "rfq".to_string(), + }, + }); + } + } + } + + other_quotes + } +} diff --git a/auction-server/src/opportunity/repository/mod.rs b/auction-server/src/opportunity/repository/mod.rs index f5f5e0a08..bc93a905a 100644 --- a/auction-server/src/opportunity/repository/mod.rs +++ b/auction-server/src/opportunity/repository/mod.rs @@ -1,16 +1,24 @@ use { super::entities, axum_prometheus::metrics, + dashmap::DashMap, express_relay::state::ExpressRelayMetadata, + governor::{ + clock::DefaultClock, + state::InMemoryState, + RateLimiter, + }, solana_sdk::pubkey::Pubkey, std::{ collections::HashMap, ops::Deref, + sync::Arc, }, tokio::sync::RwLock, }; mod add_opportunity; +mod add_other_quotes; mod get_express_relay_metadata; mod get_in_memory_opportunities; mod get_in_memory_opportunities_by_key; @@ -26,9 +34,12 @@ pub use models::*; pub const OPPORTUNITY_PAGE_SIZE_CAP: usize = 100; +type Limiter = RateLimiter; + pub struct Repository { - pub in_memory_store: InMemoryStoreSvm, - pub db: Box, + pub in_memory_store: InMemoryStoreSvm, + pub db: Box, + last_other_quotes_call: DashMap>, } @@ -72,8 +83,9 @@ impl Deref for InMemoryStoreSvm { impl Repository { pub fn new(db: impl Database) -> Self { Self { - in_memory_store: InMemoryStoreSvm::new(), - db: Box::new(db), + in_memory_store: InMemoryStoreSvm::new(), + db: Box::new(db), + last_other_quotes_call: DashMap::new(), } } pub(super) async fn update_metrics(&self) { diff --git a/auction-server/src/opportunity/repository/models.rs b/auction-server/src/opportunity/repository/models.rs index 2daaa45ab..04d2e067f 100644 --- a/auction-server/src/opportunity/repository/models.rs +++ b/auction-server/src/opportunity/repository/models.rs @@ -15,6 +15,7 @@ use { opportunity::entities::{ FeeToken, OpportunitySvm, + OtherQuote, TokenAccountInitializationConfigs, }, }, @@ -89,6 +90,7 @@ pub struct OpportunityMetadataSvmProgramSwap { #[serde(default = "default_cancellable")] pub cancellable: bool, pub minimum_lifetime: Option, + pub other_quotes: Vec, } fn default_cancellable() -> bool { @@ -148,6 +150,11 @@ pub struct Opportunity { #[async_trait] pub trait Database: Debug + Send + Sync + 'static { async fn add_opportunity(&self, opportunity: &OpportunitySvm) -> Result<(), RestError>; + async fn add_other_quotes( + &self, + opportunity_id: Uuid, + other_quotes: Vec, + ) -> Result<(), RestError>; async fn get_opportunities( &self, chain_id: ChainId, @@ -206,6 +213,33 @@ impl Database for DB { Ok(()) } + #[instrument( + target = "metrics", + name = "db_add_other_quotes", + fields( + category = "db_queries", + result = "success", + name = "add_other_quotes", + tracing_enabled + ), + skip_all + )] + async fn add_other_quotes( + &self, + opportunity_id: Uuid, + other_quotes: Vec, + ) -> Result<(), RestError> { + sqlx::query!("UPDATE opportunity SET metadata = jsonb_set(metadata, '{other_quotes}', $1::jsonb, false) WHERE id = $2", + serde_json::to_value(other_quotes).expect("Failed to serialize other quotes"), + opportunity_id) + .execute(self) + .await.map_err(|e| { + tracing::Span::current().record("result", "error"); + tracing::error!("DB: Failed to update opportunity other quotes: {}", e); + RestError::TemporarilyUnavailable + })?; + Ok(()) + } #[instrument( target = "metrics", name = "db_get_opportunities", diff --git a/auction-server/src/opportunity/service/get_quote.rs b/auction-server/src/opportunity/service/get_quote.rs index 3f9c6b67b..ceccd0765 100644 --- a/auction-server/src/opportunity/service/get_quote.rs +++ b/auction-server/src/opportunity/service/get_quote.rs @@ -183,8 +183,10 @@ impl Service { &self, quote_create: entities::QuoteCreate, ) -> Result { - let referral_fee_info = - self.unwrap_referral_fee_info(quote_create.referral_fee_info, "e_create.chain_id)?; + let referral_fee_info = self.unwrap_referral_fee_info( + quote_create.referral_fee_info.clone(), + "e_create.chain_id, + )?; // TODO*: we should fix the Opportunity struct (or create a new format) to more clearly distinguish Swap opps from traditional opps // currently, we are using the same struct and just setting the unspecified token amount to 0 @@ -262,7 +264,7 @@ impl Service { ), }; // this uses the fee-adjusted token amounts to correctly calculate the permission account - let tokens_for_permission = match quote_create.tokens { + let tokens_for_permission = match quote_create.tokens.clone() { entities::QuoteTokens::UserTokenSpecified { user_token, searcher_token, @@ -343,6 +345,7 @@ impl Service { .map(|lifetime| Duration::from_secs(lifetime as u64)) .unwrap_or(BID_MINIMUM_LIFE_TIME_SVM_OTHER), ), + other_quotes: vec![], }); Ok(entities::OpportunityCreateSvm { @@ -434,6 +437,22 @@ impl Service { )); } + let repo = self.repo.clone(); + let jupiter_ultra_client = config.jupiter_ultra_client.clone(); + self.task_tracker.spawn({ + let quote_create = input.quote_create.clone(); + let opportunity_id = opportunity.id; + async move { + let result = async { + repo.add_other_quotes(opportunity_id, jupiter_ultra_client, quote_create).await + } + .await; + + if let Err(e) = result { + tracing::warn!(error = ?e, "Failed to add other quotes in background for opportunity {}", opportunity_id); + } + } + }); // Wait to make sure searchers had enough time to submit bids sleep(BID_COLLECTION_TIME).await; diff --git a/auction-server/src/opportunity/service/mod.rs b/auction-server/src/opportunity/service/mod.rs index c89ce169b..c54b0baed 100644 --- a/auction-server/src/opportunity/service/mod.rs +++ b/auction-server/src/opportunity/service/mod.rs @@ -19,6 +19,7 @@ use { }, }, arc_swap::ArcSwap, + jupiter_swap_api_client::JupiterUltraSwapApiClient, mockall_double::double, solana_client::{ nonblocking::rpc_client::RpcClient, @@ -100,6 +101,7 @@ pub struct ConfigSvm { pub accepted_token_programs: Vec, pub ordered_fee_tokens: Vec, pub auction_service_container: AuctionServiceContainer, + pub jupiter_ultra_client: Option, } impl ConfigSvm { @@ -124,6 +126,11 @@ impl ConfigSvm { .clone(), ordered_fee_tokens: chain_store.config.ordered_fee_tokens.clone(), auction_service_container: AuctionServiceContainer::new(), + jupiter_ultra_client: chain_store + .config + .jupiter_ultra_url + .as_ref() + .map(|url| JupiterUltraSwapApiClient::new(url.to_string())), }, ) }) @@ -188,6 +195,7 @@ pub mod tests { accepted_token_programs: vec![], ordered_fee_tokens: vec![], auction_service_container: AuctionServiceContainer::new(), + jupiter_ultra_client: None, }; let mut chains_svm = HashMap::new(); diff --git a/integration.py b/integration.py index 30ef71775..e850a7b81 100644 --- a/integration.py +++ b/integration.py @@ -28,6 +28,7 @@ def main(): - TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA - TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb ordered_fee_tokens: [] + jupiter_ultra_url: https://ultra-api.jup.ag ''' with open('auction-server/config.yaml', 'w') as f: f.write(template)