@switch-win/sdk 1.2.1 → 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/README.md CHANGED
@@ -3,11 +3,11 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@switch-win/sdk.svg)](https://www.npmjs.com/package/@switch-win/sdk)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@switch-win/sdk.svg)](https://www.npmjs.com/package/@switch-win/sdk)
5
5
 
6
- > **Official integration kit for the Switch DEX Aggregator on PulseChain and Robinhood Chain**
6
+ > **Official integration kit for the Switch DEX Aggregator on PulseChain and Robinhood Chain**
7
7
 
8
8
  Everything partners need to integrate Switch swaps and limit orders — 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
10
+ **Swap API:** `https://quote.switch.win`  |  **Swap chains:** PulseChain (369), Robinhood Chain (4663)  |  **Limit orders:** PulseChain and Robinhood Chain
11
11
 
12
12
  ---
13
13
 
@@ -20,9 +20,9 @@ Switch-SDK/
20
20
  ├── src/
21
21
  │ ├── index.ts # Main entry — re-exports everything
22
22
  │ ├── types.ts # TypeScript types (swap + limit orders)
23
- │ ├── constants.ts # PulseChain addresses, ABIs, EIP-712, PLSFlow config
24
- │ ├── networks/
25
- │ │ └── robinhood.ts # Robinhood metadata, contracts, tokens, quote URL helper
23
+ │ ├── constants.ts # PulseChain addresses, ABIs, EIP-712, PLSFlow config
24
+ │ ├── networks/
25
+ │ │ └── robinhood.ts # Robinhood metadata, contracts, tokens, quote URL helper
26
26
  │ └── limit-orders.ts # Limit order helpers (build, sign, submit, query, PLSFlow)
27
27
  ├── abi/
28
28
  │ ├── SwitchRouterABI.json # Full SwitchRouter contract ABI
@@ -42,26 +42,26 @@ Switch-SDK/
42
42
 
43
43
  0. [Installation](#installation)
44
44
 
45
- ### Swaps
46
-
47
- 1. [Quickstart](#quickstart)
48
- 2. [Robinhood Chain](#robinhood-chain)
49
- 3. [Authentication](#authentication)
50
- 4. [Swap Integration Flow](#swap-integration-flow)
51
- 5. [Swap API Reference](#swap-api-reference)
52
- 6. [Error Handling](#error-handling)
53
- 7. [Partner Fee Sharing](#partner-fee-sharing)
45
+ ### Swaps
46
+
47
+ 1. [Quickstart](#quickstart)
48
+ 2. [Robinhood Chain](#robinhood-chain)
49
+ 3. [Authentication](#authentication)
50
+ 4. [Swap Integration Flow](#swap-integration-flow)
51
+ 5. [Swap API Reference](#swap-api-reference)
52
+ 6. [Error Handling](#error-handling)
53
+ 7. [Partner Fee Sharing](#partner-fee-sharing)
54
54
 
55
55
  ### Limit Orders
56
56
 
57
- 8. [Limit Orders](#limit-orders) — full guide in [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)
57
+ 8. [Limit Orders](#limit-orders) — full guide in [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)
58
58
 
59
59
  ### General
60
60
 
61
- 9. [Constants & Addresses](#constants--addresses)
62
- 10. [Full Integration Examples](#full-integration-examples)
63
- 11. [Rate Limits](#rate-limits)
64
- 12. [Support](#support)
61
+ 9. [Constants & Addresses](#constants--addresses)
62
+ 10. [Full Integration Examples](#full-integration-examples)
63
+ 11. [Rate Limits](#rate-limits)
64
+ 12. [Support](#support)
65
65
 
66
66
  ---
67
67
 
@@ -86,7 +86,7 @@ Get a swap quote and execute it in **three steps**:
86
86
  curl -H "x-api-key: YOUR_KEY" \
87
87
  "https://quote.switch.win/swap/quote?network=pulsechain&from=0xA1077a294dDE1B09bB078844df40758a5D0f9a27&to=0x95B303987A60C71504D99Aa1b13B4DA07b0790ab&amount=1000000000000000000&sender=0xYOUR_WALLET&slippage=100"
88
88
 
89
- # 2. Approve the SwitchRouter to spend your input token (ERC-20 only; skip for native currency)
89
+ # 2. Approve the SwitchRouter to spend your input token (ERC-20 only; skip for native currency)
90
90
 
91
91
  # 3. Send the transaction using the `tx` object from the response:
92
92
  # { to: "0x0305...", data: "0x...", value: "0" }
@@ -106,7 +106,7 @@ const res = await fetch(
106
106
  );
107
107
  const quote: BestPathResponse = await res.json();
108
108
 
109
- // 2. Approve SwitchRouter (ERC-20 only — skip for native currency)
109
+ // 2. Approve SwitchRouter (ERC-20 only — skip for native currency)
110
110
  const token = new ethers.Contract(fromToken, ["function approve(address,uint256)"], signer);
111
111
  await (await token.approve(SWITCH_ROUTER, amount)).wait();
112
112
 
@@ -116,40 +116,44 @@ await signer.sendTransaction(quote.tx);
116
116
 
117
117
  > **⚠️ Always use `tx.to` from the quote response** when sending swap transactions. Do NOT hardcode the router address — the contract may be redeployed.
118
118
 
119
- For a production integration with tax token handling, adapter filtering, and fee mode selection, see [Swap Integration Flow](#swap-integration-flow) and the [full examples](examples/).
120
-
121
- ### Robinhood Chain
122
-
123
- Robinhood uses the same quote endpoint; set `network=robinhood`. The dedicated
119
+ For a production integration with tax token handling, adapter filtering, and fee mode selection, see [Swap Integration Flow](#swap-integration-flow) and the [full examples](examples/).
120
+
121
+ ### Robinhood Chain
122
+
123
+ Robinhood uses the same quote endpoint; set `network=robinhood`. The dedicated
124
124
  module includes canonical chain metadata, deployed Switch contracts, vetted
125
125
  routing hubs, and a URL builder that always includes the correct network.
126
-
127
- For network configuration, deployed addresses, tax handling, execution, and
128
- the complete frontend token list, see [`ROBINHOOD.md`](ROBINHOOD.md).
129
-
130
- ```ts
131
- import {
132
- ROBINHOOD_NATIVE_ETH,
133
- ROBINHOOD_TOKENS,
134
- buildRobinhoodQuoteUrl,
135
- } from "@switch-win/sdk/networks/robinhood";
136
-
137
- const url = buildRobinhoodQuoteUrl({
138
- from: ROBINHOOD_NATIVE_ETH,
139
- to: ROBINHOOD_TOKENS.USDG.address,
140
- amount: 1_000_000_000_000_000n,
141
- sender: walletAddress,
142
- slippage: 50,
143
- });
144
-
145
- const response = await fetch(url, {
146
- headers: { "x-api-key": process.env.SWITCH_API_KEY! },
147
- });
148
- ```
149
-
150
- Always approve `ROBINHOOD_SWITCH_CONTRACTS.router` for ERC-20 input, but submit
151
- the transaction to `quote.tx.to` so integrations remain safe across router
152
- upgrades. Limit-order helpers in this package remain PulseChain-only.
126
+ The production router exposes fourteen adapters across Uniswap, SwapHood,
127
+ Up33, Sheriff, Aeon, Catnip, PancakeSwap, RobinSwap, SushiSwap, and Switch limit
128
+ orders.
129
+
130
+ For network configuration, deployed addresses, tax handling, execution, and
131
+ the complete frontend token list, see [`ROBINHOOD.md`](ROBINHOOD.md).
132
+
133
+ ```ts
134
+ import {
135
+ ROBINHOOD_NATIVE_ETH,
136
+ ROBINHOOD_TOKENS,
137
+ buildRobinhoodQuoteUrl,
138
+ } from "@switch-win/sdk/networks/robinhood";
139
+
140
+ const url = buildRobinhoodQuoteUrl({
141
+ from: ROBINHOOD_NATIVE_ETH,
142
+ to: ROBINHOOD_TOKENS.USDG.address,
143
+ amount: 1_000_000_000_000_000n,
144
+ sender: walletAddress,
145
+ slippage: 100, // 1%, matching the Robinhood frontend default
146
+ });
147
+
148
+ const response = await fetch(url, {
149
+ headers: { "x-api-key": process.env.SWITCH_API_KEY! },
150
+ });
151
+ ```
152
+
153
+ Always approve `ROBINHOOD_SWITCH_CONTRACTS.router` for ERC-20 input, but submit
154
+ the transaction to `quote.tx.to` so integrations remain safe across router
155
+ upgrades. Robinhood limit-order deployment constants and EIP-712 domain values
156
+ are exported from `src/networks/robinhood.ts`.
153
157
 
154
158
  ---
155
159
 
@@ -250,8 +254,8 @@ function determineFeeOnOutput(
250
254
  const isSellTax = fromTax.isTaxToken && fromTax.sellTaxBps > 0;
251
255
  const isBuyTax = toTax.isTaxToken && toTax.buyTaxBps > 0;
252
256
 
253
- // Both tokens are taxed — use fee on input to avoid extra output transfers.
254
- if (isSellTax && isBuyTax) return false;
257
+ // Both tokens are taxed — use fee on input to avoid extra output transfers.
258
+ if (isSellTax && isBuyTax) return false;
255
259
 
256
260
  // Only output token is tax — fee on input (avoids router holding output tokens)
257
261
  if (isBuyTax) return false;
@@ -290,15 +294,15 @@ Fee portion: Router ──transfer──▶ FeeClaimer (3rd buy tax on fee amoun
290
294
  ```
291
295
  The output token is transferred **three times** through different addresses, each incurring a buy tax. The user receives significantly less than expected.
292
296
 
293
- **Bottom line:** When the output token has a buy tax, always use `feeOnOutput=false` so the router routes output directly to the user in a single transfer. This applies to both regular swaps and limit orders.
294
-
295
- ### Executing the Swap
297
+ **Bottom line:** When the output token has a buy tax, always use `feeOnOutput=false` so the router routes output directly to the user in a single transfer. This applies to both regular swaps and limit orders.
298
+
299
+ ### Executing the Swap
296
300
 
297
301
  Once you have a quote, execute it in two steps:
298
302
 
299
303
  #### Step 1 — Approve Token Spend (ERC-20 inputs only)
300
304
 
301
- If the input token is an **ERC-20** rather than the chain's native currency, the user must approve the network's SwitchRouter contract to spend `amount` tokens before submitting the swap.
305
+ If the input token is an **ERC-20** rather than the chain's native currency, the user must approve the network's SwitchRouter contract to spend `amount` tokens before submitting the swap.
302
306
 
303
307
  Before sending an approval transaction, check whether the user already has sufficient allowance to avoid wasting gas on a redundant approve:
304
308
 
@@ -326,7 +330,7 @@ const { tx } = quoteResponse;
326
330
  const txResponse = await signer.sendTransaction({
327
331
  to: tx.to,
328
332
  data: tx.data,
329
- value: tx.value, // "0" for ERC-20 inputs, amountIn for native currency
333
+ value: tx.value, // "0" for ERC-20 inputs, amountIn for native currency
330
334
  });
331
335
 
332
336
  const receipt = await txResponse.wait();
@@ -386,7 +390,7 @@ Returns all available DEX adapters with their on-chain indices and contract addr
386
390
 
387
391
  | Param | Required | Type | Description |
388
392
  |---|---|---|---|
389
- | `network` | **Yes** | string | Target blockchain network: `"pulsechain"` or `"robinhood"`. |
393
+ | `network` | **Yes** | string | Target blockchain network: `"pulsechain"` or `"robinhood"`. |
390
394
 
391
395
  #### Authentication
392
396
 
@@ -455,7 +459,7 @@ Detects whether a token has a fee-on-transfer mechanism (tax token) and returns
455
459
  | Parameter | Required | Type | Description |
456
460
  |---|---|---|---|
457
461
  | `token` | **Yes** | address | Token address to check (0x + 40 hex chars) |
458
- | `network` | No | string | Target blockchain: `"pulsechain"` or `"robinhood"`. |
462
+ | `network` | No | string | Target blockchain: `"pulsechain"` or `"robinhood"`. |
459
463
 
460
464
  #### Latency
461
465
 
@@ -569,9 +573,9 @@ Returns the optimal split-route for a swap and (optionally) a ready-to-send tran
569
573
 
570
574
  | Parameter | Required | Type | Default | Description |
571
575
  |---|---|---|---|---|
572
- | `network` | **Yes** | string | — | Target blockchain network: `"pulsechain"` or `"robinhood"`. |
573
- | `from` | **Yes** | address | — | Input token address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the network's native currency (PLS or ETH). |
574
- | `to` | **Yes** | address | — | Output token address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the network's native currency (PLS or ETH). |
576
+ | `network` | **Yes** | string | — | Target blockchain network: `"pulsechain"` or `"robinhood"`. |
577
+ | `from` | **Yes** | address | — | Input token address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the network's native currency (PLS or ETH). |
578
+ | `to` | **Yes** | address | — | Output token address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the network's native currency (PLS or ETH). |
575
579
  | `amount` | **Yes** | string | — | Input amount in **wei** (raw integer string, no decimals). Max: 10²⁷. |
576
580
  | `sender` | No* | address | — | Sender wallet address. **Required to receive `tx` calldata in the response.** |
577
581
  | `receiver` | No | address | `sender` | Custom recipient address. If omitted, output tokens are sent to `sender`. |
@@ -660,7 +664,7 @@ GET /swap/quote?network=pulsechain&from=0xA1077a294dDE1B09bB078844df40758a5D0f9a
660
664
  "tx": {
661
665
  "to": "0x0305fcb5dA680EA6fd1B01A96C1949175B99d406",
662
666
  "data": "0x...", // ABI-encoded goSwitch() calldata with feeOnOutput = false
663
- "value": "0" // "0" for ERC-20 input; amountIn for native-currency input
667
+ "value": "0" // "0" for ERC-20 input; amountIn for native-currency input
664
668
  },
665
669
  // Same swap but with fee taken from the output token instead
666
670
  "txFeeOnOutput": {
@@ -798,7 +802,7 @@ Errors are returned as JSON with an `error` field:
798
802
  | Error | Cause |
799
803
  |---|---|
800
804
  | `"Missing required parameter: network"` | `network` query param absent |
801
- | `"This network is not supported at this time."` | `network` is not a supported value (`"pulsechain"` or `"robinhood"`) |
805
+ | `"This network is not supported at this time."` | `network` is not a supported value (`"pulsechain"` or `"robinhood"`) |
802
806
  | `"Missing required parameters: from, to, amount"` | One or more required query params absent |
803
807
  | `"Invalid from address (must be 0x + 40 hex chars)"` | `from` is not a valid hex address |
804
808
  | `"Invalid to address (must be 0x + 40 hex chars)"` | `to` is not a valid hex address |
@@ -828,7 +832,7 @@ If the swap transaction reverts on-chain, the SwitchRouter contract returns one
828
832
  | `FinalAmountOutTooLow()` | Output after fees fell below `_minTotalAmountOut` — price moved beyond your slippage tolerance. Retry with a fresh quote or increase slippage. |
829
833
  | `ExcessiveFee()` | `_fee` exceeds the contract maximum (100 bps / 1 %). |
830
834
  | `InsufficientFee()` | `_fee` is below the protocol's `MIN_FEE`. Contact the Switch team if you need a lower fee. |
831
- | `MsgValueMismatch()` | For native-currency swaps, `msg.value` must exactly equal the route's total `amountIn`. |
835
+ | `MsgValueMismatch()` | For native-currency swaps, `msg.value` must exactly equal the route's total `amountIn`. |
832
836
  | `ZeroInput()` | No input amount was provided. |
833
837
 
834
838
  ---
@@ -881,11 +885,11 @@ function shouldFeeOnOutput(from: string, to: string, quote?: BestPathResponse):
881
885
  if (toAddr === MY_PROJECT_TOKEN) return false; // fee on input = collect input
882
886
 
883
887
  // Priority 2: Avoid collecting tax tokens (fee revenue lost to transfer tax)
884
- if (quote) {
885
- const fromIsTax = quote.fromTokenTax?.isTaxToken ?? false;
886
- const toIsTax = quote.toTokenTax?.isTaxToken ?? false;
887
- if (fromIsTax && toIsTax) return false;
888
- if (fromIsTax && !toIsTax) return true; // collect non-tax output
888
+ if (quote) {
889
+ const fromIsTax = quote.fromTokenTax?.isTaxToken ?? false;
890
+ const toIsTax = quote.toTokenTax?.isTaxToken ?? false;
891
+ if (fromIsTax && toIsTax) return false;
892
+ if (fromIsTax && !toIsTax) return true; // collect non-tax output
889
893
  if (toIsTax && !fromIsTax) return false; // collect non-tax input
890
894
  }
891
895
 
@@ -916,26 +920,30 @@ await signer.sendTransaction(chosenTx);
916
920
 
917
921
  ## Limit Orders
918
922
 
919
- 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.
920
-
921
- **→ Full integration guide: [`LIMIT-ORDERS.md`](LIMIT-ORDERS.md)**
922
-
923
- Covers: creating orders, approvals, `feeOnOutput` decision guide (tax tokens & operator flexibility), querying, cancellation, API reference, types, and EIP-712 details.
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.
924
932
 
925
933
  ---
926
934
 
927
935
  ## Constants & Addresses
928
936
 
929
- PulseChain constants are importable from [`src/constants.ts`](src/constants.ts).
930
- Robinhood constants are available from
931
- [`src/networks/robinhood.ts`](src/networks/robinhood.ts); see the complete
932
- [`ROBINHOOD.md`](ROBINHOOD.md) integration reference.
937
+ PulseChain constants are importable from [`src/constants.ts`](src/constants.ts).
938
+ Robinhood constants are available from
939
+ [`src/networks/robinhood.ts`](src/networks/robinhood.ts); see the complete
940
+ [`ROBINHOOD.md`](ROBINHOOD.md) integration reference.
933
941
 
934
942
  > **⚠️ Do not hardcode the SwitchRouter address.** The router contract may be redeployed from time to time. Always use the `tx.to` (or `txFeeOnOutput.to`) address returned by the `/bestPath` API response when building your transaction. This ensures your integration automatically picks up router upgrades without code changes.
935
943
 
936
944
  | Name | Value |
937
945
  |---|---|
938
- | **Chain** | PulseChain (Chain ID `369`); Robinhood Chain uses ID `4663` and network-specific exports |
946
+ | **Chain** | PulseChain (Chain ID `369`); Robinhood Chain uses ID `4663` and network-specific exports |
939
947
  | **SwitchRouter** | `0x0305fcb5dA680EA6fd1B01A96C1949175B99d406` |
940
948
  | **SwitchLimitOrder** (V2 — current) | `0x8e3881bdF81Fc0211383B2e576076B654F7aFD86` |
941
949
  | **SwitchLimitOrder** (V1 — legacy) | `0x0e884072a891b406C0D814907A1E2310fE5F5Deb` |