@switch-win/sdk 1.2.2 → 1.2.4
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 +29 -14
- package/ROBINHOOD.md +135 -50
- package/abi/SwitchLimitOrderABI.json +1 -1
- package/abi/SwitchRouterABI.json +1 -1
- package/package.json +3 -2
- package/src/constants.ts +3 -3
- package/src/index.ts +32 -16
- package/src/limit-orders.ts +135 -19
- package/src/networks/index.ts +10 -5
- package/src/networks/robinhood.ts +227 -21
- package/src/types.ts +53 -29
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@switch-win/sdk",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
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/constants.ts
CHANGED
|
@@ -167,9 +167,9 @@ export const ERC20_ABI = [
|
|
|
167
167
|
* Normally you don't need this — the API returns pre-encoded calldata in `tx.data`.
|
|
168
168
|
* Useful only if you want to decode or manually construct calldata.
|
|
169
169
|
*/
|
|
170
|
-
export const GO_SWITCH_ABI = [
|
|
171
|
-
"function goSwitch(tuple(uint256 amountIn, tuple(address tokenIn, address tokenOut, tuple(address adapter, uint256 amountIn, uint24 fee)[] legs)[] hops)[] _routes, address _to, uint256 _minTotalAmountOut, uint256 _fee, bool _feeOnOutput, bool _unwrapOutput, address _partnerAddress) payable",
|
|
172
|
-
] as const;
|
|
170
|
+
export const GO_SWITCH_ABI = [
|
|
171
|
+
"function goSwitch(tuple(uint256 amountIn, tuple(address tokenIn, address tokenOut, tuple(address adapter, uint256 amountIn, uint24 fee, bytes data)[] legs)[] hops)[] _routes, address _to, uint256 _minTotalAmountOut, uint256 _fee, bool _feeOnOutput, bool _unwrapOutput, address _partnerAddress) payable",
|
|
172
|
+
] as const;
|
|
173
173
|
|
|
174
174
|
/**
|
|
175
175
|
* SwitchRouter custom error signatures for decoding reverts.
|
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,32 +96,46 @@ 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
|
-
|
|
123
|
-
|
|
132
|
+
ROBINHOOD_NATIVE_ETH,
|
|
133
|
+
ROBINHOOD_LIMIT_ORDER_EIP712_DOMAIN,
|
|
134
|
+
ROBINHOOD_SWITCH_CONTRACTS,
|
|
135
|
+
ROBINHOOD_ADAPTERS,
|
|
136
|
+
ROBINHOOD_TAX_SAFE_ADAPTER_INDICES,
|
|
137
|
+
ROBINHOOD_TAX_SAFE_ADAPTERS,
|
|
138
|
+
ROBINHOOD_UNISWAP_CONTRACTS,
|
|
124
139
|
ROBINHOOD_TOKENS,
|
|
125
140
|
ROBINHOOD_FRONTEND_TOKEN_LIST,
|
|
126
141
|
ROBINHOOD_FRONTEND_DEFAULT_TOKENS,
|
|
@@ -130,8 +145,9 @@ export {
|
|
|
130
145
|
buildRobinhoodQuoteUrl,
|
|
131
146
|
} from "./networks/robinhood.js";
|
|
132
147
|
|
|
133
|
-
export type {
|
|
134
|
-
|
|
148
|
+
export type {
|
|
149
|
+
RobinhoodAdapter,
|
|
150
|
+
RobinhoodToken,
|
|
135
151
|
RobinhoodQuoteParams,
|
|
136
152
|
RobinhoodTaxInfo,
|
|
137
153
|
} from "./networks/robinhood.js";
|
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,9 +1,13 @@
|
|
|
1
1
|
export {
|
|
2
2
|
ROBINHOOD_NETWORK,
|
|
3
3
|
ROBINHOOD_CHAIN,
|
|
4
|
-
ROBINHOOD_NATIVE_ETH,
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
ROBINHOOD_NATIVE_ETH,
|
|
5
|
+
ROBINHOOD_LIMIT_ORDER_EIP712_DOMAIN,
|
|
6
|
+
ROBINHOOD_SWITCH_CONTRACTS,
|
|
7
|
+
ROBINHOOD_ADAPTERS,
|
|
8
|
+
ROBINHOOD_TAX_SAFE_ADAPTER_INDICES,
|
|
9
|
+
ROBINHOOD_TAX_SAFE_ADAPTERS,
|
|
10
|
+
ROBINHOOD_UNISWAP_CONTRACTS,
|
|
7
11
|
ROBINHOOD_TOKENS,
|
|
8
12
|
ROBINHOOD_FRONTEND_TOKEN_LIST,
|
|
9
13
|
ROBINHOOD_FRONTEND_DEFAULT_TOKENS,
|
|
@@ -13,8 +17,9 @@ export {
|
|
|
13
17
|
buildRobinhoodQuoteUrl,
|
|
14
18
|
} from "./robinhood.js";
|
|
15
19
|
|
|
16
|
-
export type {
|
|
17
|
-
|
|
20
|
+
export type {
|
|
21
|
+
RobinhoodAdapter,
|
|
22
|
+
RobinhoodToken,
|
|
18
23
|
RobinhoodQuoteParams,
|
|
19
24
|
RobinhoodTaxInfo,
|
|
20
25
|
} from "./robinhood.js";
|
|
@@ -22,18 +22,173 @@ export const ROBINHOOD_NATIVE_ETH =
|
|
|
22
22
|
|
|
23
23
|
/** Switch contracts deployed on Robinhood Chain. */
|
|
24
24
|
export const ROBINHOOD_SWITCH_CONTRACTS = {
|
|
25
|
-
/** ERC-20 approval target. Use quote.tx.to when submitting a swap. */
|
|
26
|
-
router: "0x8730C3e2cF2c8CDa8E6166837A1Ed26f46aa9E59",
|
|
27
|
-
routerView: "0xFF6b56d3F444eB5b7FA1db047F57140C84810376",
|
|
28
|
-
uniswapV2Adapter: "0x7a14d7A8509a66209D4332843b983b29bF5604A4",
|
|
29
|
-
uniswapV3Adapter: "0xbcA08f296d9Ba0dc19Aa0E05D355365cE29A3205",
|
|
30
|
-
uniswapV4Adapter: "0x754dDCD05aFbAd1cc7Bc42B9268EB586F579E7F6",
|
|
25
|
+
/** ERC-20 approval target. Use quote.tx.to when submitting a swap. */
|
|
26
|
+
router: "0x8730C3e2cF2c8CDa8E6166837A1Ed26f46aa9E59",
|
|
27
|
+
routerView: "0xFF6b56d3F444eB5b7FA1db047F57140C84810376",
|
|
31
28
|
limitOrder: "0x752c50DDd3B426cAE3D7A995F313Ac74ac6B0230",
|
|
32
29
|
nativeEthFlow: "0x029FfC6aF9112eA078f1D6f4a98826DDB2136cf6",
|
|
30
|
+
uniswapV2Adapter: "0x7a14d7A8509a66209D4332843b983b29bF5604A4",
|
|
31
|
+
uniswapV3Adapter: "0xbcA08f296d9Ba0dc19Aa0E05D355365cE29A3205",
|
|
32
|
+
uniswapV4Adapter: "0x754dDCD05aFbAd1cc7Bc42B9268EB586F579E7F6",
|
|
33
33
|
limitOrderAdapter: "0x412F625072c10e58C619D1e0b3C95cd3d5689871",
|
|
34
|
+
swapHoodV2Adapter: "0x6D8746f02e52944c13824fA691c6f4186E463354",
|
|
35
|
+
swapHoodV3Adapter: "0x9645dE0AcB48F0AAefdBEb423F0558457907DE98",
|
|
36
|
+
up33Adapter: "0x388179D2FB0ABcE9b03068916aF8a3c4dfD023c8",
|
|
37
|
+
sheriffV2Adapter: "0xBDB3EB0355981500f58C9bc77c3E61762844A146",
|
|
38
|
+
sheriffAlgebraAdapter: "0xaC4da986100724983042Ec28c28db243E2f828CB",
|
|
39
|
+
aeonAlgebraAdapter: "0x20615954FB87360139e7DdDB519359498EbD1904",
|
|
40
|
+
catnipV2Adapter: "0x5b2Ca358d56490Dc86224D502522314De7707237",
|
|
41
|
+
pancakeSwapV2Adapter: "0x3B6e71A59553143937Fef74a7B50AFD24528786E",
|
|
42
|
+
robinSwapV3Adapter: "0x798f77D63b46b0E019de206E111e5ea5CC16BEc8",
|
|
43
|
+
sushiSwapV3Adapter: "0xca3EA0Fd6E31f94c81B6586836790adE638313ED",
|
|
44
|
+
gigaV2Adapter: "0xa379c7D17F7fEe735773879D4069886B117AB54a",
|
|
45
|
+
gigaV3Adapter: "0xcAa612CDe3d3FbE97Be97eB5f79BC91597432d55",
|
|
46
|
+
flapAdapter: "0x6af2A4475C44d5833575150Bf7C3D3FE6Bf4F344",
|
|
47
|
+
ramsesV3Adapter: "0xdBf182774C60932c6fe1Bf3FFaB8Ca28CCb0dC17",
|
|
48
|
+
ramsesV2Adapter: "0x5fe3b873c222e76f7630b40052f07ee06196E6d3",
|
|
34
49
|
limitOrderAdapterIndex: 3,
|
|
35
50
|
} as const;
|
|
36
51
|
|
|
52
|
+
export interface RobinhoodAdapter {
|
|
53
|
+
readonly index: number;
|
|
54
|
+
readonly name: string;
|
|
55
|
+
readonly address: string;
|
|
56
|
+
/** Whether the backend may use this adapter for transfer-tax routes. */
|
|
57
|
+
readonly taxSafe: boolean;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Snapshot of the ordered production adapter registry verified on 2026-08-02.
|
|
62
|
+
*
|
|
63
|
+
* Adapter registration can change. Fetch
|
|
64
|
+
* `GET /swap/adapters?network=robinhood` when runtime freshness matters.
|
|
65
|
+
*/
|
|
66
|
+
export const ROBINHOOD_ADAPTERS = [
|
|
67
|
+
{
|
|
68
|
+
index: 0,
|
|
69
|
+
name: "UniswapV2",
|
|
70
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.uniswapV2Adapter,
|
|
71
|
+
taxSafe: true,
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
index: 1,
|
|
75
|
+
name: "UniswapV3",
|
|
76
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.uniswapV3Adapter,
|
|
77
|
+
taxSafe: false,
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
index: 2,
|
|
81
|
+
name: "UniswapV4",
|
|
82
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.uniswapV4Adapter,
|
|
83
|
+
taxSafe: false,
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
index: 3,
|
|
87
|
+
name: "SwitchLimitOrders",
|
|
88
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.limitOrderAdapter,
|
|
89
|
+
taxSafe: false,
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
index: 4,
|
|
93
|
+
name: "SwapHoodV2",
|
|
94
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.swapHoodV2Adapter,
|
|
95
|
+
taxSafe: true,
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
index: 5,
|
|
99
|
+
name: "SwapHoodV3",
|
|
100
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.swapHoodV3Adapter,
|
|
101
|
+
taxSafe: false,
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
index: 6,
|
|
105
|
+
name: "Up33",
|
|
106
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.up33Adapter,
|
|
107
|
+
taxSafe: false,
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
index: 7,
|
|
111
|
+
name: "SheriffV2",
|
|
112
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.sheriffV2Adapter,
|
|
113
|
+
taxSafe: true,
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
index: 8,
|
|
117
|
+
name: "SheriffAlgebra",
|
|
118
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.sheriffAlgebraAdapter,
|
|
119
|
+
taxSafe: false,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
index: 9,
|
|
123
|
+
name: "AeonAlgebra",
|
|
124
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.aeonAlgebraAdapter,
|
|
125
|
+
taxSafe: false,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
index: 10,
|
|
129
|
+
name: "CatnipV2",
|
|
130
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.catnipV2Adapter,
|
|
131
|
+
taxSafe: true,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
index: 11,
|
|
135
|
+
name: "PancakeSwapV2",
|
|
136
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.pancakeSwapV2Adapter,
|
|
137
|
+
taxSafe: true,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
index: 12,
|
|
141
|
+
name: "RobinSwapV3",
|
|
142
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.robinSwapV3Adapter,
|
|
143
|
+
taxSafe: false,
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
index: 13,
|
|
147
|
+
name: "SushiSwapV3",
|
|
148
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.sushiSwapV3Adapter,
|
|
149
|
+
taxSafe: false,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
index: 14,
|
|
153
|
+
name: "GigaV2",
|
|
154
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.gigaV2Adapter,
|
|
155
|
+
taxSafe: true,
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
index: 15,
|
|
159
|
+
name: "GigaV3",
|
|
160
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.gigaV3Adapter,
|
|
161
|
+
taxSafe: false,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
index: 16,
|
|
165
|
+
name: "Flap",
|
|
166
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.flapAdapter,
|
|
167
|
+
taxSafe: true,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
index: 17,
|
|
171
|
+
name: "RamsesV3",
|
|
172
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.ramsesV3Adapter,
|
|
173
|
+
taxSafe: false,
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
index: 18,
|
|
177
|
+
name: "RamsesV2",
|
|
178
|
+
address: ROBINHOOD_SWITCH_CONTRACTS.ramsesV2Adapter,
|
|
179
|
+
taxSafe: true,
|
|
180
|
+
},
|
|
181
|
+
] as const satisfies readonly RobinhoodAdapter[];
|
|
182
|
+
|
|
183
|
+
/** Adapter indices currently eligible for Robinhood transfer-tax routes. */
|
|
184
|
+
export const ROBINHOOD_TAX_SAFE_ADAPTER_INDICES = [
|
|
185
|
+
0, 4, 7, 10, 11, 14, 16, 18,
|
|
186
|
+
] as const;
|
|
187
|
+
|
|
188
|
+
/** Current Robinhood transfer-tax-safe adapter metadata. */
|
|
189
|
+
export const ROBINHOOD_TAX_SAFE_ADAPTERS: readonly RobinhoodAdapter[] =
|
|
190
|
+
ROBINHOOD_ADAPTERS.filter((adapter) => adapter.taxSafe);
|
|
191
|
+
|
|
37
192
|
/** EIP-712 domain used for Robinhood ERC-20 limit-order signatures. */
|
|
38
193
|
export const ROBINHOOD_LIMIT_ORDER_EIP712_DOMAIN = {
|
|
39
194
|
name: "SwitchLimitOrder",
|
|
@@ -163,13 +318,49 @@ export const ROBINHOOD_TOKENS = {
|
|
|
163
318
|
name: "4663",
|
|
164
319
|
decimals: 18,
|
|
165
320
|
},
|
|
166
|
-
MARIAN: {
|
|
321
|
+
MARIAN: {
|
|
167
322
|
address: "0x01637b14B7378B99dE75A64d50656d98488D9a4d",
|
|
168
323
|
symbol: "MARIAN",
|
|
169
324
|
name: "Lady Marian",
|
|
170
|
-
decimals: 18,
|
|
171
|
-
},
|
|
172
|
-
|
|
325
|
+
decimals: 18,
|
|
326
|
+
},
|
|
327
|
+
INDEX: {
|
|
328
|
+
address: "0x56910D4409F3a0C78C64DD8D0545FF0705389870",
|
|
329
|
+
symbol: "Index",
|
|
330
|
+
name: "The Index",
|
|
331
|
+
decimals: 18,
|
|
332
|
+
},
|
|
333
|
+
VEX: {
|
|
334
|
+
address: "0x8Ff92566f2e81BDd68EDfAa8cde73942A723796b",
|
|
335
|
+
symbol: "VEX",
|
|
336
|
+
name: "ProjectVex",
|
|
337
|
+
decimals: 18,
|
|
338
|
+
},
|
|
339
|
+
HOODIE: {
|
|
340
|
+
address: "0xC72c01AAB5f5678dc1d6f5C6d2B417d91D402Ba3",
|
|
341
|
+
symbol: "HOODIE",
|
|
342
|
+
name: "HOODIE",
|
|
343
|
+
decimals: 18,
|
|
344
|
+
},
|
|
345
|
+
WISHBONE: {
|
|
346
|
+
address: "0x77581054581B9c525E7dd7a0155DE43867532d03",
|
|
347
|
+
symbol: "WISHBONE",
|
|
348
|
+
name: "WISHBONE",
|
|
349
|
+
decimals: 18,
|
|
350
|
+
},
|
|
351
|
+
VLAD: {
|
|
352
|
+
address: "0x31BE8f7485e36928C9De86566c62da82d4B6BF81",
|
|
353
|
+
symbol: "VLAD",
|
|
354
|
+
name: "The Green Bull",
|
|
355
|
+
decimals: 18,
|
|
356
|
+
},
|
|
357
|
+
AEON: {
|
|
358
|
+
address: "0xd4c93eD1843606f92CccA078941f3d52A585982f",
|
|
359
|
+
symbol: "AEON",
|
|
360
|
+
name: "Aeon",
|
|
361
|
+
decimals: 18,
|
|
362
|
+
},
|
|
363
|
+
} as const satisfies Readonly<Record<string, RobinhoodToken>>;
|
|
173
364
|
|
|
174
365
|
/** Exact ERC-20 ordering used by the Switch Robinhood token dropdown. */
|
|
175
366
|
export const ROBINHOOD_FRONTEND_TOKEN_LIST = [
|
|
@@ -187,8 +378,14 @@ export const ROBINHOOD_FRONTEND_TOKEN_LIST = [
|
|
|
187
378
|
ROBINHOOD_TOKENS.REPE,
|
|
188
379
|
ROBINHOOD_TOKENS.TENDIES,
|
|
189
380
|
ROBINHOOD_TOKENS.GME,
|
|
190
|
-
ROBINHOOD_TOKENS.TOKEN_4663,
|
|
191
|
-
ROBINHOOD_TOKENS.MARIAN,
|
|
381
|
+
ROBINHOOD_TOKENS.TOKEN_4663,
|
|
382
|
+
ROBINHOOD_TOKENS.MARIAN,
|
|
383
|
+
ROBINHOOD_TOKENS.INDEX,
|
|
384
|
+
ROBINHOOD_TOKENS.VEX,
|
|
385
|
+
ROBINHOOD_TOKENS.HOODIE,
|
|
386
|
+
ROBINHOOD_TOKENS.WISHBONE,
|
|
387
|
+
ROBINHOOD_TOKENS.VLAD,
|
|
388
|
+
ROBINHOOD_TOKENS.AEON,
|
|
192
389
|
] as const satisfies readonly RobinhoodToken[];
|
|
193
390
|
|
|
194
391
|
/**
|
|
@@ -204,24 +401,33 @@ export const ROBINHOOD_FRONTEND_DEFAULT_TOKENS = [
|
|
|
204
401
|
name: "Ether",
|
|
205
402
|
decimals: 18,
|
|
206
403
|
},
|
|
207
|
-
ROBINHOOD_TOKENS.WETH,
|
|
208
|
-
ROBINHOOD_TOKENS.USDG,
|
|
404
|
+
ROBINHOOD_TOKENS.WETH,
|
|
405
|
+
ROBINHOOD_TOKENS.USDG,
|
|
406
|
+
ROBINHOOD_TOKENS.VIRTUAL,
|
|
407
|
+
ROBINHOOD_TOKENS.CASHCAT,
|
|
408
|
+
ROBINHOOD_TOKENS.INDEX,
|
|
209
409
|
] as const satisfies readonly RobinhoodToken[];
|
|
210
410
|
|
|
211
411
|
/**
|
|
212
412
|
* Production trusted-hop addresses, ordered by routing usefulness.
|
|
213
413
|
*
|
|
214
|
-
* The 2026-07-
|
|
215
|
-
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
414
|
+
* The 2026-07-16 audit combined Dexscreener pool connectivity with Switch tax
|
|
415
|
+
* simulation, then required multiple meaningful liquidity corridors. VEX is
|
|
416
|
+
* selectable but excluded because it is taxed; INDEX is excluded because its
|
|
417
|
+
* dominant liquidity currently depends on unsupported V4 hooks. Keep this
|
|
418
|
+
* list synchronized with the Robinhood backend and operator bot.
|
|
218
419
|
*/
|
|
219
420
|
export const ROBINHOOD_TRUSTED_INTERMEDIATES = [
|
|
220
421
|
ROBINHOOD_TOKENS.WETH.address,
|
|
221
422
|
ROBINHOOD_TOKENS.USDG.address,
|
|
222
|
-
ROBINHOOD_TOKENS.VIRTUAL.address,
|
|
223
|
-
ROBINHOOD_TOKENS.CASHCAT.address,
|
|
224
|
-
|
|
423
|
+
ROBINHOOD_TOKENS.VIRTUAL.address,
|
|
424
|
+
ROBINHOOD_TOKENS.CASHCAT.address,
|
|
425
|
+
ROBINHOOD_TOKENS.HOODRAT.address,
|
|
426
|
+
ROBINHOOD_TOKENS.TENDIES.address,
|
|
427
|
+
ROBINHOOD_TOKENS.JUGGERNAUT.address,
|
|
428
|
+
ROBINHOOD_TOKENS.MARIAN.address,
|
|
429
|
+
ROBINHOOD_TOKENS.WALLET.address,
|
|
430
|
+
] as const;
|
|
225
431
|
|
|
226
432
|
/** Preferred Robinhood fee tokens, from highest to lowest priority. */
|
|
227
433
|
export const ROBINHOOD_FEE_TOKEN_PRIORITY = [
|