@oracle-agent/oracle 0.28.23 → 0.28.24
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/assets/skills/oracle-desk-product/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +18 -18
- package/dist/bin/oracle-data-mcp.mjs +8 -8
- package/dist/bin/oracle-route.mjs +12 -12
- package/dist/bin/oracle-scan.mjs +2 -2
- package/dist/cli/commands/chat.mjs +80 -80
- package/dist/cli/commands/eval.mjs +30 -30
- package/dist/cli/commands/harness.mjs +4 -4
- package/dist/cli/commands/model.mjs +65 -65
- package/dist/cli/commands/swap.mjs +7 -7
- package/dist/data/desk-data.mjs +16 -16
- package/dist/index.mjs +21 -21
- package/dist/router/index.mjs +2 -2
- package/dist/router/prepare-bridge.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var bt=Object.defineProperty;var
|
|
2
|
-
`),f=St("sha256").update(s).digest("hex").slice(0,32),l=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`;return`${e} ${t} ${l} ${f}`}function Bt(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,$e):Math.min(250*2**e,$e)+Math.floor(Math.random()*100)}function z(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function pe(e,t,r){return z(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function G(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function Pt(e){return e?e.byteLength??e.length??0:0}async function Ue(e,t,{url:r,truncate:n=!1,onOversize:a}={}){if(t==null)return await e.text();let o=Number(e.headers?.get?.("content-length"));if(Number.isFinite(o)&&o>t&&(G(e),!n))throw pe(r,`content-length ${o}`,t);let i=e.body?.getReader?.();if(!i){let c=await e.text(),u=Buffer.byteLength(c,"utf8");if(u>t){if(!n)throw pe(r,`body ${u} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let s=[],f=0,l=!1;try{for(;;){let{value:c,done:u}=await i.read();if(u)break;if(c&&(s.push(Buffer.from(c)),f+=Pt(c),f>t)){l=!0;break}}}finally{if(l)try{await i.cancel()}catch{}try{i.releaseLock?.()}catch{}}if(l&&(typeof a=="function"&&a(),!n))throw pe(r,`streamed ${f} bytes`,t);let d=Buffer.concat(s);return(l?d.subarray(0,t):d).toString("utf8")}function Fe(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Ut(e,{fetchImpl:t,method:r,headers:n,body:a,timeoutMs:o,lookupFn:i,realFetch:s,untrustedUrl:f=!1,maxResponseBytes:l=null,importUndici:d,validateResponse:c}){let u=new AbortController,p=setTimeout(()=>u.abort(),o),m=null,E=t,h=i?{lookupFn:i}:{};if(f&&!s&&!le(E))throw z(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let A=async(w,{status:I=null}={})=>{let x=await se(w,h);if(!x.ok)throw z(I==null?`HTTP refused ${w}: ${x.error}`:`HTTP redirect to ${w} ${x.error}`,I==null?{}:{status:I});let b=new URL(w).hostname;if(s){if(m&&(await m.close(),m=null),!m)try{m=await ce({requireUndici:!0,...d?{importUndici:d}:{}})}catch(S){throw z(I==null?`HTTP refused ${w}: ${S?.message||S}`:`HTTP redirect to ${w} refused: ${S?.message||S}`,I==null?{}:{status:I})}m.pin(b,x.addresses),E=m.fetch}else Te(E,b,x.addresses);return x};try{let w=String(e),I={...n||{}};f&&await A(w);for(let x=0;x<=Pe;x+=1){let b=await E(w,{method:r,headers:I,body:a,signal:u.signal,redirect:"manual"});if(vt.has(b.status)){if(r!=="GET"&&r!=="HEAD"){let v=await Ue(b,l??kt,{url:w,truncate:!0}),k=new Error(`HTTP ${b.status} ${r} ${w} redirected non-idempotent request`);throw k.status=b.status,k.body=Fe(v)??v.slice(0,300),k}if(x===Pe)throw G(b),new Error(`HTTP redirect loop for ${e}`);let g=b.headers?.get?.("location"),y;try{y=Nt(g,w)}catch(v){throw G(b),v}let _=!Tt(y,w);if(G(b),_&&(I=_t(I)),f)await A(y,{status:b.status});else if(_){let v=await se(y,h);if(!v.ok){let k=new Error(`HTTP redirect from ${w} ${v.error}`);throw k.status=b.status,k.retryable=!1,k}s&&v.addresses?.length&&(m||(m=await ce(d?{importUndici:d}:{})),m&&(m.pin(new URL(y).hostname,v.addresses),E=m.fetch))}w=y;continue}if(typeof c=="function")try{await c(b,{url:w})}catch(g){throw G(b),z(g?.message||String(g))}let S=await Ue(b,l,{url:w,onOversize:()=>u.abort()}),$=Fe(S);if(!b.ok){let g=new Error(`HTTP ${b.status} ${r} ${w}`);throw g.status=b.status,g.retryAfter=b.headers?.get?.("retry-after")??null,g.body=$??S.slice(0,300),g}return $??S}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(p),m&&await m.close()}}async function C(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,a=(t.method||"GET").toUpperCase(),o={Accept:"application/json",...t.headers||{}},i=t.body;i!=null&&typeof i!="string"&&(o["Content-Type"]=o["Content-Type"]||"application/json",i=JSON.stringify(i));let s=Number.isInteger(t.retries)?Math.max(t.retries,0):Ct,f=t.lookupFn,l=!t.fetchImpl,d=t.untrustedUrl===!0,c=t.importUndici,u=t.validateResponse,p=Number(t.maxResponseBytes),m=Number.isFinite(p)&&p>0?Math.floor(p):null,E=async()=>{let x;for(let b=0;b<=s;b++)try{return await Ut(e,{fetchImpl:r,method:a,headers:o,body:i,timeoutMs:n,lookupFn:f,realFetch:l,untrustedUrl:d,maxResponseBytes:m,importUndici:c,validateResponse:u})}catch(S){x=S;let $=S?.status,g=S?.name==="AbortError",y=new Set([408,425,429]),_=S?.retryable===!1?!1:$!=null?y.has($)||It.has($)&&Be.has(a):!g&&Be.has(a);if(b===s||!_)throw S;await $t(Bt(b,S?.retryAfter))}throw x};if(!(t.dedupe!==!1&&a==="GET"&&i==null))return E();let A=Rt(a,e,o,{untrustedUrl:d,maxResponseBytes:m}),w=de.get(A);if(w)return w;let I=E().finally(()=>de.delete(A));return de.set(A,I),I}var It,Be,Ct,$e,Le,vt,Pe,kt,de,$t,R=N(()=>{Re();It=new Set([408,425,429,500,502,503,504]),Be=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Ct=2,$e=4e3,Le=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],vt=new Set([301,302,303,307,308]),Pe=3,kt=64*1024;de=new Map;$t=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as Ft}from"node:fs";import{homedir as Lt}from"node:os";import{join as Y}from"node:path";function Dt(){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){let r=(process.env.ORACLE_EXEC_ENV_FILE||"").trim();return r?[r]:[]}let e=(process.env.ORACLE_EXEC_ENV_FILE||process.env.MAD_EXEC_ENV_FILE||"").trim(),t=Lt();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||Y(t,".config","oracle")).trim();return[e,Y(r,"exec.env")].filter(Boolean)}return[e,Y(t,".config","oracle","exec.env"),Y(t,".config","mad-desk","exec.env")].filter(Boolean)}function De(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let a of Dt())try{let o=Ft(a,"utf8"),i=o.match(new RegExp(`^${t}=(.*)$`,"m"))||o.match(new RegExp(`^${r}=(.*)$`,"m"));if(i&&(n=i[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}var Me=N(()=>{});var qe=N(()=>{});import{createHash as Mt,createHmac as je,timingSafeEqual as qt}from"node:crypto";function W(e){return Array.isArray(e)?`[${e.map(W).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${W(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Ve(e,{required:t=!1}={}){try{return De(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function me(e){let{signature:t,...r}=e;return r}function ze(e,{secret:t}={}){let r=Ve(t);return r?{...e,signature:je("sha256",r).update(W(me(e))).digest("hex")}:e}function Ht(e){let t=String(e||"").toLowerCase();if(!/^0x[0-9a-f]+$/.test(t)||t.length<10||t.length%2!==0)throw new Error("auto-slippage calldata must be even-length hex with a selector");return Mt("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function F(e,{chainId:t,venue:r,data:n,secret:a}={}){if(!e||e.mode!=="auto")throw new Error("bounded auto-slippage guard required");if(Number(e.chainId)!==Number(t))throw new Error("auto-slippage guard chain mismatch");if(String(e.venue).toLowerCase()!==String(r||"").toLowerCase())throw new Error("auto-slippage guard venue mismatch");let o=Ve(a);if(o){let p=je("sha256",o).update(W(me(e))).digest("hex");if(!jt(e.signature,p))throw new Error("auto-slippage guard signature mismatch \u2014 refusing to bind a guard this Oracle did not issue")}let i=Number(e.selectedBps),s=Number(e.capBps);if(!Number.isInteger(i)||i<0||i>Q||!Number.isInteger(s)||s<0||s>Q||i>s)throw new Error("auto-slippage guard bounds are invalid");let f=BigInt(e.quoteAmountOut??0),l=BigInt(e.minAmountOut??0);if(f<=0n||l<=0n)throw new Error("auto-slippage guard amounts must be positive");let d=f*BigInt(1e4-i),c=d/10000n;if(d%10000n!==0n&&(c+=1n),l<c)throw new Error("auto-slippage guard is under-protected relative to its quote");let u=Gt(n);if(u!=null&&u!==l)throw new Error(`auto-slippage: calldata encodes floor ${u}, not the guard floor ${l} \u2014 refusing to bind`);return ze({...me(e),calldataHash:Ht(n)},{secret:a})}function jt(e,t){let r=Buffer.from(String(e??""),"utf8"),n=Buffer.from(String(t??""),"utf8");return r.length!==n.length||r.length===0?!1:qt(r,n)}function fe(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function Vt(e){let t=e==null?Q:Number(e);if(!Number.isInteger(t)||t<0)throw new Error("auto-slippage cap must be a non-negative integer bps value");return Math.min(t,Q)}function L({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:a}={}){let o=fe(e,0),i=o>0?o>=25e4?5:o>=1e5?10:o>=5e4?20:o>=1e4?40:70:n?30:10,s=Math.min(60,Math.abs(fe(t,0))*2),f=Math.min(40,Math.floor(Math.max(0,fe(r,0))/5e3)*5),l=Math.max(25,Math.ceil(20+i+s+f)),d=Vt(a);return{mode:"auto",requiredBps:l,selectedBps:Math.min(l,d),capBps:d,executable:l<=d}}function zt({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:a=0,quoteAgeMs:o=0,crossChain:i=!1,requestedCapBps:s,quotedAtMs:f=Date.now(),ttlMs:l=He,secret:d}={}){let c=BigInt(r??0);if(c<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let u=L({liquidityUsd:n,priceChange5m:a,quoteAgeMs:o,crossChain:i,requestedCapBps:s});if(!u.executable)throw new Error(`auto-slippage requires ${u.requiredBps} bps above hard/requested cap ${u.capBps}; route blocked`);let p=Number(f);if(!Number.isFinite(p))throw new Error("auto-slippage: quotedAtMs must be a finite number");let m=Math.min(3e4,Math.max(1e3,Number(l)||He)),E=c*BigInt(1e4-u.selectedBps),h=E/10000n;if(E%10000n!==0n&&(h+=1n),h>c&&(h=c),c>0n&&h<=0n)throw new Error(`auto-slippage: quote ${c} is too small to express a ${u.selectedBps} bps floor without rounding to zero`);let A=Number((c-h)*10000n/(c===0n?1n:c));if(A>u.capBps)throw new Error(`auto-slippage: realised floor implies ${A} bps, above cap ${u.capBps} \u2014 refusing to issue a guard weaker than advertised`);return ze({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:c.toString(),minAmountOut:h.toString(),requiredBps:u.requiredBps,selectedBps:u.selectedBps,capBps:u.capBps,quotedAtMs:p,expiresAtMs:p+m},{secret:d})}function Gt(e){let t=String(e||"");if(!/^0x[0-9a-fA-F]+$/.test(t)||t.length<10||t.length%2!==0)return null;let r=t.slice(0,10).toLowerCase(),n=[];for(let o=10;o+64<=t.length;o+=64)n.push(t.slice(o,o+64));let a=o=>n[o]==null?null:BigInt("0x"+n[o]);switch(r){case"0x414bf389":return a(6);case"0x04e45aaf":return a(5);case"0xc04b8d59":{let o=a(0);if(o==null)return null;let i=Number(o)/32;return!Number.isInteger(i)||i<0?null:a(i+4)}case"0xb858183f":{let o=a(0);if(o==null)return null;let i=Number(o)/32;return!Number.isInteger(i)||i<0?null:a(i+3)}case"0xa026383e":return a(6);case"0x38ed1739":case"0x5c11d795":return a(1);case"0x7ff36ab5":case"0xb6f9de95":return a(0);case"0x18cbafe5":case"0x791ac947":return a(1);default:return null}}function T(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:a,priceChange5m:o,crossChain:i,requestedCapBps:s,quotedAtMs:f=Date.now(),ttlMs:l}={}){let d=zt({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:a,priceChange5m:o,crossChain:i,requestedCapBps:s,quotedAtMs:f,ttlMs:l});return{...e,autoSlippage:d,amountOutMinimum:d.minAmountOut}}var Q,He,P=N(()=>{Me();qe();Q=100,He=2e4});var j,J=N(()=>{j="0x000000000000000000000000000000000000dEaD"});import{createHash as Kt,createHmac as Xt,timingSafeEqual as vn}from"node:crypto";function he(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(he).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${he(e[r])}`).join(",")}}`}function Ge(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Ke(e=process.env){return Ge(process.env)||Ge(e)}function Jt(e){let{prepareHash:t,prepareMac:r,note:n,...a}=e||{};return a}function Zt(e){let t=Jt(e);return Kt("sha256").update(he(t)).digest("hex")}function er(e,t=Ke()){return t?Xt("sha256",t).update(String(e)).digest("hex"):""}function O(e,{provider:t,kind:r,env:n=process.env,nowMs:a=Date.now(),expiresAtMs:o}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let i=Object.prototype.hasOwnProperty.call(e,"oraclePrepared");if(i&&typeof e.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let s={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:i?e.oraclePrepared:!0};if(!s.provider)throw new Error("stampPrepared: provider required");if(!s.kind)throw new Error("stampPrepared: kind required");let f=Number(a),l=o==null?f+Qt:Number(o),d=l-f;if(!Number.isSafeInteger(f)||!Number.isSafeInteger(l)||d<=0||d>Wt)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let u={...s,preparedAt:f,expiresAt:l,prepareVersion:Yt},p=Zt(u),m=Ke(n),E=m?er(p,m):void 0,h={...u,prepareHash:p};return E&&(h.prepareMac=E),h}var Yt,Qt,Wt,B=N(()=>{Yt=2,Qt=300*1e3,Wt=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});import{Contract as tr,JsonRpcProvider as rr}from"ethers";function cr(e){return sr.test(String(e||""))}async function Xe(e,{contract:t=nr,rpc:r=ar,chainId:n=or,balanceOf:a}={}){if(!cr(e))throw new Error("invalid-address");if(a)return BigInt(await a(e));let o=new rr(r,n,{staticNetwork:!0}),i=new tr(t,ir,o);return BigInt(await i.balanceOf(e))}var nr,or,ar,ir,sr,Ye=N(()=>{nr="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",or=999,ar="https://rpc.hyperliquid.xyz/evm",ir=["function balanceOf(address owner) view returns (uint256)"],sr=/^0x[a-fA-F0-9]{40}$/});import{existsSync as ur,readFileSync as lr,lstatSync as dr}from"node:fs";import{homedir as Qe}from"node:os";import{join as ge}from"node:path";function mr(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(We,t)?We[t]:fr}function Er(e=process.env){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){if(e[Je])return String(e[Je]);let t=e.ORACLE_CONFIG_DIR||ge(Qe(),".config","oracle");return ge(t,"fee-recipient")}return ge(Qe(),".config","oracle","fee-recipient")}function yr(e=process.env){try{let t=Er(e);if(!ur(t)||dr(t).isSymbolicLink())return"";let r=lr(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function Ar(e,{fallback:t=0}={}){if(e==null)return t;if(String(e).trim()==="")return 0;let r=Number(e);return!Number.isFinite(r)||r<=0?0:Math.min(Math.floor(r),pr)}function xr({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[gr]||"").trim(),a=String(e[wr]||br).trim();if(r===!0)return{bps:0,recipient:"",integrator:a,action:t,applies:!1,reason:"admin-oracle"};let o=mr(t),i=Ar(e[hr],{fallback:n?o:0}),s=Math.min(i,o);if(!s)return{bps:0,recipient:"",integrator:a,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:a,action:t,applies:!1,reason:"no-recipient"};let f=yr(e);return!f||f!==n.toLowerCase()?{bps:0,recipient:"",integrator:a,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:s,recipient:n,integrator:a,action:t,applies:!0,reason:"configured"}}async function we({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:a=!1}={}){let o=xr({env:t,action:r,admin:a});if(a===!0)return{...o,holderVerificationStatus:"admin-oracle"};let i=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(i))return{...o,holderVerificationStatus:"wallet-required"};try{return BigInt(await Xe(i,n))>0n?{...o,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...o,holderVerificationStatus:"non-holder"}}catch{return{...o,holderVerificationStatus:"unavailable"}}}function Ze(e){return e?.applies?`Oracle routing fee ${e.bps} bps (${(e.bps/100).toFixed(2)}%) to ${e.recipient}.`:e?.reason==="admin-oracle"?"No Oracle fee (admin Oracle).":e?.reason==="locals-only-holder"?"No Oracle fee (Locals Only holder).":"No Oracle fee."}function et(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}var pr,fr,We,hr,gr,wr,Je,br,Z=N(()=>{Ye();pr=100,fr=5,We=Object.freeze({swap:5,bridge:5,perps:0,nft:0});hr="ORACLE_INTEGRATOR_FEE_BPS",gr="ORACLE_INTEGRATOR_FEE_RECIPIENT",wr="ORACLE_INTEGRATOR_ID",Je="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",br="oracle"});var nt={};ve(nt,{LIFI_API:()=>rt,lifiChains:()=>kr,lifiHealth:()=>Cr,lifiPrepare:()=>vr,lifiQuote:()=>ee});function Ee(e={}){return(e.baseUrl||process.env.LIFI_API_URL||rt).replace(/\/$/,"")}function Ir(e){let t=String(e||be).toLowerCase();return t===be.toLowerCase()||t===Sr}function tt(e,t){let r=String(e||"").trim();if(!/^0x[0-9a-fA-F]{40}$/.test(r))throw new Error(`lifi: ${t} must be a 20-byte address`);return r.toLowerCase()}async function Cr(e={}){let t=await C(`${Ee(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3}),r=Array.isArray(t)?t.length:t?.chains?.length||0;return{ok:r>0,chainCount:r}}async function ee(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:a=be,toToken:o,fromAmount:i,fromAddress:s=j}=e;if(r==null||!o||!i)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let f=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:a,toToken:o,fromAmount:String(i),fromAddress:s}),l=L({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!l.executable)throw new Error(`lifi: route requires ${l.requiredBps} bps above cap ${l.capBps}`);f.set("slippage",String(l.selectedBps/1e4));let d=await we({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[h,A]of Object.entries(et(d)))f.set(h,A);let c=await C(`${Ee(t)}/quote?${f}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=c?.estimate?.toAmount||c?.toAmount;if(!u)return{...c,autoSlippagePolicy:l,oracleFee:d};let p=c?.transactionRequest?.to||c?.estimate?.approvalAddress||"lifi",m=T(c,{chainId:Number(r),venue:p,amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),E=c?.estimate?.toAmountMin||c?.toAmountMin;if(E!=null&&BigInt(E)<BigInt(m.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...m,oracleFee:d}}async function vr(e={},t={}){let r=await ee(e,t),n=r?.transactionRequest;if(!n?.to||!n?.data)throw new Error("lifi: quote did not return an executable transactionRequest");let a=Number(e.fromChain);if(n.chainId!=null&&Number(n.chainId)!==a)throw new Error("lifi: transaction chain mismatch");if(e.fromAddress&&n.from&&String(n.from).toLowerCase()!==String(e.fromAddress).toLowerCase())throw new Error("lifi: transaction sender mismatch");let o=null;if(!Ir(e.fromToken)){let i=r?.estimate?.approvalAddress||r?.approvalAddress;if(!i)throw new Error("lifi: ERC20 route missing approvalAddress");let s=r?.action?.fromToken?.address||r?.estimate?.fromToken?.address||e.fromToken;o={token:tt(s,"approval token"),spender:tt(i,"approval spender"),amount:String(e.fromAmount)}}return O({provider:"lifi",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:a,quote:r,autoSlippage:r.autoSlippage,requiresApproval:o,transaction:{chainId:a,from:n.from||e.fromAddress,to:n.to,data:n.data,value:n.value??"0x0",...n.gasLimit!=null?{gasLimit:n.gasLimit}:{},slippageGuard:F(r.autoSlippage,{chainId:a,venue:n.to,data:n.data})}},{provider:"lifi",kind:"lifi-tx"})}async function kr(e={}){return C(`${Ee(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3})}var rt,be,Sr,ye=N(()=>{R();P();J();B();Z();rt="https://li.quest/v1";be="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Sr="0x0000000000000000000000000000000000000000"});var te={};ve(te,{ACROSS_API:()=>ct,HOP_API:()=>ut,RELAY_API:()=>lt,acrossHealth:()=>Dr,acrossSuggestedFees:()=>dt,hopHealth:()=>Mr,hopQuote:()=>pt,relayHealth:()=>qr,relayPrepare:()=>Hr,relayQuote:()=>xe});async function Dr(e={}){try{return{ok:!0,estimatedFillTimeSec:(await dt({token:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",destinationToken:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",originChainId:1,destinationChainId:42161,amount:"1000000000000000"},e)).estimatedFillTimeSec}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function dt(e={},t={}){let{token:r,destinationToken:n=r,originChainId:a,destinationChainId:o,amount:i}=e;if(!r||a==null||o==null||!i)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let s=new URLSearchParams({token:r,destinationToken:n,originChainId:String(a),destinationChainId:String(o),amount:String(i)}),f=(t.baseUrl||process.env.ACROSS_API_URL||ct).replace(/\/$/,"");return C(`${f}/suggested-fees?${s}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Mr(e={}){try{let t=await pt({amount:"1000000000000000",token:"ETH",fromChain:"ethereum",toChain:"arbitrum",slippage:.5},e);return{ok:!0,estimatedRecieved:t.estimatedRecieved||t.estimatedReceived}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function pt(e={},t={}){let{amount:r,token:n="ETH",fromChain:a="ethereum",toChain:o="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let i=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),s=L({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:a!==o,requestedCapBps:e.maxSlippageBps??e.slippageBps??i});if(!s.executable)throw new Error(`hop: route requires ${s.requiredBps} bps above cap ${s.capBps}`);let f=new URLSearchParams({amount:String(r),token:n,fromChain:a,toChain:o,slippage:String(s.selectedBps/100)}),l=(t.baseUrl||process.env.HOP_API_URL||ut).replace(/\/$/,""),d=await C(`${l}/quote?${f}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),c=d?.estimatedRecieved||d?.estimatedReceived;return c?T(d,{chainId:Number(e.originChainId||e.chainId||Lr[a]||0),venue:d?.tx?.to||"hop",amountOut:c,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:a!==o,requestedCapBps:e.maxSlippageBps??e.slippageBps??i}):{...d,autoSlippagePolicy:s}}async function qr(e={}){try{let t=await xe({user:j,originChainId:1,destinationChainId:8453,originCurrency:"0x0000000000000000000000000000000000000000",destinationCurrency:"0x0000000000000000000000000000000000000000",amount:"1000000000000000",tradeType:"EXACT_INPUT"},e);return{ok:!0,hasSteps:Array.isArray(t.steps),stepCount:t.steps?.length||0}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function xe(e={},t={}){let{user:r=j,originChainId:n,destinationChainId:a,originCurrency:o="0x0000000000000000000000000000000000000000",destinationCurrency:i="0x0000000000000000000000000000000000000000",amount:s,tradeType:f="EXACT_INPUT"}=e;if(n==null||a==null||!s)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let l=L({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(a),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!l.executable)throw new Error(`relay: route requires ${l.requiredBps} bps above cap ${l.capBps}`);let d=(t.baseUrl||process.env.RELAY_API_URL||lt).replace(/\/$/,""),c=await C(`${d}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(a),originCurrency:o,destinationCurrency:i,amount:String(s),tradeType:f,slippageTolerance:String(l.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=c?.details?.currencyOut?.amount;return!u||!/^\d+$/.test(String(u))?{...c,autoSlippagePolicy:l}:T(c,{chainId:Number(n),venue:c?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(a),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function Hr(e={},t={}){let r=await xe(e,t),n=Number(e.originChainId),a=(r.steps||[]).flatMap(s=>(s.items||[]).filter(f=>f?.data?.to&&f?.data?.data).map(f=>({stepId:s.id,...f.data})));if(!a.length)throw new Error("relay: quote returned no executable transaction items");let o=String(r?.autoSlippage?.venue||"").toLowerCase();if(a.some(s=>String(s.to).toLowerCase()!==o))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let i=a.map(s=>({chainId:n,from:s.from||e.user,to:s.to,data:s.data,value:s.value??"0x0",...s.gasLimit!=null||s.gas!=null?{gasLimit:s.gasLimit??s.gas}:{},slippageGuard:F(r.autoSlippage,{chainId:n,venue:s.to,data:s.data})}));return O({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:i},{provider:"relay",kind:"relay-tx"})}var ct,ut,lt,Lr,re=N(()=>{R();P();J();B();ct="https://across.to/api",ut="https://api.hop.exchange/v1",lt="https://api.relay.link",Lr={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var en=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),tn=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),rn=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var U=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"});var ke=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}};function Oe(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:a=null,feeUsd:o=null,oracleFeeBps:i=0,estimatedGas:s=null,liquidityUsd:f=null,error:l=null,executionReady:d=!1,meta:c={}}=e||{};if(l||r==null)return{source:t,quality:U.FAILED,amountOut:null,error:l||"no amountOut returned"};let u=ke(r);if(u==null||u<=0n)return{source:t,quality:U.FAILED,amountOut:null,error:"non-positive amountOut"};let p=Number(i);return{source:t,quality:a==null?U.NO_GAS:U.FULL,amountOut:u.toString(),minOut:ke(n)?.toString()??null,gasUsd:a,feeUsd:o,oracleFeeBps:Number.isFinite(p)&&p>0?Math.floor(p):0,estimatedGas:s==null?null:String(s),liquidityUsd:f==null?null:Number(f),executionReady:d,meta:c}}function _e(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:a=50,gasPriceWei:o=null,nativePriceUsd:i=null}={}){let s=e.filter(g=>g.quality!==U.FAILED),f=e.filter(g=>g.quality===U.FAILED),l=t!=null&&t>0&&r!=null&&r>=0,d=Number(o),c=Number(i),u=Number.isFinite(d)&&d>0&&Number.isFinite(c)&&c>0,p=s.map(g=>{let y=BigInt(g.amountOut),_=0n,v=!1,k=!1,V=BigInt(g.oracleFeeBps??0),Se=V>0n?y*V/10000n:0n;if(l){let K=g.gasUsd,oe=Number(g.meta?.gasUnits??g.estimatedGas);if(K==null&&u&&Number.isFinite(oe)&&oe>0){let q=oe*d/1e18*c;Number.isFinite(q)&&q>=0&&(K=q,k=!0)}let Ce=(K??0)+(g.feeUsd??0);if(Ce>0){let q=Ce/t*10**r;Number.isFinite(q)&&q>=0&&(_=BigInt(Math.floor(q)),v=!0)}else K===0&&(v=!0)}let Ie=_+Se,wt=y>Ie?y-Ie:0n;return{...g,grossOut:y.toString(),netOut:wt.toString(),costInDest:_.toString(),oracleFeeInDest:Se.toString(),costAccounted:v,gasEstimated:k}}),m=Number(a)>0?Number(a):0,E=p.reduce((g,y)=>BigInt(y.netOut)>g?BigInt(y.netOut):g,0n),h=g=>E>0n?Number((E-BigInt(g))*10000n/E):0,A=[],w=p.slice().sort((g,y)=>BigInt(y.netOut)>BigInt(g.netOut)?1:-1)[0]??null;p.sort((g,y)=>{let _=h(g.netOut)<=m?0:1,v=h(y.netOut)<=m?0:1;if(n&&m>0&&_!==v)return _-v;if(n&&m>0){let k=g.liquidityUsd??-1,V=y.liquidityUsd??-1;if(k!==V)return V-k}return BigInt(y.netOut)>BigInt(g.netOut)?1:-1}),n&&m>0&&w&&p[0]&&p[0].source!==w.source&&A.push(`liquidity-first: chose ${p[0].source} (liquidity $${p[0].liquidityUsd??"unknown"}) over best-price ${w.source} within ${m} bps`);let I=p.filter(g=>!g.costAccounted).map(g=>g.source);l?I.length&&A.push(`gas not reported by: ${I.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):A.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let x=p[0];if(l&&x&&x.costAccounted===!1){let g=p.find(y=>y.costAccounted&&h(y.netOut)<=m);g&&A.push(`winner ${x.source} has UNMEASURED gas; gas-measured ${g.source} is within ${m} bps and may net more once ${x.source}'s real gas is paid \u2014 prefer it if unsure.`)}let b=p.filter(g=>g.gasEstimated).map(g=>g.source);b.length&&A.push(`gas ESTIMATED (from gas units x current gas price, not measured) for: ${b.join(", ")}. Net includes this estimate so the ranking is gas-inclusive, but the on-chain gas may differ.`);let S=null,$=null;if(p.length>=2&&p[0].costAccounted&&p[1].costAccounted){let g=BigInt(p[0].netOut),y=BigInt(p[1].netOut);y>0n&&(S=Number((g-y)*10000n/y),$=`${p[0].source} vs ${p[1].source}`)}return{best:p[0]??null,routes:p,failed:f,improvementBps:S,spreadBasis:$,rankedOn:l?"net-of-cost":"gross",warnings:A}}async function Ne(e,{timeoutMs:t=12e3}={}){let r=(a,o)=>Promise.race([a,new Promise((i,s)=>setTimeout(()=>s(new Error(`${o}: timeout`)),t))]);return(await Promise.allSettled(e.map(a=>r(Promise.resolve().then(a.run),a.source)))).map((a,o)=>{let i=e[o].source;return a.status==="rejected"?Oe({source:i,error:String(a.reason?.message||a.reason)}):Oe({source:i,...a.value})})}ye();R();P();B();Z();R();P();B();R();P();B();R();P();import{TypedDataEncoder as uo,getAddress as lo,isAddress as po}from"ethers";var oo=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});J();B();var Eo=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),yo=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"});var Ao=Object.freeze({Order:[{name:"sellToken",type:"address"},{name:"buyToken",type:"address"},{name:"receiver",type:"address"},{name:"sellAmount",type:"uint256"},{name:"buyAmount",type:"uint256"},{name:"validTo",type:"uint32"},{name:"appData",type:"bytes32"},{name:"feeAmount",type:"uint256"},{name:"kind",type:"string"},{name:"partiallyFillable",type:"bool"},{name:"sellTokenBalance",type:"string"},{name:"buyTokenBalance",type:"string"}]}),xo=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});import{Interface as at,getAddress as Do,isAddress as Mo}from"ethers";R();var ot={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Io=new Map(Object.values(ot).map(e=>[e.chainId,e]));import{Interface as Nr,getAddress as Ro}from"ethers";var Bo=new Nr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);R();var Uo=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});P();B();var zo=new at(["function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)","function quoteExactInput(bytes path, uint256 amountIn) returns (uint256 amountOut, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)"]),Go=new at(["function exactInputSingle((address tokenIn,address tokenOut,uint24 fee,address recipient,uint256 amountIn,uint256 amountOutMinimum,uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)","function multicall(uint256 deadline,bytes[] data) payable returns (bytes[] results)"]);import{AbiCoder as Br,Interface as it,getAddress as Yo,isAddress as Qo,keccak256 as Wo}from"ethers";P();B();var ra=Br.defaultAbiCoder();var na=new it(["function quoteExactInputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountOut, uint256 gasEstimate)","function quoteExactOutputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountIn, uint256 gasEstimate)"]),oa=new it(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);R();var $r="https://coins.llama.fi",Pr="https://api.llama.fi";function Ur(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||$r).replace(/\/$/,"")}function Fr(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||Pr).replace(/\/$/,"")}async function Ae(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return C(`${Ur(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function st(e={}){return C(`${Fr(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var M=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function ft(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let a=M(n?.amountUSD);a!=null&&(t+=a,r=!0)}return r?t:null}var D=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),mt=Object.freeze({across:["across"],relay:["relaychain","relay"],lifi:["jumper-(li.fi-powered)","lifi"],stargate:["stargate-v2","stargate-v1","stargate"],hop:["hop-protocol","hop"],debridge:["debridge"],synapse:["synapse"],connext:["connext"],cbridge:["celer-bridge","celer-cbridge","cbridge"],celer:["celer-bridge","celer-cbridge","cbridge"],squid:["squid"],symbiosis:["symbiosis"],wormhole:["wormhole"],mayan:["mayan"],allbridge:["allbridge"],thorchain:["thorchain"]});async function jr(e={}){try{let t=await st({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function Vr(e,t={}){let r=D(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...mt[r]||[r]),n.push(...mt[D(e)]||[e]),n}function zr(e,t,r={}){let n=Array.isArray(e)?e:[],a=Vr(t,r).map(D).filter(Boolean);for(let o of a){let i=n.find(f=>D(f?.slug)===o||D(f?.name)===o),s=M(i?.tvl);if(s!=null)return{liquidityUsd:s,protocol:i?.name??i?.slug??o}}for(let o of a){let i=n.find(f=>{let l=D(f?.category);return!l.includes("bridge")&&!l.includes("crosschain")?!1:D(f?.slug).includes(o)||D(f?.name).includes(o)}),s=M(i?.tvl);if(s!=null)return{liquidityUsd:s,protocol:i?.name??i?.slug??o}}return null}function ht({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:a,taker:o,opts:i={}}){let s=[],f=null,l=async(d,c={})=>(f||=jr(i),zr(await f,d,c));return s.push({source:"lifi",run:async()=>{let d=await ee({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:a},i),c=d?.estimate??d?.[0]?.estimate,u={tool:d?.tool??d?.toolDetails?.name,durationSeconds:M(c?.executionDuration)},p=await l("lifi",u);return{amountOut:c?.toAmount,minOut:c?.toAmountMin,gasUsd:ft(c?.gasCosts),feeUsd:ft(c?.feeCosts),oracleFeeBps:d?.oracleFee?.applies?d.oracleFee.bps:0,liquidityUsd:p?.liquidityUsd??null,meta:{...u,liquidityProtocol:p?.protocol,oracleFee:d?.oracleFee??null}}}}),s.push({source:"relay",run:async()=>{let{relayQuote:d}=await Promise.resolve().then(()=>(re(),te)),u=(await d({user:o,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(a)},i))?.details,p={durationSeconds:M(u?.timeEstimate),rate:u?.rate},m=await l("relay",p);return{amountOut:u?.currencyOut?.amount,minOut:u?.currencyOut?.minimumAmount,gasUsd:M(u?.totalImpact?.usd)!=null?Math.abs(M(u.totalImpact.usd)):null,liquidityUsd:m?.liquidityUsd??null,meta:{...p,liquidityProtocol:m?.protocol}}}}),s.push({source:"across",run:async()=>{let{acrossSuggestedFees:d}=await Promise.resolve().then(()=>(re(),te)),c=await d({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(a)},i),u=c?.totalRelayFee?.total,p=null;if(u!=null)try{let E=BigInt(String(a))-BigInt(String(u));E>0n&&(p=E.toString())}catch{}let m=await l("across");return{amountOut:p,gasUsd:null,liquidityUsd:m?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:M(c?.estimatedFillTimeSec),limits:c?.limits?{min:c.limits.minDeposit,max:c.limits.maxDeposit}:void 0,liquidityProtocol:m?.protocol}}}}),s}Z();var Gr={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function Kr(e,t,r){let n=Gr[Number(e)];if(!n)return{priceUsd:null,decimals:null};let a=`${n}:${t}`;try{let i=(await Ae([a],r))?.coins?.[a],s=Number(i?.price),f=Number(i?.decimals);return{priceUsd:Number.isFinite(s)?s:null,decimals:Number.isFinite(f)?f:null}}catch{return{priceUsd:null,decimals:null}}}async function gt(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:a,tokenOut:o,amountIn:i}=e;if(r==null||n==null||!a||!o||i==null)throw new Error("bestBridgeRoute requires fromChainId, toChainId, tokenIn, tokenOut, amountIn");if(Number(r)===Number(n))throw new Error("bestBridgeRoute is for cross-chain; use bestSwapRoute for same-chain");let s=Kr(n,o,t),f=ht({...e,opts:t}),[l,d]=await Promise.all([Ne(f,{timeoutMs:t.timeoutMs??15e3}),s]),c=_e(l,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals,liquidityBandBps:t.liquidityBandBps??50}),u=c.routes.map(p=>({source:p.source,seconds:p.meta?.durationSeconds??null})).filter(p=>p.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:a,tokenOut:o,amountIn:String(i),...c,durations:u,sourcesTried:f.length,sourcesAnswered:l.filter(p=>p.quality!==U.FAILED).length,note:Yr(c,f.length)}}function Xr(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Ze(t)}`:""}function Yr(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=Xr(e.best);if(r===1)return`only 1 of ${t} sources answered, so this is the ONLY route, not a proven best one. Treat it as unbenchmarked.`+n;if(e.improvementBps!=null){let a=e.improvementBps,o=a/100;if(a<.01)return`best of ${r} routes, ranked on ${e.rankedOn}: effectively tied with the runner-up (${e.spreadBasis}), inside quote noise. Re-quote before you size up.`+n;let i=o>=.01?`${o.toFixed(2)}%`:`${a.toFixed(2)}bps`;return`best of ${r} routes, ranked on ${e.rankedOn}: ${i} better than the runner-up (${e.spreadBasis})`+n}return`best of ${r} routes, ranked on ${e.rankedOn}. No spread quoted: the top routes report cost differently, so the margin is not comparable.`+n}B();var Qr=/^0x[0-9a-fA-F]{40}$/,Wr=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),Jr=100,ne={relay:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:a,taker:o},i)=>{let{relayPrepare:s}=await Promise.resolve().then(()=>(re(),te)),f=await s({user:o,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(a)},i);return{transactions:f.transactions||[],amountOut:f.quote?.details?.currencyOut?.amount??null,minOut:f.quote?.details?.currencyOut?.minimumAmount??null,durationSeconds:f.quote?.details?.timeEstimate??null}},lifi:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:a,taker:o,isHolder:i},s)=>{let{lifiPrepare:f}=await Promise.resolve().then(()=>(ye(),nt)),l=await f({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:a,fromAddress:o,isHolder:i,feeAction:"bridge"},s);return{transactions:l.transaction?[l.transaction]:[],requiresApproval:l.requiresApproval??null,amountOut:l.quote?.estimate?.toAmount??null,minOut:l.quote?.estimate?.toAmountMin??null,durationSeconds:l.quote?.estimate?.executionDuration??null}}};function za(){return Object.keys(ne)}async function Ga(e,t={}){let{taker:r,fromChainId:n,toChainId:a}=e;if(!r)throw new Error("prepareBestBridgeRoute requires taker: bridge transactions are built FOR an address, and the quote-only placeholder must never end up in one");if(!Qr.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(Wr.has(r.toLowerCase()))throw new Error(`taker "${r}" is a placeholder/burn address. Bridging to it would send funds to an address nobody controls, on a chain where you cannot undo it.`);let o=await gt(e,t);if(!o.best)return{ok:!1,reason:"no source returned a usable bridge route",comparison:o};let i=e.source||o.best.source,s=o.routes.find(h=>h.source===i);if(!s)return{ok:!1,reason:`source "${i}" returned no usable route`,comparison:o};let f=ne[i];if(!f){let h=o.routes.find(A=>ne[A.source]&&A.source!==i);return{ok:!1,reason:`${i} won the comparison but has no bridge prepare path in this build. `+(h?`Next preparable route is ${h.source}; pass source:"${h.source}".`:"No route in this comparison can be prepared."),failureKind:"no-prepare-path",...h?{alternative:h.source}:{},winner:i,comparison:o}}let l;try{l=await f(e,t)}catch(h){let A=typeof h?.body=="string"?h.body:h?.body?JSON.stringify(h.body):"",w=[String(h?.message||h),A].filter(Boolean).join(" :: "),I=/allowance/i.test(w),x=!I&&/not enough|insufficient|balance/i.test(w),b=o.routes.find(S=>ne[S.source]&&S.source!==i);return{ok:!1,reason:I?`${i} will not build calldata until the token approval exists on-chain. Approve first, then prepare again. Underlying: ${w}`:x?`${i} refused to build: ${w}. Quoting works for any address; preparing needs the real funded wallet on chain ${n}.`:`${i} bridge prepare failed: ${w}`,failureKind:I?"approval-required-first":x?"taker-not-funded":"provider-error",...b?{alternative:b.source}:{},comparison:o}}let d=l.transactions||[];if(!d.length)return{ok:!1,reason:`${i} returned no executable transaction for this route`,failureKind:"provider-error",comparison:o};let c=d.filter(h=>h.chainId!=null&&Number(h.chainId)!==Number(n));if(c.length)return{ok:!1,reason:`${i} returned a transaction for chain ${c[0].chainId} but the origin chain is ${n}. Refusing to hand over a mismatched artifact.`,failureKind:"chain-mismatch",comparison:o};let u=e.driftToleranceBps??Jr,p=null,m=null;if(l.amountOut!=null&&s.grossOut!=null)try{let h=BigInt(s.grossOut),A=BigInt(l.amountOut);h>0n&&(p=Number((A-h)*10000n/h),p<-u&&(m=`route moved ${(p/100).toFixed(2)}% against you since the comparison (tolerance ${(u/100).toFixed(2)}%). Re-compare before signing.`))}catch{}let E=[...m?[m]:[],...o.warnings||[],`Bridging is NOT atomic: the origin transaction succeeding does not mean funds arrived on chain ${a}. Expect ~${l.durationSeconds!=null?`${l.durationSeconds}s`:"minutes"} before the destination credits, and do not re-send if it is pending.`];return d.length>1&&E.push(`This route needs ${d.length} transactions signed IN ORDER. Signing only the first leaves funds approved but not bridged.`),O({ok:!0,chosen:{source:i,wasWinner:i===o.best.source,netOut:s.netOut,grossOut:s.grossOut,gasUsd:s.gasUsd},artifactKind:"unsigned-transaction-sequence",fromChainId:Number(n),toChainId:Number(a),transactionCount:d.length,transactions:d,requiresApproval:l.requiresApproval??null,minOut:l.minOut??null,durationSeconds:l.durationSeconds??null,destination:d[0]?.to??null,unsigned:!0,signedBy:"user-wallet",driftBps:p,warnings:E,runnersUp:o.routes.filter(h=>h.source!==i).map(h=>({source:h.source,netOut:h.netOut,gasUsd:h.gasUsd})),comparison:{rankedOn:o.rankedOn,sourcesAnswered:o.sourcesAnswered,sourcesTried:o.sourcesTried,improvementBps:o.improvementBps},note:`UNSIGNED. ${d.length} transaction(s) on chain ${n}, crediting chain ${a}. Verify every destination address before signing.`},{provider:"router",kind:"best-bridge"})}export{Ga as prepareBestBridgeRoute,za as supportedBridgePreparers};
|
|
1
|
+
var bt=Object.defineProperty;var B=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var ve=(e,t)=>{for(var r in t)bt(e,r,{get:t[r],enumerable:!0})};import H from"node:net";import Et from"node:dns";function X(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=d=>{if(!d)return[];let c=d.split(":"),u=c.at(-1);if(u?.includes(".")){let p=u.split(".").map(Number);if(p.length!==4||p.some(m=>!Number.isInteger(m)||m<0||m>255))return null;c.splice(c.length-1,1,(p[0]<<8|p[1]).toString(16),(p[2]<<8|p[3]).toString(16))}return c.some(p=>!/^[0-9a-f]{1,4}$/.test(p))?null:c.map(p=>Number.parseInt(p,16))},[n,i]=t.split("::"),o=r(n),a=r(i);if(!o||!a)return null;let s=t.includes("::"),f=8-o.length-a.length;if(!s&&f!==0||s&&f<1)return null;let l=[...o,...Array(Math.max(0,f)).fill(0),...a];return l.length!==8?null:Uint8Array.from(l.flatMap(d=>[d>>8,d&255]))}function ie(e,t,r){let n=Math.floor(r/8),i=r%8;for(let a=0;a<n;a+=1)if(e[a]!==t[a])return!1;if(!i)return!0;let o=255<<8-i;return(e[n]&o)===(t[n]&o)}function ae(e){if(H.isIPv4(e)){let t=e.split(".").map(Number);return!(t[0]===0||t[0]===10||t[0]===127||t[0]>=224||t[0]===100&&t[1]>=64&&t[1]<=127||t[0]===169&&t[1]===254||t[0]===172&&t[1]>=16&&t[1]<=31||t[0]===192&&(t[1]===0||t[1]===2||t[1]===168)||t[0]===192&&t[1]===88&&t[2]===99||t[0]===198&&(t[1]===18||t[1]===19||t[1]===51)||t[0]===203&&t[1]===0&&t[2]===113)}if(H.isIPv6(e)){let t=X(e);if(!t)return!1;let r=X("::ffff:0:0");return ie(t,r,96)?ae([...t.slice(12)].join(".")):ie(t,X("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([i,o])=>ie(t,X(i),o)):!1}return!1}function At(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let r=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(yt.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=H.isIP(r);return n!==0&&!ae(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function se(e,{lookupFn:t=Et.promises.lookup}={}){let r=At(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:H.isIPv6(r.host)?6:4}]};let n;try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(i=>!ae(i.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function ce({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let c=await t();r=c.Agent,n=c.fetch}catch(c){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${c?.message||c}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let i=c=>String(c).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),o=new Map,a=c=>(Array.isArray(c)?c:[c]).map(u=>typeof u=="string"?{address:u}:u).filter(u=>u&&u.address).map(u=>({address:u.address,family:u.family||(H.isIPv6(u.address)?6:4)})),s=(c,u,p)=>{o.set(i(c),a(typeof u=="string"?[{address:u,family:p}]:u))},f=c=>{let u=i(c);if(H.isIP(u))return[{address:u,family:H.isIPv6(u)?6:4}];let p=o.get(u);if(!p||!p.length)throw new Error(`refused: unpinned host ${c} during pinned fetch`);return p},l=new r({connect:{lookup(c,u,p){let m;try{m=f(c)}catch(E){return p(E)}return u?.all?p(null,m):p(null,m[0].address,m[0].family)}}}),d=xt((c,u={})=>n(c,{...u,dispatcher:l}),s);return{dispatcher:l,fetch:d,pin:s,resolve:f,async close(){try{await l.destroy()}catch{}}}}function xt(e,t){if(typeof e!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof t!="function")throw new Error("markPinCapableFetch: pin must be a function");return e[ue]=Object.freeze({pin:t}),e}function le(e){return typeof e=="function"&&typeof e[ue]?.pin=="function"}function Ne(e,t,r){if(!le(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[ue].pin(t,r)}var yt,ue,Te=B(()=>{yt=new Set(["localhost","metadata.google.internal","metadata.goog"]);ue=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as St}from"node:crypto";function Ot(e){let t=String(e||"").toLowerCase();return Le.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function _t(e){let t={};for(let[r,n]of Object.entries(e||{}))Ot(r)||(t[r]=n);return t}function Bt(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let r=new URL(String(e),String(t));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${r.protocol}`);return r.toString()}function Nt(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Tt(e,t,r,n={}){let i={};for(let[d,c]of Object.entries(r||{}))i[d.toLowerCase()]=c;let o=Object.keys(i).filter(d=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(d)),s=[...new Set([...Le,...o])].sort().map(d=>`${d}=${i[d]??""}`).join(`
|
|
2
|
+
`),f=St("sha256").update(s).digest("hex").slice(0,32),l=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`;return`${e} ${t} ${l} ${f}`}function Rt(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,$e):Math.min(250*2**e,$e)+Math.floor(Math.random()*100)}function z(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function pe(e,t,r){return z(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function G(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function Pt(e){return e?e.byteLength??e.length??0:0}async function Ue(e,t,{url:r,truncate:n=!1,onOversize:i}={}){if(t==null)return await e.text();let o=Number(e.headers?.get?.("content-length"));if(Number.isFinite(o)&&o>t&&(G(e),!n))throw pe(r,`content-length ${o}`,t);let a=e.body?.getReader?.();if(!a){let c=await e.text(),u=Buffer.byteLength(c,"utf8");if(u>t){if(!n)throw pe(r,`body ${u} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let s=[],f=0,l=!1;try{for(;;){let{value:c,done:u}=await a.read();if(u)break;if(c&&(s.push(Buffer.from(c)),f+=Pt(c),f>t)){l=!0;break}}}finally{if(l)try{await a.cancel()}catch{}try{a.releaseLock?.()}catch{}}if(l&&(typeof i=="function"&&i(),!n))throw pe(r,`streamed ${f} bytes`,t);let d=Buffer.concat(s);return(l?d.subarray(0,t):d).toString("utf8")}function Fe(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Ut(e,{fetchImpl:t,method:r,headers:n,body:i,timeoutMs:o,lookupFn:a,realFetch:s,untrustedUrl:f=!1,maxResponseBytes:l=null,importUndici:d,validateResponse:c}){let u=new AbortController,p=setTimeout(()=>u.abort(),o),m=null,E=t,h=a?{lookupFn:a}:{};if(f&&!s&&!le(E))throw z(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let A=async(w,{status:I=null}={})=>{let x=await se(w,h);if(!x.ok)throw z(I==null?`HTTP refused ${w}: ${x.error}`:`HTTP redirect to ${w} ${x.error}`,I==null?{}:{status:I});let b=new URL(w).hostname;if(s){if(m&&(await m.close(),m=null),!m)try{m=await ce({requireUndici:!0,...d?{importUndici:d}:{}})}catch(S){throw z(I==null?`HTTP refused ${w}: ${S?.message||S}`:`HTTP redirect to ${w} refused: ${S?.message||S}`,I==null?{}:{status:I})}m.pin(b,x.addresses),E=m.fetch}else Ne(E,b,x.addresses);return x};try{let w=String(e),I={...n||{}};f&&await A(w);for(let x=0;x<=Pe;x+=1){let b=await E(w,{method:r,headers:I,body:i,signal:u.signal,redirect:"manual"});if(vt.has(b.status)){if(r!=="GET"&&r!=="HEAD"){let v=await Ue(b,l??kt,{url:w,truncate:!0}),k=new Error(`HTTP ${b.status} ${r} ${w} redirected non-idempotent request`);throw k.status=b.status,k.body=Fe(v)??v.slice(0,300),k}if(x===Pe)throw G(b),new Error(`HTTP redirect loop for ${e}`);let g=b.headers?.get?.("location"),y;try{y=Bt(g,w)}catch(v){throw G(b),v}let _=!Nt(y,w);if(G(b),_&&(I=_t(I)),f)await A(y,{status:b.status});else if(_){let v=await se(y,h);if(!v.ok){let k=new Error(`HTTP redirect from ${w} ${v.error}`);throw k.status=b.status,k.retryable=!1,k}s&&v.addresses?.length&&(m||(m=await ce(d?{importUndici:d}:{})),m&&(m.pin(new URL(y).hostname,v.addresses),E=m.fetch))}w=y;continue}if(typeof c=="function")try{await c(b,{url:w})}catch(g){throw G(b),z(g?.message||String(g))}let S=await Ue(b,l,{url:w,onOversize:()=>u.abort()}),$=Fe(S);if(!b.ok){let g=new Error(`HTTP ${b.status} ${r} ${w}`);throw g.status=b.status,g.retryAfter=b.headers?.get?.("retry-after")??null,g.body=$??S.slice(0,300),g}return $??S}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(p),m&&await m.close()}}async function C(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,i=(t.method||"GET").toUpperCase(),o={Accept:"application/json",...t.headers||{}},a=t.body;a!=null&&typeof a!="string"&&(o["Content-Type"]=o["Content-Type"]||"application/json",a=JSON.stringify(a));let s=Number.isInteger(t.retries)?Math.max(t.retries,0):Ct,f=t.lookupFn,l=!t.fetchImpl,d=t.untrustedUrl===!0,c=t.importUndici,u=t.validateResponse,p=Number(t.maxResponseBytes),m=Number.isFinite(p)&&p>0?Math.floor(p):null,E=async()=>{let x;for(let b=0;b<=s;b++)try{return await Ut(e,{fetchImpl:r,method:i,headers:o,body:a,timeoutMs:n,lookupFn:f,realFetch:l,untrustedUrl:d,maxResponseBytes:m,importUndici:c,validateResponse:u})}catch(S){x=S;let $=S?.status,g=S?.name==="AbortError",y=new Set([408,425,429]),_=S?.retryable===!1?!1:$!=null?y.has($)||It.has($)&&Re.has(i):!g&&Re.has(i);if(b===s||!_)throw S;await $t(Rt(b,S?.retryAfter))}throw x};if(!(t.dedupe!==!1&&i==="GET"&&a==null))return E();let A=Tt(i,e,o,{untrustedUrl:d,maxResponseBytes:m}),w=de.get(A);if(w)return w;let I=E().finally(()=>de.delete(A));return de.set(A,I),I}var It,Re,Ct,$e,Le,vt,Pe,kt,de,$t,T=B(()=>{Te();It=new Set([408,425,429,500,502,503,504]),Re=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Ct=2,$e=4e3,Le=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],vt=new Set([301,302,303,307,308]),Pe=3,kt=64*1024;de=new Map;$t=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as Ft}from"node:fs";import{homedir as Lt}from"node:os";import{join as Y}from"node:path";function Dt(){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){let r=(process.env.ORACLE_EXEC_ENV_FILE||"").trim();return r?[r]:[]}let e=(process.env.ORACLE_EXEC_ENV_FILE||process.env.MAD_EXEC_ENV_FILE||"").trim(),t=Lt();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||Y(t,".config","oracle")).trim();return[e,Y(r,"exec.env")].filter(Boolean)}return[e,Y(t,".config","oracle","exec.env"),Y(t,".config","mad-desk","exec.env")].filter(Boolean)}function De(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let i of Dt())try{let o=Ft(i,"utf8"),a=o.match(new RegExp(`^${t}=(.*)$`,"m"))||o.match(new RegExp(`^${r}=(.*)$`,"m"));if(a&&(n=a[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}var Me=B(()=>{});var qe=B(()=>{});import{createHash as Mt,createHmac as je,timingSafeEqual as qt}from"node:crypto";function W(e){return Array.isArray(e)?`[${e.map(W).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${W(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Ve(e,{required:t=!1}={}){try{return De(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function me(e){let{signature:t,...r}=e;return r}function ze(e,{secret:t}={}){let r=Ve(t);return r?{...e,signature:je("sha256",r).update(W(me(e))).digest("hex")}:e}function Ht(e){let t=String(e||"").toLowerCase();if(!/^0x[0-9a-f]+$/.test(t)||t.length<10||t.length%2!==0)throw new Error("auto-slippage calldata must be even-length hex with a selector");return Mt("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function F(e,{chainId:t,venue:r,data:n,secret:i}={}){if(!e||e.mode!=="auto")throw new Error("bounded auto-slippage guard required");if(Number(e.chainId)!==Number(t))throw new Error("auto-slippage guard chain mismatch");if(String(e.venue).toLowerCase()!==String(r||"").toLowerCase())throw new Error("auto-slippage guard venue mismatch");let o=Ve(i);if(o){let p=je("sha256",o).update(W(me(e))).digest("hex");if(!jt(e.signature,p))throw new Error("auto-slippage guard signature mismatch \u2014 refusing to bind a guard this Oracle did not issue")}let a=Number(e.selectedBps),s=Number(e.capBps);if(!Number.isInteger(a)||a<0||a>Q||!Number.isInteger(s)||s<0||s>Q||a>s)throw new Error("auto-slippage guard bounds are invalid");let f=BigInt(e.quoteAmountOut??0),l=BigInt(e.minAmountOut??0);if(f<=0n||l<=0n)throw new Error("auto-slippage guard amounts must be positive");let d=f*BigInt(1e4-a),c=d/10000n;if(d%10000n!==0n&&(c+=1n),l<c)throw new Error("auto-slippage guard is under-protected relative to its quote");let u=Gt(n);if(u!=null&&u!==l)throw new Error(`auto-slippage: calldata encodes floor ${u}, not the guard floor ${l} \u2014 refusing to bind`);return ze({...me(e),calldataHash:Ht(n)},{secret:i})}function jt(e,t){let r=Buffer.from(String(e??""),"utf8"),n=Buffer.from(String(t??""),"utf8");return r.length!==n.length||r.length===0?!1:qt(r,n)}function fe(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function Vt(e){let t=e==null?Q:Number(e);if(!Number.isInteger(t)||t<0)throw new Error("auto-slippage cap must be a non-negative integer bps value");return Math.min(t,Q)}function L({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:i}={}){let o=fe(e,0),a=o>0?o>=25e4?5:o>=1e5?10:o>=5e4?20:o>=1e4?40:70:n?30:10,s=Math.min(60,Math.abs(fe(t,0))*2),f=Math.min(40,Math.floor(Math.max(0,fe(r,0))/5e3)*5),l=Math.max(25,Math.ceil(20+a+s+f)),d=Vt(i);return{mode:"auto",requiredBps:l,selectedBps:Math.min(l,d),capBps:d,executable:l<=d}}function zt({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:i=0,quoteAgeMs:o=0,crossChain:a=!1,requestedCapBps:s,quotedAtMs:f=Date.now(),ttlMs:l=He,secret:d}={}){let c=BigInt(r??0);if(c<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let u=L({liquidityUsd:n,priceChange5m:i,quoteAgeMs:o,crossChain:a,requestedCapBps:s});if(!u.executable)throw new Error(`auto-slippage requires ${u.requiredBps} bps above hard/requested cap ${u.capBps}; route blocked`);let p=Number(f);if(!Number.isFinite(p))throw new Error("auto-slippage: quotedAtMs must be a finite number");let m=Math.min(3e4,Math.max(1e3,Number(l)||He)),E=c*BigInt(1e4-u.selectedBps),h=E/10000n;if(E%10000n!==0n&&(h+=1n),h>c&&(h=c),c>0n&&h<=0n)throw new Error(`auto-slippage: quote ${c} is too small to express a ${u.selectedBps} bps floor without rounding to zero`);let A=Number((c-h)*10000n/(c===0n?1n:c));if(A>u.capBps)throw new Error(`auto-slippage: realised floor implies ${A} bps, above cap ${u.capBps} \u2014 refusing to issue a guard weaker than advertised`);return ze({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:c.toString(),minAmountOut:h.toString(),requiredBps:u.requiredBps,selectedBps:u.selectedBps,capBps:u.capBps,quotedAtMs:p,expiresAtMs:p+m},{secret:d})}function Gt(e){let t=String(e||"");if(!/^0x[0-9a-fA-F]+$/.test(t)||t.length<10||t.length%2!==0)return null;let r=t.slice(0,10).toLowerCase(),n=[];for(let o=10;o+64<=t.length;o+=64)n.push(t.slice(o,o+64));let i=o=>n[o]==null?null:BigInt("0x"+n[o]);switch(r){case"0x414bf389":return i(6);case"0x04e45aaf":return i(5);case"0xc04b8d59":{let o=i(0);if(o==null)return null;let a=Number(o)/32;return!Number.isInteger(a)||a<0?null:i(a+4)}case"0xb858183f":{let o=i(0);if(o==null)return null;let a=Number(o)/32;return!Number.isInteger(a)||a<0?null:i(a+3)}case"0xa026383e":return i(6);case"0x38ed1739":case"0x5c11d795":return i(1);case"0x7ff36ab5":case"0xb6f9de95":return i(0);case"0x18cbafe5":case"0x791ac947":return i(1);default:return null}}function N(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:i,priceChange5m:o,crossChain:a,requestedCapBps:s,quotedAtMs:f=Date.now(),ttlMs:l}={}){let d=zt({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:i,priceChange5m:o,crossChain:a,requestedCapBps:s,quotedAtMs:f,ttlMs:l});return{...e,autoSlippage:d,amountOutMinimum:d.minAmountOut}}var Q,He,P=B(()=>{Me();qe();Q=100,He=2e4});var j,J=B(()=>{j="0x000000000000000000000000000000000000dEaD"});import{createHash as Kt,createHmac as Xt,timingSafeEqual as vn}from"node:crypto";function he(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(he).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${he(e[r])}`).join(",")}}`}function Ge(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Ke(e=process.env){return Ge(process.env)||Ge(e)}function Jt(e){let{prepareHash:t,prepareMac:r,note:n,...i}=e||{};return i}function Zt(e){let t=Jt(e);return Kt("sha256").update(he(t)).digest("hex")}function er(e,t=Ke()){return t?Xt("sha256",t).update(String(e)).digest("hex"):""}function O(e,{provider:t,kind:r,env:n=process.env,nowMs:i=Date.now(),expiresAtMs:o}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let a=Object.prototype.hasOwnProperty.call(e,"oraclePrepared");if(a&&typeof e.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let s={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:a?e.oraclePrepared:!0};if(!s.provider)throw new Error("stampPrepared: provider required");if(!s.kind)throw new Error("stampPrepared: kind required");let f=Number(i),l=o==null?f+Qt:Number(o),d=l-f;if(!Number.isSafeInteger(f)||!Number.isSafeInteger(l)||d<=0||d>Wt)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let u={...s,preparedAt:f,expiresAt:l,prepareVersion:Yt},p=Zt(u),m=Ke(n),E=m?er(p,m):void 0,h={...u,prepareHash:p};return E&&(h.prepareMac=E),h}var Yt,Qt,Wt,R=B(()=>{Yt=2,Qt=300*1e3,Wt=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});import{Contract as tr,JsonRpcProvider as rr}from"ethers";function cr(e){return sr.test(String(e||""))}async function Xe(e,{contract:t=nr,rpc:r=ir,chainId:n=or,balanceOf:i}={}){if(!cr(e))throw new Error("invalid-address");if(i)return BigInt(await i(e));let o=new rr(r,n,{staticNetwork:!0}),a=new tr(t,ar,o);return BigInt(await a.balanceOf(e))}var nr,or,ir,ar,sr,Ye=B(()=>{nr="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",or=999,ir="https://rpc.hyperliquid.xyz/evm",ar=["function balanceOf(address owner) view returns (uint256)"],sr=/^0x[a-fA-F0-9]{40}$/});import{existsSync as ur,readFileSync as lr,lstatSync as dr}from"node:fs";import{homedir as Qe}from"node:os";import{join as ge}from"node:path";function mr(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(We,t)?We[t]:fr}function Er(e=process.env){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){if(e[Je])return String(e[Je]);let t=e.ORACLE_CONFIG_DIR||ge(Qe(),".config","oracle");return ge(t,"fee-recipient")}return ge(Qe(),".config","oracle","fee-recipient")}function yr(e=process.env){try{let t=Er(e);if(!ur(t)||dr(t).isSymbolicLink())return"";let r=lr(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function Ar(e,{fallback:t=0}={}){if(e==null)return t;if(String(e).trim()==="")return 0;let r=Number(e);return!Number.isFinite(r)||r<=0?0:Math.min(Math.floor(r),pr)}function xr({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[gr]||"").trim(),i=String(e[wr]||br).trim();if(r===!0)return{bps:0,recipient:"",integrator:i,action:t,applies:!1,reason:"admin-oracle"};let o=mr(t),a=Ar(e[hr],{fallback:n?o:0}),s=Math.min(a,o);if(!s)return{bps:0,recipient:"",integrator:i,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:i,action:t,applies:!1,reason:"no-recipient"};let f=yr(e);return!f||f!==n.toLowerCase()?{bps:0,recipient:"",integrator:i,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:s,recipient:n,integrator:i,action:t,applies:!0,reason:"configured"}}async function we({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:i=!1}={}){let o=xr({env:t,action:r,admin:i});if(i===!0)return{...o,holderVerificationStatus:"admin-oracle"};let a=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(a))return{...o,holderVerificationStatus:"wallet-required"};try{return BigInt(await Xe(a,n))>0n?{...o,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...o,holderVerificationStatus:"non-holder"}}catch{return{...o,holderVerificationStatus:"unavailable"}}}function Ze(e){return e?.applies?`Oracle routing fee ${e.bps} bps (${(e.bps/100).toFixed(2)}%) to ${e.recipient}.`:e?.reason==="admin-oracle"?"No Oracle fee (admin Oracle).":e?.reason==="locals-only-holder"?"No Oracle fee (Locals Only holder).":"No Oracle fee."}function et(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}var pr,fr,We,hr,gr,wr,Je,br,Z=B(()=>{Ye();pr=100,fr=5,We=Object.freeze({swap:5,bridge:5,perps:0,nft:0});hr="ORACLE_INTEGRATOR_FEE_BPS",gr="ORACLE_INTEGRATOR_FEE_RECIPIENT",wr="ORACLE_INTEGRATOR_ID",Je="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",br="oracle"});var nt={};ve(nt,{LIFI_API:()=>rt,lifiChains:()=>kr,lifiHealth:()=>Cr,lifiPrepare:()=>vr,lifiQuote:()=>ee});function Ee(e={}){return(e.baseUrl||process.env.LIFI_API_URL||rt).replace(/\/$/,"")}function Ir(e){let t=String(e||be).toLowerCase();return t===be.toLowerCase()||t===Sr}function tt(e,t){let r=String(e||"").trim();if(!/^0x[0-9a-fA-F]{40}$/.test(r))throw new Error(`lifi: ${t} must be a 20-byte address`);return r.toLowerCase()}async function Cr(e={}){let t=await C(`${Ee(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3}),r=Array.isArray(t)?t.length:t?.chains?.length||0;return{ok:r>0,chainCount:r}}async function ee(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:i=be,toToken:o,fromAmount:a,fromAddress:s=j}=e;if(r==null||!o||!a)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let f=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:i,toToken:o,fromAmount:String(a),fromAddress:s}),l=L({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!l.executable)throw new Error(`lifi: route requires ${l.requiredBps} bps above cap ${l.capBps}`);f.set("slippage",String(l.selectedBps/1e4));let d=await we({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[h,A]of Object.entries(et(d)))f.set(h,A);let c=await C(`${Ee(t)}/quote?${f}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=c?.estimate?.toAmount||c?.toAmount;if(!u)return{...c,autoSlippagePolicy:l,oracleFee:d};let p=c?.transactionRequest?.to||c?.estimate?.approvalAddress||"lifi",m=N(c,{chainId:Number(r),venue:p,amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),E=c?.estimate?.toAmountMin||c?.toAmountMin;if(E!=null&&BigInt(E)<BigInt(m.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...m,oracleFee:d}}async function vr(e={},t={}){let r=await ee(e,t),n=r?.transactionRequest;if(!n?.to||!n?.data)throw new Error("lifi: quote did not return an executable transactionRequest");let i=Number(e.fromChain);if(n.chainId!=null&&Number(n.chainId)!==i)throw new Error("lifi: transaction chain mismatch");if(e.fromAddress&&n.from&&String(n.from).toLowerCase()!==String(e.fromAddress).toLowerCase())throw new Error("lifi: transaction sender mismatch");let o=null;if(!Ir(e.fromToken)){let a=r?.estimate?.approvalAddress||r?.approvalAddress;if(!a)throw new Error("lifi: ERC20 route missing approvalAddress");let s=r?.action?.fromToken?.address||r?.estimate?.fromToken?.address||e.fromToken;o={token:tt(s,"approval token"),spender:tt(a,"approval spender"),amount:String(e.fromAmount)}}return O({provider:"lifi",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:i,quote:r,autoSlippage:r.autoSlippage,requiresApproval:o,transaction:{chainId:i,from:n.from||e.fromAddress,to:n.to,data:n.data,value:n.value??"0x0",...n.gasLimit!=null?{gasLimit:n.gasLimit}:{},slippageGuard:F(r.autoSlippage,{chainId:i,venue:n.to,data:n.data})}},{provider:"lifi",kind:"lifi-tx"})}async function kr(e={}){return C(`${Ee(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3})}var rt,be,Sr,ye=B(()=>{T();P();J();R();Z();rt="https://li.quest/v1";be="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Sr="0x0000000000000000000000000000000000000000"});var te={};ve(te,{ACROSS_API:()=>ct,HOP_API:()=>ut,RELAY_API:()=>lt,acrossHealth:()=>Dr,acrossSuggestedFees:()=>dt,hopHealth:()=>Mr,hopQuote:()=>pt,relayHealth:()=>qr,relayPrepare:()=>Hr,relayQuote:()=>xe});async function Dr(e={}){try{return{ok:!0,estimatedFillTimeSec:(await dt({token:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",destinationToken:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",originChainId:1,destinationChainId:42161,amount:"1000000000000000"},e)).estimatedFillTimeSec}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function dt(e={},t={}){let{token:r,destinationToken:n=r,originChainId:i,destinationChainId:o,amount:a}=e;if(!r||i==null||o==null||!a)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let s=new URLSearchParams({token:r,destinationToken:n,originChainId:String(i),destinationChainId:String(o),amount:String(a)}),f=(t.baseUrl||process.env.ACROSS_API_URL||ct).replace(/\/$/,"");return C(`${f}/suggested-fees?${s}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Mr(e={}){try{let t=await pt({amount:"1000000000000000",token:"ETH",fromChain:"ethereum",toChain:"arbitrum",slippage:.5},e);return{ok:!0,estimatedRecieved:t.estimatedRecieved||t.estimatedReceived}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function pt(e={},t={}){let{amount:r,token:n="ETH",fromChain:i="ethereum",toChain:o="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let a=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),s=L({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:i!==o,requestedCapBps:e.maxSlippageBps??e.slippageBps??a});if(!s.executable)throw new Error(`hop: route requires ${s.requiredBps} bps above cap ${s.capBps}`);let f=new URLSearchParams({amount:String(r),token:n,fromChain:i,toChain:o,slippage:String(s.selectedBps/100)}),l=(t.baseUrl||process.env.HOP_API_URL||ut).replace(/\/$/,""),d=await C(`${l}/quote?${f}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),c=d?.estimatedRecieved||d?.estimatedReceived;return c?N(d,{chainId:Number(e.originChainId||e.chainId||Lr[i]||0),venue:d?.tx?.to||"hop",amountOut:c,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:i!==o,requestedCapBps:e.maxSlippageBps??e.slippageBps??a}):{...d,autoSlippagePolicy:s}}async function qr(e={}){try{let t=await xe({user:j,originChainId:1,destinationChainId:8453,originCurrency:"0x0000000000000000000000000000000000000000",destinationCurrency:"0x0000000000000000000000000000000000000000",amount:"1000000000000000",tradeType:"EXACT_INPUT"},e);return{ok:!0,hasSteps:Array.isArray(t.steps),stepCount:t.steps?.length||0}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function xe(e={},t={}){let{user:r=j,originChainId:n,destinationChainId:i,originCurrency:o="0x0000000000000000000000000000000000000000",destinationCurrency:a="0x0000000000000000000000000000000000000000",amount:s,tradeType:f="EXACT_INPUT"}=e;if(n==null||i==null||!s)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let l=L({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(i),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!l.executable)throw new Error(`relay: route requires ${l.requiredBps} bps above cap ${l.capBps}`);let d=(t.baseUrl||process.env.RELAY_API_URL||lt).replace(/\/$/,""),c=await C(`${d}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(i),originCurrency:o,destinationCurrency:a,amount:String(s),tradeType:f,slippageTolerance:String(l.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=c?.details?.currencyOut?.amount;return!u||!/^\d+$/.test(String(u))?{...c,autoSlippagePolicy:l}:N(c,{chainId:Number(n),venue:c?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(i),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function Hr(e={},t={}){let r=await xe(e,t),n=Number(e.originChainId),i=(r.steps||[]).flatMap(s=>(s.items||[]).filter(f=>f?.data?.to&&f?.data?.data).map(f=>({stepId:s.id,...f.data})));if(!i.length)throw new Error("relay: quote returned no executable transaction items");let o=String(r?.autoSlippage?.venue||"").toLowerCase();if(i.some(s=>String(s.to).toLowerCase()!==o))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let a=i.map(s=>({chainId:n,from:s.from||e.user,to:s.to,data:s.data,value:s.value??"0x0",...s.gasLimit!=null||s.gas!=null?{gasLimit:s.gasLimit??s.gas}:{},slippageGuard:F(r.autoSlippage,{chainId:n,venue:s.to,data:s.data})}));return O({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:a},{provider:"relay",kind:"relay-tx"})}var ct,ut,lt,Lr,re=B(()=>{T();P();J();R();ct="https://across.to/api",ut="https://api.hop.exchange/v1",lt="https://api.relay.link",Lr={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var en=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),tn=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),rn=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var U=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"});var ke=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}};function Oe(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:i=null,feeUsd:o=null,oracleFeeBps:a=0,estimatedGas:s=null,liquidityUsd:f=null,error:l=null,executionReady:d=!1,meta:c={}}=e||{};if(l||r==null)return{source:t,quality:U.FAILED,amountOut:null,error:l||"no amountOut returned"};let u=ke(r);if(u==null||u<=0n)return{source:t,quality:U.FAILED,amountOut:null,error:"non-positive amountOut"};let p=Number(a);return{source:t,quality:i==null?U.NO_GAS:U.FULL,amountOut:u.toString(),minOut:ke(n)?.toString()??null,gasUsd:i,feeUsd:o,oracleFeeBps:Number.isFinite(p)&&p>0?Math.floor(p):0,estimatedGas:s==null?null:String(s),liquidityUsd:f==null?null:Number(f),executionReady:d,meta:c}}function _e(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:i=50,gasPriceWei:o=null,nativePriceUsd:a=null}={}){let s=e.filter(g=>g.quality!==U.FAILED),f=e.filter(g=>g.quality===U.FAILED),l=t!=null&&t>0&&r!=null&&r>=0,d=Number(o),c=Number(a),u=Number.isFinite(d)&&d>0&&Number.isFinite(c)&&c>0,p=s.map(g=>{let y=BigInt(g.amountOut),_=0n,v=!1,k=!1,V=BigInt(g.oracleFeeBps??0),Se=V>0n?y*V/10000n:0n;if(l){let K=g.gasUsd,oe=Number(g.meta?.gasUnits??g.estimatedGas);if(K==null&&u&&Number.isFinite(oe)&&oe>0){let q=oe*d/1e18*c;Number.isFinite(q)&&q>=0&&(K=q,k=!0)}let Ce=(K??0)+(g.feeUsd??0);if(Ce>0){let q=Ce/t*10**r;Number.isFinite(q)&&q>=0&&(_=BigInt(Math.floor(q)),v=!0)}else K===0&&(v=!0)}let Ie=_+Se,wt=y>Ie?y-Ie:0n;return{...g,grossOut:y.toString(),netOut:wt.toString(),costInDest:_.toString(),oracleFeeInDest:Se.toString(),costAccounted:v,gasEstimated:k}}),m=Number(i)>0?Number(i):0,E=p.reduce((g,y)=>BigInt(y.netOut)>g?BigInt(y.netOut):g,0n),h=g=>E>0n?Number((E-BigInt(g))*10000n/E):0,A=[],w=p.slice().sort((g,y)=>BigInt(y.netOut)>BigInt(g.netOut)?1:-1)[0]??null;p.sort((g,y)=>{let _=h(g.netOut)<=m?0:1,v=h(y.netOut)<=m?0:1;if(n&&m>0&&_!==v)return _-v;if(n&&m>0){let k=g.liquidityUsd??-1,V=y.liquidityUsd??-1;if(k!==V)return V-k}return BigInt(y.netOut)>BigInt(g.netOut)?1:-1}),n&&m>0&&w&&p[0]&&p[0].source!==w.source&&A.push(`liquidity-first: chose ${p[0].source} (liquidity $${p[0].liquidityUsd??"unknown"}) over best-price ${w.source} within ${m} bps`);let I=p.filter(g=>!g.costAccounted).map(g=>g.source);l?I.length&&A.push(`gas not reported by: ${I.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):A.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let x=p[0];if(l&&x&&x.costAccounted===!1){let g=p.find(y=>y.costAccounted&&h(y.netOut)<=m);g&&A.push(`winner ${x.source} has UNMEASURED gas; gas-measured ${g.source} is within ${m} bps and may net more once ${x.source}'s real gas is paid \u2014 prefer it if unsure.`)}let b=p.filter(g=>g.gasEstimated).map(g=>g.source);b.length&&A.push(`gas ESTIMATED (from gas units x current gas price, not measured) for: ${b.join(", ")}. Net includes this estimate so the ranking is gas-inclusive, but the on-chain gas may differ.`);let S=null,$=null;if(p.length>=2&&p[0].costAccounted&&p[1].costAccounted){let g=BigInt(p[0].netOut),y=BigInt(p[1].netOut);y>0n&&(S=Number((g-y)*10000n/y),$=`${p[0].source} vs ${p[1].source}`)}return{best:p[0]??null,routes:p,failed:f,improvementBps:S,spreadBasis:$,rankedOn:l?"net-of-cost":"gross",warnings:A}}async function Be(e,{timeoutMs:t=12e3}={}){let r=(i,o)=>Promise.race([i,new Promise((a,s)=>setTimeout(()=>s(new Error(`${o}: timeout`)),t))]);return(await Promise.allSettled(e.map(i=>r(Promise.resolve().then(i.run),i.source)))).map((i,o)=>{let a=e[o].source;return i.status==="rejected"?Oe({source:a,error:String(i.reason?.message||i.reason)}):Oe({source:a,...i.value})})}ye();T();P();R();Z();T();P();R();T();P();R();T();P();import{TypedDataEncoder as uo,getAddress as lo,isAddress as po}from"ethers";var oo=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});J();R();var Eo=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),yo=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"});var Ao=Object.freeze({Order:[{name:"sellToken",type:"address"},{name:"buyToken",type:"address"},{name:"receiver",type:"address"},{name:"sellAmount",type:"uint256"},{name:"buyAmount",type:"uint256"},{name:"validTo",type:"uint32"},{name:"appData",type:"bytes32"},{name:"feeAmount",type:"uint256"},{name:"kind",type:"string"},{name:"partiallyFillable",type:"bool"},{name:"sellTokenBalance",type:"string"},{name:"buyTokenBalance",type:"string"}]}),xo=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});import{Interface as it,getAddress as Do,isAddress as Mo}from"ethers";T();var ot={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Io=new Map(Object.values(ot).map(e=>[e.chainId,e]));import{Interface as Br,getAddress as To}from"ethers";var Ro=new Br(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);T();var Uo=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});P();R();var zo=new it(["function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)","function quoteExactInput(bytes path, uint256 amountIn) returns (uint256 amountOut, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)"]),Go=new it(["function exactInputSingle((address tokenIn,address tokenOut,uint24 fee,address recipient,uint256 amountIn,uint256 amountOutMinimum,uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)","function multicall(uint256 deadline,bytes[] data) payable returns (bytes[] results)"]);import{AbiCoder as Rr,Interface as at,getAddress as Qo,isAddress as Wo,keccak256 as Jo}from"ethers";P();R();var ni=Rr.defaultAbiCoder();var oi=new at(["function quoteExactInputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountOut, uint256 gasEstimate)","function quoteExactOutputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountIn, uint256 gasEstimate)"]),ii=new at(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);T();var $r="https://coins.llama.fi",Pr="https://api.llama.fi";function Ur(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||$r).replace(/\/$/,"")}function Fr(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||Pr).replace(/\/$/,"")}async function Ae(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return C(`${Ur(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function st(e={}){return C(`${Fr(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var M=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function ft(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let i=M(n?.amountUSD);i!=null&&(t+=i,r=!0)}return r?t:null}var D=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),mt=Object.freeze({across:["across"],relay:["relaychain","relay"],lifi:["jumper-(li.fi-powered)","lifi"],stargate:["stargate-v2","stargate-v1","stargate"],hop:["hop-protocol","hop"],debridge:["debridge"],synapse:["synapse"],connext:["connext"],cbridge:["celer-bridge","celer-cbridge","cbridge"],celer:["celer-bridge","celer-cbridge","cbridge"],squid:["squid"],symbiosis:["symbiosis"],wormhole:["wormhole"],mayan:["mayan"],allbridge:["allbridge"],thorchain:["thorchain"]});async function jr(e={}){try{let t=await st({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function Vr(e,t={}){let r=D(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...mt[r]||[r]),n.push(...mt[D(e)]||[e]),n}function zr(e,t,r={}){let n=Array.isArray(e)?e:[],i=Vr(t,r).map(D).filter(Boolean);for(let o of i){let a=n.find(f=>D(f?.slug)===o||D(f?.name)===o),s=M(a?.tvl);if(s!=null)return{liquidityUsd:s,protocol:a?.name??a?.slug??o}}for(let o of i){let a=n.find(f=>{let l=D(f?.category);return!l.includes("bridge")&&!l.includes("crosschain")?!1:D(f?.slug).includes(o)||D(f?.name).includes(o)}),s=M(a?.tvl);if(s!=null)return{liquidityUsd:s,protocol:a?.name??a?.slug??o}}return null}function ht({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:i,taker:o,opts:a={}}){let s=[],f=null,l=async(d,c={})=>(f||=jr(a),zr(await f,d,c));return s.push({source:"lifi",run:async()=>{let d=await ee({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:i},a),c=d?.estimate??d?.[0]?.estimate,u={tool:d?.tool??d?.toolDetails?.name,durationSeconds:M(c?.executionDuration)},p=await l("lifi",u);return{amountOut:c?.toAmount,minOut:c?.toAmountMin,gasUsd:ft(c?.gasCosts),feeUsd:ft(c?.feeCosts),oracleFeeBps:d?.oracleFee?.applies?d.oracleFee.bps:0,liquidityUsd:p?.liquidityUsd??null,meta:{...u,liquidityProtocol:p?.protocol,oracleFee:d?.oracleFee??null}}}}),s.push({source:"relay",run:async()=>{let{relayQuote:d}=await Promise.resolve().then(()=>(re(),te)),u=(await d({user:o,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(i)},a))?.details,p={durationSeconds:M(u?.timeEstimate),rate:u?.rate},m=await l("relay",p);return{amountOut:u?.currencyOut?.amount,minOut:u?.currencyOut?.minimumAmount,gasUsd:M(u?.totalImpact?.usd)!=null?Math.abs(M(u.totalImpact.usd)):null,liquidityUsd:m?.liquidityUsd??null,meta:{...p,liquidityProtocol:m?.protocol}}}}),s.push({source:"across",run:async()=>{let{acrossSuggestedFees:d}=await Promise.resolve().then(()=>(re(),te)),c=await d({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(i)},a),u=c?.totalRelayFee?.total,p=null;if(u!=null)try{let E=BigInt(String(i))-BigInt(String(u));E>0n&&(p=E.toString())}catch{}let m=await l("across");return{amountOut:p,gasUsd:null,liquidityUsd:m?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:M(c?.estimatedFillTimeSec),limits:c?.limits?{min:c.limits.minDeposit,max:c.limits.maxDeposit}:void 0,liquidityProtocol:m?.protocol}}}}),s}Z();var Gr={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function Kr(e,t,r){let n=Gr[Number(e)];if(!n)return{priceUsd:null,decimals:null};let i=`${n}:${t}`;try{let a=(await Ae([i],r))?.coins?.[i],s=Number(a?.price),f=Number(a?.decimals);return{priceUsd:Number.isFinite(s)?s:null,decimals:Number.isFinite(f)?f:null}}catch{return{priceUsd:null,decimals:null}}}async function gt(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:i,tokenOut:o,amountIn:a}=e;if(r==null||n==null||!i||!o||a==null)throw new Error("bestBridgeRoute requires fromChainId, toChainId, tokenIn, tokenOut, amountIn");if(Number(r)===Number(n))throw new Error("bestBridgeRoute is for cross-chain; use bestSwapRoute for same-chain");let s=Kr(n,o,t),f=ht({...e,opts:t}),[l,d]=await Promise.all([Be(f,{timeoutMs:t.timeoutMs??15e3}),s]),c=_e(l,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals,liquidityBandBps:t.liquidityBandBps??50}),u=c.routes.map(p=>({source:p.source,seconds:p.meta?.durationSeconds??null})).filter(p=>p.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:i,tokenOut:o,amountIn:String(a),...c,durations:u,sourcesTried:f.length,sourcesAnswered:l.filter(p=>p.quality!==U.FAILED).length,note:Yr(c,f.length)}}function Xr(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Ze(t)}`:""}function Yr(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=Xr(e.best);if(r===1)return`only 1 of ${t} sources answered, so this is the ONLY route, not a proven best one. Treat it as unbenchmarked.`+n;if(e.improvementBps!=null){let i=e.improvementBps,o=i/100;if(i<.01)return`best of ${r} routes, ranked on ${e.rankedOn}: effectively tied with the runner-up (${e.spreadBasis}), inside quote noise. Re-quote before you size up.`+n;let a=o>=.01?`${o.toFixed(2)}%`:`${i.toFixed(2)}bps`;return`best of ${r} routes, ranked on ${e.rankedOn}: ${a} better than the runner-up (${e.spreadBasis})`+n}return`best of ${r} routes, ranked on ${e.rankedOn}. No spread quoted: the top routes report cost differently, so the margin is not comparable.`+n}R();var Qr=/^0x[0-9a-fA-F]{40}$/,Wr=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),Jr=100,ne={relay:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:i,taker:o},a)=>{let{relayPrepare:s}=await Promise.resolve().then(()=>(re(),te)),f=await s({user:o,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(i)},a);return{transactions:f.transactions||[],amountOut:f.quote?.details?.currencyOut?.amount??null,minOut:f.quote?.details?.currencyOut?.minimumAmount??null,durationSeconds:f.quote?.details?.timeEstimate??null}},lifi:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:i,taker:o,isHolder:a},s)=>{let{lifiPrepare:f}=await Promise.resolve().then(()=>(ye(),nt)),l=await f({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:i,fromAddress:o,isHolder:a,feeAction:"bridge"},s);return{transactions:l.transaction?[l.transaction]:[],requiresApproval:l.requiresApproval??null,amountOut:l.quote?.estimate?.toAmount??null,minOut:l.quote?.estimate?.toAmountMin??null,durationSeconds:l.quote?.estimate?.executionDuration??null}}};function Gi(){return Object.keys(ne)}async function Ki(e,t={}){let{taker:r,fromChainId:n,toChainId:i}=e;if(!r)throw new Error("prepareBestBridgeRoute requires taker: bridge transactions are built FOR an address, and the quote-only placeholder must never end up in one");if(!Qr.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(Wr.has(r.toLowerCase()))throw new Error(`taker "${r}" is a placeholder/burn address. Bridging to it would send funds to an address nobody controls, on a chain where you cannot undo it.`);let o=await gt(e,t);if(!o.best)return{ok:!1,reason:"no source returned a usable bridge route",comparison:o};let a=e.source||o.best.source,s=o.routes.find(h=>h.source===a);if(!s)return{ok:!1,reason:`source "${a}" returned no usable route`,comparison:o};let f=ne[a];if(!f){let h=o.routes.find(A=>ne[A.source]&&A.source!==a);return{ok:!1,reason:`${a} won the comparison but has no bridge prepare path in this build. `+(h?`Next preparable route is ${h.source}; pass source:"${h.source}".`:"No route in this comparison can be prepared."),failureKind:"no-prepare-path",...h?{alternative:h.source}:{},winner:a,comparison:o}}let l;try{l=await f(e,t)}catch(h){let A=typeof h?.body=="string"?h.body:h?.body?JSON.stringify(h.body):"",w=[String(h?.message||h),A].filter(Boolean).join(" :: "),I=/allowance/i.test(w),x=!I&&/not enough|insufficient|balance/i.test(w),b=o.routes.find(S=>ne[S.source]&&S.source!==a);return{ok:!1,reason:I?`${a} will not build calldata until the token approval exists on-chain. Approve first, then prepare again. Underlying: ${w}`:x?`${a} refused to build: ${w}. Quoting works for any address; preparing needs the real funded wallet on chain ${n}.`:`${a} bridge prepare failed: ${w}`,failureKind:I?"approval-required-first":x?"taker-not-funded":"provider-error",...b?{alternative:b.source}:{},comparison:o}}let d=l.transactions||[];if(!d.length)return{ok:!1,reason:`${a} returned no executable transaction for this route`,failureKind:"provider-error",comparison:o};let c=d.filter(h=>h.chainId!=null&&Number(h.chainId)!==Number(n));if(c.length)return{ok:!1,reason:`${a} returned a transaction for chain ${c[0].chainId} but the origin chain is ${n}. Refusing to hand over a mismatched artifact.`,failureKind:"chain-mismatch",comparison:o};let u=e.driftToleranceBps??Jr,p=null,m=null;if(l.amountOut!=null&&s.grossOut!=null)try{let h=BigInt(s.grossOut),A=BigInt(l.amountOut);h>0n&&(p=Number((A-h)*10000n/h),p<-u&&(m=`route moved ${(p/100).toFixed(2)}% against you since the comparison (tolerance ${(u/100).toFixed(2)}%). Re-compare before signing.`))}catch{}let E=[...m?[m]:[],...o.warnings||[],`Bridging is NOT atomic: the origin transaction succeeding does not mean funds arrived on chain ${i}. Expect ~${l.durationSeconds!=null?`${l.durationSeconds}s`:"minutes"} before the destination credits, and do not re-send if it is pending.`];return d.length>1&&E.push(`This route needs ${d.length} transactions signed IN ORDER. Signing only the first leaves funds approved but not bridged.`),O({ok:!0,chosen:{source:a,wasWinner:a===o.best.source,netOut:s.netOut,grossOut:s.grossOut,gasUsd:s.gasUsd},artifactKind:"unsigned-transaction-sequence",fromChainId:Number(n),toChainId:Number(i),transactionCount:d.length,transactions:d,requiresApproval:l.requiresApproval??null,minOut:l.minOut??null,durationSeconds:l.durationSeconds??null,destination:d[0]?.to??null,unsigned:!0,signedBy:"user-wallet",driftBps:p,warnings:E,runnersUp:o.routes.filter(h=>h.source!==a).map(h=>({source:h.source,netOut:h.netOut,gasUsd:h.gasUsd})),comparison:{rankedOn:o.rankedOn,sourcesAnswered:o.sourcesAnswered,sourcesTried:o.sourcesTried,improvementBps:o.improvementBps},note:`UNSIGNED. ${d.length} transaction(s) on chain ${n}, crediting chain ${i}. Verify every destination address before signing.`},{provider:"router",kind:"best-bridge"})}export{Ki as prepareBestBridgeRoute,Gi as supportedBridgePreparers};
|
package/package.json
CHANGED