Implement hybrid quote/routing per ADR (contracts, indexer, and/or client) #75

Closed
opened 2026-04-09 03:24:01 +00:00 by PlasticDigits · 7 comments
PlasticDigits commented 2026-04-09 03:24:01 +00:00 (Migrated from gitlab.com)

Type

missing-implementation — blocked on ADR

Evidence

  • route_solver.rs; pair/router simulation — see #64

Dependencies

Acceptance criteria

  • Matches ADR; regression tests updated

Epic

#59

## Type **missing-implementation** — blocked on ADR ## Evidence - `route_solver.rs`; pair/router simulation — see #64 ## Dependencies - **#64** (and optionally #65) ## Acceptance criteria - [ ] Matches ADR; regression tests updated ## Epic #59
PlasticDigits commented 2026-04-09 03:24:01 +00:00 (Migrated from gitlab.com)

marked this issue as related to #59

marked this issue as related to #59
PlasticDigits commented 2026-04-09 03:24:02 +00:00 (Migrated from gitlab.com)

marked this issue as related to #64

marked this issue as related to #64
PlasticDigits commented 2026-04-13 04:48:14 +00:00 (Migrated from gitlab.com)

Implemented hybrid-aware routing via POST /api/v1/route/solve: clients send hybrid_by_hop aligned with BFS hops; the indexer merges terra_swap.hybrid into router_operations and runs LCD simulate_swap_operations when ROUTER_ADDRESS and amount_in are set. GET remains pool-only. ADR 0001, docs/limit-orders.md, indexer invariants, and audit L8 were updated; integration tests in indexer/tests/api_route_solve.rs cover merge + LCD mock. The dApp uses postRouteSolve for direct CW20 estimates when a book leg is enabled (falls back to pool-only pair sim if the indexer is unavailable). @brouie please verify against staging/local indexer + LCD.

Implemented hybrid-aware routing via **POST /api/v1/route/solve**: clients send `hybrid_by_hop` aligned with BFS hops; the indexer merges `terra_swap.hybrid` into `router_operations` and runs LCD `simulate_swap_operations` when `ROUTER_ADDRESS` and `amount_in` are set. GET remains pool-only. ADR 0001, `docs/limit-orders.md`, indexer invariants, and audit L8 were updated; integration tests in `indexer/tests/api_route_solve.rs` cover merge + LCD mock. The dApp uses `postRouteSolve` for direct CW20 estimates when a book leg is enabled (falls back to pool-only pair sim if the indexer is unavailable). @brouie please verify against staging/local indexer + LCD.
PlasticDigits commented 2026-04-13 04:48:48 +00:00 (Migrated from gitlab.com)

mentioned in issue #59

mentioned in issue #59
Brouie commented 2026-04-20 06:35:05 +00:00 (Migrated from gitlab.com)

@PlasticDigits Code-level verification on current main:

Indexer side:

  • indexer/src/api/mod.rs line 351 registers POST /api/v1/route/solve route
  • indexer/src/api/route_solver.rs implements the handler with hybrid_by_hop merge logic (lines 41, 49, 170, 213-221), including length mismatch validation
  • Integration tests at indexer/tests/api_route_solve.rs (merge + LCD mock coverage)
  • GET remains pool-only (hybrid: null) as designed

Frontend side:

  • frontend-dapp/src/services/indexer/client.ts line 312 (GET) and line 315 (postRouteSolve POST)
  • Vitest at frontend-dapp/src/services/indexer/tests/client.test.ts lines 59-83

ADR + docs:

  • docs/adr/0001-hybrid-quoting-and-routing.md present
  • docs/limit-orders.md updated with the hybrid flow

Full ADR 0001 implementation in place. Holding close until I run against staging/local indexer + LCD and verify hybrid estimates match expected book+pool math. Will update once verified live.

@PlasticDigits Code-level verification on current main: **Indexer side:** - indexer/src/api/mod.rs line 351 registers POST /api/v1/route/solve route - indexer/src/api/route_solver.rs implements the handler with hybrid_by_hop merge logic (lines 41, 49, 170, 213-221), including length mismatch validation - Integration tests at indexer/tests/api_route_solve.rs (merge + LCD mock coverage) - GET remains pool-only (hybrid: null) as designed **Frontend side:** - frontend-dapp/src/services/indexer/client.ts line 312 (GET) and line 315 (postRouteSolve POST) - Vitest at frontend-dapp/src/services/indexer/__tests__/client.test.ts lines 59-83 **ADR + docs:** - docs/adr/0001-hybrid-quoting-and-routing.md present - docs/limit-orders.md updated with the hybrid flow Full ADR 0001 implementation in place. Holding close until I run against staging/local indexer + LCD and verify hybrid estimates match expected book+pool math. Will update once verified live.
Brouie commented 2026-04-20 06:53:58 +00:00 (Migrated from gitlab.com)

mentioned in issue #86

mentioned in issue #86
Brouie commented 2026-04-20 08:54:35 +00:00 (Migrated from gitlab.com)

@PlasticDigits Live verification complete on current main. Stack: LocalTerra + Postgres (:5433) + indexer (:3001, catching up past 1.63M blocks) with 23 deployed pairs.

Test cases

1. POST with hybrid_by_hop=null (pool-only):

{
  "estimated_amount_out": "96174419",
  "hops": [{...}],
  "router_operations": [{"terra_swap": {..., "hybrid": null}}]
}

LCD simulate_swap_operations ran (ROUTER_ADDRESS configured + amount_in provided), returning 96174419 for 1M offer. hybrid:null as designed.

2. POST with explicit hybrid_by_hop=[null]: Same result -- hybrid:null, estimated_out 96174419. Confirms explicit null hops are merged correctly.

3. POST with hybrid_by_hop=[] (length mismatch):

HTTP 400: 'hybrid_by_hop length 0 does not match hop count 1'

Clear validation error per route_solver.rs line 217-221.

4. GET /route/solve (pool-only by contract):

{ "estimated_amount_out": null, "router_operations": [{"terra_swap": {..., "hybrid": null}}] }

hybrid:null, estimated_out null (GET doesn't run LCD sim -- ADR 0001).

All expected behaviors verified. Hybrid merge logic, length validation, GET vs POST separation working correctly. Closing.

@PlasticDigits Live verification complete on current main. Stack: LocalTerra + Postgres (:5433) + indexer (:3001, catching up past 1.63M blocks) with 23 deployed pairs. ## Test cases **1. POST with hybrid_by_hop=null (pool-only):** ``` { "estimated_amount_out": "96174419", "hops": [{...}], "router_operations": [{"terra_swap": {..., "hybrid": null}}] } ``` LCD simulate_swap_operations ran (ROUTER_ADDRESS configured + amount_in provided), returning 96174419 for 1M offer. hybrid:null as designed. **2. POST with explicit hybrid_by_hop=[null]:** Same result -- hybrid:null, estimated_out 96174419. Confirms explicit null hops are merged correctly. **3. POST with hybrid_by_hop=[] (length mismatch):** ``` HTTP 400: 'hybrid_by_hop length 0 does not match hop count 1' ``` Clear validation error per route_solver.rs line 217-221. **4. GET /route/solve (pool-only by contract):** ``` { "estimated_amount_out": null, "router_operations": [{"terra_swap": {..., "hybrid": null}}] } ``` hybrid:null, estimated_out null (GET doesn't run LCD sim -- ADR 0001). All expected behaviors verified. Hybrid merge logic, length validation, GET vs POST separation working correctly. Closing.
Brouie (Migrated from gitlab.com) closed this issue 2026-04-20 08:54:40 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
code/cl8y-dex-terraclassic#75
No description provided.