@peachprojects/aggregator-sdk 0.1.2 → 0.1.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/dist/index.mjs CHANGED
@@ -1,75 +1,75 @@
1
- import { ethers as l } from "ethers";
2
- const q = "https://api.peach.ag", he = 50, b = 10000n, L = 500, fe = 5e3, T = 1200, W = 6e4, $ = [50, 100, 200, 400, 800, 1200], Q = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
3
- function _(w) {
4
- return w.toLowerCase() === Q.toLowerCase();
1
+ import { ethers as m } from "ethers";
2
+ const J = "https://api.peach.ag", Se = 50, _ = 10000n, U = 500, Ie = 5e3, N = 1200, G = 6e4, M = [50, 100, 200, 400, 800, 1200], q = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
3
+ function T(f) {
4
+ return f.toLowerCase() === q.toLowerCase();
5
5
  }
6
- const we = 4001;
7
- var f = /* @__PURE__ */ ((w) => (w.PancakeV2 = "PancakeV2", w.PancakeV3 = "PancakeV3", w.PancakeInfinityCl = "Pancake_Infinity_Cl", w.UniswapV3 = "UniswapV3", w.UniswapV4 = "UniswapV4", w.Dodo = "Dodo", w.Thena = "Thena", w.NomiswapStable = "Nomiswap_Stable", w.Biswap = "Biswap", w.Apeswap = "Apeswap", w.BabyDogeSwap = "BabyDogeSwap", w.BabySwap = "BabySwap", w))(f || {});
8
- const me = {
6
+ const Pe = 4001;
7
+ var d = /* @__PURE__ */ ((f) => (f.PancakeV1 = "PancakeV1", f.PancakeV2 = "PancakeV2", f.PancakeV3 = "PancakeV3", f.PancakeInfinityCl = "Pancake_Infinity_Cl", f.PancakeInfinityLb = "Pancake_Infinity_Lb", f.UniswapV2 = "UniswapV2", f.UniswapV3 = "UniswapV3", f.UniswapV4 = "UniswapV4", f.Dodo = "Dodo", f.ThenaV3 = "ThenaV3", f.ThenaFusion = "Thena_Fusion", f.NomiswapStable = "Nomiswap_Stable", f.Biswap = "Biswap", f.Apeswap = "Apeswap", f.BabyDogeSwap = "BabyDogeSwap", f.BabySwap = "BabySwap", f.BakerySwap = "BakerySwap", f.PancakeStable = "Pancake_Stable", f.ListaStable = "Lista_Stable", f.SquadSwapV3 = "SquadSwap_V3", f.SquadSwapV2 = "SquadSwap_V2", f.Wombat = "Wombat", f.SushiSwapV2 = "SushiSwap_V2", f.SushiSwapV3 = "SushiSwap_V3", f))(d || {});
8
+ const ke = {
9
9
  chainId: 56,
10
10
  rpcUrl: "https://bsc-dataseed.binance.org",
11
11
  weth: "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",
12
12
  // WBNB
13
13
  adapters: []
14
- }, ve = {
14
+ }, Ee = {
15
15
  chainId: 97,
16
16
  rpcUrl: "https://bsc-testnet-rpc.publicnode.com",
17
17
  weth: "0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd",
18
18
  // WBNB Testnet
19
19
  adapters: []
20
20
  };
21
- class x extends Error {
21
+ class B extends Error {
22
22
  constructor(e) {
23
23
  super(e), this.name = "CustomFeeError";
24
24
  }
25
25
  }
26
- class H extends Error {
27
- constructor(e, t, o) {
28
- super(e), this.name = "ExecuteTimeoutError", this.stage = t, this.txHash = o;
26
+ class Q extends Error {
27
+ constructor(e, t, n) {
28
+ super(e), this.name = "ExecuteTimeoutError", this.stage = t, this.txHash = n;
29
29
  }
30
30
  }
31
- const k = {
31
+ const O = "0x000000000022D473030F116dDEE9F6B43aC78BA3", $ = (1n << 160n) - 1n, E = {
32
32
  /** Default route search depth */
33
33
  depth: 3,
34
34
  /** Default trade split count */
35
35
  splitCount: 20,
36
36
  /** Default DEX providers */
37
- providers: ["PANCAKEV2", "PANCAKEV3", "PANCAKE_INFINITY_CL", "UNISWAPV3", "UNISWAPV4", "DODO", "THENA", "NOMISWAP_STABLE", "BISWAP", "APESWAP", "BABYDOGESWAP", "BABYSWAP"],
37
+ providers: ["PANCAKEV1", "PANCAKEV2", "PANCAKEV3", "PANCAKE_INFINITY_CL", "PANCAKE_INFINITY_LB", "UNISWAPV2", "UNISWAPV3", "UNISWAPV4", "DODO", "THENAV3", "NOMISWAP_STABLE", "BISWAP", "APESWAP", "BABYDOGESWAP", "BABYSWAP", "BAKERYSWAP", "PANCAKE_STABLE", "LISTA_STABLE", "SQUADSWAP_V3", "SQUADSWAP_V2", "WOMBAT", "THENA_FUSION", "SUSHISWAP_V2", "SUSHISWAP_V3"],
38
38
  /** Default client version for V3 API */
39
39
  clientVersion: 1001500
40
- }, z = 1e4;
41
- function J(w) {
40
+ }, ee = 1e4;
41
+ function te(f) {
42
42
  const e = {};
43
- return w.forEach((t, o) => {
44
- e[o] = t;
43
+ return f.forEach((t, n) => {
44
+ e[n] = t;
45
45
  }), e;
46
46
  }
47
- class X {
47
+ class ne {
48
48
  constructor(e = {}) {
49
- this.baseUrl = e.baseUrl || q, this.timeout = e.timeout || z, this.extraHeaders = e.headers ? { ...e.headers } : {};
49
+ this.baseUrl = e.baseUrl || J, this.timeout = e.timeout || ee, this.extraHeaders = e.headers ? { ...e.headers } : {};
50
50
  }
51
51
  async findRoutes(e) {
52
52
  const {
53
53
  from: t,
54
- target: o,
55
- amount: n,
56
- byAmountIn: s = !0,
57
- depth: r = k.depth,
58
- splitCount: a = k.splitCount,
59
- providers: i = k.providers,
54
+ target: n,
55
+ amount: s,
56
+ byAmountIn: o = !0,
57
+ depth: r = E.depth,
58
+ splitCount: a = E.splitCount,
59
+ providers: i = E.providers,
60
60
  includeResponseHeaders: c = !1
61
61
  } = e, u = new URLSearchParams({
62
62
  from: t,
63
- target: o,
64
- amount: n.toString(),
65
- by_amount_in: s.toString(),
63
+ target: n,
64
+ amount: s.toString(),
65
+ by_amount_in: o.toString(),
66
66
  depth: r.toString(),
67
67
  split_count: a.toString(),
68
68
  providers: i.join(","),
69
- v: k.clientVersion.toString()
70
- }), d = `${this.baseUrl}/router/find_routes?${u}`, p = new AbortController(), g = setTimeout(() => p.abort(), this.timeout);
69
+ v: E.clientVersion.toString()
70
+ }), l = `${this.baseUrl}/router/find_routes?${u}`, p = new AbortController(), A = setTimeout(() => p.abort(), this.timeout);
71
71
  try {
72
- const m = await fetch(d, {
72
+ const w = await fetch(l, {
73
73
  method: "GET",
74
74
  headers: {
75
75
  Accept: "application/json",
@@ -77,31 +77,31 @@ class X {
77
77
  },
78
78
  signal: p.signal
79
79
  });
80
- if (clearTimeout(g), !m.ok)
81
- throw new A(
82
- `API request failed: ${m.status} ${m.statusText}`,
83
- m.status
80
+ if (clearTimeout(A), !w.ok)
81
+ throw new S(
82
+ `API request failed: ${w.status} ${w.statusText}`,
83
+ w.status
84
84
  );
85
- const v = await m.json();
85
+ const v = await w.json();
86
86
  if (v.code !== 200)
87
- throw new A(v.msg || "Route not found", v.code);
87
+ throw new S(v.msg || "Route not found", v.code);
88
88
  if (!v.data || !v.data.paths || v.data.paths.length === 0)
89
- throw new A("No routes found", 404);
89
+ throw new S("No routes found", 404);
90
90
  return c ? {
91
91
  data: v.data,
92
- responseHeaders: J(m.headers)
92
+ responseHeaders: te(w.headers)
93
93
  } : v.data;
94
- } catch (m) {
95
- throw clearTimeout(g), m instanceof A ? m : m instanceof Error ? m.name === "AbortError" ? new A("API request timeout", 408) : new A(`API request failed: ${m.message}`, 0) : new A("Unknown API error", 0);
94
+ } catch (w) {
95
+ throw clearTimeout(A), w instanceof S ? w : w instanceof Error ? w.name === "AbortError" ? new S("API request timeout", 408) : new S(`API request failed: ${w.message}`, 0) : new S("Unknown API error", 0);
96
96
  }
97
97
  }
98
98
  /**
99
99
  * Get service status including available providers
100
100
  */
101
101
  async getStatus() {
102
- const e = `${this.baseUrl}/router/status`, t = new AbortController(), o = setTimeout(() => t.abort(), this.timeout);
102
+ const e = `${this.baseUrl}/router/status`, t = new AbortController(), n = setTimeout(() => t.abort(), this.timeout);
103
103
  try {
104
- const n = await fetch(e, {
104
+ const s = await fetch(e, {
105
105
  method: "GET",
106
106
  headers: {
107
107
  Accept: "application/json",
@@ -109,17 +109,17 @@ class X {
109
109
  },
110
110
  signal: t.signal
111
111
  });
112
- if (clearTimeout(o), !n.ok)
113
- throw new A(
114
- `API request failed: ${n.status} ${n.statusText}`,
115
- n.status
112
+ if (clearTimeout(n), !s.ok)
113
+ throw new S(
114
+ `API request failed: ${s.status} ${s.statusText}`,
115
+ s.status
116
116
  );
117
- const s = await n.json();
118
- if (s.code !== 200)
119
- throw new A(s.msg || "Failed to get status", s.code);
120
- return s.data;
121
- } catch (n) {
122
- throw clearTimeout(o), n instanceof A ? n : n instanceof Error ? n.name === "AbortError" ? new A("API request timeout", 408) : new A(`API request failed: ${n.message}`, 0) : new A("Unknown API error", 0);
117
+ const o = await s.json();
118
+ if (o.code !== 200)
119
+ throw new S(o.msg || "Failed to get status", o.code);
120
+ return o.data;
121
+ } catch (s) {
122
+ throw clearTimeout(n), s instanceof S ? s : s instanceof Error ? s.name === "AbortError" ? new S("API request timeout", 408) : new S(`API request failed: ${s.message}`, 0) : new S("Unknown API error", 0);
123
123
  }
124
124
  }
125
125
  /**
@@ -141,22 +141,22 @@ class X {
141
141
  return this.baseUrl;
142
142
  }
143
143
  }
144
- class A extends Error {
144
+ class S extends Error {
145
145
  constructor(e, t) {
146
146
  super(e), this.name = "ApiError", this.code = t;
147
147
  }
148
148
  }
149
- async function U(w, e = W) {
149
+ async function W(f, e = G) {
150
150
  if (e <= 0)
151
- return w;
151
+ return f;
152
152
  let t;
153
153
  try {
154
154
  return await Promise.race([
155
- w,
156
- new Promise((o, n) => {
155
+ f,
156
+ new Promise((n, s) => {
157
157
  t = setTimeout(() => {
158
- n(
159
- new H(
158
+ s(
159
+ new Q(
160
160
  `Wallet did not settle sendTransaction within ${e}ms.`,
161
161
  "wallet_send"
162
162
  )
@@ -168,9 +168,13 @@ async function U(w, e = W) {
168
168
  t && clearTimeout(t);
169
169
  }
170
170
  }
171
- const B = [
171
+ const R = [
172
172
  "function swap((address srcToken, address dstToken, uint256 amountIn, uint256 amountOutMin, (address adapter, address pool, address tokenIn, address tokenOut, uint256 amountIn, bytes extraData)[] steps, address[] intermediateTokens, uint256 deadline, bytes32 quoteId, uint256 expectAmountOut, address feeReceiver, uint16 feeBps) params) external returns (uint256 amountOut)",
173
173
  "function swapETH((address srcToken, address dstToken, uint256 amountIn, uint256 amountOutMin, (address adapter, address pool, address tokenIn, address tokenOut, uint256 amountIn, bytes extraData)[] steps, address[] intermediateTokens, uint256 deadline, bytes32 quoteId, uint256 expectAmountOut, address feeReceiver, uint16 feeBps) params) external payable returns (uint256 amountOut)",
174
+ // Permit2 (AllowanceTransfer) entrypoints. Second arg is the Permit2Sig tuple:
175
+ // ((PermitDetails details, address spender, uint256 sigDeadline) permitSingle, bytes signature)
176
+ "function swapWithPermit2((address srcToken, address dstToken, uint256 amountIn, uint256 amountOutMin, (address adapter, address pool, address tokenIn, address tokenOut, uint256 amountIn, bytes extraData)[] steps, address[] intermediateTokens, uint256 deadline, bytes32 quoteId, uint256 expectAmountOut, address feeReceiver, uint16 feeBps) params, (((address token, uint160 amount, uint48 expiration, uint48 nonce) details, address spender, uint256 sigDeadline) permitSingle, bytes signature) p2) external returns (uint256 amountOut)",
177
+ "function swapETHWithPermit2((address srcToken, address dstToken, uint256 amountIn, uint256 amountOutMin, (address adapter, address pool, address tokenIn, address tokenOut, uint256 amountIn, bytes extraData)[] steps, address[] intermediateTokens, uint256 deadline, bytes32 quoteId, uint256 expectAmountOut, address feeReceiver, uint16 feeBps) params, (((address token, uint160 amount, uint48 expiration, uint48 nonce) details, address spender, uint256 sigDeadline) permitSingle, bytes signature) p2) external returns (uint256 amountOut)",
174
178
  "function isAdapterRegistered(address adapter) external view returns (bool)",
175
179
  "function getAdapterProtocolId(address adapter) external view returns (bytes32)",
176
180
  "function WETH() external view returns (address)",
@@ -181,40 +185,65 @@ const B = [
181
185
  "function maxProtocolCutBps() external view returns (uint16)",
182
186
  "function protocolFeeReceiver() external view returns (address)",
183
187
  "function protocolCutBps() external view returns (uint16)"
184
- ], y = [
188
+ ], b = [
185
189
  "function approve(address spender, uint256 amount) external returns (bool)",
186
190
  "function allowance(address owner, address spender) external view returns (uint256)",
187
191
  "function balanceOf(address account) external view returns (uint256)",
188
192
  "function decimals() external view returns (uint8)",
189
193
  "function symbol() external view returns (string)"
190
- ], ee = "0xa0FfB9c1CE1Fe56963B0321B32E7A0302114058b", V = {
191
- PANCAKEV3: f.PancakeV3,
192
- PANCAKEV2: f.PancakeV2,
193
- PANCAKE_INFINITY_CL: f.PancakeInfinityCl,
194
- UNISWAPV3: f.UniswapV3,
195
- UNISWAPV4: f.UniswapV4,
196
- DODO: f.Dodo,
197
- THENA: f.Thena,
198
- NOMISWAP_STABLE: f.NomiswapStable,
199
- BISWAP: f.Biswap,
200
- APESWAP: f.Apeswap,
201
- BABYDOGESWAP: f.BabyDogeSwap,
202
- BABYSWAP: f.BabySwap
203
- };
204
- class K {
205
- constructor(e, t, o) {
206
- this.config = e, this.provider = t || new l.JsonRpcProvider(e.rpcUrl), this.routerContract = new l.Contract(
207
- e.routerAddress || l.ZeroAddress,
208
- B,
194
+ ], se = [
195
+ "function allowance(address user, address token, address spender) external view returns (uint160 amount, uint48 expiration, uint48 nonce)"
196
+ ], re = {
197
+ PermitDetails: [
198
+ { name: "token", type: "address" },
199
+ { name: "amount", type: "uint160" },
200
+ { name: "expiration", type: "uint48" },
201
+ { name: "nonce", type: "uint48" }
202
+ ],
203
+ PermitSingle: [
204
+ { name: "details", type: "PermitDetails" },
205
+ { name: "spender", type: "address" },
206
+ { name: "sigDeadline", type: "uint256" }
207
+ ]
208
+ }, oe = "0xa0FfB9c1CE1Fe56963B0321B32E7A0302114058b", ae = "0xC697d2898e0D09264376196696c51D7aBbbAA4a9", ie = "0x28e2ea090877bf75740558f6bfb36a5ffee9e9df", H = {
209
+ PANCAKEV3: d.PancakeV3,
210
+ PANCAKEV2: d.PancakeV2,
211
+ PANCAKEV1: d.PancakeV1,
212
+ PANCAKE_INFINITY_CL: d.PancakeInfinityCl,
213
+ PANCAKE_INFINITY_LB: d.PancakeInfinityLb,
214
+ UNISWAPV2: d.UniswapV2,
215
+ UNISWAPV3: d.UniswapV3,
216
+ UNISWAPV4: d.UniswapV4,
217
+ DODO: d.Dodo,
218
+ THENAV3: d.ThenaV3,
219
+ NOMISWAP_STABLE: d.NomiswapStable,
220
+ BISWAP: d.Biswap,
221
+ APESWAP: d.Apeswap,
222
+ BABYDOGESWAP: d.BabyDogeSwap,
223
+ BABYSWAP: d.BabySwap,
224
+ BAKERYSWAP: d.BakerySwap,
225
+ PANCAKE_STABLE: d.PancakeStable,
226
+ LISTA_STABLE: d.ListaStable,
227
+ SQUADSWAP_V3: d.SquadSwapV3,
228
+ SQUADSWAP_V2: d.SquadSwapV2,
229
+ WOMBAT: d.Wombat,
230
+ THENA_FUSION: d.ThenaFusion,
231
+ SUSHISWAP_V2: d.SushiSwapV2,
232
+ SUSHISWAP_V3: d.SushiSwapV3
233
+ }, C = class C {
234
+ constructor(e, t, n) {
235
+ this.config = e, this.provider = t || new m.JsonRpcProvider(e.rpcUrl), this.routerContract = new m.Contract(
236
+ e.routerAddress || m.ZeroAddress,
237
+ R,
209
238
  this.provider
210
- ), this.apiClient = new X(o?.api);
239
+ ), this.apiClient = new ne(n?.api);
211
240
  }
212
241
  /**
213
242
  * Get the effective router address for a quote.
214
243
  */
215
244
  getRouterAddress(e) {
216
245
  const t = e.routerAddress || this.config.routerAddress;
217
- if (!t || t === l.ZeroAddress)
246
+ if (!t || t === m.ZeroAddress)
218
247
  throw new Error("No router address available. Provide routerAddress in config or use API-based getQuote.");
219
248
  return t;
220
249
  }
@@ -224,25 +253,25 @@ class K {
224
253
  applySlippage(e, t) {
225
254
  if (t < 0 || t > 1e4)
226
255
  throw new Error("slippageBps must be between 0 and 10000");
227
- const o = e.amountOutMin * (b - BigInt(t)) / b;
228
- return { ...e, amountOutMin: o };
256
+ const n = e.amountOutMin * (_ - BigInt(t)) / _;
257
+ return { ...e, amountOutMin: n };
229
258
  }
230
259
  /**
231
260
  * Build transaction requests for an approval (if needed) and the swap itself.
232
261
  */
233
- async swap(e, t, o) {
234
- const n = this.getRouterAddress(e), { tx: s, method: r } = this.buildSwapTransactionRequest(e, o);
262
+ async swap(e, t, n) {
263
+ const s = this.getRouterAddress(e), { tx: o, method: r } = this.buildSwapTransactionRequest(e, n);
235
264
  let a;
236
265
  return e.srcNative || (a = await this.buildApprovalRequest(
237
266
  e.srcToken,
238
267
  t,
239
268
  e.amountIn,
240
- n,
241
- o
269
+ s,
270
+ n
242
271
  )), {
243
- routerAddress: n,
272
+ routerAddress: s,
244
273
  method: r,
245
- tx: s,
274
+ tx: o,
246
275
  approval: a
247
276
  };
248
277
  }
@@ -251,19 +280,19 @@ class K {
251
280
  *
252
281
  * @deprecated Prefer swap(), then send the returned tx request with your wallet/client.
253
282
  */
254
- async execute(e, t, o) {
255
- const n = await t.getAddress(), s = await this.swap(e, n, o);
283
+ async execute(e, t, n) {
284
+ const s = await t.getAddress(), o = await this.swap(e, s, n);
256
285
  try {
257
- return s.approval && await (await this.sendTransactionWithTimeout(
286
+ return o.approval && await (await this.sendTransactionWithTimeout(
258
287
  t,
259
- s.approval.tx,
260
- o
261
- )).wait(), await this.sendTransactionWithTimeout(t, s.tx, o);
288
+ o.approval.tx,
289
+ n
290
+ )).wait(), await this.sendTransactionWithTimeout(t, o.tx, n);
262
291
  } catch (r) {
263
292
  const a = r instanceof Error ? r.message : String(r), i = /estimateGas/i.test(a), c = /missing revert data/i.test(a) || a.includes("reason=null") && a.includes("data=null");
264
293
  if (i && (c || /reason=null|data=null/.test(a))) {
265
- const u = "Transaction reverted during gas estimation and the RPC did not return a revert reason. Try: 1) Get a fresh quote and confirm immediately 2) Switch network or RPC 3) Increase slippage.", d = new Error(`${u} (estimateGas/missing revert data)`);
266
- throw d.cause = r, d;
294
+ const u = "Transaction reverted during gas estimation and the RPC did not return a revert reason. Try: 1) Get a fresh quote and confirm immediately 2) Switch network or RPC 3) Increase slippage.", l = new Error(`${u} (estimateGas/missing revert data)`);
295
+ throw l.cause = r, l;
267
296
  }
268
297
  throw r;
269
298
  }
@@ -294,8 +323,8 @@ class K {
294
323
  };
295
324
  }
296
325
  getProtocolForProvider(e) {
297
- if (e in V)
298
- return V[e];
326
+ if (e in H)
327
+ return H[e];
299
328
  throw new Error(`Unsupported provider: ${e}`);
300
329
  }
301
330
  /**
@@ -307,11 +336,11 @@ class K {
307
336
  * @returns Encoded calldata and transaction info (to address, value)
308
337
  */
309
338
  encodeSwapCalldata(e, t) {
310
- const o = e.routerAddress ?? this.config.routerAddress ?? this.routerContract.target, n = this.applySlippage(e.params, t), s = e.srcNative === !0 || e.dstNative === !0, r = this.encodeParams(n);
311
- if (s) {
339
+ const n = e.routerAddress ?? this.config.routerAddress ?? this.routerContract.target, s = this.applySlippage(e.params, t), o = e.srcNative === !0 || e.dstNative === !0, r = this.encodeParams(s);
340
+ if (o) {
312
341
  const a = this.routerContract.interface.encodeFunctionData("swapETH", [r]);
313
342
  return {
314
- to: o,
343
+ to: n,
315
344
  data: a,
316
345
  value: e.srcNative ? e.amountIn : 0n,
317
346
  method: "swapETH"
@@ -319,7 +348,7 @@ class K {
319
348
  } else {
320
349
  const a = this.routerContract.interface.encodeFunctionData("swap", [r]);
321
350
  return {
322
- to: o,
351
+ to: n,
323
352
  data: a,
324
353
  value: 0n,
325
354
  method: "swap"
@@ -327,66 +356,187 @@ class K {
327
356
  }
328
357
  }
329
358
  buildSwapTransactionRequest(e, t) {
330
- const { to: o, data: n, value: s, method: r } = this.encodeSwapCalldata(e, t.slippageBps);
359
+ const { to: n, data: s, value: o, method: r } = this.encodeSwapCalldata(e, t.slippageBps);
331
360
  return {
332
361
  method: r,
333
- tx: this.applyTxOverrides({ to: o, data: n, value: s }, t, !0)
362
+ tx: this.applyTxOverrides({ to: n, data: s, value: o }, t, !0)
334
363
  };
335
364
  }
336
- async buildApprovalRequest(e, t, o, n, s) {
337
- const r = await this.getAllowance(e, t, n);
338
- if (!(r >= o))
365
+ async buildApprovalRequest(e, t, n, s, o) {
366
+ const r = await this.getAllowance(e, t, s);
367
+ if (!(r >= n))
339
368
  return {
340
369
  token: e,
341
370
  owner: t,
342
- spender: n,
371
+ spender: s,
343
372
  currentAllowance: r,
344
- requiredAmount: o,
345
- approveAmount: l.MaxUint256,
346
- tx: this.buildApprovalTransactionRequest(e, n, s)
373
+ requiredAmount: n,
374
+ approveAmount: m.MaxUint256,
375
+ tx: this.buildApprovalTransactionRequest(e, s, o)
347
376
  };
348
377
  }
349
- buildApprovalTransactionRequest(e, t, o) {
350
- const s = new l.Interface(y).encodeFunctionData("approve", [t, l.MaxUint256]);
351
- return this.applyTxOverrides({ to: e, data: s, value: 0n }, o, !1);
378
+ buildApprovalTransactionRequest(e, t, n) {
379
+ const o = new m.Interface(b).encodeFunctionData("approve", [t, m.MaxUint256]);
380
+ return this.applyTxOverrides({ to: e, data: o, value: 0n }, n, !1);
381
+ }
382
+ async getAllowance(e, t, n) {
383
+ return new m.Contract(e, b, this.provider).allowance(t, n);
384
+ }
385
+ // ═══════════════════════════════════════════════════════════════════
386
+ // Permit2 (AllowanceTransfer)
387
+ // ═══════════════════════════════════════════════════════════════════
388
+ /**
389
+ * Read the current Permit2 AllowanceTransfer state for (owner, token, spender).
390
+ * `spender` defaults to the router address. The returned `nonce` feeds the next PermitSingle;
391
+ * `amount` / `expiration` decide whether a fresh signature is needed.
392
+ */
393
+ async getPermit2Allowance(e, t, n) {
394
+ const s = new m.Contract(O, se, this.provider), o = n ?? this.resolveRouterAddress(), [r, a, i] = await s.allowance(t, e, o);
395
+ return { amount: BigInt(r), expiration: Number(a), nonce: Number(i) };
396
+ }
397
+ /**
398
+ * Build the ONE-TIME `token.approve(PERMIT2, max)` tx, or undefined when the token's existing
399
+ * Permit2 allowance already covers `amount`. This is the only on-chain approval Permit2 needs;
400
+ * once set, every future swap of this token is signature-only.
401
+ */
402
+ async buildPermit2TokenApproval(e, t, n, s = {}) {
403
+ if (await this.getAllowance(e, t, O) >= n)
404
+ return;
405
+ const a = new m.Interface(b).encodeFunctionData("approve", [O, m.MaxUint256]), i = { to: e, data: a, value: 0n };
406
+ return s.gasPrice && (i.gasPrice = s.gasPrice), i;
407
+ }
408
+ /**
409
+ * Build the EIP-712 PermitSingle the user signs to grant the router a Permit2 allowance.
410
+ * Reads the current sequential nonce from Permit2; `permitSingle.spender` is the router.
411
+ * Pass the result straight into `signer.signTypedData(domain, types, values)`.
412
+ */
413
+ async buildPermit2TypedData(e, t, n = {}) {
414
+ if (e.srcNative)
415
+ throw new Error("Permit2 cannot be used for native-token input; use swapETH instead.");
416
+ const s = this.getRouterAddress(e);
417
+ this.assertUint160(e.amountIn);
418
+ const { nonce: o } = await this.getPermit2Allowance(e.srcToken, t, s), r = Math.floor(Date.now() / 1e3), a = n.permitAmount ?? $;
419
+ this.assertUint160(a);
420
+ const i = {
421
+ details: {
422
+ token: e.srcToken,
423
+ amount: a,
424
+ expiration: n.expiration ?? r + 720 * 60 * 60,
425
+ // 30 days
426
+ nonce: o
427
+ },
428
+ spender: s,
429
+ sigDeadline: n.sigDeadline ?? BigInt(r + 1800)
430
+ // 30 min
431
+ };
432
+ return {
433
+ domain: { name: "Permit2", chainId: this.config.chainId, verifyingContract: O },
434
+ types: re,
435
+ values: i
436
+ };
437
+ }
438
+ /**
439
+ * Encode calldata for swapWithPermit2 / swapETHWithPermit2. Routes to swapETHWithPermit2
440
+ * when the quote's dstToken is native. Pass `"0x"` as `signature` to reuse an existing
441
+ * on-chain Permit2 allowance (the router then skips the permit() call).
442
+ */
443
+ encodeSwapWithPermit2Calldata(e, t, n, s) {
444
+ if (e.srcNative)
445
+ throw new Error("Permit2 cannot be used for native-token input; use swapETH instead.");
446
+ const o = this.getRouterAddress(e), r = this.applySlippage(e.params, t), a = this.encodeParams(r), i = { permitSingle: n, signature: s }, c = e.dstNative ? "swapETHWithPermit2" : "swapWithPermit2", u = this.routerContract.interface.encodeFunctionData(c, [a, i]);
447
+ return { to: o, data: u, value: 0n, method: c };
448
+ }
449
+ /**
450
+ * Prepare a single-transaction Permit2 swap. Returns the optional one-time token->Permit2
451
+ * approval, the EIP-712 payload to sign (or undefined when an existing allowance can be
452
+ * reused), and a `buildSwapTx(signature)` closure for the final swap tx.
453
+ *
454
+ * Integrator flow:
455
+ * const req = await client.swapWithPermit2(quote, owner, { slippageBps: 50 });
456
+ * if (req.permit2Approval) await signer.sendTransaction(req.permit2Approval); // once per token
457
+ * const sig = req.typedData
458
+ * ? await signer.signTypedData(req.typedData.domain, req.typedData.types, req.typedData.values)
459
+ * : "0x";
460
+ * await signer.sendTransaction(req.buildSwapTx(sig));
461
+ */
462
+ async swapWithPermit2(e, t, n) {
463
+ if (e.srcNative)
464
+ throw new Error("Permit2 cannot be used for native-token input; use swapETH instead.");
465
+ const s = this.getRouterAddress(e);
466
+ this.assertUint160(e.amountIn);
467
+ const o = await this.buildPermit2TokenApproval(
468
+ e.srcToken,
469
+ t,
470
+ e.amountIn,
471
+ n
472
+ ), r = await this.getPermit2Allowance(e.srcToken, t, s), a = Math.floor(Date.now() / 1e3), i = !o && r.amount >= e.amountIn && r.expiration > a;
473
+ let c, u;
474
+ i ? u = {
475
+ details: {
476
+ token: e.srcToken,
477
+ amount: r.amount,
478
+ expiration: r.expiration,
479
+ nonce: r.nonce
480
+ },
481
+ spender: s,
482
+ sigDeadline: 0n
483
+ } : (c = await this.buildPermit2TypedData(e, t, n), u = c.values);
484
+ const l = e.dstNative ? "swapETHWithPermit2" : "swapWithPermit2";
485
+ return {
486
+ routerAddress: s,
487
+ method: l,
488
+ permit2Approval: o,
489
+ typedData: c,
490
+ permitSingle: u,
491
+ buildSwapTx: (p) => {
492
+ const { to: A, data: w, value: v } = this.encodeSwapWithPermit2Calldata(
493
+ e,
494
+ n.slippageBps,
495
+ u,
496
+ p
497
+ );
498
+ return this.applyTxOverrides({ to: A, data: w, value: v }, n, !0);
499
+ }
500
+ };
352
501
  }
353
- async getAllowance(e, t, o) {
354
- return new l.Contract(e, y, this.provider).allowance(t, o);
502
+ assertUint160(e) {
503
+ if (e > $)
504
+ throw new Error(`amount ${e} exceeds Permit2 uint160 max`);
355
505
  }
356
- applyTxOverrides(e, t, o) {
357
- const n = { ...e };
358
- return t.gasPrice && (n.gasPrice = t.gasPrice), o && t.gasLimit && (n.gasLimit = t.gasLimit), n;
506
+ applyTxOverrides(e, t, n) {
507
+ const s = { ...e };
508
+ return t.gasPrice && (s.gasPrice = t.gasPrice), n && t.gasLimit && (s.gasLimit = t.gasLimit), s;
359
509
  }
360
- async sendTransactionWithTimeout(e, t, o) {
361
- const n = o.timeoutMs ?? W;
362
- if (n <= 0)
510
+ async sendTransactionWithTimeout(e, t, n) {
511
+ const s = n.timeoutMs ?? G;
512
+ if (s <= 0)
363
513
  return e.sendTransaction(t);
364
- const s = e;
365
- if (typeof s.sendUncheckedTransaction == "function" && s.provider) {
366
- const r = await U(
367
- s.sendUncheckedTransaction(t),
368
- n
514
+ const o = e;
515
+ if (typeof o.sendUncheckedTransaction == "function" && o.provider) {
516
+ const r = await W(
517
+ o.sendUncheckedTransaction(t),
518
+ s
369
519
  ), a = await this.waitForTransactionResponse(
370
- s.provider,
520
+ o.provider,
371
521
  r,
372
- n,
373
- o.transactionResponsePollingIntervalsMs
522
+ s,
523
+ n.transactionResponsePollingIntervalsMs
374
524
  );
375
525
  if (a.response)
376
526
  return a.response;
377
527
  const i = a.rpcErrors > 0 ? `${a.rpcErrors} transient provider error(s) and ${a.nullResponses} null response(s)` : `${a.nullResponses} null response(s)`;
378
- throw new H(
379
- `Transaction was broadcast but provider did not return TransactionResponse within ${n}ms (${i}).`,
528
+ throw new Q(
529
+ `Transaction was broadcast but provider did not return TransactionResponse within ${s}ms (${i}).`,
380
530
  "provider_index",
381
531
  r
382
532
  );
383
533
  }
384
- return U(e.sendTransaction(t), n);
534
+ return W(e.sendTransaction(t), s);
385
535
  }
386
- async waitForTransactionResponse(e, t, o, n = $) {
387
- const s = Date.now() + o;
536
+ async waitForTransactionResponse(e, t, n, s = M) {
537
+ const o = Date.now() + n;
388
538
  let r = 0, a = 0, i = 0;
389
- for (; Date.now() < s; ) {
539
+ for (; Date.now() < o; ) {
390
540
  try {
391
541
  const u = await e.getTransaction(t);
392
542
  if (u)
@@ -395,8 +545,8 @@ class K {
395
545
  } catch {
396
546
  i++;
397
547
  }
398
- const c = this.getNextPollingDelay(n, r);
399
- r++, await this.delay(Math.min(c, Math.max(25, s - Date.now())));
548
+ const c = this.getNextPollingDelay(s, r);
549
+ r++, await this.delay(Math.min(c, Math.max(25, o - Date.now())));
400
550
  }
401
551
  return { response: null, nullResponses: a, rpcErrors: i };
402
552
  }
@@ -406,24 +556,24 @@ class K {
406
556
  });
407
557
  }
408
558
  getNextPollingDelay(e, t) {
409
- return e.length === 0 ? $.at(-1) ?? 1200 : e[Math.min(t, e.length - 1)] ?? 1200;
559
+ return e.length === 0 ? M.at(-1) ?? 1200 : e[Math.min(t, e.length - 1)] ?? 1200;
410
560
  }
411
561
  /**
412
562
  * Get token metadata and, optionally, the balance for a specific owner.
413
563
  */
414
564
  async getTokenInfo(e, t) {
415
- const o = new l.Contract(e, y, this.provider), [n, s, r] = await Promise.all([
416
- o.symbol(),
417
- o.decimals(),
418
- t ? o.balanceOf(t) : Promise.resolve(void 0)
565
+ const n = new m.Contract(e, b, this.provider), [s, o, r] = await Promise.all([
566
+ n.symbol(),
567
+ n.decimals(),
568
+ t ? n.balanceOf(t) : Promise.resolve(void 0)
419
569
  ]);
420
- return r === void 0 ? { symbol: n, decimals: s } : { symbol: n, decimals: s, balance: r };
570
+ return r === void 0 ? { symbol: s, decimals: o } : { symbol: s, decimals: o, balance: r };
421
571
  }
422
572
  /**
423
573
  * Get user token balance
424
574
  */
425
575
  async getBalance(e, t) {
426
- return new l.Contract(e, y, this.provider).balanceOf(t);
576
+ return new m.Contract(e, b, this.provider).balanceOf(t);
427
577
  }
428
578
  /**
429
579
  * Get quote via API
@@ -431,22 +581,22 @@ class K {
431
581
  * @throws CustomFeeError if `options.customFee` is malformed
432
582
  */
433
583
  async getQuote(e) {
434
- const { srcToken: t, dstToken: o, amountIn: n, options: s = {} } = e, {
584
+ const { srcToken: t, dstToken: n, amountIn: s, options: o = {} } = e, {
435
585
  byAmountIn: r = !0,
436
- depth: a = k.depth,
437
- splitCount: i = k.splitCount,
438
- providers: c = k.providers,
439
- deadlineSeconds: u = T,
440
- includeResponseHeaders: d = !1,
586
+ depth: a = E.depth,
587
+ splitCount: i = E.splitCount,
588
+ providers: c = E.providers,
589
+ deadlineSeconds: u = N,
590
+ includeResponseHeaders: l = !1,
441
591
  customFee: p
442
- } = s;
443
- K.validateCustomFee(p);
444
- const g = _(t), m = _(o), v = g ? this.config.weth : t, C = m ? this.config.weth : o;
445
- if (d) {
446
- const { data: P, responseHeaders: S } = await this.apiClient.findRoutes({
592
+ } = o;
593
+ C.validateCustomFee(p);
594
+ const A = T(t), w = T(n), v = A ? this.config.weth : t, g = w ? this.config.weth : n;
595
+ if (l) {
596
+ const { data: k, responseHeaders: x } = await this.apiClient.findRoutes({
447
597
  from: v,
448
- target: C,
449
- amount: n,
598
+ target: g,
599
+ amount: s,
450
600
  byAmountIn: r,
451
601
  depth: a,
452
602
  splitCount: i,
@@ -454,34 +604,34 @@ class K {
454
604
  includeResponseHeaders: !0
455
605
  });
456
606
  return this.buildQuoteFromApi(
457
- P,
607
+ k,
458
608
  v,
459
- C,
609
+ g,
460
610
  u,
461
611
  c,
462
- g,
463
- m,
464
- S,
612
+ A,
613
+ w,
614
+ x,
465
615
  p
466
616
  );
467
617
  }
468
- const E = await this.apiClient.findRoutes({
618
+ const P = await this.apiClient.findRoutes({
469
619
  from: v,
470
- target: C,
471
- amount: n,
620
+ target: g,
621
+ amount: s,
472
622
  byAmountIn: r,
473
623
  depth: a,
474
624
  splitCount: i,
475
625
  providers: c
476
626
  });
477
627
  return this.buildQuoteFromApi(
478
- E,
628
+ P,
479
629
  v,
480
- C,
630
+ g,
481
631
  u,
482
632
  c,
483
- g,
484
- m,
633
+ A,
634
+ w,
485
635
  void 0,
486
636
  p
487
637
  );
@@ -492,17 +642,17 @@ class K {
492
642
  */
493
643
  static validateCustomFee(e) {
494
644
  if (!e) return;
495
- const { feeAccount: t, feeBps: o } = e;
496
- if (!Number.isInteger(o) || o < 1 || o > L)
497
- throw new x(
498
- `customFee.feeBps must be an integer in [1, ${L}] (5%), got ${o}`
645
+ const { feeAccount: t, feeBps: n } = e;
646
+ if (!Number.isInteger(n) || n < 1 || n > U)
647
+ throw new B(
648
+ `customFee.feeBps must be an integer in [1, ${U}] (5%), got ${n}`
499
649
  );
500
- if (!t || !l.isAddress(t))
501
- throw new x(
650
+ if (!t || !m.isAddress(t))
651
+ throw new B(
502
652
  `customFee.feeAccount must be a valid address, got ${t}`
503
653
  );
504
- if (t === l.ZeroAddress)
505
- throw new x("customFee.feeAccount must not be the zero address");
654
+ if (t === m.ZeroAddress)
655
+ throw new B("customFee.feeAccount must not be the zero address");
506
656
  }
507
657
  /**
508
658
  * Resolve the router address for read methods: argument → quote.routerAddress →
@@ -511,7 +661,7 @@ class K {
511
661
  */
512
662
  resolveRouterAddress(e) {
513
663
  const t = e ?? this.config.routerAddress;
514
- if (!t || t === l.ZeroAddress)
664
+ if (!t || t === m.ZeroAddress)
515
665
  throw new Error(
516
666
  "No router address available. Pass one explicitly or set config.routerAddress."
517
667
  );
@@ -529,13 +679,13 @@ class K {
529
679
  * Pass an explicit address when reading from a different deployment.
530
680
  */
531
681
  async getProtocolFeeConfig(e) {
532
- const t = this.resolveRouterAddress(e), o = new l.Contract(t, B, this.provider), [n, s] = await Promise.all([
533
- o.protocolFeeReceiver(),
534
- o.protocolCutBps()
682
+ const t = this.resolveRouterAddress(e), n = new m.Contract(t, R, this.provider), [s, o] = await Promise.all([
683
+ n.protocolFeeReceiver(),
684
+ n.protocolCutBps()
535
685
  ]);
536
686
  return {
537
- protocolFeeReceiver: n,
538
- protocolCutBps: Number(s)
687
+ protocolFeeReceiver: s,
688
+ protocolCutBps: Number(o)
539
689
  };
540
690
  }
541
691
  /**
@@ -564,36 +714,36 @@ class K {
564
714
  * @param routerAddress Optional router address. Defaults to `config.routerAddress`.
565
715
  */
566
716
  async getRouterConfig(e) {
567
- const t = this.resolveRouterAddress(e), o = new l.Contract(t, B, this.provider), [
568
- n,
717
+ const t = this.resolveRouterAddress(e), n = new m.Contract(t, R, this.provider), [
569
718
  s,
719
+ o,
570
720
  r,
571
721
  a,
572
722
  i,
573
723
  c,
574
724
  u,
575
- d
725
+ l
576
726
  ] = await Promise.all([
577
- o.WETH(),
578
- o.owner(),
579
- o.pendingOwner(),
580
- o.paused(),
581
- o.maxCustomFeeBps(),
582
- o.maxProtocolCutBps(),
583
- o.protocolFeeReceiver(),
584
- o.protocolCutBps()
727
+ n.WETH(),
728
+ n.owner(),
729
+ n.pendingOwner(),
730
+ n.paused(),
731
+ n.maxCustomFeeBps(),
732
+ n.maxProtocolCutBps(),
733
+ n.protocolFeeReceiver(),
734
+ n.protocolCutBps()
585
735
  ]);
586
736
  return {
587
737
  address: t,
588
- weth: n,
589
- owner: s,
738
+ weth: s,
739
+ owner: o,
590
740
  pendingOwner: r,
591
741
  paused: !!a,
592
742
  maxCustomFeeBps: Number(i),
593
743
  maxProtocolCutBps: Number(c),
594
744
  protocolFee: {
595
745
  protocolFeeReceiver: u,
596
- protocolCutBps: Number(d)
746
+ protocolCutBps: Number(l)
597
747
  }
598
748
  };
599
749
  }
@@ -601,12 +751,12 @@ class K {
601
751
  * Filter paths by allowed providers, removing paths with disallowed providers
602
752
  * and cascade-removing orphaned paths that depend on removed paths.
603
753
  */
604
- filterPathsByProviders(e, t, o, n) {
605
- const s = new Set(t.map((p) => p.toUpperCase()));
606
- let r = e.filter((p) => s.has(p.provider.toUpperCase()));
754
+ filterPathsByProviders(e, t, n, s) {
755
+ const o = new Set(t.map((p) => p.toUpperCase()));
756
+ let r = e.filter((p) => o.has(p.provider.toUpperCase()));
607
757
  if (r.length === e.length)
608
758
  return r;
609
- const a = o.toLowerCase(), i = n.toLowerCase(), c = /* @__PURE__ */ new Set();
759
+ const a = n.toLowerCase(), i = s.toLowerCase(), c = /* @__PURE__ */ new Set();
610
760
  c.add(a);
611
761
  let u = !0;
612
762
  for (; u; ) {
@@ -614,14 +764,14 @@ class K {
614
764
  for (const p of r)
615
765
  c.has(p.token_in.toLowerCase()) && !c.has(p.token_out.toLowerCase()) && (c.add(p.token_out.toLowerCase()), u = !0);
616
766
  }
617
- const d = /* @__PURE__ */ new Set();
618
- for (d.add(i), u = !0; u; ) {
767
+ const l = /* @__PURE__ */ new Set();
768
+ for (l.add(i), u = !0; u; ) {
619
769
  u = !1;
620
770
  for (const p of r)
621
- d.has(p.token_out.toLowerCase()) && !d.has(p.token_in.toLowerCase()) && (d.add(p.token_in.toLowerCase()), u = !0);
771
+ l.has(p.token_out.toLowerCase()) && !l.has(p.token_in.toLowerCase()) && (l.add(p.token_in.toLowerCase()), u = !0);
622
772
  }
623
773
  return r.length, r = r.filter(
624
- (p) => c.has(p.token_in.toLowerCase()) && d.has(p.token_out.toLowerCase())
774
+ (p) => c.has(p.token_in.toLowerCase()) && l.has(p.token_out.toLowerCase())
625
775
  ), r;
626
776
  }
627
777
  /**
@@ -633,77 +783,77 @@ class K {
633
783
  * @param dstToken - Destination token address (last path token_out)
634
784
  * @param deadlineSeconds - Optional deadline in seconds from now (default: 20 min)
635
785
  */
636
- buildQuoteFromRouteData(e, t, o, n, s) {
786
+ buildQuoteFromRouteData(e, t, n, s, o) {
637
787
  const r = this.buildQuoteFromRouteDataInternal(
638
788
  e,
639
789
  t,
640
- o,
641
- n ?? T,
790
+ n,
791
+ s ?? N,
642
792
  void 0
643
793
  );
644
- return s?.srcNative && (r.srcNative = !0), s?.dstNative && (r.dstNative = !0), r;
794
+ return o?.srcNative && (r.srcNative = !0), o?.dstNative && (r.dstNative = !0), r;
645
795
  }
646
796
  /**
647
797
  * Build Quote from API response
648
798
  */
649
- buildQuoteFromApi(e, t, o, n, s, r, a, i, c) {
799
+ buildQuoteFromApi(e, t, n, s, o, r, a, i, c) {
650
800
  const u = this.buildQuoteFromRouteDataInternal(
651
801
  e,
652
802
  t,
653
- o,
654
803
  n,
655
804
  s,
805
+ o,
656
806
  c
657
807
  );
658
808
  return r && (u.srcNative = !0), a && (u.dstNative = !0), i && (u.responseHeaders = i), u;
659
809
  }
660
- buildQuoteFromRouteDataInternal(e, t, o, n, s, r) {
810
+ buildQuoteFromRouteDataInternal(e, t, n, s, o, r) {
661
811
  const a = t.toLowerCase();
662
812
  e.paths.length;
663
813
  let i = e.paths.filter((h) => !(!(h.token_in.toLowerCase() === a) && BigInt(h.amount_in) === 0n && BigInt(h.amount_out) === 0n));
664
814
  if (i.length === 0)
665
- throw new A("All route paths have zero amounts", 4001);
666
- if (s && s.length > 0 && (i = this.filterPathsByProviders(i, s, t, o), i.length === 0))
667
- throw new A("No valid route paths remaining after provider filtering", 4001);
668
- const c = o.toLowerCase();
669
- let u = 0n, d = 0n;
815
+ throw new S("All route paths have zero amounts", 4001);
816
+ if (o && o.length > 0 && (i = this.filterPathsByProviders(i, o, t, n), i.length === 0))
817
+ throw new S("No valid route paths remaining after provider filtering", 4001);
818
+ const c = n.toLowerCase();
819
+ let u = 0n, l = 0n;
670
820
  for (const h of i)
671
- h.token_in.toLowerCase() === a && (u += BigInt(h.amount_in)), h.token_out.toLowerCase() === c && (d += BigInt(h.amount_out));
821
+ h.token_in.toLowerCase() === a && (u += BigInt(h.amount_in)), h.token_out.toLowerCase() === c && (l += BigInt(h.amount_out));
672
822
  const p = BigInt(
673
- Math.floor(Date.now() / 1e3) + n
674
- ), g = /* @__PURE__ */ new Map();
823
+ Math.floor(Date.now() / 1e3) + s
824
+ ), A = /* @__PURE__ */ new Map();
675
825
  for (const h of i) {
676
826
  const I = h.token_in.toLowerCase();
677
- g.set(I, (g.get(I) ?? 0) + 1);
827
+ A.set(I, (A.get(I) ?? 0) + 1);
678
828
  }
679
- const m = /* @__PURE__ */ new Map(), v = i.map((h) => {
680
- const I = h.token_in.toLowerCase(), N = (m.get(I) ?? 0) + 1;
681
- m.set(I, N);
682
- const D = g.get(I), Z = D > 1 && N < D, j = I === a;
829
+ const w = /* @__PURE__ */ new Map(), v = i.map((h) => {
830
+ const I = h.token_in.toLowerCase(), V = (w.get(I) ?? 0) + 1;
831
+ w.set(I, V);
832
+ const L = A.get(I), z = L > 1 && V < L, X = I === a;
683
833
  return {
684
834
  adapter: h.adapter,
685
- pool: h.provider.toUpperCase() === "PANCAKE_INFINITY_CL" ? ee : h.provider.toUpperCase() === "UNISWAPV4" ? l.ZeroAddress : h.pool,
835
+ pool: h.provider.toUpperCase() === "PANCAKE_INFINITY_CL" ? oe : h.provider.toUpperCase() === "PANCAKE_INFINITY_LB" ? ae : h.provider.toUpperCase() === "UNISWAPV4" ? ie : h.pool,
686
836
  tokenIn: h.token_in,
687
837
  tokenOut: h.token_out,
688
- amountIn: j || Z ? BigInt(h.amount_in) : 0n,
838
+ amountIn: X || z ? BigInt(h.amount_in) : 0n,
689
839
  extraData: h.extra_data || "0x"
690
840
  };
691
- }), C = /* @__PURE__ */ new Set();
841
+ }), g = /* @__PURE__ */ new Set();
692
842
  for (const h of i)
693
- h.token_out.toLowerCase() !== c && C.add(h.token_out);
694
- const E = Array.from(C), P = r?.feeBps ?? 0, S = r?.feeAccount ?? l.ZeroAddress, R = d, F = P > 0 ? R * BigInt(P) / b : 0n, O = R - F, G = {
843
+ h.token_out.toLowerCase() !== c && g.add(h.token_out);
844
+ const P = Array.from(g), k = r?.feeBps ?? 0, x = r?.feeAccount ?? m.ZeroAddress, D = l, F = k > 0 ? D * BigInt(k) / _ : 0n, y = D - F, Z = {
695
845
  srcToken: t,
696
- dstToken: o,
846
+ dstToken: n,
697
847
  amountIn: u,
698
- amountOutMin: O,
848
+ amountOutMin: y,
699
849
  steps: v,
700
- intermediateTokens: E,
850
+ intermediateTokens: P,
701
851
  deadline: p,
702
- quoteId: e.request_id ? l.id(e.request_id).slice(0, 66) : l.ZeroHash,
703
- expectAmountOut: O,
704
- feeReceiver: S,
705
- feeBps: P
706
- }, Y = {
852
+ quoteId: e.request_id ? m.id(e.request_id).slice(0, 66) : m.ZeroHash,
853
+ expectAmountOut: y,
854
+ feeReceiver: x,
855
+ feeBps: k
856
+ }, j = {
707
857
  routes: [
708
858
  {
709
859
  steps: i.map((h) => ({
@@ -720,32 +870,32 @@ class K {
720
870
  amountOut: BigInt(h.amount_out)
721
871
  })),
722
872
  amountIn: u,
723
- amountOut: d,
873
+ amountOut: l,
724
874
  gasEstimate: BigInt(e.gas)
725
875
  }
726
876
  ],
727
877
  percentages: [1e4],
728
878
  totalAmountIn: u,
729
- totalAmountOut: d,
879
+ totalAmountOut: l,
730
880
  totalGasEstimate: BigInt(e.gas)
731
881
  };
732
882
  if (!e.contracts?.router)
733
- throw new A("API response missing contracts.router address", 4002);
883
+ throw new S("API response missing contracts.router address", 4002);
734
884
  return {
735
885
  srcToken: t,
736
- dstToken: o,
886
+ dstToken: n,
737
887
  amountIn: u,
738
888
  // Quote.amountOut reflects the user-perceived output (post custom fee).
739
889
  // Wallets / UIs should display this number; the gross figure is at route.totalAmountOut.
740
- amountOut: O,
890
+ amountOut: y,
741
891
  priceImpact: parseFloat(e.deviation_ratio || "0"),
742
- route: Y,
743
- params: G,
892
+ route: j,
893
+ params: Z,
744
894
  gasEstimate: BigInt(e.gas),
745
895
  routerAddress: e.contracts?.router,
746
- customFee: P > 0 ? {
747
- feeAccount: S,
748
- feeBps: P,
896
+ customFee: k > 0 ? {
897
+ feeAccount: x,
898
+ feeBps: k,
749
899
  feeAmount: F
750
900
  } : void 0
751
901
  };
@@ -767,23 +917,23 @@ class K {
767
917
  * @param stateOverrides - Optional state overrides for ERC20 balance/allowance
768
918
  * @returns Simulated amountOut and method used
769
919
  */
770
- async simulate(e, t, o, n) {
771
- const s = o || l.ZeroAddress, { to: r, data: a, value: i, method: c } = this.encodeSwapCalldata(e, t);
772
- if (n) {
773
- const u = this.getJsonRpcProviderForStateOverrides(), d = i > 0n ? "0x" + i.toString(16) : void 0, p = await u.send("eth_call", [
774
- { from: s, to: r, data: a, value: d },
920
+ async simulate(e, t, n, s) {
921
+ const o = n || m.ZeroAddress, { to: r, data: a, value: i, method: c } = this.encodeSwapCalldata(e, t);
922
+ if (s) {
923
+ const u = this.getJsonRpcProviderForStateOverrides(), l = i > 0n ? "0x" + i.toString(16) : void 0, p = await u.send("eth_call", [
924
+ { from: o, to: r, data: a, value: l },
775
925
  "latest",
776
- n
777
- ]), [g] = this.routerContract.interface.decodeFunctionResult(c, p);
778
- return { amountOut: g, method: c };
926
+ s
927
+ ]), [A] = this.routerContract.interface.decodeFunctionResult(c, p);
928
+ return { amountOut: A, method: c };
779
929
  } else {
780
930
  const u = await this.provider.call({
781
- from: s,
931
+ from: o,
782
932
  to: r,
783
933
  data: a,
784
934
  value: i > 0n ? i : void 0
785
- }), [d] = this.routerContract.interface.decodeFunctionResult(c, u);
786
- return { amountOut: d, method: c };
935
+ }), [l] = this.routerContract.interface.decodeFunctionResult(c, u);
936
+ return { amountOut: l, method: c };
787
937
  }
788
938
  }
789
939
  getJsonRpcProviderForStateOverrides() {
@@ -796,92 +946,167 @@ class K {
796
946
  /**
797
947
  * Format simulate error with human-readable details
798
948
  */
799
- formatSimulateError(e, t, o, n) {
800
- const s = e instanceof Error ? e : new Error(String(e)), r = e;
949
+ formatSimulateError(e, t, n, s) {
950
+ const o = e instanceof Error ? e : new Error(String(e)), r = e;
801
951
  let a = "unknown";
802
952
  if (r.reason && typeof r.reason == "string")
803
953
  a = r.reason;
804
954
  else if (r.revert && typeof r.revert == "object") {
805
- const d = r.revert;
806
- d.args && Array.isArray(d.args) && (a = d.args.join(", "));
807
- } else s.message && (a = s.message);
955
+ const l = r.revert;
956
+ l.args && Array.isArray(l.args) && (a = l.args.join(", "));
957
+ } else o.message && (a = o.message);
808
958
  const i = t.params.steps.map(
809
- (d, p) => ` Step ${p}: ${d.tokenIn.slice(0, 10)}→${d.tokenOut.slice(0, 10)} via adapter ${d.adapter.slice(0, 10)} pool ${d.pool.slice(0, 10)}`
959
+ (l, p) => ` Step ${p}: ${l.tokenIn.slice(0, 10)}→${l.tokenOut.slice(0, 10)} via adapter ${l.adapter.slice(0, 10)} pool ${l.pool.slice(0, 10)}`
810
960
  ).join(`
811
961
  `), c = [
812
- `Simulate ${o} failed: ${a}`,
962
+ `Simulate ${n} failed: ${a}`,
813
963
  ` Route: ${t.srcToken} → ${t.dstToken}`,
814
964
  ` AmountIn: ${t.amountIn}`,
815
965
  ` AmountOutMin: ${t.params.amountOutMin}`,
816
966
  ` Router: ${t.routerAddress}`,
817
- ` Caller: ${n}`,
967
+ ` Caller: ${s}`,
818
968
  ` Steps (${t.params.steps.length}):`,
819
969
  i
820
970
  ].join(`
821
971
  `), u = new Error(c);
822
- return u.cause = s, u.reason = a, u;
972
+ return u.cause = o, u.reason = a, u;
823
973
  }
824
974
  /**
825
- * Find which step in the route causes the same revert as the full route (e.g. MUL_ERROR).
826
- * Simulates with steps [0..1], [0..2], ... and returns the first step whose revert
827
- * matches fullRouteError. Ignores steps that revert with a different reason (e.g. unknown custom error).
975
+ * Pinpoint the first problematic step in a route.
976
+ *
977
+ * For each prefix [0..n), builds a rebased truncated quote (dstToken = last
978
+ * step's tokenOut, amountOutMin/expectAmountOut/customFee zeroed) and simulates it:
979
+ *
980
+ * - If the prefix REVERTS, that prefix's final step is the culprit. When a
981
+ * `fullRouteError` is supplied we only return when the prefix's revert
982
+ * matches the full-route reason; otherwise any revert qualifies.
983
+ * - If the prefix succeeds but its output is materially smaller than the
984
+ * aggregator's per-hop quoted amountOut, that step is flagged as the
985
+ * first deviator. This catches silent failures like transfer-tax tokens
986
+ * where simulation doesn't revert mid-route but cumulative shortfall
987
+ * eventually trips the final InsufficientOutput check.
828
988
  *
829
989
  * @param quote - Full quote from getQuote (the one that fails when simulated)
830
990
  * @param slippageBps - Same as for simulate
831
991
  * @param fromAddress - Same as for simulate
832
992
  * @param stateOverrides - Same as for simulate (use when simulating ERC20 sell with arbitrary address)
833
- * @param fullRouteError - The error from simulating the full route. Required so we match by revert reason (e.g. "MUL_ERROR"); only the step that produces the same reason is returned.
834
- * @returns The step index and step details whose revert matches fullRouteError, or null if none match or full route succeeds
993
+ * @param fullRouteError - Optional: the error from simulating the full route. If provided, prefix reverts whose reason differs are skipped (useful for MUL_ERROR-style targeted matching).
994
+ * @param deviationThresholdBps - Maximum tolerated per-step shortfall vs quoted amountOut before flagging the step (default 50 = 0.5%).
995
+ * @returns The first step matching the criteria above, or null if every prefix simulates within tolerance.
835
996
  */
836
- async findFailingStep(e, t, o, n, s) {
837
- const r = e.params.steps;
838
- if (!r.length) return null;
839
- const a = s != null ? this.normalizeRevertReason(s) : void 0;
840
- for (let i = 1; i <= r.length; i++) {
841
- const c = this.quoteWithFirstNSteps(e, i);
997
+ async findFailingStep(e, t, n, s, o, r = 50) {
998
+ const a = e.params.steps;
999
+ if (!a.length) return null;
1000
+ const i = o != null ? this.normalizeRevertReason(o) : void 0;
1001
+ for (let c = 1; c <= a.length; c++) {
1002
+ const u = this.buildTruncatedQuote(e, c);
1003
+ let l, p;
842
1004
  try {
843
- await this.simulate(c, t, o, n);
844
- } catch (u) {
845
- const d = this.normalizeRevertReason(u), p = u?.message ?? u?.reason ?? u?.shortMessage;
846
- if (a != null ? d === a : !0)
1005
+ l = (await this.simulate(u, t, n, s)).amountOut;
1006
+ } catch (g) {
1007
+ p = g;
1008
+ }
1009
+ if (p !== void 0) {
1010
+ const g = this.normalizeRevertReason(p), P = p?.shortMessage ?? p?.reason ?? p?.message;
1011
+ if (i == null || g === i)
847
1012
  return {
848
- stepIndex: i - 1,
849
- step: r[i - 1],
850
- error: u,
851
- revertMessage: typeof p == "string" ? p : void 0,
852
- fullRouteRevertMessage: a ?? void 0
1013
+ stepIndex: c - 1,
1014
+ step: a[c - 1],
1015
+ error: p,
1016
+ revertMessage: typeof P == "string" ? P : g,
1017
+ fullRouteRevertMessage: i
853
1018
  };
1019
+ continue;
1020
+ }
1021
+ if (l === void 0) continue;
1022
+ const A = this.getQuotedStepAmountOut(e, c - 1);
1023
+ if (A === void 0 || A === 0n) continue;
1024
+ const w = A > l ? A - l : 0n;
1025
+ if (w === 0n) continue;
1026
+ const v = w * _ / A;
1027
+ if (v > BigInt(r)) {
1028
+ const g = `Step ${c - 1} deviates: quoted=${A} simulated=${l} shortfall=${w} (${v}bps, threshold=${r}bps). Likely cause: transfer-tax on ${a[c - 1].tokenOut}, stale pool data, or dynamic-fee drift.`;
1029
+ return {
1030
+ stepIndex: c - 1,
1031
+ step: a[c - 1],
1032
+ error: new Error(g),
1033
+ revertMessage: g,
1034
+ fullRouteRevertMessage: i
1035
+ };
854
1036
  }
855
1037
  }
856
1038
  return null;
857
1039
  }
858
- /** Extract a comparable revert reason (e.g. "MUL_ERROR") from an error for findFailingStep matching. */
1040
+ /** Extract a comparable revert reason (e.g. "MUL_ERROR", "InsufficientOutput", "0xc956d868") from an error. */
859
1041
  normalizeRevertReason(e) {
860
1042
  if (e == null) return;
861
1043
  const t = e;
862
1044
  if (typeof t.reason == "string" && t.reason.length > 0) return t.reason;
863
- const o = t.shortMessage ?? t.message;
864
- if (typeof o != "string") return;
865
- const n = o.match(/reason="([^"]+)"/);
866
- if (n) return n[1];
867
- const s = o.match(/reverted:\s*"([^"]+)"/);
868
- if (s) return s[1];
869
- const r = o.match(/execution reverted:\s*"([^"]+)"/);
1045
+ const n = this.extractRevertData(e);
1046
+ if (n && n.length >= 10) {
1047
+ const c = n.slice(0, 10).toLowerCase();
1048
+ return C.KNOWN_ERROR_SELECTORS[c] ?? c;
1049
+ }
1050
+ const s = t.shortMessage ?? t.message;
1051
+ if (typeof s != "string") return;
1052
+ const o = s.match(/reason="([^"]+)"/);
1053
+ if (o) return o[1];
1054
+ const r = s.match(/reverted:\s*"([^"]+)"/);
870
1055
  if (r) return r[1];
1056
+ const a = s.match(/execution reverted:\s*"([^"]+)"/);
1057
+ if (a) return a[1];
1058
+ const i = s.match(/\b0x[0-9a-fA-F]{8}\b/);
1059
+ if (i) {
1060
+ const c = i[0].toLowerCase();
1061
+ return C.KNOWN_ERROR_SELECTORS[c] ?? c;
1062
+ }
871
1063
  }
872
- /** Build a quote that only includes the first stepCount steps (for findFailingStep). */
873
- quoteWithFirstNSteps(e, t) {
874
- const o = e.params.steps.slice(0, t), n = e.dstToken.toLowerCase(), s = /* @__PURE__ */ new Set(), r = [];
875
- for (const a of o) {
876
- const i = a.tokenOut.toLowerCase();
877
- i !== n && !s.has(i) && (s.add(i), r.push(a.tokenOut));
1064
+ /** Walk an error object (including nested `info`/`error`/`cause`/`revert`) for the first hex revert-data blob. */
1065
+ extractRevertData(e) {
1066
+ const t = /* @__PURE__ */ new Set(), n = [e];
1067
+ for (; n.length; ) {
1068
+ const s = n.shift();
1069
+ if (s == null || typeof s != "object" || t.has(s)) continue;
1070
+ t.add(s);
1071
+ const o = s, r = o.data;
1072
+ if (typeof r == "string" && /^0x[0-9a-fA-F]{8,}$/.test(r)) return r;
1073
+ for (const a of ["info", "error", "cause", "revert", "originalError"])
1074
+ o[a] && n.push(o[a]);
1075
+ }
1076
+ }
1077
+ /** Read the aggregator's quoted per-step amountOut from the quote's flattened route. */
1078
+ getQuotedStepAmountOut(e, t) {
1079
+ return e.route?.routes?.[0]?.steps?.[t]?.amountOut;
1080
+ }
1081
+ /**
1082
+ * Build a quote that simulates only the first `stepCount` steps by rebasing
1083
+ * dstToken to the last included step's tokenOut and zeroing all output
1084
+ * constraints (amountOutMin/expectAmountOut/customFee). Without this rebase
1085
+ * the truncated call would always revert — the router would expect the
1086
+ * original dstToken to arrive, which never happens for an intermediate prefix.
1087
+ */
1088
+ buildTruncatedQuote(e, t) {
1089
+ const n = e.params.steps.slice(0, t), o = n[n.length - 1].tokenOut, r = o.toLowerCase(), a = e.srcToken.toLowerCase(), i = t === e.params.steps.length, c = /* @__PURE__ */ new Set(), u = [];
1090
+ for (const l of n) {
1091
+ const p = l.tokenOut.toLowerCase();
1092
+ p === r || p === a || c.has(p) || (c.add(p), u.push(l.tokenOut));
878
1093
  }
879
1094
  return {
880
1095
  ...e,
1096
+ dstToken: o,
1097
+ // Native unwrap only makes sense when we're simulating the true dstToken.
1098
+ dstNative: i ? e.dstNative : !1,
1099
+ amountOut: i ? e.amountOut : 0n,
1100
+ customFee: i ? e.customFee : void 0,
881
1101
  params: {
882
1102
  ...e.params,
883
- steps: o,
884
- intermediateTokens: r
1103
+ dstToken: o,
1104
+ amountOutMin: i ? e.params.amountOutMin : 0n,
1105
+ expectAmountOut: i ? e.params.expectAmountOut : 0n,
1106
+ feeReceiver: i ? e.params.feeReceiver : m.ZeroAddress,
1107
+ feeBps: i ? e.params.feeBps : 0,
1108
+ steps: n,
1109
+ intermediateTokens: u
885
1110
  }
886
1111
  };
887
1112
  }
@@ -902,68 +1127,72 @@ class K {
902
1127
  * @param balance - Balance to inject (default: 1M tokens with 18 decimals)
903
1128
  * @param spenderAddress - Spender to approve (default: routerAddress). Pass quote.routerAddress when simulating API quotes.
904
1129
  */
905
- buildStateOverrides(e, t, o, n, s, r) {
906
- if (r?.isNative || _(e))
1130
+ buildStateOverrides(e, t, n, s, o, r) {
1131
+ if (r?.isNative || T(e))
907
1132
  return {};
908
- if (!o || o === l.ZeroAddress)
1133
+ if (!n || n === m.ZeroAddress)
909
1134
  throw new Error("buildStateOverrides requires a non-zero routerAddress.");
910
- const a = l.AbiCoder.defaultAbiCoder(), i = n || l.parseUnits("1000000", 18), c = s ?? o, u = l.zeroPadValue(l.toBeHex(i), 32), d = l.zeroPadValue(l.toBeHex(l.MaxUint256), 32), p = {}, g = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 50, 51, 52, 100, 101, 102];
911
- for (const m of g) {
912
- const v = l.keccak256(a.encode(["address", "uint256"], [t, m]));
1135
+ const a = m.AbiCoder.defaultAbiCoder(), i = s || m.parseUnits("1000000", 18), c = o ?? n, u = m.zeroPadValue(m.toBeHex(i), 32), l = m.zeroPadValue(m.toBeHex(m.MaxUint256), 32), p = {}, A = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 50, 51, 52, 100, 101, 102];
1136
+ for (const w of A) {
1137
+ const v = m.keccak256(a.encode(["address", "uint256"], [t, w]));
913
1138
  p[v] = u;
914
- const C = l.keccak256(a.encode(["address", "uint256"], [t, m])), E = l.keccak256(a.encode(["address", "bytes32"], [c, C]));
915
- p[E] = d;
1139
+ const g = m.keccak256(a.encode(["address", "uint256"], [t, w])), P = m.keccak256(a.encode(["address", "bytes32"], [c, g]));
1140
+ p[P] = l;
916
1141
  }
917
1142
  return {
918
1143
  [e.toLowerCase()]: { stateDiff: p }
919
1144
  };
920
1145
  }
921
- }
922
- const M = [
1146
+ };
1147
+ C.KNOWN_ERROR_SELECTORS = {
1148
+ "0x2c19b8b8": "InsufficientOutput"
1149
+ };
1150
+ let K = C;
1151
+ const Y = [
923
1152
  "function token0() external view returns (address)",
924
1153
  "function token1() external view returns (address)",
925
1154
  "function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)"
926
- ], te = [
1155
+ ], ce = [
927
1156
  "function token0() external view returns (address)",
928
1157
  "function token1() external view returns (address)",
929
1158
  "function fee() external view returns (uint24)",
930
1159
  "function liquidity() external view returns (uint128)",
931
1160
  "function slot0() external view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint32 feeProtocol, bool unlocked)"
932
- ], oe = "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73", ne = [
1161
+ ], ue = "0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73", de = [
933
1162
  "function getPair(address tokenA, address tokenB) external view returns (address pair)"
934
- ], re = "0x86407bEa2078ea5f5EB5A52B2caA963bC1F889Da", se = [
1163
+ ], le = "0x86407bEa2078ea5f5EB5A52B2caA963bC1F889Da", pe = [
935
1164
  "function getPair(address tokenA, address tokenB) external view returns (address pair)"
936
- ], ae = "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865", ie = [
1165
+ ], me = "0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865", fe = [
937
1166
  "function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool)"
938
- ], ce = [100, 500, 2500, 1e4], ue = 60000n, de = 120000n, le = 100000n;
939
- class Ae {
1167
+ ], he = [100, 500, 2500, 1e4], we = 60000n, Ae = 120000n, ve = 100000n;
1168
+ class Ce {
940
1169
  constructor(e, t) {
941
- this.poolCache = /* @__PURE__ */ new Map(), this.provider = e, this.v2Factory = new l.Contract(
942
- oe,
943
- ne,
1170
+ this.poolCache = /* @__PURE__ */ new Map(), this.provider = e, this.v2Factory = new m.Contract(
1171
+ ue,
1172
+ de,
944
1173
  e
945
- ), this.v3Factory = new l.Contract(
946
- ae,
947
- ie,
1174
+ ), this.v3Factory = new m.Contract(
1175
+ me,
1176
+ fe,
948
1177
  e
949
- ), this.babySwapFactory = new l.Contract(
950
- re,
951
- se,
1178
+ ), this.babySwapFactory = new m.Contract(
1179
+ le,
1180
+ pe,
952
1181
  e
953
1182
  );
954
1183
  }
955
1184
  /**
956
1185
  * Discover optimal route
957
1186
  */
958
- async findBestRoute(e, t, o) {
959
- const n = await this.discoverPools(e, t);
960
- if (n.length === 0)
1187
+ async findBestRoute(e, t, n) {
1188
+ const s = await this.discoverPools(e, t);
1189
+ if (s.length === 0)
961
1190
  throw new Error(`No pools found for ${e} -> ${t}`);
962
1191
  const r = (await this.calculateRoutes(
963
- n,
1192
+ s,
964
1193
  e,
965
1194
  t,
966
- o
1195
+ n
967
1196
  )).reduce(
968
1197
  (a, i) => i.amountOut > a.amountOut ? i : a
969
1198
  );
@@ -971,7 +1200,7 @@ class Ae {
971
1200
  routes: [r],
972
1201
  percentages: [1e4],
973
1202
  // 100%
974
- totalAmountIn: o,
1203
+ totalAmountIn: n,
975
1204
  totalAmountOut: r.amountOut,
976
1205
  totalGasEstimate: r.gasEstimate
977
1206
  };
@@ -980,60 +1209,60 @@ class Ae {
980
1209
  * Discover available pools (direct path)
981
1210
  */
982
1211
  async discoverPools(e, t) {
983
- const o = [];
1212
+ const n = [];
984
1213
  try {
985
- const n = await this.findV2Pool(e, t);
986
- n && o.push(n);
1214
+ const s = await this.findV2Pool(e, t);
1215
+ s && n.push(s);
987
1216
  } catch {
988
1217
  }
989
- for (const n of ce)
1218
+ for (const s of he)
990
1219
  try {
991
- const s = await this.findV3Pool(e, t, n);
992
- s && o.push(s);
1220
+ const o = await this.findV3Pool(e, t, s);
1221
+ o && n.push(o);
993
1222
  } catch {
994
1223
  }
995
1224
  try {
996
- const n = await this.findBabySwapPool(e, t);
997
- n && o.push(n);
1225
+ const s = await this.findBabySwapPool(e, t);
1226
+ s && n.push(s);
998
1227
  } catch {
999
1228
  }
1000
- return o;
1229
+ return n;
1001
1230
  }
1002
1231
  /**
1003
1232
  * Find V2 pool
1004
1233
  */
1005
1234
  async findV2Pool(e, t) {
1006
- const o = `v2-${e}-${t}`;
1007
- if (this.poolCache.has(o))
1008
- return this.poolCache.get(o);
1009
- const n = await this.v2Factory.getPair(e, t);
1010
- if (n === l.ZeroAddress)
1235
+ const n = `v2-${e}-${t}`;
1236
+ if (this.poolCache.has(n))
1237
+ return this.poolCache.get(n);
1238
+ const s = await this.v2Factory.getPair(e, t);
1239
+ if (s === m.ZeroAddress)
1011
1240
  return null;
1012
- const s = new l.Contract(n, M, this.provider), [r, a, i] = await Promise.all([
1013
- s.token0(),
1014
- s.token1(),
1015
- s.getReserves()
1241
+ const o = new m.Contract(s, Y, this.provider), [r, a, i] = await Promise.all([
1242
+ o.token0(),
1243
+ o.token1(),
1244
+ o.getReserves()
1016
1245
  ]), c = {
1017
- address: n,
1246
+ address: s,
1018
1247
  token0: r,
1019
1248
  token1: a,
1020
- protocol: f.PancakeV2,
1249
+ protocol: d.PancakeV2,
1021
1250
  reserve0: i.reserve0,
1022
1251
  reserve1: i.reserve1
1023
1252
  };
1024
- return this.poolCache.set(o, c), c;
1253
+ return this.poolCache.set(n, c), c;
1025
1254
  }
1026
1255
  /**
1027
1256
  * Find V3 pool
1028
1257
  */
1029
- async findV3Pool(e, t, o) {
1030
- const n = `v3-${e}-${t}-${o}`;
1031
- if (this.poolCache.has(n))
1032
- return this.poolCache.get(n);
1033
- const s = await this.v3Factory.getPool(e, t, o);
1034
- if (s === l.ZeroAddress)
1258
+ async findV3Pool(e, t, n) {
1259
+ const s = `v3-${e}-${t}-${n}`;
1260
+ if (this.poolCache.has(s))
1261
+ return this.poolCache.get(s);
1262
+ const o = await this.v3Factory.getPool(e, t, n);
1263
+ if (o === m.ZeroAddress)
1035
1264
  return null;
1036
- const r = new l.Contract(s, te, this.provider), [a, i, c] = await Promise.all([
1265
+ const r = new m.Contract(o, ce, this.provider), [a, i, c] = await Promise.all([
1037
1266
  r.token0(),
1038
1267
  r.token1(),
1039
1268
  r.liquidity()
@@ -1041,102 +1270,102 @@ class Ae {
1041
1270
  if (c === 0n)
1042
1271
  return null;
1043
1272
  const u = {
1044
- address: s,
1273
+ address: o,
1045
1274
  token0: a,
1046
1275
  token1: i,
1047
- protocol: f.PancakeV3,
1048
- fee: o,
1276
+ protocol: d.PancakeV3,
1277
+ fee: n,
1049
1278
  liquidity: c
1050
1279
  };
1051
- return this.poolCache.set(n, u), u;
1280
+ return this.poolCache.set(s, u), u;
1052
1281
  }
1053
1282
  /**
1054
1283
  * Find BabySwap pool (V2 fork, 0.2% fee)
1055
1284
  */
1056
1285
  async findBabySwapPool(e, t) {
1057
- const o = `babyswap-${e}-${t}`;
1058
- if (this.poolCache.has(o))
1059
- return this.poolCache.get(o);
1060
- const n = await this.babySwapFactory.getPair(e, t);
1061
- if (n === l.ZeroAddress)
1286
+ const n = `babyswap-${e}-${t}`;
1287
+ if (this.poolCache.has(n))
1288
+ return this.poolCache.get(n);
1289
+ const s = await this.babySwapFactory.getPair(e, t);
1290
+ if (s === m.ZeroAddress)
1062
1291
  return null;
1063
- const s = new l.Contract(n, M, this.provider), [r, a, i] = await Promise.all([
1064
- s.token0(),
1065
- s.token1(),
1066
- s.getReserves()
1292
+ const o = new m.Contract(s, Y, this.provider), [r, a, i] = await Promise.all([
1293
+ o.token0(),
1294
+ o.token1(),
1295
+ o.getReserves()
1067
1296
  ]), c = {
1068
- address: n,
1297
+ address: s,
1069
1298
  token0: r,
1070
1299
  token1: a,
1071
- protocol: f.BabySwap,
1300
+ protocol: d.BabySwap,
1072
1301
  reserve0: i.reserve0,
1073
1302
  reserve1: i.reserve1
1074
1303
  };
1075
- return this.poolCache.set(o, c), c;
1304
+ return this.poolCache.set(n, c), c;
1076
1305
  }
1077
1306
  /**
1078
1307
  * Calculate route quotes
1079
1308
  */
1080
- async calculateRoutes(e, t, o, n) {
1081
- const s = [];
1309
+ async calculateRoutes(e, t, n, s) {
1310
+ const o = [];
1082
1311
  for (const r of e)
1083
1312
  try {
1084
1313
  const a = await this.getAmountOut(
1085
1314
  r,
1086
1315
  t,
1087
- o,
1088
- n
1316
+ n,
1317
+ s
1089
1318
  );
1090
- a > 0n && s.push({
1319
+ a > 0n && o.push({
1091
1320
  steps: [
1092
1321
  {
1093
1322
  pool: r,
1094
1323
  tokenIn: t,
1095
- tokenOut: o,
1096
- amountIn: n,
1324
+ tokenOut: n,
1325
+ amountIn: s,
1097
1326
  amountOut: a
1098
1327
  }
1099
1328
  ],
1100
- amountIn: n,
1329
+ amountIn: s,
1101
1330
  amountOut: a,
1102
- gasEstimate: r.protocol === f.PancakeV2 || r.protocol === f.BabySwap ? ue : r.protocol === f.Dodo ? le : de
1331
+ gasEstimate: r.protocol === d.PancakeV2 || r.protocol === d.BabySwap ? we : r.protocol === d.Dodo ? ve : Ae
1103
1332
  });
1104
1333
  } catch {
1105
1334
  }
1106
- return s;
1335
+ return o;
1107
1336
  }
1108
1337
  /**
1109
1338
  * Get output for a single pool
1110
1339
  */
1111
- async getAmountOut(e, t, o, n) {
1112
- if (e.protocol === f.PancakeV2)
1113
- return this.getV2AmountOut(e, t, n);
1114
- if (e.protocol === f.BabySwap)
1115
- return this.getBabySwapAmountOut(e, t, n);
1116
- if (e.protocol === f.Dodo)
1340
+ async getAmountOut(e, t, n, s) {
1341
+ if (e.protocol === d.PancakeV2)
1342
+ return this.getV2AmountOut(e, t, s);
1343
+ if (e.protocol === d.BabySwap)
1344
+ return this.getBabySwapAmountOut(e, t, s);
1345
+ if (e.protocol === d.Dodo)
1117
1346
  throw new Error("DODO amount out not supported in local route discovery");
1118
- return this.estimateV3AmountOut(e, t, n);
1347
+ return this.estimateV3AmountOut(e, t, s);
1119
1348
  }
1120
1349
  /**
1121
1350
  * V2 output calculation
1122
1351
  */
1123
- getV2AmountOut(e, t, o) {
1124
- const n = t.toLowerCase() === e.token0.toLowerCase(), [s, r] = n ? [e.reserve0, e.reserve1] : [e.reserve1, e.reserve0], a = o * 9975n, i = a * r, c = s * 10000n + a;
1352
+ getV2AmountOut(e, t, n) {
1353
+ const s = t.toLowerCase() === e.token0.toLowerCase(), [o, r] = s ? [e.reserve0, e.reserve1] : [e.reserve1, e.reserve0], a = n * 9975n, i = a * r, c = o * 10000n + a;
1125
1354
  return i / c;
1126
1355
  }
1127
1356
  /**
1128
1357
  * BabySwap output calculation (V2 fork, 0.2% fee — coefficient 2 in 1000-scale)
1129
1358
  */
1130
- getBabySwapAmountOut(e, t, o) {
1131
- const n = t.toLowerCase() === e.token0.toLowerCase(), [s, r] = n ? [e.reserve0, e.reserve1] : [e.reserve1, e.reserve0], a = o * 998n, i = a * r, c = s * 1000n + a;
1359
+ getBabySwapAmountOut(e, t, n) {
1360
+ const s = t.toLowerCase() === e.token0.toLowerCase(), [o, r] = s ? [e.reserve0, e.reserve1] : [e.reserve1, e.reserve0], a = n * 998n, i = a * r, c = o * 1000n + a;
1132
1361
  return i / c;
1133
1362
  }
1134
1363
  /**
1135
1364
  * V3 output estimation (simplified)
1136
1365
  */
1137
- estimateV3AmountOut(e, t, o) {
1138
- const s = 1000000n - BigInt(e.fee || 2500);
1139
- return o * s / 1000000n;
1366
+ estimateV3AmountOut(e, t, n) {
1367
+ const o = 1000000n - BigInt(e.fee || 2500);
1368
+ return n * o / 1000000n;
1140
1369
  }
1141
1370
  /**
1142
1371
  * Clear cache
@@ -1145,33 +1374,33 @@ class Ae {
1145
1374
  this.poolCache.clear();
1146
1375
  }
1147
1376
  }
1148
- class ge {
1377
+ class be {
1149
1378
  constructor(e) {
1150
1379
  this.adapters = e;
1151
1380
  }
1152
1381
  /**
1153
1382
  * Build SwapParams from split route
1154
1383
  */
1155
- build(e, t, o, n, s = T) {
1384
+ build(e, t, n, s, o = N) {
1156
1385
  const r = this.flattenRoutes(e), a = this.mergeIdenticalPools(r), i = this.topologicalSort(a, t), c = this.convertToSwapSteps(i), u = this.extractIntermediates(
1157
1386
  i,
1158
1387
  t,
1159
- o
1160
- ), d = BigInt(Math.floor(Date.now() / 1e3) + s);
1388
+ n
1389
+ ), l = BigInt(Math.floor(Date.now() / 1e3) + o);
1161
1390
  return {
1162
1391
  srcToken: t,
1163
- dstToken: o,
1392
+ dstToken: n,
1164
1393
  amountIn: e.totalAmountIn,
1165
- amountOutMin: n,
1394
+ amountOutMin: s,
1166
1395
  steps: c,
1167
1396
  intermediateTokens: u,
1168
- deadline: d,
1169
- quoteId: l.ZeroHash,
1397
+ deadline: l,
1398
+ quoteId: m.ZeroHash,
1170
1399
  expectAmountOut: e.totalAmountOut,
1171
1400
  // SwapBuilder is the legacy direct-build path that does not know about custom fees.
1172
1401
  // Integrators that want custom fees should use PeachClient.getQuote with options.customFee
1173
1402
  // instead, which sets these fields and adjusts amountOutMin accordingly.
1174
- feeReceiver: l.ZeroAddress,
1403
+ feeReceiver: m.ZeroAddress,
1175
1404
  feeBps: 0
1176
1405
  };
1177
1406
  }
@@ -1180,17 +1409,17 @@ class ge {
1180
1409
  */
1181
1410
  flattenRoutes(e) {
1182
1411
  const t = [];
1183
- for (let o = 0; o < e.routes.length; o++) {
1184
- const n = e.routes[o], s = e.percentages[o], r = e.totalAmountIn * BigInt(s) / b;
1185
- for (let a = 0; a < n.steps.length; a++) {
1186
- const i = n.steps[a];
1412
+ for (let n = 0; n < e.routes.length; n++) {
1413
+ const s = e.routes[n], o = e.percentages[n], r = e.totalAmountIn * BigInt(o) / _;
1414
+ for (let a = 0; a < s.steps.length; a++) {
1415
+ const i = s.steps[a];
1187
1416
  t.push({
1188
1417
  pool: i.pool,
1189
1418
  tokenIn: i.tokenIn,
1190
1419
  tokenOut: i.tokenOut,
1191
1420
  // Only first step has fixed amount, subsequent steps depend on previous output
1192
1421
  amountIn: a === 0 ? r : 0n,
1193
- routeIndex: o,
1422
+ routeIndex: n,
1194
1423
  stepIndex: a
1195
1424
  });
1196
1425
  }
@@ -1202,54 +1431,54 @@ class ge {
1202
1431
  * Key: pool + tokenIn + tokenOut
1203
1432
  */
1204
1433
  mergeIdenticalPools(e) {
1205
- const t = /* @__PURE__ */ new Map(), o = [];
1206
- for (const n of e) {
1207
- const s = `${n.pool.address}-${n.tokenIn}-${n.tokenOut}`;
1208
- if (t.has(s)) {
1209
- const r = t.get(s);
1210
- n.amountIn > 0n && r.amountIn > 0n && (r.amountIn = 0n);
1434
+ const t = /* @__PURE__ */ new Map(), n = [];
1435
+ for (const s of e) {
1436
+ const o = `${s.pool.address}-${s.tokenIn}-${s.tokenOut}`;
1437
+ if (t.has(o)) {
1438
+ const r = t.get(o);
1439
+ s.amountIn > 0n && r.amountIn > 0n && (r.amountIn = 0n);
1211
1440
  } else {
1212
- const r = { ...n };
1213
- t.set(s, r), o.push(r);
1441
+ const r = { ...s };
1442
+ t.set(o, r), n.push(r);
1214
1443
  }
1215
1444
  }
1216
- for (const n of o) {
1217
- const s = `${n.pool.address}-${n.tokenIn}-${n.tokenOut}`;
1445
+ for (const s of n) {
1446
+ const o = `${s.pool.address}-${s.tokenIn}-${s.tokenOut}`;
1218
1447
  e.filter(
1219
- (a) => `${a.pool.address}-${a.tokenIn}-${a.tokenOut}` === s
1220
- ).length > 1 && (n.amountIn = 0n);
1448
+ (a) => `${a.pool.address}-${a.tokenIn}-${a.tokenOut}` === o
1449
+ ).length > 1 && (s.amountIn = 0n);
1221
1450
  }
1222
- return o;
1451
+ return n;
1223
1452
  }
1224
1453
  /**
1225
1454
  * Topological sort (Kahn's Algorithm)
1226
1455
  */
1227
1456
  topologicalSort(e, t) {
1228
- const o = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map();
1457
+ const n = /* @__PURE__ */ new Map(), s = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Map();
1229
1458
  for (const i of e) {
1230
1459
  const c = this.stepKey(i);
1231
- n.set(c, i), o.set(c, 0), s.set(c, []);
1460
+ s.set(c, i), n.set(c, 0), o.set(c, []);
1232
1461
  }
1233
1462
  for (const i of e) {
1234
1463
  const c = this.stepKey(i);
1235
1464
  if (i.tokenIn !== t) {
1236
1465
  for (const u of e)
1237
1466
  if (u.tokenOut === i.tokenIn) {
1238
- const d = this.stepKey(u);
1239
- d !== c && (s.get(d).push(c), o.set(c, (o.get(c) || 0) + 1));
1467
+ const l = this.stepKey(u);
1468
+ l !== c && (o.get(l).push(c), n.set(c, (n.get(c) || 0) + 1));
1240
1469
  }
1241
1470
  }
1242
1471
  }
1243
1472
  const r = [];
1244
- for (const [i, c] of o)
1473
+ for (const [i, c] of n)
1245
1474
  c === 0 && r.push(i);
1246
1475
  const a = [];
1247
1476
  for (; r.length > 0; ) {
1248
- const i = r.shift(), c = n.get(i);
1477
+ const i = r.shift(), c = s.get(i);
1249
1478
  a.push(c);
1250
- for (const u of s.get(i) || []) {
1251
- const d = (o.get(u) || 0) - 1;
1252
- o.set(u, d), d === 0 && r.push(u);
1479
+ for (const u of o.get(i) || []) {
1480
+ const l = (n.get(u) || 0) - 1;
1481
+ n.set(u, l), l === 0 && r.push(u);
1253
1482
  }
1254
1483
  }
1255
1484
  if (a.length !== e.length)
@@ -1261,11 +1490,11 @@ class ge {
1261
1490
  */
1262
1491
  convertToSwapSteps(e) {
1263
1492
  return e.map((t) => {
1264
- const o = this.adapters.get(t.pool.protocol);
1265
- if (!o)
1493
+ const n = this.adapters.get(t.pool.protocol);
1494
+ if (!n)
1266
1495
  throw new Error(`No adapter for protocol: ${t.pool.protocol}`);
1267
1496
  return {
1268
- adapter: o,
1497
+ adapter: n,
1269
1498
  pool: t.pool.address,
1270
1499
  tokenIn: t.tokenIn,
1271
1500
  tokenOut: t.tokenOut,
@@ -1279,24 +1508,47 @@ class ge {
1279
1508
  */
1280
1509
  encodeExtraData(e) {
1281
1510
  switch (e.protocol) {
1282
- case f.PancakeV2:
1511
+ case d.PancakeV1:
1512
+ return "0x";
1513
+ case d.PancakeV2:
1283
1514
  return "0x";
1284
1515
  // V2 doesn't need extra parameters
1285
- case f.PancakeV3:
1286
- case f.UniswapV3:
1287
- case f.UniswapV4:
1516
+ case d.UniswapV2:
1517
+ return "0x";
1518
+ case d.PancakeV3:
1519
+ case d.UniswapV3:
1520
+ case d.UniswapV4:
1521
+ case d.SquadSwapV3:
1522
+ case d.ThenaFusion:
1523
+ return "0x";
1524
+ case d.PancakeInfinityCl:
1525
+ case d.PancakeInfinityLb:
1526
+ return "0x";
1527
+ case d.Dodo:
1528
+ return "0x";
1529
+ case d.NomiswapStable:
1530
+ return "0x";
1531
+ case d.Biswap:
1532
+ return "0x";
1533
+ case d.Apeswap:
1534
+ return "0x";
1535
+ case d.BabyDogeSwap:
1536
+ return "0x";
1537
+ case d.BabySwap:
1538
+ return "0x";
1539
+ case d.BakerySwap:
1288
1540
  return "0x";
1289
- case f.Dodo:
1541
+ case d.SquadSwapV2:
1290
1542
  return "0x";
1291
- case f.NomiswapStable:
1543
+ case d.SushiSwapV2:
1292
1544
  return "0x";
1293
- case f.Biswap:
1545
+ case d.SushiSwapV3:
1294
1546
  return "0x";
1295
- case f.Apeswap:
1547
+ case d.PancakeStable:
1296
1548
  return "0x";
1297
- case f.BabyDogeSwap:
1549
+ case d.ListaStable:
1298
1550
  return "0x";
1299
- case f.BabySwap:
1551
+ case d.Wombat:
1300
1552
  return "0x";
1301
1553
  default:
1302
1554
  return "0x";
@@ -1305,11 +1557,11 @@ class ge {
1305
1557
  /**
1306
1558
  * Extract intermediate tokens
1307
1559
  */
1308
- extractIntermediates(e, t, o) {
1309
- const n = /* @__PURE__ */ new Set();
1310
- for (const s of e)
1311
- s.tokenOut !== o && n.add(s.tokenOut);
1312
- return n.delete(t), n.delete(o), Array.from(n);
1560
+ extractIntermediates(e, t, n) {
1561
+ const s = /* @__PURE__ */ new Set();
1562
+ for (const o of e)
1563
+ o.tokenOut !== n && s.add(o.tokenOut);
1564
+ return s.delete(t), s.delete(n), Array.from(s);
1313
1565
  }
1314
1566
  /**
1315
1567
  * Generate unique step key
@@ -1319,28 +1571,30 @@ class ge {
1319
1571
  }
1320
1572
  }
1321
1573
  export {
1322
- k as API_DEFAULTS,
1323
- X as ApiClient,
1324
- A as ApiError,
1325
- b as BPS_DENOMINATOR,
1326
- me as BSC_MAINNET_CONFIG,
1327
- ve as BSC_TESTNET_CONFIG,
1328
- x as CustomFeeError,
1329
- q as DEFAULT_API_URL,
1330
- T as DEFAULT_DEADLINE_SECONDS,
1331
- W as DEFAULT_EXECUTE_TIMEOUT_MS,
1332
- he as DEFAULT_SLIPPAGE_BPS,
1333
- $ as DEFAULT_TRANSACTION_RESPONSE_POLL_INTERVALS_MS,
1334
- we as ERR_ZERO_AMOUNT_PATHS,
1335
- H as ExecuteTimeoutError,
1336
- L as MAX_FEE_BPS,
1337
- fe as MAX_PLATFORM_CUT_BPS,
1338
- Q as NATIVE_TOKEN_ADDRESS,
1574
+ E as API_DEFAULTS,
1575
+ ne as ApiClient,
1576
+ S as ApiError,
1577
+ _ as BPS_DENOMINATOR,
1578
+ ke as BSC_MAINNET_CONFIG,
1579
+ Ee as BSC_TESTNET_CONFIG,
1580
+ B as CustomFeeError,
1581
+ J as DEFAULT_API_URL,
1582
+ N as DEFAULT_DEADLINE_SECONDS,
1583
+ G as DEFAULT_EXECUTE_TIMEOUT_MS,
1584
+ Se as DEFAULT_SLIPPAGE_BPS,
1585
+ M as DEFAULT_TRANSACTION_RESPONSE_POLL_INTERVALS_MS,
1586
+ Pe as ERR_ZERO_AMOUNT_PATHS,
1587
+ Q as ExecuteTimeoutError,
1588
+ U as MAX_FEE_BPS,
1589
+ Ie as MAX_PLATFORM_CUT_BPS,
1590
+ q as NATIVE_TOKEN_ADDRESS,
1591
+ O as PERMIT2_ADDRESS,
1592
+ $ as PERMIT2_MAX_AMOUNT,
1339
1593
  K as PeachClient,
1340
- f as ProtocolType,
1341
- Ae as RouteDiscovery,
1342
- ge as SwapBuilder,
1343
- _ as isNativeTokenAddress,
1344
- U as withWalletSendTimeout
1594
+ d as ProtocolType,
1595
+ Ce as RouteDiscovery,
1596
+ be as SwapBuilder,
1597
+ T as isNativeTokenAddress,
1598
+ W as withWalletSendTimeout
1345
1599
  };
1346
1600
  //# sourceMappingURL=index.mjs.map