@switch-win/sdk 1.2.2 → 1.2.3
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.
- package/LIMIT-ORDERS.md +737 -0
- package/README.md +15 -8
- package/ROBINHOOD.md +111 -47
- package/package.json +3 -2
- package/src/index.ts +25 -13
- package/src/limit-orders.ts +135 -19
- package/src/networks/index.ts +3 -2
- package/src/networks/robinhood.ts +66 -15
- package/src/types.ts +33 -11
package/README.md
CHANGED
|
@@ -121,8 +121,11 @@ For a production integration with tax token handling, adapter filtering, and fee
|
|
|
121
121
|
### Robinhood Chain
|
|
122
122
|
|
|
123
123
|
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.
|
|
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 fourteen adapters across Uniswap, SwapHood,
|
|
127
|
+
Up33, Sheriff, Aeon, Catnip, PancakeSwap, RobinSwap, SushiSwap, and Switch limit
|
|
128
|
+
orders.
|
|
126
129
|
|
|
127
130
|
For network configuration, deployed addresses, tax handling, execution, and
|
|
128
131
|
the complete frontend token list, see [`ROBINHOOD.md`](ROBINHOOD.md).
|
|
@@ -139,7 +142,7 @@ const url = buildRobinhoodQuoteUrl({
|
|
|
139
142
|
to: ROBINHOOD_TOKENS.USDG.address,
|
|
140
143
|
amount: 1_000_000_000_000_000n,
|
|
141
144
|
sender: walletAddress,
|
|
142
|
-
slippage:
|
|
145
|
+
slippage: 100, // 1%, matching the Robinhood frontend default
|
|
143
146
|
});
|
|
144
147
|
|
|
145
148
|
const response = await fetch(url, {
|
|
@@ -917,11 +920,15 @@ await signer.sendTransaction(chosenTx);
|
|
|
917
920
|
|
|
918
921
|
## Limit Orders
|
|
919
922
|
|
|
920
|
-
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.
|
|
921
|
-
|
|
922
|
-
**→ Full integration guide: [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)**
|
|
923
|
-
|
|
924
|
-
Covers
|
|
923
|
+
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.
|
|
924
|
+
|
|
925
|
+
**→ Full integration guide: [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)**
|
|
926
|
+
|
|
927
|
+
Covers both `pulsechain` and `robinhood`: creating orders, live deployment
|
|
928
|
+
discovery, approvals, `feeOnOutput` decision rules, native PLS/ETH flows,
|
|
929
|
+
querying, cancellation, API types, and EIP-712 details. Use
|
|
930
|
+
`fetchLimitOrderConfig({ network })` at startup and include `network` in every
|
|
931
|
+
orderbook request.
|
|
925
932
|
|
|
926
933
|
---
|
|
927
934
|
|
package/ROBINHOOD.md
CHANGED
|
@@ -11,8 +11,8 @@ Production integration reference for Switch swaps on Robinhood Chain mainnet.
|
|
|
11
11
|
| Explorer | `https://robinhoodchain.blockscout.com` |
|
|
12
12
|
| Quote API | `https://quote.switch.win/swap/quote` |
|
|
13
13
|
| Tax API | `https://quote.switch.win/swap/checkTax` |
|
|
14
|
-
| Supported liquidity | Uniswap V2,
|
|
15
|
-
| Limit orders |
|
|
14
|
+
| Supported liquidity | 14 adapters: Uniswap V2/V3/V4, Switch limit orders, SwapHood, Up33, Sheriff, Aeon, Catnip, PancakeSwap, RobinSwap, and SushiSwap |
|
|
15
|
+
| Limit orders | Available: EIP-712 ERC-20 orders plus native ETH flow |
|
|
16
16
|
|
|
17
17
|
## Contents
|
|
18
18
|
|
|
@@ -111,6 +111,16 @@ await window.ethereum.request({
|
|
|
111
111
|
| SwitchLimitOrder | `0x752c50DDd3B426cAE3D7A995F313Ac74ac6B0230` |
|
|
112
112
|
| Native ETH flow | `0x029FfC6aF9112eA078f1D6f4a98826DDB2136cf6` |
|
|
113
113
|
| Switch Limit Order adapter (index 3) | `0x412F625072c10e58C619D1e0b3C95cd3d5689871` |
|
|
114
|
+
| SwapHood V2 adapter (index 4) | `0x6D8746f02e52944c13824fA691c6f4186E463354` |
|
|
115
|
+
| SwapHood V3 adapter (index 5) | `0x9645dE0AcB48F0AAefdBEb423F0558457907DE98` |
|
|
116
|
+
| Up33 CL adapter (index 6) | `0x388179D2FB0ABcE9b03068916aF8a3c4dfD023c8` |
|
|
117
|
+
| Sheriff V2 adapter (index 7) | `0xBDB3EB0355981500f58C9bc77c3E61762844A146` |
|
|
118
|
+
| Sheriff Algebra adapter (index 8) | `0xeFE1affb0e2Bb8A9F7d9D30751bAF679996ADA26` |
|
|
119
|
+
| Aeon Algebra adapter (index 9) | `0x20615954FB87360139e7DdDB519359498EbD1904` |
|
|
120
|
+
| Catnip V2 adapter (index 10) | `0x5b2Ca358d56490Dc86224D502522314De7707237` |
|
|
121
|
+
| PancakeSwap V2 adapter (index 11) | `0x3B6e71A59553143937Fef74a7B50AFD24528786E` |
|
|
122
|
+
| RobinSwap V3 adapter (index 12) | `0x798f77D63b46b0E019de206E111e5ea5CC16BEc8` |
|
|
123
|
+
| SushiSwap V3 adapter (index 13) | `0xca3EA0Fd6E31f94c81B6586836790adE638313ED` |
|
|
114
124
|
|
|
115
125
|
The V4 adapter was created in
|
|
116
126
|
[deployment transaction `0x60d5...34a7`](https://robinhoodchain.blockscout.com/tx/0x60d56466a8162a643a15ecde98322ec05ea23d44d03fbd817df4ddbaef4834a7)
|
|
@@ -162,6 +172,26 @@ Submit signed orders to `POST /limit-orders?network=robinhood`. For
|
|
|
162
172
|
`feeOnOutput=false`, approve `ROBINHOOD_SWITCH_CONTRACTS.limitOrder`; for
|
|
163
173
|
`feeOnOutput=true`, approve `ROBINHOOD_SWITCH_CONTRACTS.router`.
|
|
164
174
|
|
|
175
|
+
Applications should fetch `/limit-orders/config?network=robinhood` at startup
|
|
176
|
+
instead of relying only on static addresses. The SDK exposes this as:
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const config = await fetchLimitOrderConfig({ network: "robinhood" });
|
|
180
|
+
const signing = getNetworkEIP712SigningParams(
|
|
181
|
+
"robinhood",
|
|
182
|
+
config.limitOrderContract,
|
|
183
|
+
);
|
|
184
|
+
const approvalTarget = getLimitOrderApprovalTarget(
|
|
185
|
+
"robinhood",
|
|
186
|
+
order.feeOnOutput,
|
|
187
|
+
{ limitOrderContract: config.limitOrderContract },
|
|
188
|
+
);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Include `limitOrderContract: config.limitOrderContract` with the submitted
|
|
192
|
+
signed order. Every returned order also carries its own deployment address;
|
|
193
|
+
operators must fill and makers must cancel against that per-order address.
|
|
194
|
+
|
|
165
195
|
Native ETH input orders are created on-chain through
|
|
166
196
|
`ROBINHOOD_SWITCH_CONTRACTS.nativeEthFlow` and are indexed from its events; do
|
|
167
197
|
not POST them as signed EOA orders. Native ETH output is represented by WETH in
|
|
@@ -221,9 +251,10 @@ The canonical Robinhood V4 infrastructure is available through
|
|
|
221
251
|
| Universal Router | `0x8876789976decbfcbbbe364623c63652db8c0904` |
|
|
222
252
|
| Permit2 | `0x000000000022D473030F116dDEE9F6B43aC78BA3` |
|
|
223
253
|
|
|
224
|
-
Tax-token safety is unchanged: if either side is detected as a transfer-tax
|
|
225
|
-
token, the complete route is restricted to
|
|
226
|
-
|
|
254
|
+
Tax-token safety is unchanged: if either side is detected as a transfer-tax
|
|
255
|
+
token, the complete route is restricted to direct-pair V2 adapters `0`, `4`,
|
|
256
|
+
`7`, `10`, and `11`. Concentrated-liquidity adapters are excluded from that
|
|
257
|
+
quote.
|
|
227
258
|
|
|
228
259
|
## Swap integration flow
|
|
229
260
|
|
|
@@ -239,8 +270,9 @@ Use the same sequence as a PulseChain integration:
|
|
|
239
270
|
6. Show `expectedOutputAmount`, `minAmountOut`, route allocation, and detected
|
|
240
271
|
taxes to the user.
|
|
241
272
|
|
|
242
|
-
Any swap involving a tax token is routed entirely through
|
|
243
|
-
|
|
273
|
+
Any swap involving a tax token is routed entirely through the tax-safe
|
|
274
|
+
direct-pair V2 adapter set (`0`, `4`, `7`, `10`, and `11`). This also applies
|
|
275
|
+
when both input and output are tax tokens.
|
|
244
276
|
|
|
245
277
|
## Quickstart
|
|
246
278
|
|
|
@@ -257,7 +289,7 @@ const url = buildRobinhoodQuoteUrl({
|
|
|
257
289
|
to: ROBINHOOD_TOKENS.USDG.address,
|
|
258
290
|
amount: 1_000_000_000_000_000n,
|
|
259
291
|
sender: walletAddress,
|
|
260
|
-
slippage:
|
|
292
|
+
slippage: 100, // 1.00%, the Robinhood frontend default
|
|
261
293
|
feeOnOutput,
|
|
262
294
|
});
|
|
263
295
|
|
|
@@ -281,7 +313,7 @@ Equivalent curl request:
|
|
|
281
313
|
|
|
282
314
|
```bash
|
|
283
315
|
curl -H "x-api-key: YOUR_KEY" \
|
|
284
|
-
"https://quote.switch.win/swap/quote?network=robinhood&from=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&to=0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168&amount=1000000000000000&sender=0xYOUR_WALLET&slippage=
|
|
316
|
+
"https://quote.switch.win/swap/quote?network=robinhood&from=0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE&to=0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168&amount=1000000000000000&sender=0xYOUR_WALLET&slippage=100"
|
|
285
317
|
```
|
|
286
318
|
|
|
287
319
|
Omit `sender` for a display-only quote. Fetch again with the sender immediately
|
|
@@ -374,7 +406,7 @@ const quoteUrl = buildRobinhoodQuoteUrl({
|
|
|
374
406
|
to: tokenOut,
|
|
375
407
|
amount: amountIn,
|
|
376
408
|
sender: walletAddress,
|
|
377
|
-
slippage:
|
|
409
|
+
slippage: 100,
|
|
378
410
|
feeOnOutput,
|
|
379
411
|
});
|
|
380
412
|
|
|
@@ -441,17 +473,28 @@ Robinhood currently returns:
|
|
|
441
473
|
|
|
442
474
|
| Index | Adapter |
|
|
443
475
|
|---:|---|
|
|
444
|
-
| `0` | Uniswap V2 |
|
|
445
|
-
| `1` | Uniswap V3 |
|
|
446
|
-
| `2` | Uniswap V4 |
|
|
476
|
+
| `0` | Uniswap V2 |
|
|
477
|
+
| `1` | Uniswap V3 |
|
|
478
|
+
| `2` | Uniswap V4 |
|
|
479
|
+
| `3` | Switch Limit Orders |
|
|
480
|
+
| `4` | SwapHood V2 |
|
|
481
|
+
| `5` | SwapHood V3 |
|
|
482
|
+
| `6` | Up33 CL |
|
|
483
|
+
| `7` | Sheriff V2 |
|
|
484
|
+
| `8` | Sheriff Algebra |
|
|
485
|
+
| `9` | Aeon Algebra |
|
|
486
|
+
| `10` | Catnip V2 |
|
|
487
|
+
| `11` | PancakeSwap V2 |
|
|
488
|
+
| `12` | RobinSwap V3 |
|
|
489
|
+
| `13` | SushiSwap V3 |
|
|
447
490
|
|
|
448
491
|
Treat the endpoint response, not this document, as the source of truth for
|
|
449
492
|
which adapters are currently selectable.
|
|
450
493
|
|
|
451
|
-
Do not permanently hard-code the available adapter list in an integration.
|
|
452
|
-
Fetch it when presenting routing-source controls. If a quote involves a tax
|
|
453
|
-
token, the backend
|
|
454
|
-
filter that excludes
|
|
494
|
+
Do not permanently hard-code the available adapter list in an integration.
|
|
495
|
+
Fetch it when presenting routing-source controls. If a quote involves a tax
|
|
496
|
+
token, the backend restricts routing to tax-safe adapters `0`, `4`, `7`, `10`,
|
|
497
|
+
and `11`; an explicit filter that excludes all of them is rejected.
|
|
455
498
|
|
|
456
499
|
### Check token tax
|
|
457
500
|
|
|
@@ -487,7 +530,7 @@ GET https://quote.switch.win/swap/quote
|
|
|
487
530
|
| `amount` | Yes | Raw input amount. |
|
|
488
531
|
| `sender` | No | Required when transaction calldata is needed. |
|
|
489
532
|
| `receiver` | No | Output recipient; defaults to `sender`. |
|
|
490
|
-
| `slippage` | No | Basis points;
|
|
533
|
+
| `slippage` | No | Basis points; API fallback `50` (`0.5%`). The Switch Robinhood frontend explicitly requests `100` (`1%`). |
|
|
491
534
|
| `fee` | No | Partner/protocol fee in basis points. |
|
|
492
535
|
| `partnerAddress` | No | Fee-sharing recipient. |
|
|
493
536
|
| `feeOnOutput` | No | `true` takes the fee from output; `false` takes it from input. |
|
|
@@ -529,7 +572,7 @@ Common Robinhood errors include:
|
|
|
529
572
|
- Missing or unsupported `network`.
|
|
530
573
|
- Invalid token, sender, receiver, or partner address.
|
|
531
574
|
- Invalid raw amount, slippage, fee, gas price, or adapter filter.
|
|
532
|
-
- A tax-token quote explicitly excluded
|
|
575
|
+
- A tax-token quote explicitly excluded every tax-safe direct-pair V2 adapter.
|
|
533
576
|
- No viable route across the currently active adapters, or insufficient liquidity.
|
|
534
577
|
- RPC timeout or public-RPC rate limiting.
|
|
535
578
|
- Missing executable transaction because `sender` was omitted.
|
|
@@ -576,7 +619,13 @@ into the UI separately from this list.
|
|
|
576
619
|
| TENDIES | TENDIES | `0x45242320DBB855EeA8Fd36804C6487E10E97FCF9` | 18 |
|
|
577
620
|
| GME | GameStop | `0x7e86381A763F0Ecca2bDF27C54eAC403ddD48123` | 18 |
|
|
578
621
|
| 4663 | 4663 | `0xd4052415613B34Af236024B895574c467f65b6dD` | 18 |
|
|
579
|
-
| MARIAN | Lady Marian | `0x01637b14B7378B99dE75A64d50656d98488D9a4d` | 18 |
|
|
622
|
+
| MARIAN | Lady Marian | `0x01637b14B7378B99dE75A64d50656d98488D9a4d` | 18 |
|
|
623
|
+
| Index | The Index | `0x56910D4409F3a0C78C64DD8D0545FF0705389870` | 18 |
|
|
624
|
+
| VEX | ProjectVex | `0x8Ff92566f2e81BDd68EDfAa8cde73942A723796b` | 18 |
|
|
625
|
+
| HOODIE | HOODIE | `0xC72c01AAB5f5678dc1d6f5C6d2B417d91D402Ba3` | 18 |
|
|
626
|
+
| WISHBONE | WISHBONE | `0x77581054581B9c525E7dd7a0155DE43867532d03` | 18 |
|
|
627
|
+
| VLAD | The Green Bull | `0x31BE8f7485e36928C9De86566c62da82d4B6BF81` | 18 |
|
|
628
|
+
| AEON | Aeon | `0xd4c93eD1843606f92CccA078941f3d52A585982f` | 18 |
|
|
580
629
|
|
|
581
630
|
The ordered list is exported as `ROBINHOOD_FRONTEND_TOKEN_LIST`.
|
|
582
631
|
|
|
@@ -586,22 +635,38 @@ Always identify tokens by address and obtain a fresh quote and tax check.
|
|
|
586
635
|
|
|
587
636
|
### Routing configuration
|
|
588
637
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
638
|
+
The production router currently exposes fourteen ordered adapters:
|
|
639
|
+
|
|
640
|
+
| Index | Venue | Routing family |
|
|
641
|
+
|---:|---|---|
|
|
642
|
+
| `0` | Uniswap V2 | Direct-pair V2 |
|
|
643
|
+
| `1` | Uniswap V3 | V3 tiers `100`, `500`, `3000`, `10000` |
|
|
644
|
+
| `2` | Uniswap V4 | Complete hookless static-fee `PoolKey` |
|
|
645
|
+
| `3` | Switch limit orders | Signed/on-chain order liquidity |
|
|
646
|
+
| `4` | SwapHood V2 | Pair-owned variable-fee V2 |
|
|
647
|
+
| `5` | SwapHood V3 | Pancake V3 tiers `100`, `500`, `2500`, `10000` |
|
|
648
|
+
| `6` | Up33 | Slipstream CL tick spacings `1`, `10`, `50`, `60`, `100`, `200`, `2000` |
|
|
649
|
+
| `7` | Sheriff V2 | Pair-owned variable-fee V2 |
|
|
650
|
+
| `8` | Sheriff | Algebra Integral |
|
|
651
|
+
| `9` | Aeon | Algebra Integral with plugin-aware fees |
|
|
652
|
+
| `10` | Catnip | Direct-pair V2, fixed 30 bps |
|
|
653
|
+
| `11` | PancakeSwap | Direct-pair V2, fixed 25 bps |
|
|
654
|
+
| `12` | RobinSwap | V3 tiers `100`, `500`, `2500`, `3000`, `10000` |
|
|
655
|
+
| `13` | SushiSwap | V3 tiers `500`, `3000`, `10000` |
|
|
656
|
+
|
|
657
|
+
V4 pools are discovered by complete `PoolKey`, not by applying a V3 fee-tier
|
|
658
|
+
list. Native-ETH V4 currencies are normalized through the WETH/native alias
|
|
659
|
+
described above. V3-style and Up33 route legs preserve the exact fee tier or
|
|
660
|
+
tick spacing that won the quote for every direct and multi-hop allocation.
|
|
661
|
+
|
|
662
|
+
Trusted routing hubs are WETH, USDG, VIRTUAL, CASHCAT, HOODRAT, TENDIES,
|
|
663
|
+
JUGGERNAUT, MARIAN, and WALLET. The expanded set was selected from the
|
|
664
|
+
2026-07-16 pair-connectivity audit and zero-tax checks. VEX is excluded because
|
|
665
|
+
it is taxed; INDEX remains an endpoint token but is excluded because its
|
|
666
|
+
dominant liquidity depends on V4 hooks that are not yet supported. If either side is
|
|
667
|
+
detected as a transfer-tax token, the backend restricts the entire route to
|
|
668
|
+
direct-pair V2 adapters `0`, `4`, `7`, `10`, and `11`; concentrated-liquidity
|
|
669
|
+
and limit-order adapters are excluded.
|
|
605
670
|
|
|
606
671
|
The API may split a quote across routes and adapters. Integrators should render
|
|
607
672
|
the returned `paths` or `routeAllocation` instead of assuming a single path.
|
|
@@ -616,17 +681,16 @@ For server integrations, contact Switch to coordinate the expected request
|
|
|
616
681
|
rate and IP allowlisting. Do not distribute one production key across
|
|
617
682
|
untrusted clients.
|
|
618
683
|
|
|
619
|
-
## Current limitations
|
|
620
|
-
|
|
621
|
-
-
|
|
622
|
-
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
- Contract and token addresses must be treated as chain-specific.
|
|
684
|
+
## Current limitations
|
|
685
|
+
|
|
686
|
+
- Rialto liquidity is not integrated.
|
|
687
|
+
- Robinhood market routing is limited to the fourteen production adapters
|
|
688
|
+
listed above. Always use `/swap/adapters` as the runtime source of truth.
|
|
689
|
+
- The first V4 phase intentionally excludes hooked and dynamic-fee pools.
|
|
690
|
+
- A V4 allocation currently selects its best single PoolKey; intra-V4
|
|
691
|
+
multi-pool splitting is not yet enabled. V4 can still split against other
|
|
692
|
+
eligible adapters.
|
|
693
|
+
- Contract and token addresses must be treated as chain-specific.
|
|
630
694
|
|
|
631
695
|
See the main [SDK reference](README.md) for authentication, partner fees,
|
|
632
696
|
response types, error handling, and the complete swap API schema.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@switch-win/sdk",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.3",
|
|
4
4
|
"description": "Official integration kit for the Switch DEX Aggregator on PulseChain and Robinhood Chain",
|
|
5
5
|
"author": "BuildTheTech",
|
|
6
6
|
"license": "MIT",
|
|
@@ -37,7 +37,8 @@
|
|
|
37
37
|
"src/",
|
|
38
38
|
"abi/",
|
|
39
39
|
"README.md",
|
|
40
|
-
"ROBINHOOD.md"
|
|
40
|
+
"ROBINHOOD.md",
|
|
41
|
+
"LIMIT-ORDERS.md"
|
|
41
42
|
],
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"typescript": "^5.9.3"
|
package/src/index.ts
CHANGED
|
@@ -45,8 +45,9 @@ export type {
|
|
|
45
45
|
CancelLimitOrderResponse,
|
|
46
46
|
ListLimitOrdersResponse,
|
|
47
47
|
LimitOrderPair,
|
|
48
|
-
LimitOrderStats,
|
|
49
|
-
|
|
48
|
+
LimitOrderStats,
|
|
49
|
+
LimitOrderConfigResponse,
|
|
50
|
+
LimitOrderMutationResponse,
|
|
50
51
|
} from "./types.js";
|
|
51
52
|
|
|
52
53
|
export { isErrorResponse } from "./types.js";
|
|
@@ -95,31 +96,42 @@ export {
|
|
|
95
96
|
// Limit Order helpers
|
|
96
97
|
export {
|
|
97
98
|
buildLimitOrder,
|
|
98
|
-
getEIP712SigningParams,
|
|
99
|
+
getEIP712SigningParams,
|
|
100
|
+
getNetworkEIP712SigningParams,
|
|
101
|
+
getLimitOrderNetworkConfig,
|
|
102
|
+
getLimitOrderApprovalTarget,
|
|
99
103
|
getApprovalTarget,
|
|
100
104
|
getRouterApprovalTarget,
|
|
101
105
|
shouldUnwrapOutput,
|
|
102
|
-
getPLSFlowAddress,
|
|
103
|
-
|
|
106
|
+
getPLSFlowAddress,
|
|
107
|
+
getNativeFlowAddress,
|
|
108
|
+
isNativePLS,
|
|
109
|
+
isNativeCurrency,
|
|
104
110
|
submitLimitOrder,
|
|
105
111
|
cancelLimitOrder,
|
|
106
112
|
fetchLimitOrders,
|
|
107
113
|
fetchLimitOrder,
|
|
108
|
-
fetchLimitOrderPairs,
|
|
109
|
-
|
|
110
|
-
|
|
114
|
+
fetchLimitOrderPairs,
|
|
115
|
+
fetchLimitOrderConfig,
|
|
116
|
+
fetchLimitOrderStats,
|
|
117
|
+
LIMIT_ORDER_NETWORK_CONFIGS,
|
|
118
|
+
} from "./limit-orders.js";
|
|
111
119
|
|
|
112
120
|
export type {
|
|
113
|
-
BuildLimitOrderOptions,
|
|
114
|
-
ListLimitOrdersOptions,
|
|
115
|
-
|
|
121
|
+
BuildLimitOrderOptions,
|
|
122
|
+
ListLimitOrdersOptions,
|
|
123
|
+
LimitOrderNetwork,
|
|
124
|
+
LimitOrderNetworkConfig,
|
|
125
|
+
LimitOrderNetworkOptions,
|
|
126
|
+
} from "./limit-orders.js";
|
|
116
127
|
|
|
117
128
|
// Network-specific swap configuration
|
|
118
129
|
export {
|
|
119
130
|
ROBINHOOD_NETWORK,
|
|
120
131
|
ROBINHOOD_CHAIN,
|
|
121
|
-
ROBINHOOD_NATIVE_ETH,
|
|
122
|
-
|
|
132
|
+
ROBINHOOD_NATIVE_ETH,
|
|
133
|
+
ROBINHOOD_LIMIT_ORDER_EIP712_DOMAIN,
|
|
134
|
+
ROBINHOOD_SWITCH_CONTRACTS,
|
|
123
135
|
ROBINHOOD_UNISWAP_CONTRACTS,
|
|
124
136
|
ROBINHOOD_TOKENS,
|
|
125
137
|
ROBINHOOD_FRONTEND_TOKEN_LIST,
|
package/src/limit-orders.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* Switch Limit Orders (V2) — Helper Functions
|
|
3
3
|
*
|
|
4
4
|
* Provides a complete toolkit for creating, signing, submitting, querying,
|
|
5
|
-
* and cancelling EIP-712 signed limit orders on PulseChain
|
|
5
|
+
* and cancelling EIP-712 signed limit orders on PulseChain and Robinhood
|
|
6
|
+
* Chain.
|
|
6
7
|
*
|
|
7
8
|
* ## How it works
|
|
8
9
|
*
|
|
@@ -10,7 +11,8 @@
|
|
|
10
11
|
* 2. **Sign** via EIP-712 with your wallet (ethers.js `signTypedData`)
|
|
11
12
|
* 3. **Submit** the signed order to the Switch backend with `submitLimitOrder()`
|
|
12
13
|
* 4. The Switch filler bot monitors active orders and fills them when profitable
|
|
13
|
-
* 5. **Cancel** an order on-chain via `invalidateNonce()
|
|
14
|
+
* 5. **Cancel** an order on-chain via `invalidateNonce()`; the backend indexer
|
|
15
|
+
* observes the cancellation event
|
|
14
16
|
*
|
|
15
17
|
* @example
|
|
16
18
|
* ```ts
|
|
@@ -26,7 +28,8 @@ import type {
|
|
|
26
28
|
ListLimitOrdersResponse,
|
|
27
29
|
LimitOrderRecord,
|
|
28
30
|
LimitOrderPair,
|
|
29
|
-
LimitOrderStats,
|
|
31
|
+
LimitOrderStats,
|
|
32
|
+
LimitOrderConfigResponse,
|
|
30
33
|
LimitOrderStatus,
|
|
31
34
|
ErrorResponse,
|
|
32
35
|
} from "./types.js";
|
|
@@ -40,8 +43,15 @@ import {
|
|
|
40
43
|
SWITCH_LIMIT_ORDER,
|
|
41
44
|
SWITCH_ROUTER,
|
|
42
45
|
SWITCH_PLS_FLOW,
|
|
43
|
-
WPLS,
|
|
44
|
-
|
|
46
|
+
WPLS,
|
|
47
|
+
NATIVE_PLS,
|
|
48
|
+
} from "./constants.js";
|
|
49
|
+
import {
|
|
50
|
+
ROBINHOOD_CHAIN,
|
|
51
|
+
ROBINHOOD_NATIVE_ETH,
|
|
52
|
+
ROBINHOOD_SWITCH_CONTRACTS,
|
|
53
|
+
ROBINHOOD_TOKENS,
|
|
54
|
+
} from "./networks/robinhood.js";
|
|
45
55
|
|
|
46
56
|
// ── Re-export EIP-712 constants for convenience ─────────────────────────────
|
|
47
57
|
|
|
@@ -247,7 +257,7 @@ export function shouldUnwrapOutput(
|
|
|
247
257
|
}
|
|
248
258
|
|
|
249
259
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
250
|
-
//
|
|
260
|
+
// Native-currency flow (SwitchPLSFlow ABI: PLS on PulseChain, ETH on Robinhood)
|
|
251
261
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
252
262
|
|
|
253
263
|
/**
|
|
@@ -262,8 +272,83 @@ export function getPLSFlowAddress(nativeFlowContract?: string): string {
|
|
|
262
272
|
return nativeFlowContract || SWITCH_PLS_FLOW;
|
|
263
273
|
}
|
|
264
274
|
|
|
275
|
+
/** Networks supported by the shared Switch limit-order API. */
|
|
276
|
+
export type LimitOrderNetwork = "pulsechain" | "robinhood";
|
|
277
|
+
|
|
278
|
+
/** Complete deployment metadata needed to create or fill limit orders. */
|
|
279
|
+
export interface LimitOrderNetworkConfig {
|
|
280
|
+
network: LimitOrderNetwork;
|
|
281
|
+
chainId: number;
|
|
282
|
+
chainName: string;
|
|
283
|
+
nativeSymbol: "PLS" | "ETH";
|
|
284
|
+
nativeSentinel: string;
|
|
285
|
+
wrappedNativeToken: string;
|
|
286
|
+
routerContract: string;
|
|
287
|
+
limitOrderContract: string;
|
|
288
|
+
nativeFlowContract: string;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/** Static defaults. Prefer {@link fetchLimitOrderConfig} at application startup. */
|
|
292
|
+
export const LIMIT_ORDER_NETWORK_CONFIGS: Readonly<
|
|
293
|
+
Record<LimitOrderNetwork, LimitOrderNetworkConfig>
|
|
294
|
+
> = {
|
|
295
|
+
pulsechain: {
|
|
296
|
+
network: "pulsechain",
|
|
297
|
+
chainId: 369,
|
|
298
|
+
chainName: "PulseChain",
|
|
299
|
+
nativeSymbol: "PLS",
|
|
300
|
+
nativeSentinel: NATIVE_PLS,
|
|
301
|
+
wrappedNativeToken: WPLS,
|
|
302
|
+
routerContract: SWITCH_ROUTER,
|
|
303
|
+
limitOrderContract: SWITCH_LIMIT_ORDER,
|
|
304
|
+
nativeFlowContract: SWITCH_PLS_FLOW,
|
|
305
|
+
},
|
|
306
|
+
robinhood: {
|
|
307
|
+
network: "robinhood",
|
|
308
|
+
chainId: ROBINHOOD_CHAIN.id,
|
|
309
|
+
chainName: ROBINHOOD_CHAIN.name,
|
|
310
|
+
nativeSymbol: "ETH",
|
|
311
|
+
nativeSentinel: ROBINHOOD_NATIVE_ETH,
|
|
312
|
+
wrappedNativeToken: ROBINHOOD_TOKENS.WETH.address,
|
|
313
|
+
routerContract: ROBINHOOD_SWITCH_CONTRACTS.router,
|
|
314
|
+
limitOrderContract: ROBINHOOD_SWITCH_CONTRACTS.limitOrder,
|
|
315
|
+
nativeFlowContract: ROBINHOOD_SWITCH_CONTRACTS.nativeEthFlow,
|
|
316
|
+
},
|
|
317
|
+
} as const;
|
|
318
|
+
|
|
319
|
+
/** Return the static deployment defaults for a supported limit-order network. */
|
|
320
|
+
export function getLimitOrderNetworkConfig(
|
|
321
|
+
network: LimitOrderNetwork = "pulsechain",
|
|
322
|
+
): LimitOrderNetworkConfig {
|
|
323
|
+
return LIMIT_ORDER_NETWORK_CONFIGS[network];
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
/** Build the correct EIP-712 signing domain for a supported network. */
|
|
327
|
+
export function getNetworkEIP712SigningParams(
|
|
328
|
+
network: LimitOrderNetwork,
|
|
329
|
+
limitOrderContract?: string,
|
|
330
|
+
) {
|
|
331
|
+
const config = getLimitOrderNetworkConfig(network);
|
|
332
|
+
return getEIP712SigningParams(
|
|
333
|
+
limitOrderContract ?? config.limitOrderContract,
|
|
334
|
+
config.chainId,
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/** Resolve the maker's ERC-20 approval target for the selected fee mode. */
|
|
339
|
+
export function getLimitOrderApprovalTarget(
|
|
340
|
+
network: LimitOrderNetwork,
|
|
341
|
+
feeOnOutput: boolean,
|
|
342
|
+
overrides: { limitOrderContract?: string; routerContract?: string } = {},
|
|
343
|
+
): string {
|
|
344
|
+
const config = getLimitOrderNetworkConfig(network);
|
|
345
|
+
return feeOnOutput
|
|
346
|
+
? getRouterApprovalTarget(overrides.routerContract ?? config.routerContract)
|
|
347
|
+
: getApprovalTarget(overrides.limitOrderContract ?? config.limitOrderContract);
|
|
348
|
+
}
|
|
349
|
+
|
|
265
350
|
export interface LimitOrderNetworkOptions {
|
|
266
|
-
network?:
|
|
351
|
+
network?: LimitOrderNetwork;
|
|
267
352
|
}
|
|
268
353
|
|
|
269
354
|
function endpointForNetwork(endpoint: string, network?: string): string {
|
|
@@ -282,10 +367,27 @@ function endpointForNetwork(endpoint: string, network?: string): string {
|
|
|
282
367
|
* @param tokenIn - The input token address
|
|
283
368
|
* @returns `true` if tokenIn is the native PLS sentinel address
|
|
284
369
|
*/
|
|
285
|
-
export function isNativePLS(tokenIn: string): boolean {
|
|
370
|
+
export function isNativePLS(tokenIn: string): boolean {
|
|
286
371
|
const NATIVE_SENTINEL = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
|
|
287
372
|
return tokenIn.toLowerCase() === NATIVE_SENTINEL.toLowerCase();
|
|
288
|
-
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/** Network-neutral native-currency sentinel check (PLS or ETH). */
|
|
376
|
+
export function isNativeCurrency(tokenIn: string): boolean {
|
|
377
|
+
const normalized = tokenIn.toLowerCase();
|
|
378
|
+
return (
|
|
379
|
+
normalized === NATIVE_PLS.toLowerCase() ||
|
|
380
|
+
normalized === ROBINHOOD_NATIVE_ETH.toLowerCase()
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/** Return the native-order flow contract for PulseChain or Robinhood Chain. */
|
|
385
|
+
export function getNativeFlowAddress(
|
|
386
|
+
network: LimitOrderNetwork,
|
|
387
|
+
nativeFlowContract?: string,
|
|
388
|
+
): string {
|
|
389
|
+
return nativeFlowContract ?? getLimitOrderNetworkConfig(network).nativeFlowContract;
|
|
390
|
+
}
|
|
289
391
|
|
|
290
392
|
// ═══════════════════════════════════════════════════════════════════════════════
|
|
291
393
|
// API Helpers
|
|
@@ -310,7 +412,7 @@ export function isNativePLS(tokenIn: string): boolean {
|
|
|
310
412
|
* 4. Do **not** navigate away or close the signing flow until the
|
|
311
413
|
* backend confirms the order.
|
|
312
414
|
*
|
|
313
|
-
*
|
|
415
|
+
* Native PLS/ETH flow orders are an exception — they are recorded
|
|
314
416
|
* on-chain first, so the backend can discover them via event indexing
|
|
315
417
|
* even if the POST never arrives.
|
|
316
418
|
*
|
|
@@ -344,16 +446,17 @@ export async function submitLimitOrder(
|
|
|
344
446
|
}
|
|
345
447
|
|
|
346
448
|
/**
|
|
347
|
-
*
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
449
|
+
* Legacy helper for backend deployments that implemented REST cancellation.
|
|
450
|
+
*
|
|
451
|
+
* The current hosted Switch API intentionally has no DELETE endpoint.
|
|
452
|
+
* Cancellation must be performed on-chain with `invalidateNonce(nonce)` on
|
|
453
|
+
* the contract stored in the order's `limitOrderContract` field. The indexer
|
|
454
|
+
* then updates the order status from the emitted event.
|
|
353
455
|
*
|
|
354
456
|
* @param maker - Maker address
|
|
355
457
|
* @param nonce - Nonce of the order to cancel
|
|
356
|
-
* @returns Success confirmation or error
|
|
458
|
+
* @returns Success confirmation or error on compatible legacy backends
|
|
459
|
+
* @deprecated Do not use with the hosted Switch API; cancel on-chain instead.
|
|
357
460
|
*/
|
|
358
461
|
export async function cancelLimitOrder(
|
|
359
462
|
maker: string,
|
|
@@ -372,7 +475,7 @@ export async function cancelLimitOrder(
|
|
|
372
475
|
/** Filter options for listing limit orders */
|
|
373
476
|
export interface ListLimitOrdersOptions {
|
|
374
477
|
/** Backend network process to query. */
|
|
375
|
-
network?:
|
|
478
|
+
network?: LimitOrderNetwork;
|
|
376
479
|
/** Filter by order status. Default: `"ACTIVE"` */
|
|
377
480
|
status?: LimitOrderStatus;
|
|
378
481
|
/** Filter by maker address */
|
|
@@ -476,7 +579,20 @@ export async function fetchLimitOrderPairs(
|
|
|
476
579
|
): Promise<LimitOrderPair[]> {
|
|
477
580
|
const res = await fetch(endpointForNetwork(LIMIT_ORDER_PAIRS_ENDPOINT, options.network));
|
|
478
581
|
return res.json() as Promise<LimitOrderPair[]>;
|
|
479
|
-
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/** Fetch the active deployment and EIP-712 domain for a network. */
|
|
585
|
+
export async function fetchLimitOrderConfig(
|
|
586
|
+
options: LimitOrderNetworkOptions = {},
|
|
587
|
+
): Promise<LimitOrderConfigResponse> {
|
|
588
|
+
const res = await fetch(
|
|
589
|
+
endpointForNetwork(`${LIMIT_ORDERS_ENDPOINT}/config`, options.network),
|
|
590
|
+
);
|
|
591
|
+
if (!res.ok) {
|
|
592
|
+
throw new Error(`Failed to fetch limit-order config (${res.status})`);
|
|
593
|
+
}
|
|
594
|
+
return res.json() as Promise<LimitOrderConfigResponse>;
|
|
595
|
+
}
|
|
480
596
|
|
|
481
597
|
/**
|
|
482
598
|
* Fetch summary statistics for all limit orders.
|
package/src/networks/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
export {
|
|
2
2
|
ROBINHOOD_NETWORK,
|
|
3
3
|
ROBINHOOD_CHAIN,
|
|
4
|
-
ROBINHOOD_NATIVE_ETH,
|
|
5
|
-
|
|
4
|
+
ROBINHOOD_NATIVE_ETH,
|
|
5
|
+
ROBINHOOD_LIMIT_ORDER_EIP712_DOMAIN,
|
|
6
|
+
ROBINHOOD_SWITCH_CONTRACTS,
|
|
6
7
|
ROBINHOOD_UNISWAP_CONTRACTS,
|
|
7
8
|
ROBINHOOD_TOKENS,
|
|
8
9
|
ROBINHOOD_FRONTEND_TOKEN_LIST,
|