@switch-win/sdk 1.2.9 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/GASLESS.md +434 -0
  3. package/LIMIT-ORDERS.md +213 -205
  4. package/README.md +134 -105
  5. package/ROBINHOOD.md +201 -198
  6. package/abi/GaslessSwitchV2ABI.json +1095 -0
  7. package/dist/constants.d.ts +276 -0
  8. package/dist/constants.d.ts.map +1 -0
  9. package/dist/constants.js +403 -0
  10. package/dist/constants.js.map +1 -0
  11. package/dist/gasless-client.d.ts +82 -0
  12. package/dist/gasless-client.d.ts.map +1 -0
  13. package/dist/gasless-client.js +467 -0
  14. package/dist/gasless-client.js.map +1 -0
  15. package/dist/gasless-index.d.ts +5 -0
  16. package/dist/gasless-index.d.ts.map +1 -0
  17. package/dist/gasless-index.js +5 -0
  18. package/dist/gasless-index.js.map +1 -0
  19. package/dist/gasless-operators.d.ts +32 -0
  20. package/dist/gasless-operators.d.ts.map +1 -0
  21. package/dist/gasless-operators.js +132 -0
  22. package/dist/gasless-operators.js.map +1 -0
  23. package/dist/gasless-store.d.ts +18 -0
  24. package/dist/gasless-store.d.ts.map +1 -0
  25. package/dist/gasless-store.js +83 -0
  26. package/dist/gasless-store.js.map +1 -0
  27. package/dist/gasless-types.d.ts +222 -0
  28. package/dist/gasless-types.d.ts.map +1 -0
  29. package/dist/gasless-types.js +2 -0
  30. package/dist/gasless-types.js.map +1 -0
  31. package/dist/gasless.d.ts +135 -0
  32. package/dist/gasless.d.ts.map +1 -0
  33. package/dist/gasless.js +513 -0
  34. package/dist/gasless.js.map +1 -0
  35. package/dist/index.d.ts +29 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +30 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/limit-orders.d.ts +440 -0
  40. package/dist/limit-orders.d.ts.map +1 -0
  41. package/dist/limit-orders.js +387 -0
  42. package/dist/limit-orders.js.map +1 -0
  43. package/dist/networks/index.d.ts +3 -0
  44. package/dist/networks/index.d.ts.map +1 -0
  45. package/dist/networks/index.js +2 -0
  46. package/dist/networks/index.js.map +1 -0
  47. package/dist/networks/robinhood.d.ts +536 -0
  48. package/dist/networks/robinhood.d.ts.map +1 -0
  49. package/dist/networks/robinhood.js +489 -0
  50. package/dist/networks/robinhood.js.map +1 -0
  51. package/dist/types.d.ts +436 -0
  52. package/dist/types.d.ts.map +1 -0
  53. package/dist/types.js +19 -0
  54. package/dist/types.js.map +1 -0
  55. package/examples/gasless-nextjs-proxy.ts +87 -0
  56. package/examples/gasless-operator.ts +76 -0
  57. package/examples/gasless-swap.ts +173 -0
  58. package/examples/limit-order-ethers.ts +195 -0
  59. package/examples/nextjs-proxy.ts +82 -0
  60. package/examples/react-hooks.tsx +396 -0
  61. package/examples/swap-ethers.ts +209 -0
  62. package/examples/swap-web3py.py +267 -0
  63. package/package.json +53 -12
  64. package/src/constants.ts +184 -182
  65. package/src/gasless-client.ts +824 -0
  66. package/src/gasless-index.ts +4 -0
  67. package/src/gasless-operators.ts +227 -0
  68. package/src/gasless-store.ts +137 -0
  69. package/src/gasless-types.ts +262 -0
  70. package/src/gasless.ts +756 -0
  71. package/src/index.ts +69 -63
  72. package/src/limit-orders.ts +206 -195
  73. package/src/types.ts +80 -55
package/README.md CHANGED
@@ -5,9 +5,20 @@
5
5
 
6
6
  > **Official integration kit for the Switch DEX Aggregator on PulseChain and Robinhood Chain**
7
7
 
8
- Everything partners need to integrate Switch swaps and limit orders — API docs, TypeScript types, ABIs, constants, and ready-to-use examples.
8
+ Everything partners need to integrate Switch swaps, limit orders, and GaslessSwitch — API docs, TypeScript types, ABIs, constants, and ready-to-use examples.
9
9
 
