@switch-win/sdk 1.2.1 → 1.2.2
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 +81 -80
- package/ROBINHOOD.md +629 -597
- package/package.json +1 -1
- package/src/index.ts +26 -26
- package/src/limit-orders.ts +60 -30
- package/src/networks/index.ts +20 -20
- package/src/networks/robinhood.ts +327 -315
package/README.md
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/@switch-win/sdk)
|
|
4
4
|
[](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,41 @@ 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
|
|
124
|
-
module includes canonical chain metadata, deployed Switch contracts, vetted
|
|
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.
|
|
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
|
+
module includes canonical chain metadata, deployed Switch contracts, vetted
|
|
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. Robinhood limit-order deployment constants and EIP-712 domain values
|
|
153
|
+
are exported from `src/networks/robinhood.ts`.
|
|
153
154
|
|
|
154
155
|
---
|
|
155
156
|
|
|
@@ -250,8 +251,8 @@ function determineFeeOnOutput(
|
|
|
250
251
|
const isSellTax = fromTax.isTaxToken && fromTax.sellTaxBps > 0;
|
|
251
252
|
const isBuyTax = toTax.isTaxToken && toTax.buyTaxBps > 0;
|
|
252
253
|
|
|
253
|
-
// Both tokens are taxed — use fee on input to avoid extra output transfers.
|
|
254
|
-
if (isSellTax && isBuyTax) return false;
|
|
254
|
+
// Both tokens are taxed — use fee on input to avoid extra output transfers.
|
|
255
|
+
if (isSellTax && isBuyTax) return false;
|
|
255
256
|
|
|
256
257
|
// Only output token is tax — fee on input (avoids router holding output tokens)
|
|
257
258
|
if (isBuyTax) return false;
|
|
@@ -290,15 +291,15 @@ Fee portion: Router ──transfer──▶ FeeClaimer (3rd buy tax on fee amoun
|
|
|
290
291
|
```
|
|
291
292
|
The output token is transferred **three times** through different addresses, each incurring a buy tax. The user receives significantly less than expected.
|
|
292
293
|
|
|
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
|
|
294
|
+
**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.
|
|
295
|
+
|
|
296
|
+
### Executing the Swap
|
|
296
297
|
|
|
297
298
|
Once you have a quote, execute it in two steps:
|
|
298
299
|
|
|
299
300
|
#### Step 1 — Approve Token Spend (ERC-20 inputs only)
|
|
300
301
|
|
|
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.
|
|
302
|
+
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
303
|
|
|
303
304
|
Before sending an approval transaction, check whether the user already has sufficient allowance to avoid wasting gas on a redundant approve:
|
|
304
305
|
|
|
@@ -326,7 +327,7 @@ const { tx } = quoteResponse;
|
|
|
326
327
|
const txResponse = await signer.sendTransaction({
|
|
327
328
|
to: tx.to,
|
|
328
329
|
data: tx.data,
|
|
329
|
-
value: tx.value, // "0" for ERC-20 inputs, amountIn for native currency
|
|
330
|
+
value: tx.value, // "0" for ERC-20 inputs, amountIn for native currency
|
|
330
331
|
});
|
|
331
332
|
|
|
332
333
|
const receipt = await txResponse.wait();
|
|
@@ -386,7 +387,7 @@ Returns all available DEX adapters with their on-chain indices and contract addr
|
|
|
386
387
|
|
|
387
388
|
| Param | Required | Type | Description |
|
|
388
389
|
|---|---|---|---|
|
|
389
|
-
| `network` | **Yes** | string | Target blockchain network: `"pulsechain"` or `"robinhood"`. |
|
|
390
|
+
| `network` | **Yes** | string | Target blockchain network: `"pulsechain"` or `"robinhood"`. |
|
|
390
391
|
|
|
391
392
|
#### Authentication
|
|
392
393
|
|
|
@@ -455,7 +456,7 @@ Detects whether a token has a fee-on-transfer mechanism (tax token) and returns
|
|
|
455
456
|
| Parameter | Required | Type | Description |
|
|
456
457
|
|---|---|---|---|
|
|
457
458
|
| `token` | **Yes** | address | Token address to check (0x + 40 hex chars) |
|
|
458
|
-
| `network` | No | string | Target blockchain: `"pulsechain"` or `"robinhood"`. |
|
|
459
|
+
| `network` | No | string | Target blockchain: `"pulsechain"` or `"robinhood"`. |
|
|
459
460
|
|
|
460
461
|
#### Latency
|
|
461
462
|
|
|
@@ -569,9 +570,9 @@ Returns the optimal split-route for a swap and (optionally) a ready-to-send tran
|
|
|
569
570
|
|
|
570
571
|
| Parameter | Required | Type | Default | Description |
|
|
571
572
|
|---|---|---|---|---|
|
|
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). |
|
|
573
|
+
| `network` | **Yes** | string | — | Target blockchain network: `"pulsechain"` or `"robinhood"`. |
|
|
574
|
+
| `from` | **Yes** | address | — | Input token address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the network's native currency (PLS or ETH). |
|
|
575
|
+
| `to` | **Yes** | address | — | Output token address. Use `0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE` for the network's native currency (PLS or ETH). |
|
|
575
576
|
| `amount` | **Yes** | string | — | Input amount in **wei** (raw integer string, no decimals). Max: 10²⁷. |
|
|
576
577
|
| `sender` | No* | address | — | Sender wallet address. **Required to receive `tx` calldata in the response.** |
|
|
577
578
|
| `receiver` | No | address | `sender` | Custom recipient address. If omitted, output tokens are sent to `sender`. |
|
|
@@ -660,7 +661,7 @@ GET /swap/quote?network=pulsechain&from=0xA1077a294dDE1B09bB078844df40758a5D0f9a
|
|
|
660
661
|
"tx": {
|
|
661
662
|
"to": "0x0305fcb5dA680EA6fd1B01A96C1949175B99d406",
|
|
662
663
|
"data": "0x...", // ABI-encoded goSwitch() calldata with feeOnOutput = false
|
|
663
|
-
"value": "0" // "0" for ERC-20 input; amountIn for native-currency input
|
|
664
|
+
"value": "0" // "0" for ERC-20 input; amountIn for native-currency input
|
|
664
665
|
},
|
|
665
666
|
// Same swap but with fee taken from the output token instead
|
|
666
667
|
"txFeeOnOutput": {
|
|
@@ -798,7 +799,7 @@ Errors are returned as JSON with an `error` field:
|
|
|
798
799
|
| Error | Cause |
|
|
799
800
|
|---|---|
|
|
800
801
|
| `"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"`) |
|
|
802
|
+
| `"This network is not supported at this time."` | `network` is not a supported value (`"pulsechain"` or `"robinhood"`) |
|
|
802
803
|
| `"Missing required parameters: from, to, amount"` | One or more required query params absent |
|
|
803
804
|
| `"Invalid from address (must be 0x + 40 hex chars)"` | `from` is not a valid hex address |
|
|
804
805
|
| `"Invalid to address (must be 0x + 40 hex chars)"` | `to` is not a valid hex address |
|
|
@@ -828,7 +829,7 @@ If the swap transaction reverts on-chain, the SwitchRouter contract returns one
|
|
|
828
829
|
| `FinalAmountOutTooLow()` | Output after fees fell below `_minTotalAmountOut` — price moved beyond your slippage tolerance. Retry with a fresh quote or increase slippage. |
|
|
829
830
|
| `ExcessiveFee()` | `_fee` exceeds the contract maximum (100 bps / 1 %). |
|
|
830
831
|
| `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`. |
|
|
832
|
+
| `MsgValueMismatch()` | For native-currency swaps, `msg.value` must exactly equal the route's total `amountIn`. |
|
|
832
833
|
| `ZeroInput()` | No input amount was provided. |
|
|
833
834
|
|
|
834
835
|
---
|
|
@@ -881,11 +882,11 @@ function shouldFeeOnOutput(from: string, to: string, quote?: BestPathResponse):
|
|
|
881
882
|
if (toAddr === MY_PROJECT_TOKEN) return false; // fee on input = collect input
|
|
882
883
|
|
|
883
884
|
// 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
|
|
885
|
+
if (quote) {
|
|
886
|
+
const fromIsTax = quote.fromTokenTax?.isTaxToken ?? false;
|
|
887
|
+
const toIsTax = quote.toTokenTax?.isTaxToken ?? false;
|
|
888
|
+
if (fromIsTax && toIsTax) return false;
|
|
889
|
+
if (fromIsTax && !toIsTax) return true; // collect non-tax output
|
|
889
890
|
if (toIsTax && !fromIsTax) return false; // collect non-tax input
|
|
890
891
|
}
|
|
891
892
|
|
|
@@ -926,16 +927,16 @@ Covers: creating orders, approvals, `feeOnOutput` decision guide (tax tokens & o
|
|
|
926
927
|
|
|
927
928
|
## Constants & Addresses
|
|
928
929
|
|
|
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.
|
|
930
|
+
PulseChain constants are importable from [`src/constants.ts`](src/constants.ts).
|
|
931
|
+
Robinhood constants are available from
|
|
932
|
+
[`src/networks/robinhood.ts`](src/networks/robinhood.ts); see the complete
|
|
933
|
+
[`ROBINHOOD.md`](ROBINHOOD.md) integration reference.
|
|
933
934
|
|
|
934
935
|
> **⚠️ 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
936
|
|
|
936
937
|
| Name | Value |
|
|
937
938
|
|---|---|
|
|
938
|
-
| **Chain** | PulseChain (Chain ID `369`); Robinhood Chain uses ID `4663` and network-specific exports |
|
|
939
|
+
| **Chain** | PulseChain (Chain ID `369`); Robinhood Chain uses ID `4663` and network-specific exports |
|
|
939
940
|
| **SwitchRouter** | `0x0305fcb5dA680EA6fd1B01A96C1949175B99d406` |
|
|
940
941
|
| **SwitchLimitOrder** (V2 — current) | `0x8e3881bdF81Fc0211383B2e576076B654F7aFD86` |
|
|
941
942
|
| **SwitchLimitOrder** (V1 — legacy) | `0x0e884072a891b406C0D814907A1E2310fE5F5Deb` |
|