Всередині найшвидшого свопу Stellar: мульти-маршрутна оцінка
Як Shadow Pocket оцінює маршрути ордербуку та AMM-пулів паралельно, щоб знайти найкращий курс обміну на Stellar, оновлюючи його щоледжера.
Більшість DEX-інтерфейсів на Stellar обирають один маршрут для вашого свопу. Вони перевіряють ордербук, можливо, дивляться на пул ліквідності й видають число. Shadow Pocket робить принципово інше — оцінює всі можливі маршрути паралельно та відправляє 100% вашої угоди через той, який повертає максимальний вихід.
Проблема одномаршрутних свопів
Коли ви обмінюєте Актив A на Актив B у Stellar, існує кілька можливих майданчиків виконання:
- Ордербук SDEX — лімітні ордери, розміщені трейдерами та маркет-мейкерами.
- AMM-пули ліквідності — пули з постійним добутком, де ціна визначається алгоритмічно.
- Крос-пейр шляхи — маршрути A → C → B, що використовують проміжні активи як мости.
Одномаршрутний підхід обирає один і сподівається на краще. Але ліквідність зміщується з кожним закриттям леджера (приблизно кожні 5 секунд). Ордербук може мати чудову ціну на малій глибині, але розвалюватися на великих обсягах. Пул може пропонувати кращі курси для великих свопів завдяки безперервній кривій ліквідності. А іноді крос-пейр шлях через XLM або USDC б'є обидва прямих варіанти.
Помилка у виборі коштує користувачу реальних грошей.
Як працює паралельна оцінка
Бекенд Shadow Pocket оцінює всі доступні маршрути незалежно для кожного запиту котирування. Ось процес:
- Виявлення — система визначає всі життєздатні маршрути: прямий ордербук, кожен релевантний AMM-пул та крос-пейр шляхи через основні мостові активи.
- Паралельна симуляція — кожен маршрут симулюється незалежно з точною сумою введення. Симуляція ордербуку проходить по книзі, заповнюючи ордери на кожному ціновому рівні. Симуляція пулів використовує формулу постійного добутку. Симуляція шляхів ланцюжком зв'язує множинні операції.
- Порівняння виходу — кожен маршрут повертає симульовану суму виходу з урахуванням проковзування при конкретному розмірі введення.
- Вибір переможця — маршрут із найбільшим виходом обирається. Без розділення, без часткового заповнення — 100% угоди йде через найкращий шлях.
Бекенд завжди повертає результат ордербуку першим у відповіді, за ним ідуть маршрути пулів, щоб фронтенд міг відображати інформацію про ліквідність за маршрутами, хоча виконується лише найкращий.
Чому 100% в один маршрут (а не розділення)
Розділення маршрутів звучить розумно в теорії — відправити частину угоди через ордербук і частину через пул, щоб мінімізувати ціновий вплив. На практиці, у Stellar, це вносить складність, яка рідко окупається:
- Комісії транзакцій мізерні — немає причин оптимізації газу для батчингу.
- Атомарне виконання — транзакції Stellar або повністю виконуються, або повністю відкочуються. Розділення додає операції, збільшуючи шанс часткового збою.
- Тайминг леджера — ціни змінюються кожні 5 секунд. На момент виконання розділеного ордера оптимальне співвідношення розділення може зміститися.
Для переважної більшості обсягів угод на Stellar відправка 100% через єдиний найкращий маршрут перевершує будь-яку стратегію розділення. Математика проста: симулюй усі варіанти, обери переможця.
Оновлення по леджеру через SSE
Котирування свопів швидко застарівають. Shadow Pocket підтримує їх актуальність за допомогою Server-Sent Events (SSE), підключених до потоку леджерів Stellar:
- Фронтенд відкриває SSE-з'єднання до ендпоінту
/ledgers?cursor=now. - Щоразу, коли закривається новий леджер (~5 секунд), спрацьовує подія.
- Фронтенд застосовує debounce і запускає новий запит котирування.
- Бекенд заново оцінює всі маршрути з поточним станом ордербуку та пулів.
- UI оновлює відображуваний курс, суму виходу та розбивку за маршрутами.
Це означає, що користувач завжди бачить котирування, яке відображає поточний стан леджера — а не щось 30-секундної давності, що могло суттєво змінитися.
Деталі реалізації
Кілька інженерних рішень, що забезпечують надійну роботу:
Керування debounce-таймером — таймер debounce оновлення котирування має коректно обнулятися в callback setTimeout. Якщо посилання на таймер застаріло, UI може застрягти у стані завантаження назавжди.
Незалежність стану завантаження — індикатор завантаження котирування свопу скидається поза перевіркою abort signal. Це запобігає дедлоку, за якого скасований запит назавжди залишає UI у стані завантаження.
Обхід Service Worker — content type text/event-stream для SSE виключений з логіки precache Service Worker. Без цього обходу Service Worker перехоплював би потокове з'єднання та ламав оновлення в реальному часі.
Незалежна оцінка маршрутів — бекенд не використовує жадібний підхід (спершу перевірити ордербук, потім заповнити залишок із пулів). Кожен маршрут оцінюється для повної суми незалежно, забезпечуючи чесне порівняння.
Результат
Користувач бачить інтерфейс обміну, що оновлюється в реальному часі, показує точно, яким маршрутом піде його угода, і гарантує найкращий доступний курс по всіх майданчиках виконання на Stellar. Без ручного вибору маршруту, без застарілих котирувань, без вгадування з розділенням.
Швидкі свопи — це не про сиру швидкість. Це про те, щоб завжди мати найсвіжішу, найточнішу інформацію, коли натискаєш «Обміняти».