@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@switch-win/sdk",
3
- "version": "1.2.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
- LimitOrderMutationResponse,
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
- isNativePLS,
106
+ getPLSFlowAddress,
107
+ getNativeFlowAddress,
108
+ isNativePLS,
109
+ isNativeCurrency,
104
110
  submitLimitOrder,
105
111
  cancelLimitOrder,
106
112
  fetchLimitOrders,
107
113
  fetchLimitOrder,
108
- fetchLimitOrderPairs,
109
- fetchLimitOrderStats,
110
- } from "./limit-orders.js";
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
- } from "./limit-orders.js";
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
- ROBINHOOD_SWITCH_CONTRACTS,
123
- ROBINHOOD_UNISWAP_CONTRACTS,
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
- RobinhoodToken,
148
+ export type {
149
+ RobinhoodAdapter,
150
+ RobinhoodToken,
135
151
  RobinhoodQuoteParams,
136
152
  RobinhoodTaxInfo,
137
153
  } from "./networks/robinhood.js";
@@ -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()` + notify backend with `cancelLimitOrder()`
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
- } from "./constants.js";
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
- // PLSFlow (Native PLS Limit Orders)
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?: "pulsechain" | "robinhood";
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
- * PLSFlow (native PLS) orders are an exception — they are recorded
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
- * Cancel a limit order on the Switch backend (marks it CANCELLED in the DB).
348
- *
349
- * **Important:** This only removes the order from the backend orderbook. To
350
- * prevent the order from being filled on-chain, you MUST also call
351
- * `invalidateNonce(nonce)` on the SwitchLimitOrder contract. See the
352
- * cancellation guide in the README.
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?: "pulsechain" | "robinhood";
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.
@@ -1,9 +1,13 @@
1
1
  export {
2
2
  ROBINHOOD_NETWORK,
3
3
  ROBINHOOD_CHAIN,
4
- ROBINHOOD_NATIVE_ETH,
5
- ROBINHOOD_SWITCH_CONTRACTS,
6
- ROBINHOOD_UNISWAP_CONTRACTS,
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
- RobinhoodToken,
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
- } as const satisfies Readonly<Record<string, RobinhoodToken>>;
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-11 audit enumerated every pool creation from the Robinhood
215
- * Uniswap V2/V3 factories, then required multiple meaningful counterparties
216
- * and a successful zero-tax simulation. Keep this list synchronized with the
217
- * Robinhood backend routing configuration.
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
- ] as const;
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 = [