10
- **Swap API:** `https://quote.switch.win`  |  **Swap chains:** PulseChain (369), Robinhood Chain (4663)  |  **Limit orders:** PulseChain and Robinhood Chain
10
+ **Version 1.3.1 clarifies gasless output display and order signing.** GaslessSwitch
11
+ V2 helpers and examples were introduced in 1.3.0. See [GASLESS.md](GASLESS.md)
12
+ for the checked quote, approval, signing, submission, and recovery flow.
13
+
14
+ **Gasless fee policy:** Every GaslessSwitch settlement charges a fixed
15
+ **0.1% protocol fee (10 bps)**. Integrators cannot customize or waive this fee.
16
+ The operator can also receive up to **0.05%**, including settlement gas, under
17
+ the separate on-chain payout cap. If you do not want to offer the fixed gasless
18
+ fee policy, **offer regular swaps only** in your integration. See
19
+ [regular-only integration](GASLESS.md#regular-only-integration) for the steps.
20
+
21
+ **Swap API:** `https://quote.switch.win`  |  **Swap chains:** PulseChain (369), Robinhood Chain (4663)  |  **Limit orders:** PulseChain and Robinhood Chain
11
22
 
12
23
  ---
13
24
 
@@ -56,6 +67,24 @@ Switch-SDK/
56
67
 
57
68
  8. [Limit Orders](#limit-orders) — full guide in [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)
58
69
 
70
+ ### Gasless swaps
71
+
72
+ - [GaslessSwitch V2 integration](GASLESS.md) — settlement gas eligibility, tax
73
+ tokens, 0.1% protocol fee, 0.05% total operator cap, native wrapping,
74
+ durable pending orders, and settlement links.
75
+ - [Browser flow example](examples/gasless-swap.ts),
76
+ [backend proxy](examples/gasless-nextjs-proxy.ts), and
77
+ [operator execution validation](examples/gasless-operator.ts).
78
+ - Import the dedicated flow from `@switch-win/sdk/gasless`; ordinary
79
+ `buildLimitOrder` / LO signing and approval helpers target a different contract.
80
+ - Show `prepared.expectedOutput` as the main output estimate, matching Regular.
81
+ Show `prepared.minAmountOut` separately as minimum received and use it for
82
+ order signing. See [display versus signing](GASLESS.md#expected-output-versus-signed-minimum).
83
+ - [API eligibility and fallback](GASLESS.md#api-eligibility-response):
84
+ `client.quote()` exposes `decision.eligibility` for both accepted and rejected
85
+ quotes, including PLS/ETH payout, gas reserves, freshness and rejection reason.
86
+ Only `decision.eligible` enables signing; a finished simulation alone does not.
87
+
59
88
  ### General
60
89
 
61
90
  9. [Constants & Addresses](#constants--addresses)
@@ -121,12 +150,12 @@ For a production integration with tax token handling, adapter filtering, and fee
121
150
  ### Robinhood Chain
122
151
 
123
152
  Robinhood uses the same quote endpoint; set `network=robinhood`. The dedicated
124
- module includes canonical chain metadata, deployed Switch contracts, vetted
125
- routing hubs, and a URL builder that always includes the correct network.
126
- The production router exposes nineteen adapters across Uniswap, SwapHood,
127
- Up33, Sheriff, Aeon, Catnip, PancakeSwap, RobinSwap, SushiSwap, GIGA, Flap,
128
- Ramses, and Switch limit orders. `ROBINHOOD_ADAPTERS` contains a typed snapshot;
129
- fetch `/swap/adapters?network=robinhood` when runtime freshness matters.
153
+ module includes canonical chain metadata, deployed Switch contracts, vetted
154
+ routing hubs, and a URL builder that always includes the correct network.
155
+ The production router exposes nineteen adapters across Uniswap, SwapHood,
156
+ Up33, Sheriff, Aeon, Catnip, PancakeSwap, RobinSwap, SushiSwap, GIGA, Flap,
157
+ Ramses, and Switch limit orders. `ROBINHOOD_ADAPTERS` contains a typed snapshot;
158
+ fetch `/swap/adapters?network=robinhood` when runtime freshness matters.
130
159
 
131
160
  For network configuration, deployed addresses, tax handling, execution, and
132
161
  the complete frontend token list, see [`ROBINHOOD.md`](ROBINHOOD.md).
@@ -143,7 +172,7 @@ const url = buildRobinhoodQuoteUrl({
143
172
  to: ROBINHOOD_TOKENS.USDG.address,
144
173
  amount: 1_000_000_000_000_000n,
145
174
  sender: walletAddress,
146
- slippage: 100, // 1%, matching the Robinhood frontend default
175
+ slippage: 100, // 1%, matching the Robinhood frontend default
147
176
  });
148
177
 
149
178
  const response = await fetch(url, {
@@ -153,8 +182,8 @@ const response = await fetch(url, {
153
182
 
154
183
  Always approve `ROBINHOOD_SWITCH_CONTRACTS.router` for ERC-20 input, but submit
155
184
  the transaction to `quote.tx.to` so integrations remain safe across router
156
- upgrades. Robinhood limit-order deployment constants and EIP-712 domain values
157
- are exported from `src/networks/robinhood.ts`.
185
+ upgrades. Robinhood limit-order deployment constants and EIP-712 domain values
186
+ are exported from `src/networks/robinhood.ts`.
158
187
 
159
188
  ---
160
189
 
@@ -217,7 +246,7 @@ For the most accurate swap quotes — especially with tax tokens — follow this
217
246
  │ → Detect transfer taxes on both tokens │
218
247
  │ → Determine feeOnOutput based on tax results + your fee strategy │
219
248
  ├────────────────────────────────────────────────────────────────────────────┤
220
- │ Step 3: GET /swap/quote?...&feeOnOutput=true/false&adapters=0,3,7 │
249
+ │ Step 3: GET /swap/quote?...&feeOnOutput=true/false&adapters=0,3,7 │
221
250
  │ → Pass feeOnOutput + adapter filter for an exact expectedOutputAmount │
222
251
  │ → Display quote and execute swap │
223
252
  └────────────────────────────────────────────────────────────────────────────┘
@@ -230,7 +259,7 @@ The SwitchRouter contract supports two fee modes:
230
259
  - **`feeOnOutput=true`** — The full input is routed through DEX pools, then the protocol fee is deducted from the output.
231
260
  - **`feeOnOutput=false`** — The protocol fee is deducted from the input *before* routing, and the reduced amount enters the DEX pools.
232
261
 
233
- Due to AMM curve concavity (Jensen's inequality), `AMM(amount × 0.999) ≠ AMM(amount) × 0.999`. This means the backend **must know which mode you'll use** to compute an exact `expectedOutputAmount`. If the backend routes as `feeOnOutput=true` but you send the `tx` (fee on input), the expected output will be slightly over-estimated (always in the user's favor — they receive more than quoted).
262
+ Due to AMM curve concavity (Jensen's inequality), `AMM(amount × 0.999) ≠ AMM(amount) × 0.999`. This means the backend **must know which mode you'll use** to compute an exact `expectedOutputAmount`. If the backend routes as `feeOnOutput=true` but you send the `tx` (fee on input), the expected output will be slightly over-estimated (always in the user's favor — they receive more than quoted).
234
263
 
235
264
  By passing `feeOnOutput` explicitly, the backend adjusts routing to match the actual on-chain execution, giving you a spot-on estimate.
236
265
 
@@ -407,41 +436,41 @@ curl -H "x-api-key: YOUR_KEY" "https://quote.switch.win/swap/adapters?network=pu
407
436
 
408
437
  ```json
409
438
  {
410
- "adapters": [
411
- { "index": 0, "name": "UniswapV2", "address": "0x971eeb4a5080834f7df2b9d7a11dfbeaa7bc187e" },
412
- { "index": 1, "name": "SushiV2", "address": "0x5ef53d5eb4f011d9bed35e7112945f0dc96b3822" },
413
- { "index": 2, "name": "PulseXV1", "address": "0x6f5ccfca1f1d3fff70202463df05573cc1668cb6" },
414
- { "index": 3, "name": "PulseXV2", "address": "0x393e382520b93b8f662dc76295000930c06d689f" },
415
- { "index": 4, "name": "9inchV2", "address": "0x4810beadf72a1f297f4e5ff71424d98b2bf4441e" },
416
- { "index": 5, "name": "DextopV2", "address": "0xd096faccdd475f2c86f3c668958fcd435e32bdc2" },
417
- { "index": 6, "name": "9mmV2", "address": "0x67a25e62309e39e7b46f3b6f868bcf336c4ce8e2" },
418
- { "index": 7, "name": "UniswapV3", "address": "0xc39cb531f71059fd427a63bf8a2f4b822d6b9b02" },
419
- { "index": 8, "name": "9mmV3", "address": "0x32a63187814d6b81badc6c13dc9d46a8050fad12" },
420
- { "index": 9, "name": "9inchV3", "address": "0xe46ef88400997a84336e1a3c14d2528da90572b6" },
421
- { "index": 10, "name": "pDexV3", "address": "0xb718836aca6ddb8745a0cecc687467dda648bdf2" },
422
- { "index": 11, "name": "DextopV3", "address": "0x8b8024ca2a4fdb34697620b80320e76c41a67124" },
423
- { "index": 12, "name": "Phux", "address": "0x98ae0249da42f789b9745b248d346a727f37e937" },
424
- { "index": 13, "name": "Tide", "address": "0xd9a17779db4173d099064e26a5d5916717dacf5" },
425
- { "index": 14, "name": "PulseXStable", "address": "0xf3b9742c859d089b6a2e3b3228dabb2c842b57d2" },
426
- { "index": 15, "name": "AgoraX", "address": "0x79ea0ec76b510d08bf4ca9a4a53a1f9f80ea1697" },
427
- { "index": 16, "name": "JoltOTC", "address": "0x033372eb8df4baad260e20d716742a825f1f113f" },
428
- { "index": 17, "name": "SwitchLimitOrder", "address": "0x7b9761484301a8fe4a2ba47194f7646eef8e1cdd" },
429
- { "index": 18, "name": "SwitchX", "address": "0xf8744452598883792f235b92452127f4a8587db3" },
430
- { "index": 19, "name": "LibertySwapV3", "address": "0xba24bb413ab32f02073385850907ebcf0a357e70" },
431
- { "index": 20, "name": "FinvestaV3", "address": "0x012c44d0c465819ef3ceac208e0c1b272087a8b4" },
432
- { "index": 21, "name": "TrenchV2", "address": "0xaf48bb0936d9fa522650236917321d89978a8591" },
433
- { "index": 22, "name": "TrenchV3", "address": "0x01957ec5fcc079f1bb388b9f261278dac42cf2e9" }
434
- ]
435
- }
436
- ```
437
-
438
- Finvesta is a Liberty-style V3 venue with fee tiers `100`, `500`, `2500`, and
439
- `10000`. It can be selected for normal routes, but it is not transfer-tax safe.
440
- Trench V2 is a direct-pair adapter with dynamic pair-specific fees and is
441
- eligible for transfer-tax-sensitive hops. Trench V3 uses direct pool simulation
442
- across fee tiers `100`, `500`, `2500`, `3000`, and `10000`; like other V3
443
- callback adapters, it is not transfer-tax safe.
444
- Always treat the live `/swap/adapters` response as the runtime source of truth.
439
+ "adapters": [
440
+ { "index": 0, "name": "UniswapV2", "address": "0x971eeb4a5080834f7df2b9d7a11dfbeaa7bc187e" },
441
+ { "index": 1, "name": "SushiV2", "address": "0x5ef53d5eb4f011d9bed35e7112945f0dc96b3822" },
442
+ { "index": 2, "name": "PulseXV1", "address": "0x6f5ccfca1f1d3fff70202463df05573cc1668cb6" },
443
+ { "index": 3, "name": "PulseXV2", "address": "0x393e382520b93b8f662dc76295000930c06d689f" },
444
+ { "index": 4, "name": "9inchV2", "address": "0x4810beadf72a1f297f4e5ff71424d98b2bf4441e" },
445
+ { "index": 5, "name": "DextopV2", "address": "0xd096faccdd475f2c86f3c668958fcd435e32bdc2" },
446
+ { "index": 6, "name": "9mmV2", "address": "0x67a25e62309e39e7b46f3b6f868bcf336c4ce8e2" },
447
+ { "index": 7, "name": "UniswapV3", "address": "0xc39cb531f71059fd427a63bf8a2f4b822d6b9b02" },
448
+ { "index": 8, "name": "9mmV3", "address": "0x32a63187814d6b81badc6c13dc9d46a8050fad12" },
449
+ { "index": 9, "name": "9inchV3", "address": "0xe46ef88400997a84336e1a3c14d2528da90572b6" },
450
+ { "index": 10, "name": "pDexV3", "address": "0xb718836aca6ddb8745a0cecc687467dda648bdf2" },
451
+ { "index": 11, "name": "DextopV3", "address": "0x8b8024ca2a4fdb34697620b80320e76c41a67124" },
452
+ { "index": 12, "name": "Phux", "address": "0x98ae0249da42f789b9745b248d346a727f37e937" },
453
+ { "index": 13, "name": "Tide", "address": "0xd9a17779db4173d099064e26a5d5916717dacf5" },
454
+ { "index": 14, "name": "PulseXStable", "address": "0xf3b9742c859d089b6a2e3b3228dabb2c842b57d2" },
455
+ { "index": 15, "name": "AgoraX", "address": "0x79ea0ec76b510d08bf4ca9a4a53a1f9f80ea1697" },
456
+ { "index": 16, "name": "JoltOTC", "address": "0x033372eb8df4baad260e20d716742a825f1f113f" },
457
+ { "index": 17, "name": "SwitchLimitOrder", "address": "0x7b9761484301a8fe4a2ba47194f7646eef8e1cdd" },
458
+ { "index": 18, "name": "SwitchX", "address": "0xf8744452598883792f235b92452127f4a8587db3" },
459
+ { "index": 19, "name": "LibertySwapV3", "address": "0xba24bb413ab32f02073385850907ebcf0a357e70" },
460
+ { "index": 20, "name": "FinvestaV3", "address": "0x012c44d0c465819ef3ceac208e0c1b272087a8b4" },
461
+ { "index": 21, "name": "TrenchV2", "address": "0xaf48bb0936d9fa522650236917321d89978a8591" },
462
+ { "index": 22, "name": "TrenchV3", "address": "0x01957ec5fcc079f1bb388b9f261278dac42cf2e9" }
463
+ ]
464
+ }
465
+ ```
466
+
467
+ Finvesta is a Liberty-style V3 venue with fee tiers `100`, `500`, `2500`, and
468
+ `10000`. It can be selected for normal routes, but it is not transfer-tax safe.
469
+ Trench V2 is a direct-pair adapter with dynamic pair-specific fees and is
470
+ eligible for transfer-tax-sensitive hops. Trench V3 uses direct pool simulation
471
+ across fee tiers `100`, `500`, `2500`, `3000`, and `10000`; like other V3
472
+ callback adapters, it is not transfer-tax safe.
473
+ Always treat the live `/swap/adapters` response as the runtime source of truth.
445
474
 
446
475
  #### Using adapter indices to filter routing
447
476
 
@@ -451,8 +480,8 @@ Pass adapter indices as a comma-separated `adapters` param to `/swap/quote`:
451
480
  # Route only through PulseXV2 (index 3):
452
481
  GET /swap/quote?...&adapters=3
453
482
 
454
- # Route through PulseXV2 + UniswapV3:
455
- GET /swap/quote?...&adapters=3,7
483
+ # Route through PulseXV2 + UniswapV3:
484
+ GET /swap/quote?...&adapters=3,7
456
485
 
457
486
  # Exclude nothing (default — omit the param):
458
487
  GET /swap/quote?...
@@ -598,17 +627,17 @@ Returns the optimal split-route for a swap and (optionally) a ready-to-send tran
598
627
  | `sender` | No* | address | — | Sender wallet address. **Required to receive `tx` calldata in the response.** |
599
628
  | `receiver` | No | address | `sender` | Custom recipient address. If omitted, output tokens are sent to `sender`. |
600
629
  | `slippage` | No | integer | `50` | Slippage tolerance in **basis points** (bps). `50` = 0.50 %. Range: `0`–`5000`. |
601
- | `fee` | No | integer | `10` | Protocol fee in basis points (0.10 %). Range: `10`–`100`. Defaults to `10` if omitted. |
630
+ | `fee` | No | integer | `10` | Regular swap protocol fee in basis points. Range: `10`–`100`; defaults to `10`. Gasless quotes require exactly `10` for the fixed 0.1% settlement fee; see [gasless fee policy](GASLESS.md#fixed-gasless-fee). |
602
631
  | `partnerAddress` | No | address | `0x0…0` | Your partner wallet to receive 50 % of collected fees. Omit or pass `0x0` for no partner. |
603
632
  | `feeOnOutput` | No | string | `"false"` | Controls fee mode. `"true"` = fee deducted from output. `"false"` = fee deducted from input (default). Affects `expectedOutputAmount` accuracy — see [Swap Integration Flow](#swap-integration-flow). |
604
- | `adapters` | No | string | — | Comma-separated adapter indices to restrict routing (e.g. `"3"` for PulseXV2 only, `"3,7"` for PulseXV2 + UniswapV3). Get available indices from [List Adapters](#list-adapters). |
633
+ | `adapters` | No | string | — | Comma-separated adapter indices to restrict routing (e.g. `"3"` for PulseXV2 only, `"3,7"` for PulseXV2 + UniswapV3). Get available indices from [List Adapters](#list-adapters). |
605
634
 
606
635
  > \* If `sender` is omitted, the response will still contain routing data, `minAmountOut`, and tax info, but the `tx` object will be absent. This is useful for **showing estimated swap output before the user connects their wallet** — you can display prices, routes, and tax warnings without requiring a wallet connection. Once the user connects, re-fetch the quote with `sender` to get the ready-to-send `tx` object.
607
636
 
608
637
  #### Example Request
609
638
 
610
639
  ```
611
- GET /swap/quote?network=pulsechain&from=0xA1077a294dDE1B09bB078844df40758a5D0f9a27&to=0x95B303987A60C71504D99Aa1b13B4DA07b0790ab&amount=1000000000000000000&sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&slippage=100&fee=10&partnerAddress=0xYourPartnerWallet&feeOnOutput=true
640
+ GET /swap/quote?network=pulsechain&from=0xA1077a294dDE1B09bB078844df40758a5D0f9a27&to=0x95B303987A60C71504D99Aa1b13B4DA07b0790ab&amount=1000000000000000000&sender=0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045&slippage=100&fee=10&partnerAddress=0xYourPartnerWallet&feeOnOutput=true
612
641
  ```
613
642
 
614
643
  #### Example Response
@@ -680,13 +709,13 @@ GET /swap/quote?network=pulsechain&from=0xA1077a294dDE1B09bB078844df40758a5D0f9a
680
709
  // Transaction object — only present when `sender` is provided
681
710
  // ⚠️ Always use tx.to from this response — do NOT hardcode the router address
682
711
  "tx": {
683
- "to": "0x2dFc8B6e13fF7F04e37Ef97006084805D65a6F19",
712
+ "to": "0x2dFc8B6e13fF7F04e37Ef97006084805D65a6F19",
684
713
  "data": "0x...", // ABI-encoded goSwitch() calldata with feeOnOutput = false
685
714
  "value": "0" // "0" for ERC-20 input; amountIn for native-currency input
686
715
  },
687
716
  // Same swap but with fee taken from the output token instead
688
717
  "txFeeOnOutput": {
689
- "to": "0x2dFc8B6e13fF7F04e37Ef97006084805D65a6F19",
718
+ "to": "0x2dFc8B6e13fF7F04e37Ef97006084805D65a6F19",
690
719
  "data": "0x...", // ABI-encoded goSwitch() calldata with feeOnOutput = true
691
720
  "value": "0"
692
721
  }
@@ -705,11 +734,11 @@ GET /swap/quote?network=pulsechain&from=0xA1077a294dDE1B09bB078844df40758a5D0f9a
705
734
  | `toToken` | `string` | Output token address |
706
735
  | `receiver` | `string?` | Recipient address for output tokens. Same as `sender` unless a custom `receiver` was specified. |
707
736
  | `totalAmountIn` | `string` | Total input amount in wei |
708
- | `totalAmountOut` | `string` | Quoted route output in wei before the Switch protocol fee and slippage. Protocol-native quoters such as Flap Portal may already include their token-tax effect. |
737
+ | `totalAmountOut` | `string` | Quoted route output in wei before the Switch protocol fee and slippage. Protocol-native quoters such as Flap Portal may already include their token-tax effect. |
709
738
  | `expectedOutputAmount` | `string` | Expected output the user will actually receive, in wei. Accounts for sell tax, protocol fee, and buy tax — but NOT slippage. This is the most accurate value to display as the estimated received amount. When `feeOnOutput` is passed correctly, this is **exact** (matches on-chain execution). |
710
- | `minAmountOut` | `string` | Minimum acceptable output after adapter-specific tax accounting, fee, and slippage. Use the API value directly; do not recompute it by multiplying the reported tax rates. This is encoded in `tx.data` as `_minTotalAmountOut`. |
739
+ | `minAmountOut` | `string` | Minimum acceptable output after adapter-specific tax accounting, fee, and slippage. Use the API value directly; do not recompute it by multiplying the reported tax rates. This is encoded in `tx.data` as `_minTotalAmountOut`. |
711
740
  | `paths` | `SwapPath[]` | Human-readable path descriptions |
712
- | `routeAllocation` | `RouteAllocationPlan` | Human-readable structured route breakdown for display and analytics. It is not a drop-in on-chain ABI value. |
741
+ | `routeAllocation` | `RouteAllocationPlan` | Human-readable structured route breakdown for display and analytics. It is not a drop-in on-chain ABI value. |
713
742
  | `tx` | `SwapTransaction?` | Ready-to-send transaction (fee on input). Only present when `sender` is provided. |
714
743
  | `txFeeOnOutput` | `SwapTransaction?` | Ready-to-send transaction (fee on output). Only present when `sender` is provided. Choose between `tx` and `txFeeOnOutput` at send time. |
715
744
  | `fromTokenTax` | `TokenTaxResponse?` | Transfer tax info for the input token. See [Tax Tokens Deep Dive](#tax-tokens-deep-dive). |
@@ -790,16 +819,16 @@ Present on every quote response as `fromTokenTax` and `toTokenTax`. Reports whet
790
819
 
791
820
  | Field | Type | Description |
792
821
  |---|---|---|
793
- | `adapter` | `string` | Human-readable DEX adapter name (e.g. `"PulseXV2"`) |
794
- | `amountIn` | `string` | Input amount routed through this adapter |
795
- | `amountOut` | `string` | Expected output from this adapter |
796
- | `fee` | `number?` | V3 fee tier or concentrated-liquidity tick-spacing hint; zero when unused |
797
-
798
- Use the API-provided `tx.data` for execution. If you intentionally construct
799
- router or limit-order calldata yourself, each on-chain adapter leg is
800
- `{ adapter, amountIn, fee, data }`; `data` is required and should be `0x` for
801
- adapters that need no payload. The display-oriented `routeAllocation` does not
802
- contain enough information to encode every route family.
822
+ | `adapter` | `string` | Human-readable DEX adapter name (e.g. `"PulseXV2"`) |
823
+ | `amountIn` | `string` | Input amount routed through this adapter |
824
+ | `amountOut` | `string` | Expected output from this adapter |
825
+ | `fee` | `number?` | V3 fee tier or concentrated-liquidity tick-spacing hint; zero when unused |
826
+
827
+ Use the API-provided `tx.data` for execution. If you intentionally construct
828
+ router or limit-order calldata yourself, each on-chain adapter leg is
829
+ `{ adapter, amountIn, fee, data }`; `data` is required and should be `0x` for
830
+ adapters that need no payload. The display-oriented `routeAllocation` does not
831
+ contain enough information to encode every route family.
803
832
 
804
833
  ---
805
834
 
@@ -836,7 +865,7 @@ Errors are returned as JSON with an `error` field:
836
865
  | `"Amount must be greater than 0"` | `amount` is zero or negative |
837
866
  | `"Amount exceeds maximum allowed value"` | `amount` exceeds 10²⁷ (1 billion tokens @ 18 decimals) |
838
867
  | `"Slippage must be a number between 0 and 5000 (basis points)"` | `slippage` out of range |
839
- | `"Fee must be a number between 10 and 100 (basis points). Minimum fee is 0.10%."` | `fee` out of range or below minimum |
868
+ | `"Fee must be a number between 10 and 100 (basis points). Minimum fee is 0.10%."` | `fee` out of range or below minimum |
840
869
  | `"receiver must be a valid Ethereum address (0x + 40 hex chars)"` | Malformed receiver address |
841
870
  | `"partnerAddress must be a valid Ethereum address (0x + 40 hex chars)"` | Malformed partner address |
842
871
  | `"Failed to find route"` | No viable swap path exists, or route computation timed out (30s limit) |
@@ -866,7 +895,7 @@ If the swap transaction reverts on-chain, the SwitchRouter contract returns one
866
895
 
867
896
  Switch supports a **50/50 fee-sharing** model for integration partners:
868
897
 
869
- 1. Set a `fee` (e.g. `10` = 0.10 %, the current minimum) and your `partnerAddress` when calling the API.
898
+ 1. Set a `fee` (e.g. `10` = 0.10 %, the current minimum) and your `partnerAddress` when calling the API.
870
899
  2. The SwitchRouter contract automatically splits collected fees **during the swap**:
871
900
  - **50 %** sent to the protocol
872
901
  - **50 %** sent directly to your `partnerAddress`
@@ -945,15 +974,15 @@ await signer.sendTransaction(chosenTx);
945
974
 
946
975
  ## Limit Orders
947
976
 
948
- Switch Limit Orders let users place **gasless, signed orders** that are filled automatically when market conditions are met — no gas to create, no token deposits, EIP-712 signed.
949
-
950
- **→ Full integration guide: [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)**
951
-
952
- Covers both `pulsechain` and `robinhood`: creating orders, live deployment
953
- discovery, approvals, `feeOnOutput` decision rules, native PLS/ETH flows,
954
- querying, cancellation, API types, and EIP-712 details. Use
955
- `fetchLimitOrderConfig({ network })` at startup and include `network` in every
956
- orderbook request.
977
+ Switch Limit Orders let users place **gasless, signed orders** that are filled automatically when market conditions are met — no gas to create, no token deposits, EIP-712 signed.
978
+
979
+ **→ Full integration guide: [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)**
980
+
981
+ Covers both `pulsechain` and `robinhood`: creating orders, live deployment
982
+ discovery, approvals, `feeOnOutput` decision rules, native PLS/ETH flows,
983
+ querying, cancellation, API types, and EIP-712 details. Use
984
+ `fetchLimitOrderConfig({ network })` at startup and include `network` in every
985
+ orderbook request.
957
986
 
958
987
  ---
959
988
 
@@ -969,34 +998,34 @@ Robinhood constants are available from
969
998
  | Name | Value |
970
999
  |---|---|
971
1000
  | **Chain** | PulseChain (Chain ID `369`); Robinhood Chain uses ID `4663` and network-specific exports |
972
- | **SwitchRouter** (current) | `0x2dFc8B6e13fF7F04e37Ef97006084805D65a6F19` |
973
- | **SwitchRouter** (legacy) | `0x0305fcb5dA680EA6fd1B01A96C1949175B99d406` |
974
- | **SwitchLimitOrder** (V3 — current protected) | `0x2afBf0aB8d958a0227742F7a8BdA00c96372E4D7` |
975
- | **SwitchLimitOrder** (V2 — legacy) | `0x8e3881bdF81Fc0211383B2e576076B654F7aFD86` |
976
- | **SwitchLimitOrder** (V1 — legacy) | `0x0e884072a891b406C0D814907A1E2310fE5F5Deb` |
977
- | **SwitchPLSFlow** (V3 — current protected) | `0x0362177FF2ad25a33a879c881a5055575C63a4cE` |
978
- | **SwitchPLSFlow** (V2 — legacy) | `0xCf5606bdC750d8626Cec32CA2E1BB207968db1D5` |
979
- | **SwitchPLSFlow** (V1 — legacy) | `0x88c9e2C83b6B7c707602e548481e58E920694E64` |
980
- | **Direct-fill quoter** | `0x23A95b0f69c993CFe6180a266A93F7560102e929` |
981
- | **Limit-order adapter** | Index `17`; `0x7B9761484301a8FE4a2BA47194F7646eEF8e1cDd` |
982
- | **LimitOrderAdmin** | `0x9C8B9012AfC0489dE612F7039665212EB88be127` |
983
- | **OperatorAccessRegistry** | `0x7dA1AB04A712479569cCaD783Ca6114b763e36Ad` |
984
- | **Native PLS sentinel** | `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` |
985
- | **WPLS** | `0xA1077a294dDE1B09bB078844df40758a5D0f9a27` |
986
- | **Finvesta V3 adapter** | Index `20`; `0x012c44d0C465819eF3CeAC208e0c1B272087a8b4` (not transfer-tax safe) |
987
- | **Finvesta V3 factory** | `0x7f5c7C5144b4B4c6e954A5b2D75C318C5467EFDc` |
988
- | **Finvesta fee tiers** | `100`, `500`, `2500`, `10000` |
989
- | **Trench V2 adapter** | Index `21`; `0xAf48bb0936D9fA522650236917321D89978A8591` (direct-pair, transfer-tax safe) |
990
- | **Trench V2 factory** | `0xA024e4574406BEf89e624c75758c700B5bED27C7` |
991
- | **Trench V3 adapter** | Index `22`; `0x01957eC5FCC079f1bB388b9f261278daC42cf2E9` (not transfer-tax safe) |
992
- | **Trench V3 factory** | `0xCAeF0a906F3323595A8faA14DF7eDee6F59220af` |
993
- | **Trench V3 fee tiers** | `100`, `500`, `2500`, `3000`, `10000` |
994
- | **Fee denominator** | `10000` (basis points) |
1001
+ | **SwitchRouter** (current) | `0x2dFc8B6e13fF7F04e37Ef97006084805D65a6F19` |
1002
+ | **SwitchRouter** (legacy) | `0x0305fcb5dA680EA6fd1B01A96C1949175B99d406` |
1003
+ | **SwitchLimitOrder** (V3 — current protected) | `0x2afBf0aB8d958a0227742F7a8BdA00c96372E4D7` |
1004
+ | **SwitchLimitOrder** (V2 — legacy) | `0x8e3881bdF81Fc0211383B2e576076B654F7aFD86` |
1005
+ | **SwitchLimitOrder** (V1 — legacy) | `0x0e884072a891b406C0D814907A1E2310fE5F5Deb` |
1006
+ | **SwitchPLSFlow** (V3 — current protected) | `0x0362177FF2ad25a33a879c881a5055575C63a4cE` |
1007
+ | **SwitchPLSFlow** (V2 — legacy) | `0xCf5606bdC750d8626Cec32CA2E1BB207968db1D5` |
1008
+ | **SwitchPLSFlow** (V1 — legacy) | `0x88c9e2C83b6B7c707602e548481e58E920694E64` |
1009
+ | **Direct-fill quoter** | `0x23A95b0f69c993CFe6180a266A93F7560102e929` |
1010
+ | **Limit-order adapter** | Index `17`; `0x7B9761484301a8FE4a2BA47194F7646eEF8e1cDd` |
1011
+ | **LimitOrderAdmin** | `0x9C8B9012AfC0489dE612F7039665212EB88be127` |
1012
+ | **OperatorAccessRegistry** | `0x7dA1AB04A712479569cCaD783Ca6114b763e36Ad` |
1013
+ | **Native PLS sentinel** | `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` |
1014
+ | **WPLS** | `0xA1077a294dDE1B09bB078844df40758a5D0f9a27` |
1015
+ | **Finvesta V3 adapter** | Index `20`; `0x012c44d0C465819eF3CeAC208e0c1B272087a8b4` (not transfer-tax safe) |
1016
+ | **Finvesta V3 factory** | `0x7f5c7C5144b4B4c6e954A5b2D75C318C5467EFDc` |
1017
+ | **Finvesta fee tiers** | `100`, `500`, `2500`, `10000` |
1018
+ | **Trench V2 adapter** | Index `21`; `0xAf48bb0936D9fA522650236917321D89978A8591` (direct-pair, transfer-tax safe) |
1019
+ | **Trench V2 factory** | `0xA024e4574406BEf89e624c75758c700B5bED27C7` |
1020
+ | **Trench V3 adapter** | Index `22`; `0x01957eC5FCC079f1bB388b9f261278daC42cf2E9` (not transfer-tax safe) |
1021
+ | **Trench V3 factory** | `0xCAeF0a906F3323595A8faA14DF7eDee6F59220af` |
1022
+ | **Trench V3 fee tiers** | `100`, `500`, `2500`, `3000`, `10000` |
1023
+ | **Fee denominator** | `10000` (basis points) |
995
1024
  | **Max slippage** | `5000` bps (50 %) |
996
1025
  | **Max fee** | `100` bps (1 %) |
997
- | **Regular swap fee** | `10` bps (0.10 %) — enforced on-chain by `MIN_FEE` |
998
- | **Limit-order fee** | `30` bps (0.30 %); the LimitOrder is Router-fee-exempt |
999
- | **Maximum operator excess** | `500` bps (5 %) of the protected contract's cap base |
1026
+ | **Regular swap fee** | `10` bps (0.10 %) — enforced on-chain by `MIN_FEE` |
1027
+ | **Limit-order fee** | `30` bps (0.30 %); the LimitOrder is Router-fee-exempt |
1028
+ | **Maximum operator excess** | `500` bps (5 %) of the protected contract's cap base |
1000
1029
  | **Default slippage** | `50` bps (0.50 %) |
1001
1030
  | **Swap API base** | `https://quote.switch.win` |
1002
1031
  | **Limit Order API base** | `https://quote.switch.win` |