@peachprojects/aggregator-sdk 0.0.0-experimental-20260326083014 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -8
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +9 -7
- package/dist/index.mjs +66 -72
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -6,9 +6,9 @@ TypeScript SDK for the DEX Aggregator on BSC.
|
|
|
6
6
|
|
|
7
7
|
GitBook-ready documentation pages live in [`docs/`](docs/README.md). The docs are organized around the actual integration flow:
|
|
8
8
|
|
|
9
|
-
-
|
|
10
|
-
- quote,
|
|
11
|
-
-
|
|
9
|
+
- quick start
|
|
10
|
+
- quote, approve, swap, and simulation flow
|
|
11
|
+
- compact SDK/API reference and troubleshooting
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
@@ -24,11 +24,10 @@ import { ethers } from 'ethers';
|
|
|
24
24
|
|
|
25
25
|
const provider = new ethers.JsonRpcProvider('https://bsc-dataseed.binance.org');
|
|
26
26
|
|
|
27
|
-
const client = new PeachClient(BSC_MAINNET_CONFIG, provider
|
|
28
|
-
api: { baseUrl: 'https://api.cipheron.org' },
|
|
29
|
-
});
|
|
27
|
+
const client = new PeachClient(BSC_MAINNET_CONFIG, provider);
|
|
30
28
|
|
|
31
|
-
//
|
|
29
|
+
// By default uses https://api.peach.ag. Override with:
|
|
30
|
+
// new PeachClient(config, provider, { api: { baseUrl: 'https://api.cipheron.org' } });
|
|
32
31
|
|
|
33
32
|
// Get quote
|
|
34
33
|
const quote = await client.getQuote({
|
|
@@ -68,7 +67,7 @@ const quote = await client.getQuote({
|
|
|
68
67
|
byAmountIn?: boolean, // true: input→output (default: true)
|
|
69
68
|
depth?: number, // Route search depth (default: 3)
|
|
70
69
|
splitCount?: number, // Trade split count (default: 20)
|
|
71
|
-
providers?: string[], // DEX providers (default:
|
|
70
|
+
providers?: string[], // DEX providers (default: all 7 — PANCAKEV2, PANCAKEV3, PANCAKE_INFINITY_CL, UNISWAPV3, UNISWAPV4, DODO, THENA)
|
|
72
71
|
deadlineSeconds?: number, // Tx deadline in seconds (default: 1200 = 20min)
|
|
73
72
|
}
|
|
74
73
|
});
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("ethers"),$=50,P=10000n,_=1200,x=6e4,S=[50,100,200,400,800,1200],L="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";function C(m){return m.toLowerCase()===L.toLowerCase()}const B=4001;var w=(m=>(m.PancakeV2="PancakeV2",m.PancakeV3="PancakeV3",m.PancakeInfinityCl="Pancake_Infinity_Cl",m.UniswapV3="UniswapV3",m.UniswapV4="UniswapV4",m.Dodo="Dodo",m.Thena="Thena",m))(w||{});const K={chainId:56,rpcUrl:"https://bsc-dataseed.binance.org",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",adapters:[]},W={chainId:97,rpcUrl:"https://bsc-testnet-rpc.publicnode.com",weth:"0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd",adapters:[]};class R extends Error{constructor(t,e,n){super(t),this.name="ExecuteTimeoutError",this.stage=e,this.txHash=n}}const I={depth:3,splitCount:20,providers:["PANCAKEV2","PANCAKEV3","PANCAKE_INFINITY_CL","UNISWAPV3","UNISWAPV4","DODO","THENA"],clientVersion:1001500},G=1e4;class F{constructor(t){if(!t.baseUrl)throw new Error("ApiClient requires a baseUrl");this.baseUrl=t.baseUrl,this.timeout=t.timeout||G}async findRoutes(t){const{from:e,target:n,amount:o,byAmountIn:s=!0,depth:r=I.depth,splitCount:a=I.splitCount,providers:i=I.providers}=t,c=new URLSearchParams({from:e,target:n,amount:o.toString(),by_amount_in:s.toString(),depth:r.toString(),split_count:a.toString(),providers:i.join(","),v:I.clientVersion.toString()}),u=`${this.baseUrl}/router/find_routes?${c}`,d=new AbortController,l=setTimeout(()=>d.abort(),this.timeout);try{const f=await fetch(u,{method:"GET",headers:{Accept:"application/json"},signal:d.signal});if(clearTimeout(l),!f.ok)throw new v(`API request failed: ${f.status} ${f.statusText}`,f.status);const A=await f.json();if(A.code!==200)throw new v(A.msg||"Route not found",A.code);if(!A.data||!A.data.paths||A.data.paths.length===0)throw new v("No routes found",404);return A.data}catch(f){throw clearTimeout(l),f instanceof v?f:f instanceof Error?f.name==="AbortError"?new v("API request timeout",408):new v(`API request failed: ${f.message}`,0):new v("Unknown API error",0)}}async getStatus(){const t=`${this.baseUrl}/router/status`,e=new AbortController,n=setTimeout(()=>e.abort(),this.timeout);try{const o=await fetch(t,{method:"GET",headers:{Accept:"application/json"},signal:e.signal});if(clearTimeout(n),!o.ok)throw new v(`API request failed: ${o.status} ${o.statusText}`,o.status);const s=await o.json();if(s.code!==200)throw new v(s.msg||"Failed to get status",s.code);return s.data}catch(o){throw clearTimeout(n),o instanceof v?o:o instanceof Error?o.name==="AbortError"?new v("API request timeout",408):new v(`API request failed: ${o.message}`,0):new v("Unknown API error",0)}}async getAvailableProviders(){return(await this.getStatus()).providers}setBaseUrl(t){this.baseUrl=t}getBaseUrl(){return this.baseUrl}}class v extends Error{constructor(t,e){super(t),this.name="ApiError",this.code=e}}async function y(m,t=x){if(t<=0)return m;let e;try{return await Promise.race([m,new Promise((n,o)=>{e=setTimeout(()=>{o(new R(`Wallet did not settle sendTransaction within ${t}ms.`,"wallet_send"))},t)})])}finally{e&&clearTimeout(e)}}const H=["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) params) external returns (uint256 amountOut)","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) params) external payable returns (uint256 amountOut)","function isAdapterRegistered(address adapter) external view returns (bool)","function WETH() external view returns (address)"],k=["function approve(address spender, uint256 amount) external returns (bool)","function allowance(address owner, address spender) external view returns (uint256)","function balanceOf(address account) external view returns (uint256)","function decimals() external view returns (uint8)","function symbol() external view returns (string)"],q="0xa0FfB9c1CE1Fe56963B0321B32E7A0302114058b",D={PANCAKEV3:w.PancakeV3,PANCAKEV2:w.PancakeV2,PANCAKE_INFINITY_CL:w.PancakeInfinityCl,UNISWAPV3:w.UniswapV3,UNISWAPV4:w.UniswapV4,DODO:w.Dodo,THENA:w.Thena};class j{constructor(t,e,n){this.config=t,this.provider=e||new p.ethers.JsonRpcProvider(t.rpcUrl),this.routerContract=new p.ethers.Contract(t.routerAddress||p.ethers.ZeroAddress,H,this.provider),this.apiClient=n?.api?new F(n.api):null}getRouterAddress(t){const e=t.routerAddress||this.config.routerAddress;if(!e||e===p.ethers.ZeroAddress)throw new Error("No router address available. Provide routerAddress in config or use API-based getQuote.");return e}applySlippage(t,e){if(e<0||e>1e4)throw new Error("slippageBps must be between 0 and 10000");const n=t.amountOutMin*(P-BigInt(e))/P;return{...t,amountOutMin:n}}async swap(t,e,n){const o=this.getRouterAddress(t),{tx:s,method:r}=this.buildSwapTransactionRequest(t,n);let a;return t.srcNative||(a=await this.buildApprovalRequest(t.srcToken,e,t.amountIn,o,n)),{routerAddress:o,method:r,tx:s,approval:a}}async execute(t,e,n){const o=await e.getAddress(),s=await this.swap(t,o,n);try{return s.approval&&await(await this.sendTransactionWithTimeout(e,s.approval.tx,n)).wait(),await this.sendTransactionWithTimeout(e,s.tx,n)}catch(r){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");if(i&&(c||/reason=null|data=null/.test(a))){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)`);throw d.cause=r,d}throw r}}encodeParams(t){return{srcToken:t.srcToken,dstToken:t.dstToken,amountIn:t.amountIn,amountOutMin:t.amountOutMin,steps:t.steps.map(e=>({adapter:e.adapter,pool:e.pool,tokenIn:e.tokenIn,tokenOut:e.tokenOut,amountIn:e.amountIn,extraData:e.extraData})),intermediateTokens:t.intermediateTokens,deadline:t.deadline,quoteId:t.quoteId,expectAmountOut:t.expectAmountOut}}getProtocolForProvider(t){if(t in D)return D[t];throw new Error(`Unsupported provider: ${t}`)}encodeSwapCalldata(t,e){const n=t.routerAddress??this.config.routerAddress??this.routerContract.target,o=this.applySlippage(t.params,e),s=t.srcNative===!0||t.dstNative===!0,r=this.encodeParams(o);if(s){const a=this.routerContract.interface.encodeFunctionData("swapETH",[r]);return{to:n,data:a,value:t.srcNative?t.amountIn:0n,method:"swapETH"}}else{const a=this.routerContract.interface.encodeFunctionData("swap",[r]);return{to:n,data:a,value:0n,method:"swap"}}}buildSwapTransactionRequest(t,e){const{to:n,data:o,value:s,method:r}=this.encodeSwapCalldata(t,e.slippageBps);return{method:r,tx:this.applyTxOverrides({to:n,data:o,value:s},e,!0)}}async buildApprovalRequest(t,e,n,o,s){const r=await this.getAllowance(t,e,o);if(!(r>=n))return{token:t,owner:e,spender:o,currentAllowance:r,requiredAmount:n,approveAmount:p.ethers.MaxUint256,tx:this.buildApprovalTransactionRequest(t,o,s)}}buildApprovalTransactionRequest(t,e,n){const s=new p.ethers.Interface(k).encodeFunctionData("approve",[e,p.ethers.MaxUint256]);return this.applyTxOverrides({to:t,data:s,value:0n},n,!1)}async getAllowance(t,e,n){return new p.ethers.Contract(t,k,this.provider).allowance(e,n)}applyTxOverrides(t,e,n){const o={...t};return e.gasPrice&&(o.gasPrice=e.gasPrice),n&&e.gasLimit&&(o.gasLimit=e.gasLimit),o}async sendTransactionWithTimeout(t,e,n){const o=n.timeoutMs??x;if(o<=0)return t.sendTransaction(e);const s=t;if(typeof s.sendUncheckedTransaction=="function"&&s.provider){const r=await y(s.sendUncheckedTransaction(e),o),a=await this.waitForTransactionResponse(s.provider,r,o,n.transactionResponsePollingIntervalsMs);if(a.response)return a.response;const i=a.rpcErrors>0?`${a.rpcErrors} transient provider error(s) and ${a.nullResponses} null response(s)`:`${a.nullResponses} null response(s)`;throw new R(`Transaction was broadcast but provider did not return TransactionResponse within ${o}ms (${i}).`,"provider_index",r)}return y(t.sendTransaction(e),o)}async waitForTransactionResponse(t,e,n,o=S){const s=Date.now()+n;let r=0,a=0,i=0;for(;Date.now()<s;){try{const u=await t.getTransaction(e);if(u)return{response:u,nullResponses:a,rpcErrors:i};a++}catch{i++}const c=this.getNextPollingDelay(o,r);r++,await this.delay(Math.min(c,Math.max(25,s-Date.now())))}return{response:null,nullResponses:a,rpcErrors:i}}async delay(t){t<=0||await new Promise(e=>{setTimeout(e,t)})}getNextPollingDelay(t,e){return t.length===0?S.at(-1)??1200:t[Math.min(e,t.length-1)]??1200}async getTokenInfo(t,e){const n=new p.ethers.Contract(t,k,this.provider),[o,s,r]=await Promise.all([n.symbol(),n.decimals(),e?n.balanceOf(e):Promise.resolve(void 0)]);return r===void 0?{symbol:o,decimals:s}:{symbol:o,decimals:s,balance:r}}async getBalance(t,e){return new p.ethers.Contract(t,k,this.provider).balanceOf(e)}async getQuote(t){const{srcToken:e,dstToken:n,amountIn:o,options:s={}}=t,{byAmountIn:r=!0,depth:a=I.depth,splitCount:i=I.splitCount,providers:c=I.providers,deadlineSeconds:u=_}=s;if(!this.apiClient)throw new Error("API client is not configured. getQuote() requires PeachClientOptions.api.");const d=C(e),l=C(n),f=d?this.config.weth:e,A=l?this.config.weth:n,E=await this.apiClient.findRoutes({from:f,target:A,amount:o,byAmountIn:r,depth:a,splitCount:i,providers:c});return this.buildQuoteFromApi(E,f,A,u,c,d,l)}filterPathsByProviders(t,e,n,o){const s=new Set(e.map(l=>l.toUpperCase()));let r=t.filter(l=>s.has(l.provider.toUpperCase()));if(r.length===t.length)return r;const a=n.toLowerCase(),i=o.toLowerCase(),c=new Set;c.add(a);let u=!0;for(;u;){u=!1;for(const l of r)c.has(l.token_in.toLowerCase())&&!c.has(l.token_out.toLowerCase())&&(c.add(l.token_out.toLowerCase()),u=!0)}const d=new Set;for(d.add(i),u=!0;u;){u=!1;for(const l of r)d.has(l.token_out.toLowerCase())&&!d.has(l.token_in.toLowerCase())&&(d.add(l.token_in.toLowerCase()),u=!0)}return r.length,r=r.filter(l=>c.has(l.token_in.toLowerCase())&&d.has(l.token_out.toLowerCase())),r}buildQuoteFromRouteData(t,e,n,o,s){const r=this.buildQuoteFromRouteDataInternal(t,e,n,o??_,void 0);return s?.srcNative&&(r.srcNative=!0),s?.dstNative&&(r.dstNative=!0),r}buildQuoteFromApi(t,e,n,o,s,r,a){const i=this.buildQuoteFromRouteDataInternal(t,e,n,o,s);return r&&(i.srcNative=!0),a&&(i.dstNative=!0),i}buildQuoteFromRouteDataInternal(t,e,n,o,s){const r=e.toLowerCase();t.paths.length;let a=t.paths.filter(h=>!(!(h.token_in.toLowerCase()===r)&&BigInt(h.amount_in)===0n&&BigInt(h.amount_out)===0n));if(a.length===0)throw new v("All route paths have zero amounts",4001);if(s&&s.length>0&&(a=this.filterPathsByProviders(a,s,e,n),a.length===0))throw new v("No valid route paths remaining after provider filtering",4001);const i=n.toLowerCase();let c=0n,u=0n;for(const h of a)h.token_in.toLowerCase()===r&&(c+=BigInt(h.amount_in)),h.token_out.toLowerCase()===i&&(u+=BigInt(h.amount_out));const d=BigInt(Math.floor(Date.now()/1e3)+o),l=new Map;for(const h of a){const g=h.token_in.toLowerCase();l.set(g,(l.get(g)??0)+1)}const f=new Map,A=a.map(h=>{const g=h.token_in.toLowerCase(),b=(f.get(g)??0)+1;f.set(g,b);const N=l.get(g),V=N>1&&b<N,M=g===r;return{adapter:h.adapter,pool:h.provider.toUpperCase()==="PANCAKE_INFINITY_CL"?q:h.provider.toUpperCase()==="UNISWAPV4"?p.ethers.ZeroAddress:h.pool,tokenIn:h.token_in,tokenOut:h.token_out,amountIn:M||V?BigInt(h.amount_in):0n,extraData:h.extra_data||"0x"}}),E=new Set;for(const h of a)h.token_out.toLowerCase()!==i&&E.add(h.token_out);const T=Array.from(E),O={srcToken:e,dstToken:n,amountIn:c,amountOutMin:u,steps:A,intermediateTokens:T,deadline:d,quoteId:t.request_id?p.ethers.id(t.request_id).slice(0,66):p.ethers.ZeroHash,expectAmountOut:u},U={routes:[{steps:a.map(h=>({pool:{address:h.pool,token0:h.token_in,token1:h.token_out,protocol:this.getProtocolForProvider(h.provider),fee:h.fee_rate?Math.round(parseFloat(h.fee_rate)*1e6):void 0},tokenIn:h.token_in,tokenOut:h.token_out,amountIn:BigInt(h.amount_in),amountOut:BigInt(h.amount_out)})),amountIn:c,amountOut:u,gasEstimate:BigInt(t.gas)}],percentages:[1e4],totalAmountIn:c,totalAmountOut:u,totalGasEstimate:BigInt(t.gas)};if(!t.contracts?.router)throw new v("API response missing contracts.router address",4002);return{srcToken:e,dstToken:n,amountIn:c,amountOut:u,priceImpact:parseFloat(t.deviation_ratio||"0"),route:U,params:O,gasEstimate:BigInt(t.gas),routerAddress:t.contracts?.router}}async getAvailableProviders(){if(!this.apiClient)throw new Error("API client is not configured. getAvailableProviders() requires PeachClientOptions.api.");return this.apiClient.getAvailableProviders()}async simulate(t,e,n,o){const s=n||p.ethers.ZeroAddress,{to:r,data:a,value:i,method:c}=this.encodeSwapCalldata(t,e);if(console.log("[PeachClient] simulate using router:",r),o){const u=this.getJsonRpcProviderForStateOverrides(),d=i>0n?"0x"+i.toString(16):void 0,l=await u.send("eth_call",[{from:s,to:r,data:a,value:d},"latest",o]),[f]=this.routerContract.interface.decodeFunctionResult(c,l);return{amountOut:f,method:c}}else{const u=await this.provider.call({from:s,to:r,data:a,value:i>0n?i:void 0}),[d]=this.routerContract.interface.decodeFunctionResult(c,u);return{amountOut:d,method:c}}}getJsonRpcProviderForStateOverrides(){if(typeof this.provider.send!="function")throw new Error("stateOverrides require a JsonRpcProvider-compatible provider with send(method, params).");return this.provider}formatSimulateError(t,e,n,o){const s=t instanceof Error?t:new Error(String(t)),r=t;let a="unknown";if(r.reason&&typeof r.reason=="string")a=r.reason;else if(r.revert&&typeof r.revert=="object"){const d=r.revert;d.args&&Array.isArray(d.args)&&(a=d.args.join(", "))}else s.message&&(a=s.message);const i=e.params.steps.map((d,l)=>` Step ${l}: ${d.tokenIn.slice(0,10)}→${d.tokenOut.slice(0,10)} via adapter ${d.adapter.slice(0,10)} pool ${d.pool.slice(0,10)}`).join(`
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("ethers"),L="https://api.peach.ag",B=50,P=10000n,C=1200,x=6e4,S=[50,100,200,400,800,1200],F="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";function _(w){return w.toLowerCase()===F.toLowerCase()}const K=4001;var m=(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))(m||{});const W={chainId:56,rpcUrl:"https://bsc-dataseed.binance.org",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",adapters:[]},G={chainId:97,rpcUrl:"https://bsc-testnet-rpc.publicnode.com",weth:"0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd",adapters:[]};class R extends Error{constructor(t,e,n){super(t),this.name="ExecuteTimeoutError",this.stage=e,this.txHash=n}}const I={depth:3,splitCount:20,providers:["PANCAKEV2","PANCAKEV3","PANCAKE_INFINITY_CL","UNISWAPV3","UNISWAPV4","DODO","THENA"],clientVersion:1001500},H=1e4;class U{constructor(t={}){this.baseUrl=t.baseUrl||L,this.timeout=t.timeout||H}async findRoutes(t){const{from:e,target:n,amount:o,byAmountIn:s=!0,depth:r=I.depth,splitCount:a=I.splitCount,providers:i=I.providers}=t,c=new URLSearchParams({from:e,target:n,amount:o.toString(),by_amount_in:s.toString(),depth:r.toString(),split_count:a.toString(),providers:i.join(","),v:I.clientVersion.toString()}),u=`${this.baseUrl}/router/find_routes?${c}`,d=new AbortController,l=setTimeout(()=>d.abort(),this.timeout);try{const f=await fetch(u,{method:"GET",headers:{Accept:"application/json"},signal:d.signal});if(clearTimeout(l),!f.ok)throw new A(`API request failed: ${f.status} ${f.statusText}`,f.status);const v=await f.json();if(v.code!==200)throw new A(v.msg||"Route not found",v.code);if(!v.data||!v.data.paths||v.data.paths.length===0)throw new A("No routes found",404);return v.data}catch(f){throw clearTimeout(l),f instanceof A?f:f instanceof Error?f.name==="AbortError"?new A("API request timeout",408):new A(`API request failed: ${f.message}`,0):new A("Unknown API error",0)}}async getStatus(){const t=`${this.baseUrl}/router/status`,e=new AbortController,n=setTimeout(()=>e.abort(),this.timeout);try{const o=await fetch(t,{method:"GET",headers:{Accept:"application/json"},signal:e.signal});if(clearTimeout(n),!o.ok)throw new A(`API request failed: ${o.status} ${o.statusText}`,o.status);const s=await o.json();if(s.code!==200)throw new A(s.msg||"Failed to get status",s.code);return s.data}catch(o){throw clearTimeout(n),o instanceof A?o:o instanceof Error?o.name==="AbortError"?new A("API request timeout",408):new A(`API request failed: ${o.message}`,0):new A("Unknown API error",0)}}async getAvailableProviders(){return(await this.getStatus()).providers}setBaseUrl(t){this.baseUrl=t}getBaseUrl(){return this.baseUrl}}class A extends Error{constructor(t,e){super(t),this.name="ApiError",this.code=e}}async function y(w,t=x){if(t<=0)return w;let e;try{return await Promise.race([w,new Promise((n,o)=>{e=setTimeout(()=>{o(new R(`Wallet did not settle sendTransaction within ${t}ms.`,"wallet_send"))},t)})])}finally{e&&clearTimeout(e)}}const j=["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) params) external returns (uint256 amountOut)","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) params) external payable returns (uint256 amountOut)","function isAdapterRegistered(address adapter) external view returns (bool)","function WETH() external view returns (address)"],k=["function approve(address spender, uint256 amount) external returns (bool)","function allowance(address owner, address spender) external view returns (uint256)","function balanceOf(address account) external view returns (uint256)","function decimals() external view returns (uint8)","function symbol() external view returns (string)"],q="0xa0FfB9c1CE1Fe56963B0321B32E7A0302114058b",D={PANCAKEV3:m.PancakeV3,PANCAKEV2:m.PancakeV2,PANCAKE_INFINITY_CL:m.PancakeInfinityCl,UNISWAPV3:m.UniswapV3,UNISWAPV4:m.UniswapV4,DODO:m.Dodo,THENA:m.Thena};class Z{constructor(t,e,n){this.config=t,this.provider=e||new p.ethers.JsonRpcProvider(t.rpcUrl),this.routerContract=new p.ethers.Contract(t.routerAddress||p.ethers.ZeroAddress,j,this.provider),this.apiClient=new U(n?.api)}getRouterAddress(t){const e=t.routerAddress||this.config.routerAddress;if(!e||e===p.ethers.ZeroAddress)throw new Error("No router address available. Provide routerAddress in config or use API-based getQuote.");return e}applySlippage(t,e){if(e<0||e>1e4)throw new Error("slippageBps must be between 0 and 10000");const n=t.amountOutMin*(P-BigInt(e))/P;return{...t,amountOutMin:n}}async swap(t,e,n){const o=this.getRouterAddress(t),{tx:s,method:r}=this.buildSwapTransactionRequest(t,n);let a;return t.srcNative||(a=await this.buildApprovalRequest(t.srcToken,e,t.amountIn,o,n)),{routerAddress:o,method:r,tx:s,approval:a}}async execute(t,e,n){const o=await e.getAddress(),s=await this.swap(t,o,n);try{return s.approval&&await(await this.sendTransactionWithTimeout(e,s.approval.tx,n)).wait(),await this.sendTransactionWithTimeout(e,s.tx,n)}catch(r){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");if(i&&(c||/reason=null|data=null/.test(a))){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)`);throw d.cause=r,d}throw r}}encodeParams(t){return{srcToken:t.srcToken,dstToken:t.dstToken,amountIn:t.amountIn,amountOutMin:t.amountOutMin,steps:t.steps.map(e=>({adapter:e.adapter,pool:e.pool,tokenIn:e.tokenIn,tokenOut:e.tokenOut,amountIn:e.amountIn,extraData:e.extraData})),intermediateTokens:t.intermediateTokens,deadline:t.deadline,quoteId:t.quoteId,expectAmountOut:t.expectAmountOut}}getProtocolForProvider(t){if(t in D)return D[t];throw new Error(`Unsupported provider: ${t}`)}encodeSwapCalldata(t,e){const n=t.routerAddress??this.config.routerAddress??this.routerContract.target,o=this.applySlippage(t.params,e),s=t.srcNative===!0||t.dstNative===!0,r=this.encodeParams(o);if(s){const a=this.routerContract.interface.encodeFunctionData("swapETH",[r]);return{to:n,data:a,value:t.srcNative?t.amountIn:0n,method:"swapETH"}}else{const a=this.routerContract.interface.encodeFunctionData("swap",[r]);return{to:n,data:a,value:0n,method:"swap"}}}buildSwapTransactionRequest(t,e){const{to:n,data:o,value:s,method:r}=this.encodeSwapCalldata(t,e.slippageBps);return{method:r,tx:this.applyTxOverrides({to:n,data:o,value:s},e,!0)}}async buildApprovalRequest(t,e,n,o,s){const r=await this.getAllowance(t,e,o);if(!(r>=n))return{token:t,owner:e,spender:o,currentAllowance:r,requiredAmount:n,approveAmount:p.ethers.MaxUint256,tx:this.buildApprovalTransactionRequest(t,o,s)}}buildApprovalTransactionRequest(t,e,n){const s=new p.ethers.Interface(k).encodeFunctionData("approve",[e,p.ethers.MaxUint256]);return this.applyTxOverrides({to:t,data:s,value:0n},n,!1)}async getAllowance(t,e,n){return new p.ethers.Contract(t,k,this.provider).allowance(e,n)}applyTxOverrides(t,e,n){const o={...t};return e.gasPrice&&(o.gasPrice=e.gasPrice),n&&e.gasLimit&&(o.gasLimit=e.gasLimit),o}async sendTransactionWithTimeout(t,e,n){const o=n.timeoutMs??x;if(o<=0)return t.sendTransaction(e);const s=t;if(typeof s.sendUncheckedTransaction=="function"&&s.provider){const r=await y(s.sendUncheckedTransaction(e),o),a=await this.waitForTransactionResponse(s.provider,r,o,n.transactionResponsePollingIntervalsMs);if(a.response)return a.response;const i=a.rpcErrors>0?`${a.rpcErrors} transient provider error(s) and ${a.nullResponses} null response(s)`:`${a.nullResponses} null response(s)`;throw new R(`Transaction was broadcast but provider did not return TransactionResponse within ${o}ms (${i}).`,"provider_index",r)}return y(t.sendTransaction(e),o)}async waitForTransactionResponse(t,e,n,o=S){const s=Date.now()+n;let r=0,a=0,i=0;for(;Date.now()<s;){try{const u=await t.getTransaction(e);if(u)return{response:u,nullResponses:a,rpcErrors:i};a++}catch{i++}const c=this.getNextPollingDelay(o,r);r++,await this.delay(Math.min(c,Math.max(25,s-Date.now())))}return{response:null,nullResponses:a,rpcErrors:i}}async delay(t){t<=0||await new Promise(e=>{setTimeout(e,t)})}getNextPollingDelay(t,e){return t.length===0?S.at(-1)??1200:t[Math.min(e,t.length-1)]??1200}async getTokenInfo(t,e){const n=new p.ethers.Contract(t,k,this.provider),[o,s,r]=await Promise.all([n.symbol(),n.decimals(),e?n.balanceOf(e):Promise.resolve(void 0)]);return r===void 0?{symbol:o,decimals:s}:{symbol:o,decimals:s,balance:r}}async getBalance(t,e){return new p.ethers.Contract(t,k,this.provider).balanceOf(e)}async getQuote(t){const{srcToken:e,dstToken:n,amountIn:o,options:s={}}=t,{byAmountIn:r=!0,depth:a=I.depth,splitCount:i=I.splitCount,providers:c=I.providers,deadlineSeconds:u=C}=s,d=_(e),l=_(n),f=d?this.config.weth:e,v=l?this.config.weth:n,E=await this.apiClient.findRoutes({from:f,target:v,amount:o,byAmountIn:r,depth:a,splitCount:i,providers:c});return this.buildQuoteFromApi(E,f,v,u,c,d,l)}filterPathsByProviders(t,e,n,o){const s=new Set(e.map(l=>l.toUpperCase()));let r=t.filter(l=>s.has(l.provider.toUpperCase()));if(r.length===t.length)return r;const a=n.toLowerCase(),i=o.toLowerCase(),c=new Set;c.add(a);let u=!0;for(;u;){u=!1;for(const l of r)c.has(l.token_in.toLowerCase())&&!c.has(l.token_out.toLowerCase())&&(c.add(l.token_out.toLowerCase()),u=!0)}const d=new Set;for(d.add(i),u=!0;u;){u=!1;for(const l of r)d.has(l.token_out.toLowerCase())&&!d.has(l.token_in.toLowerCase())&&(d.add(l.token_in.toLowerCase()),u=!0)}return r.length,r=r.filter(l=>c.has(l.token_in.toLowerCase())&&d.has(l.token_out.toLowerCase())),r}buildQuoteFromRouteData(t,e,n,o,s){const r=this.buildQuoteFromRouteDataInternal(t,e,n,o??C,void 0);return s?.srcNative&&(r.srcNative=!0),s?.dstNative&&(r.dstNative=!0),r}buildQuoteFromApi(t,e,n,o,s,r,a){const i=this.buildQuoteFromRouteDataInternal(t,e,n,o,s);return r&&(i.srcNative=!0),a&&(i.dstNative=!0),i}buildQuoteFromRouteDataInternal(t,e,n,o,s){const r=e.toLowerCase();t.paths.length;let a=t.paths.filter(h=>!(!(h.token_in.toLowerCase()===r)&&BigInt(h.amount_in)===0n&&BigInt(h.amount_out)===0n));if(a.length===0)throw new A("All route paths have zero amounts",4001);if(s&&s.length>0&&(a=this.filterPathsByProviders(a,s,e,n),a.length===0))throw new A("No valid route paths remaining after provider filtering",4001);const i=n.toLowerCase();let c=0n,u=0n;for(const h of a)h.token_in.toLowerCase()===r&&(c+=BigInt(h.amount_in)),h.token_out.toLowerCase()===i&&(u+=BigInt(h.amount_out));const d=BigInt(Math.floor(Date.now()/1e3)+o),l=new Map;for(const h of a){const g=h.token_in.toLowerCase();l.set(g,(l.get(g)??0)+1)}const f=new Map,v=a.map(h=>{const g=h.token_in.toLowerCase(),b=(f.get(g)??0)+1;f.set(g,b);const N=l.get(g),M=N>1&&b<N,$=g===r;return{adapter:h.adapter,pool:h.provider.toUpperCase()==="PANCAKE_INFINITY_CL"?q:h.provider.toUpperCase()==="UNISWAPV4"?p.ethers.ZeroAddress:h.pool,tokenIn:h.token_in,tokenOut:h.token_out,amountIn:$||M?BigInt(h.amount_in):0n,extraData:h.extra_data||"0x"}}),E=new Set;for(const h of a)h.token_out.toLowerCase()!==i&&E.add(h.token_out);const T=Array.from(E),O={srcToken:e,dstToken:n,amountIn:c,amountOutMin:u,steps:v,intermediateTokens:T,deadline:d,quoteId:t.request_id?p.ethers.id(t.request_id).slice(0,66):p.ethers.ZeroHash,expectAmountOut:u},V={routes:[{steps:a.map(h=>({pool:{address:h.pool,token0:h.token_in,token1:h.token_out,protocol:this.getProtocolForProvider(h.provider),fee:h.fee_rate?Math.round(parseFloat(h.fee_rate)*1e6):void 0},tokenIn:h.token_in,tokenOut:h.token_out,amountIn:BigInt(h.amount_in),amountOut:BigInt(h.amount_out)})),amountIn:c,amountOut:u,gasEstimate:BigInt(t.gas)}],percentages:[1e4],totalAmountIn:c,totalAmountOut:u,totalGasEstimate:BigInt(t.gas)};if(!t.contracts?.router)throw new A("API response missing contracts.router address",4002);return{srcToken:e,dstToken:n,amountIn:c,amountOut:u,priceImpact:parseFloat(t.deviation_ratio||"0"),route:V,params:O,gasEstimate:BigInt(t.gas),routerAddress:t.contracts?.router}}async getAvailableProviders(){return this.apiClient.getAvailableProviders()}async simulate(t,e,n,o){const s=n||p.ethers.ZeroAddress,{to:r,data:a,value:i,method:c}=this.encodeSwapCalldata(t,e);if(console.log("[PeachClient] simulate using router:",r),o){const u=this.getJsonRpcProviderForStateOverrides(),d=i>0n?"0x"+i.toString(16):void 0,l=await u.send("eth_call",[{from:s,to:r,data:a,value:d},"latest",o]),[f]=this.routerContract.interface.decodeFunctionResult(c,l);return{amountOut:f,method:c}}else{const u=await this.provider.call({from:s,to:r,data:a,value:i>0n?i:void 0}),[d]=this.routerContract.interface.decodeFunctionResult(c,u);return{amountOut:d,method:c}}}getJsonRpcProviderForStateOverrides(){if(typeof this.provider.send!="function")throw new Error("stateOverrides require a JsonRpcProvider-compatible provider with send(method, params).");return this.provider}formatSimulateError(t,e,n,o){const s=t instanceof Error?t:new Error(String(t)),r=t;let a="unknown";if(r.reason&&typeof r.reason=="string")a=r.reason;else if(r.revert&&typeof r.revert=="object"){const d=r.revert;d.args&&Array.isArray(d.args)&&(a=d.args.join(", "))}else s.message&&(a=s.message);const i=e.params.steps.map((d,l)=>` Step ${l}: ${d.tokenIn.slice(0,10)}→${d.tokenOut.slice(0,10)} via adapter ${d.adapter.slice(0,10)} pool ${d.pool.slice(0,10)}`).join(`
|
|
2
2
|
`),c=[`Simulate ${n} failed: ${a}`,` Route: ${e.srcToken} → ${e.dstToken}`,` AmountIn: ${e.amountIn}`,` AmountOutMin: ${e.params.amountOutMin}`,` Router: ${e.routerAddress}`,` Caller: ${o}`,` Steps (${e.params.steps.length}):`,i].join(`
|
|
3
|
-
`),u=new Error(c);return u.cause=s,u.reason=a,u}async findFailingStep(t,e,n,o,s){const r=t.params.steps;if(!r.length)return null;const a=s!=null?this.normalizeRevertReason(s):void 0;for(let i=1;i<=r.length;i++){const c=this.quoteWithFirstNSteps(t,i);try{await this.simulate(c,e,n,o)}catch(u){const d=this.normalizeRevertReason(u),l=u?.message??u?.reason??u?.shortMessage;if(a!=null?d===a:!0)return{stepIndex:i-1,step:r[i-1],error:u,revertMessage:typeof l=="string"?l:void 0,fullRouteRevertMessage:a??void 0}}}return null}normalizeRevertReason(t){if(t==null)return;const e=t;if(typeof e.reason=="string"&&e.reason.length>0)return e.reason;const n=e.shortMessage??e.message;if(typeof n!="string")return;const o=n.match(/reason="([^"]+)"/);if(o)return o[1];const s=n.match(/reverted:\s*"([^"]+)"/);if(s)return s[1];const r=n.match(/execution reverted:\s*"([^"]+)"/);if(r)return r[1]}quoteWithFirstNSteps(t,e){const n=t.params.steps.slice(0,e),o=t.dstToken.toLowerCase(),s=new Set,r=[];for(const a of n){const i=a.tokenOut.toLowerCase();i!==o&&!s.has(i)&&(s.add(i),r.push(a.tokenOut))}return{...t,params:{...t.params,steps:n,intermediateTokens:r}}}buildStateOverrides(t,e,n,o,s,r){if(r?.isNative||
|
|
3
|
+
`),u=new Error(c);return u.cause=s,u.reason=a,u}async findFailingStep(t,e,n,o,s){const r=t.params.steps;if(!r.length)return null;const a=s!=null?this.normalizeRevertReason(s):void 0;for(let i=1;i<=r.length;i++){const c=this.quoteWithFirstNSteps(t,i);try{await this.simulate(c,e,n,o)}catch(u){const d=this.normalizeRevertReason(u),l=u?.message??u?.reason??u?.shortMessage;if(a!=null?d===a:!0)return{stepIndex:i-1,step:r[i-1],error:u,revertMessage:typeof l=="string"?l:void 0,fullRouteRevertMessage:a??void 0}}}return null}normalizeRevertReason(t){if(t==null)return;const e=t;if(typeof e.reason=="string"&&e.reason.length>0)return e.reason;const n=e.shortMessage??e.message;if(typeof n!="string")return;const o=n.match(/reason="([^"]+)"/);if(o)return o[1];const s=n.match(/reverted:\s*"([^"]+)"/);if(s)return s[1];const r=n.match(/execution reverted:\s*"([^"]+)"/);if(r)return r[1]}quoteWithFirstNSteps(t,e){const n=t.params.steps.slice(0,e),o=t.dstToken.toLowerCase(),s=new Set,r=[];for(const a of n){const i=a.tokenOut.toLowerCase();i!==o&&!s.has(i)&&(s.add(i),r.push(a.tokenOut))}return{...t,params:{...t.params,steps:n,intermediateTokens:r}}}buildStateOverrides(t,e,n,o,s,r){if(r?.isNative||_(t))return{};if(!n||n===p.ethers.ZeroAddress)throw new Error("buildStateOverrides requires a non-zero routerAddress.");const a=p.ethers.AbiCoder.defaultAbiCoder(),i=o||p.ethers.parseUnits("1000000",18),c=s??n,u=p.ethers.zeroPadValue(p.ethers.toBeHex(i),32),d=p.ethers.zeroPadValue(p.ethers.toBeHex(p.ethers.MaxUint256),32),l={},f=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,50,51,52,100,101,102];for(const v of f){const E=p.ethers.keccak256(a.encode(["address","uint256"],[e,v]));l[E]=u;const T=p.ethers.keccak256(a.encode(["address","uint256"],[e,v])),O=p.ethers.keccak256(a.encode(["address","bytes32"],[c,T]));l[O]=d}return{[t.toLowerCase()]:{stateDiff:l}}}}const Q=["function token0() external view returns (address)","function token1() external view returns (address)","function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast)"],Y=["function token0() external view returns (address)","function token1() external view returns (address)","function fee() external view returns (uint24)","function liquidity() external view returns (uint128)","function slot0() external view returns (uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint32 feeProtocol, bool unlocked)"],z="0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73",J=["function getPair(address tokenA, address tokenB) external view returns (address pair)"],X="0x0BFbCF9fa4f9C56B0F40a671Ad40E0805A091865",tt=["function getPool(address tokenA, address tokenB, uint24 fee) external view returns (address pool)"],et=[100,500,2500,1e4],nt=60000n,ot=120000n,rt=100000n;class st{constructor(t,e){this.poolCache=new Map,this.provider=t,this.config=e,this.v2Factory=new p.ethers.Contract(z,J,t),this.v3Factory=new p.ethers.Contract(X,tt,t)}async findBestRoute(t,e,n){const o=await this.discoverPools(t,e);if(o.length===0)throw new Error(`No pools found for ${t} -> ${e}`);const r=(await this.calculateRoutes(o,t,e,n)).reduce((a,i)=>i.amountOut>a.amountOut?i:a);return{routes:[r],percentages:[1e4],totalAmountIn:n,totalAmountOut:r.amountOut,totalGasEstimate:r.gasEstimate}}async discoverPools(t,e){const n=[];try{const o=await this.findV2Pool(t,e);o&&n.push(o)}catch{}for(const o of et)try{const s=await this.findV3Pool(t,e,o);s&&n.push(s)}catch{}return n}async findV2Pool(t,e){const n=`v2-${t}-${e}`;if(this.poolCache.has(n))return this.poolCache.get(n);const o=await this.v2Factory.getPair(t,e);if(o===p.ethers.ZeroAddress)return null;const s=new p.ethers.Contract(o,Q,this.provider),[r,a,i]=await Promise.all([s.token0(),s.token1(),s.getReserves()]),c={address:o,token0:r,token1:a,protocol:m.PancakeV2,reserve0:i.reserve0,reserve1:i.reserve1};return this.poolCache.set(n,c),c}async findV3Pool(t,e,n){const o=`v3-${t}-${e}-${n}`;if(this.poolCache.has(o))return this.poolCache.get(o);const s=await this.v3Factory.getPool(t,e,n);if(s===p.ethers.ZeroAddress)return null;const r=new p.ethers.Contract(s,Y,this.provider),[a,i,c]=await Promise.all([r.token0(),r.token1(),r.liquidity()]);if(c===0n)return null;const u={address:s,token0:a,token1:i,protocol:m.PancakeV3,fee:n,liquidity:c};return this.poolCache.set(o,u),u}async calculateRoutes(t,e,n,o){const s=[];for(const r of t)try{const a=await this.getAmountOut(r,e,n,o);a>0n&&s.push({steps:[{pool:r,tokenIn:e,tokenOut:n,amountIn:o,amountOut:a}],amountIn:o,amountOut:a,gasEstimate:r.protocol===m.PancakeV2?nt:r.protocol===m.Dodo?rt:ot})}catch{}return s}async getAmountOut(t,e,n,o){if(t.protocol===m.PancakeV2)return this.getV2AmountOut(t,e,o);if(t.protocol===m.Dodo)throw new Error("DODO amount out not supported in local route discovery");return this.estimateV3AmountOut(t,e,o)}getV2AmountOut(t,e,n){const o=e.toLowerCase()===t.token0.toLowerCase(),[s,r]=o?[t.reserve0,t.reserve1]:[t.reserve1,t.reserve0],a=n*9975n,i=a*r,c=s*10000n+a;return i/c}estimateV3AmountOut(t,e,n){const s=1000000n-BigInt(t.fee||2500);return n*s/1000000n}clearCache(){this.poolCache.clear()}}class at{constructor(t){this.adapters=t}build(t,e,n,o,s=C){const r=this.flattenRoutes(t),a=this.mergeIdenticalPools(r),i=this.topologicalSort(a,e),c=this.convertToSwapSteps(i),u=this.extractIntermediates(i,e,n),d=BigInt(Math.floor(Date.now()/1e3)+s);return{srcToken:e,dstToken:n,amountIn:t.totalAmountIn,amountOutMin:o,steps:c,intermediateTokens:u,deadline:d,quoteId:p.ethers.ZeroHash,expectAmountOut:t.totalAmountOut}}flattenRoutes(t){const e=[];for(let n=0;n<t.routes.length;n++){const o=t.routes[n],s=t.percentages[n],r=t.totalAmountIn*BigInt(s)/P;for(let a=0;a<o.steps.length;a++){const i=o.steps[a];e.push({pool:i.pool,tokenIn:i.tokenIn,tokenOut:i.tokenOut,amountIn:a===0?r:0n,routeIndex:n,stepIndex:a})}}return e}mergeIdenticalPools(t){const e=new Map,n=[];for(const o of t){const s=`${o.pool.address}-${o.tokenIn}-${o.tokenOut}`;if(e.has(s)){const r=e.get(s);o.amountIn>0n&&r.amountIn>0n&&(r.amountIn=0n)}else{const r={...o};e.set(s,r),n.push(r)}}for(const o of n){const s=`${o.pool.address}-${o.tokenIn}-${o.tokenOut}`;t.filter(a=>`${a.pool.address}-${a.tokenIn}-${a.tokenOut}`===s).length>1&&(o.amountIn=0n)}return n}topologicalSort(t,e){const n=new Map,o=new Map,s=new Map;for(const i of t){const c=this.stepKey(i);o.set(c,i),n.set(c,0),s.set(c,[])}for(const i of t){const c=this.stepKey(i);if(i.tokenIn!==e){for(const u of t)if(u.tokenOut===i.tokenIn){const d=this.stepKey(u);d!==c&&(s.get(d).push(c),n.set(c,(n.get(c)||0)+1))}}}const r=[];for(const[i,c]of n)c===0&&r.push(i);const a=[];for(;r.length>0;){const i=r.shift(),c=o.get(i);a.push(c);for(const u of s.get(i)||[]){const d=(n.get(u)||0)-1;n.set(u,d),d===0&&r.push(u)}}if(a.length!==t.length)throw new Error("Circular dependency detected in route");return a}convertToSwapSteps(t){return t.map(e=>{const n=this.adapters.get(e.pool.protocol);if(!n)throw new Error(`No adapter for protocol: ${e.pool.protocol}`);return{adapter:n,pool:e.pool.address,tokenIn:e.tokenIn,tokenOut:e.tokenOut,amountIn:e.amountIn,extraData:this.encodeExtraData(e.pool)}})}encodeExtraData(t){switch(t.protocol){case m.PancakeV2:return"0x";case m.PancakeV3:case m.UniswapV3:case m.UniswapV4:return"0x";case m.Dodo:return"0x";default:return"0x"}}extractIntermediates(t,e,n){const o=new Set;for(const s of t)s.tokenOut!==n&&o.add(s.tokenOut);return o.delete(e),o.delete(n),Array.from(o)}stepKey(t){return`${t.pool.address}-${t.tokenIn}-${t.tokenOut}`}}exports.API_DEFAULTS=I;exports.ApiClient=U;exports.ApiError=A;exports.BPS_DENOMINATOR=P;exports.BSC_MAINNET_CONFIG=W;exports.BSC_TESTNET_CONFIG=G;exports.DEFAULT_API_URL=L;exports.DEFAULT_DEADLINE_SECONDS=C;exports.DEFAULT_EXECUTE_TIMEOUT_MS=x;exports.DEFAULT_SLIPPAGE_BPS=B;exports.DEFAULT_TRANSACTION_RESPONSE_POLL_INTERVALS_MS=S;exports.ERR_ZERO_AMOUNT_PATHS=K;exports.ExecuteTimeoutError=R;exports.NATIVE_TOKEN_ADDRESS=F;exports.PeachClient=Z;exports.ProtocolType=m;exports.RouteDiscovery=st;exports.SwapBuilder=at;exports.isNativeTokenAddress=_;exports.withWalletSendTimeout=y;
|
|
4
4
|
//# sourceMappingURL=index.cjs.map
|