@oracle-agent/oracle 0.22.16 → 0.23.0

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.
@@ -0,0 +1 @@
1
+ function b(t,e="amount"){if(typeof t=="bigint")return t;if(typeof t=="number"){if(!Number.isInteger(t))throw new Error(`${e} must be an integer`);if(!Number.isSafeInteger(t))throw new Error(`${e} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return BigInt(t)}let r=String(t??"").trim();if(r==="")throw new Error(`${e} is required`);if(!/^-?\d+$/.test(r)&&!/^0x[0-9a-fA-F]+$/.test(r))throw new Error(`${e} must be an integer in decimal or 0x-hex form, got ${JSON.stringify(r)}`);try{return BigInt(r)}catch{throw new Error(`${e} must be an integer, got ${JSON.stringify(r)}`)}}var P=1,o=Object.freeze({BUY:"BUY",PASS:"PASS",NO_TRADE:"NO_TRADE"}),U=Object.freeze(["reveal","repriced","reprice","price_drop","relisted"]),C=10000n,j=Object.freeze({minTraitSales:3,minTraitVolumeWei:"1000000000000000000",minVolumeCoverage:3,minEdgeBps:1200,minEdgeBpsWithoutEvent:2e3,maxPremiumOverCollectionFloorBps:5e3,maxListingAgeMs:900*1e3,maxEventAgeMs:1800*1e3,maxMarketDataAgeMs:3600*1e3,maxTraitWindowHours:72,marketplaceFeeBps:250,royaltyBps:500,maxSpendWei:null});function I(t,e,r,{positive:i=!0,allowZero:s=!1}={}){if(t==null||t==="")return r.push(`${e}: missing`),null;let n;try{n=b(t,e)}catch(l){return r.push(`${e}: ${String(l?.message||l)}`),null}return n<0n?(r.push(`${e}: must not be negative`),null):i&&!s&&n===0n?(r.push(`${e}: must be positive`),null):n}function re(t,e,r){if(t==null||t==="")return r.push(`${e}: missing`),null;let i=Number(t);return!Number.isInteger(i)||i<0?(r.push(`${e}: must be a non-negative integer`),null):i}function E(t){let e=Number(t);return Number.isFinite(e)?e:null}function c(...t){for(let e of t)if(e!=null&&e!=="")return e;return null}function q(t,e){return e==null||e===0n?null:Number(t*C/e)}function ie(t){let e=E(c(t?.rarityPct,t?.rarity_pct));if(e!=null&&e>0)return Math.round(e*100);let r=E(c(t?.traitSupply,t?.supply,t?.count)),i=E(c(t?.collectionSupply,t?.totalSupply));return r!=null&&i!=null&&r>0&&i>0?Math.round(r/i*1e4):null}function ne(t={}){let e={...j,...t||{}},r=Number(e.marketplaceFeeBps)||0,i=Number(e.royaltyBps)||0;if(r<0||i<0||r+i>=1e4)throw new Error("trait sniper: marketplaceFeeBps + royaltyBps must be >= 0 and < 10000");return e}function d(t,e,r,i={}){return{ok:t===o.BUY,decision:t,failureKind:e,reasons:r,version:P,executed:!1,signed:!1,broadcast:!1,requiresUserSignature:!0,...i}}function G(t={}){let e;try{e=ne(t.policy)}catch(y){return d(o.NO_TRADE,"bad-policy",[String(y?.message||y)])}let r=Number.isFinite(Number(t.nowMs))?Number(t.nowMs):Date.now(),i=t.listing||{},s=t.trait||{},n=t.traitMarket||t.traitStats||{},l=t.collectionMarket||t.collection||{},p={chainId:E(c(t.chainId,i.chainId))??null,contract:String(c(t.contract,t.collectionAddress,i.contract,"")||"")||null,tokenId:String(c(i.tokenId,t.tokenId,"")||"")||null,marketplace:String(c(i.marketplace,i.source,"")||"")||null,trait:{type:String(c(s.type,s.traitType,"")||"")||null,value:String(c(s.value,s.traitValue,"")||"")||null,rarityBps:ie(s)}},u=[],a=I(c(i.priceWei,i.price),"listing.priceWei",u),S=I(c(n.floorPriceWei,n.floorWei),"traitMarket.floorPriceWei",u),g=I(c(n.volumeWei,n.volume),"traitMarket.volumeWei",u,{allowZero:!0}),w=I(c(l.floorPriceWei,l.floorWei),"collectionMarket.floorPriceWei",u),$=re(c(n.sales,n.salesCount),"traitMarket.sales",u),A=E(c(n.windowHours,n.window_hours));if((A==null||A<=0)&&u.push("traitMarket.windowHours: missing"),u.length)return d(o.NO_TRADE,"insufficient-data",[`missing or unusable market data \u2014 ${u.join("; ")}`],{identity:p,dataGaps:u,liquidity:null,edge:null});if(A>e.maxTraitWindowHours)return d(o.NO_TRADE,"window-too-wide",[`trait stats aggregate ${A}h > maxTraitWindowHours ${e.maxTraitWindowHours}h \u2014 not recent liquidity`],{identity:p,dataGaps:[],liquidity:null,edge:null});let D=E(c(n.observedAtMs,n.asOfMs,l.observedAtMs));if(D==null)return d(o.NO_TRADE,"insufficient-data",["missing or unusable market data \u2014 traitMarket.observedAtMs: missing"],{identity:p,dataGaps:["traitMarket.observedAtMs: missing"],liquidity:null,edge:null});let M=r-D;if(M>e.maxMarketDataAgeMs)return d(o.NO_TRADE,"stale-market-data",[`market snapshot is ${M}ms old > maxMarketDataAgeMs ${e.maxMarketDataAgeMs}ms`],{identity:p,marketAgeMs:M,liquidity:null,edge:null});if(i.flagged===!0||i.reported===!0)return d(o.NO_TRADE,"listing-flagged",["listing is flagged/reported by the marketplace \u2014 a cheap flagged token is cheap for a reason"],{identity:p,liquidity:null,edge:null});let z=g>=a*BigInt(Math.max(0,Math.trunc(e.minVolumeCoverage))),R=b(e.minTraitVolumeWei??0,"policy.minTraitVolumeWei"),N={sales:$,minSales:e.minTraitSales,volumeWei:g.toString(),minVolumeWei:R.toString(),windowHours:A,coverageX:a===0n?null:Number(g/a),minCoverageX:e.minVolumeCoverage,illiquid:!1},x=[];if($<e.minTraitSales&&x.push(`only ${$} trait sale(s) in ${A}h, need ${e.minTraitSales}`),g<R&&x.push(`trait volume ${g} wei below minTraitVolumeWei ${R} wei`),z||x.push(`trait volume ${g} wei does not cover ${e.minVolumeCoverage}x the ${a} wei listing \u2014 no exit depth`),x.length){N.illiquid=!0;let y=p.trait.rarityBps;return y!=null&&y<=100&&x.push(`trait is rare (${y} bps of supply) but rarity is ranking-only \u2014 an unsold rare trait is an illiquid bag, not an edge`),d(o.NO_TRADE,"illiquid-trait",x,{identity:p,liquidity:N,edge:null,marketAgeMs:M})}let W=String(c(t.event?.kind,t.event?.type,i.eventKind,"")||"").toLowerCase(),V=E(c(t.event?.atMs,i.eventAtMs)),v=V==null?null:r-V,k=U.includes(W)&&v!=null&&v>=0&&v<=e.maxEventAgeMs,_=k?e.minEdgeBps:e.minEdgeBpsWithoutEvent,Q=BigInt(Math.trunc(e.marketplaceFeeBps)),Z=BigInt(Math.trunc(e.royaltyBps)),H=S*(C-Q-Z)/C,O=H-a,ee=q(S-a,S),B=q(a-w,w),T=q(O,a),te={listingPriceWei:a.toString(),traitFloorWei:S.toString(),collectionFloorWei:w.toString(),netExitWei:H.toString(),edgeWei:O.toString(),edgeBps:T,requiredEdgeBps:_,discountToTraitFloorBps:ee,premiumToCollectionFloorBps:B,feeBps:e.marketplaceFeeBps,royaltyBps:e.royaltyBps,triggered:k,eventKind:W||null,eventAgeMs:v},h={identity:p,liquidity:N,edge:te,marketAgeMs:M},L=E(c(i.listedAtMs,i.listedAt)),m=L==null?null:r-L;if(i.stale===!0)return d(o.PASS,"listing-stale",["listing is marked stale by the caller"],h);if(m==null)return d(o.NO_TRADE,"insufficient-data",["missing or unusable market data \u2014 listing.listedAtMs: missing"],{...h,dataGaps:["listing.listedAtMs: missing"]});if(m<0)return d(o.NO_TRADE,"listing-in-future",[`listing.listedAtMs is ${-m}ms in the future`],h);if(m>e.maxListingAgeMs)return d(o.PASS,"listing-stale",[`listing is ${m}ms old > maxListingAgeMs ${e.maxListingAgeMs}ms \u2014 the mispricing is not live`],{...h,listingAgeMs:m});if(e.maxSpendWei!=null&&e.maxSpendWei!==""){let y=b(e.maxSpendWei,"policy.maxSpendWei");if(a>y)return d(o.PASS,"spend-cap",[`listing ${a} wei exceeds maxSpendWei ${y} wei`],{...h,listingAgeMs:m})}return a>=S?d(o.PASS,"no-discount",[`listing ${a} wei is at or above the trait floor ${S} wei`],{...h,listingAgeMs:m}):B!=null&&B>e.maxPremiumOverCollectionFloorBps?d(o.PASS,"collection-floor-premium",[`listing sits ${B} bps over the collection floor > maxPremiumOverCollectionFloorBps ${e.maxPremiumOverCollectionFloorBps} bps`],{...h,listingAgeMs:m}):O<=0n||T==null||T<_?d(o.PASS,"edge-below-threshold",[`net edge ${T??0} bps after ${e.marketplaceFeeBps}+${e.royaltyBps} bps costs is below the ${_} bps required${k?"":" without a reveal/reprice trigger"}`],{...h,listingAgeMs:m}):d(o.BUY,null,[`${$} trait sale(s) and ${g} wei of volume in ${A}h clear the liquidity gate`,`net edge ${T} bps vs trait floor after ${e.marketplaceFeeBps}+${e.royaltyBps} bps costs, required ${_} bps`,k?`${W} event ${v}ms ago explains the mispricing`:"no trigger event \u2014 cleared the higher untriggered bar"],{...h,listingAgeMs:m})}function oe(t=[],e={}){if(!Array.isArray(t))throw new TypeError("scanTraitListings: listings array required");let r=t.map((n,l)=>{let p={...e,...n,policy:{...e.policy||{},...n?.policy||{}}},u=G(p);return{index:l,...u}}),i=r.filter(n=>n.decision===o.BUY),s=[...i].sort((n,l)=>{let p=(l.edge?.edgeBps??0)-(n.edge?.edgeBps??0);if(p!==0)return p;let u=n.identity?.trait?.rarityBps??Number.MAX_SAFE_INTEGER,a=l.identity?.trait?.rarityBps??Number.MAX_SAFE_INTEGER;return u!==a?u-a:n.index-l.index});return{evaluated:r,ranked:s,counts:{total:r.length,buy:i.length,pass:r.filter(n=>n.decision===o.PASS).length,noTrade:r.filter(n=>n.decision===o.NO_TRADE).length},executed:!1,signed:!1,broadcast:!1}}import{createHash as se,createHmac as ae,timingSafeEqual as Ae}from"node:crypto";var ce=2,le=300*1e3,we=(()=>{let t=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(t)&&t>0?t:1800*1e3})();function F(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(F).join(",")}]`:`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${F(t[r])}`).join(",")}}`}function Y(t){let e=String(t?.ORACLE_STAMP_HMAC_SECRET||"").trim();return e.length>=16?e:""}function X(t=process.env){return Y(process.env)||Y(t)}function ue(t){let{oraclePrepared:e,prepareHash:r,prepareMac:i,note:s,...n}=t||{};return n}function pe(t){let e=ue(t);return se("sha256").update(F(e)).digest("hex")}function de(t,e=X()){return e?ae("sha256",e).update(String(t)).digest("hex"):""}function J(t,{provider:e,kind:r,env:i=process.env}={}){if(!t||typeof t!="object")throw new Error("stampPrepared: payload object required");let s={...t,provider:t.provider||e,kind:t.kind||r,requiresUserSignature:t.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!s.provider)throw new Error("stampPrepared: provider required");if(!s.kind)throw new Error("stampPrepared: kind required");let n=Date.now(),l=n+le,u={...s,preparedAt:n,expiresAt:l,prepareVersion:ce},a=pe(u),S=X(i),g=S?de(a,S):void 0,w={...u,oraclePrepared:!0,prepareHash:a};return g&&(w.prepareMac=g),w}var me=/^0x[0-9a-fA-F]{40}$/,ge=10000n,f=class extends Error{constructor(e,r){super(e),this.name="TraitSnipePrepareError",this.failureKind=r}};function K(t={}){let e=t.verdict;if(!e||typeof e!="object")throw new f("prepareTraitSnipeCandidate: verdict object required","verdict-required");if(e.decision!==o.BUY||e.ok!==!0)throw new f(`prepareTraitSnipeCandidate: refusing to prepare a ${e.decision||"unknown"} verdict \u2014 only BUY is preparable`,"not-a-buy");if(!e.edge||!e.liquidity||e.liquidity.illiquid===!0)throw new f("prepareTraitSnipeCandidate: verdict is missing its edge/liquidity evidence","evidence-required");let r=String(t.buyer||"").trim();if(!me.test(r))throw new f("prepareTraitSnipeCandidate: buyer must be a 0x EVM address \u2014 Oracle never derives it from a key","buyer-required");let i=e.identity||{};if(!i.contract||!i.tokenId)throw new f("prepareTraitSnipeCandidate: verdict identity needs contract and tokenId","identity-required");let s=Number(i.chainId);if(!Number.isInteger(s)||s<=0)throw new f("prepareTraitSnipeCandidate: chainId required","chain-required");let n=b(e.edge.listingPriceWei,"listingPriceWei"),l=BigInt(Math.max(0,Math.trunc(Number(t.maxSlippageBps??0))));if(l>1000n)throw new f("prepareTraitSnipeCandidate: maxSlippageBps is capped at 1000","slippage-cap");let p=n+n*l/ge;return J({provider:"nft-trait-sniper",kind:"nft-trait-snipe-intent",traitSniperVersion:P,chainId:s,contract:i.contract,tokenId:i.tokenId,marketplace:i.marketplace,trait:i.trait,buyer:r,intent:{action:"nft-buy-listing",chainId:s,contract:i.contract,tokenId:i.tokenId,marketplace:i.marketplace,listingPriceWei:n.toString(),maxPriceWei:p.toString(),maxSlippageBps:Number(l),buyer:r},transaction:null,calldata:null,decision:e.decision,reasons:e.reasons,liquidity:e.liquidity,edge:e.edge,requiresUserSignature:!0,requiresExternalFillRoute:!0,marketplaceContacted:!1,orderSubmitted:!1,note:"Unsigned intent metadata only. Oracle did not contact a marketplace, build fill calldata, sign, or broadcast. A user-controlled client must source the order and the user must sign it."},{provider:"nft-trait-sniper",kind:"nft-trait-snipe-intent"})}function fe(t={},e={}){let r=Array.isArray(t.ranked)?t.ranked[0]:null;return r?{candidate:K({...e,verdict:r}),verdict:r}:{candidate:null,verdict:null}}export{j as DEFAULT_TRAIT_SNIPE_POLICY,o as TRAIT_DECISIONS,P as TRAIT_SNIPER_VERSION,U as TRIGGER_EVENTS,f as TraitSnipePrepareError,G as evaluateTraitListing,fe as prepareTopTraitSnipe,K as prepareTraitSnipeCandidate,oe as scanTraitListings};
@@ -1,2 +1,2 @@
1
1
  var yt=Object.defineProperty;var P=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var At=(e,t)=>{for(var r in t)yt(e,r,{get:t[r],enumerable:!0})};import{createHash as xt}from"node:crypto";function vt(e){let t=String(e||"").toLowerCase();return xe.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function kt(e){let t={};for(let[r,n]of Object.entries(e||{}))vt(r)||(t[r]=n);return t}function _t(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 Ot(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Rt(e,t,r){let n={};for(let[i,d]of Object.entries(r||{}))n[i.toLowerCase()]=d;let o=Object.keys(n).filter(i=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(i)),u=[...new Set([...xe,...o])].sort().map(i=>`${i}=${n[i]??""}`).join(`
2
- `),c=xt("sha256").update(u).digest("hex").slice(0,32);return`${e} ${t} ${c}`}function Tt(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ye):Math.min(250*2**e,ye)+Math.floor(Math.random()*100)}async function Nt(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s}){let u=new AbortController,c=setTimeout(()=>u.abort(),s);try{let i=String(e),d={...n||{}};for(let p=0;p<=Ae;p+=1){let l=await t(i,{method:r,headers:d,body:o,signal:u.signal,redirect:"manual"}),a=await l.text(),m=null;if(a)try{m=JSON.parse(a)}catch{m=null}if(Ct.has(l.status)){if(r!=="GET"&&r!=="HEAD"){let w=new Error(`HTTP ${l.status} ${r} ${i} redirected non-idempotent request`);throw w.status=l.status,w.body=m??a.slice(0,300),w}if(p===Ae)throw new Error(`HTTP redirect loop for ${e}`);let h=_t(l.headers?.get?.("location"),i);Ot(h,i)||(d=kt(d)),i=h;continue}if(!l.ok){let h=new Error(`HTTP ${l.status} ${r} ${i}`);throw h.status=l.status,h.retryAfter=l.headers?.get?.("retry-after")??null,h.body=m??a.slice(0,300),h}return m??a}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(c)}}async function y(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,o=(t.method||"GET").toUpperCase(),s={Accept:"application/json",...t.headers||{}},u=t.body;u!=null&&typeof u!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",u=JSON.stringify(u));let c=Number.isInteger(t.retries)?Math.max(t.retries,0):It,i=async()=>{let m;for(let h=0;h<=c;h++)try{return await Nt(e,{fetchImpl:r,method:o,headers:s,body:u,timeoutMs:n})}catch(w){m=w;let b=w?.status,f=w?.name==="AbortError",g=new Set([408,425,429]),E=b!=null?g.has(b)||St.has(b)&&Ee.has(o):!f&&Ee.has(o);if(h===c||!E)throw w;await Bt(Tt(h,w?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&u==null))return i();let p=Rt(o,e,s),l=re.get(p);if(l)return l;let a=i().finally(()=>re.delete(p));return re.set(p,a),a}var St,Ee,It,ye,xe,Ct,Ae,re,Bt,I=P(()=>{St=new Set([408,425,429,500,502,503,504]),Ee=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),It=2,ye=4e3,xe=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ct=new Set([301,302,303,307,308]),Ae=3;re=new Map;Bt=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as Pt}from"node:fs";import{homedir as Ut}from"node:os";import{join as V}from"node:path";function $t(){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=Ut();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||V(t,".config","oracle")).trim();return[e,V(r,"exec.env")].filter(Boolean)}return[e,V(t,".config","oracle","exec.env"),V(t,".config","mad-desk","exec.env")].filter(Boolean)}function Se(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of $t())try{let s=Pt(o,"utf8"),u=s.match(new RegExp(`^${t}=(.*)$`,"m"))||s.match(new RegExp(`^${r}=(.*)$`,"m"));if(u&&(n=u[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 Ie=P(()=>{});var Ce=P(()=>{});import{createHash as Lt,createHmac as Ft,timingSafeEqual as Dn}from"node:crypto";function oe(e){return Array.isArray(e)?`[${e.map(oe).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${oe(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Dt(e,{required:t=!1}={}){try{return Se(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function _e(e){let{signature:t,...r}=e;return r}function Oe(e,{secret:t}={}){let r=Dt(t);return r?{...e,signature:Ft("sha256",r).update(oe(_e(e))).digest("hex")}:e}function Mt(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 Lt("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function U(e,{chainId:t,venue:r,data:n,secret:o}={}){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");return Oe({..._e(e),calldataHash:Mt(n)},{secret:o})}function ne(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function qt(e){let t=e==null?ve: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,ve)}function O({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let s=ne(e,0),u=s>0?s>=25e4?5:s>=1e5?10:s>=5e4?20:s>=1e4?40:70:n?30:10,c=Math.min(60,Math.abs(ne(t,0))*2),i=Math.min(40,Math.floor(Math.max(0,ne(r,0))/5e3)*5),d=Math.max(25,Math.ceil(20+u+c+i)),p=qt(o);return{mode:"auto",requiredBps:d,selectedBps:Math.min(d,p),capBps:p,executable:d<=p}}function Ht({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:s=0,crossChain:u=!1,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d=ke,secret:p}={}){let l=BigInt(r??0);if(l<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let a=O({liquidityUsd:n,priceChange5m:o,quoteAgeMs:s,crossChain:u,requestedCapBps:c});if(!a.executable)throw new Error(`auto-slippage requires ${a.requiredBps} bps above hard/requested cap ${a.capBps}; route blocked`);let m=Number(i);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let h=Math.min(3e4,Math.max(1e3,Number(d)||ke)),w=l*BigInt(1e4-a.selectedBps),b=w/10000n;if(w%10000n!==0n&&(b+=1n),b>l&&(b=l),l>0n&&b<=0n)throw new Error(`auto-slippage: quote ${l} is too small to express a ${a.selectedBps} bps floor without rounding to zero`);let f=Number((l-b)*10000n/(l===0n?1n:l));if(f>a.capBps)throw new Error(`auto-slippage: realised floor implies ${f} bps, above cap ${a.capBps} \u2014 refusing to issue a guard weaker than advertised`);return Oe({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:l.toString(),minAmountOut:b.toString(),requiredBps:a.requiredBps,selectedBps:a.selectedBps,capBps:a.capBps,quotedAtMs:m,expiresAtMs:m+h},{secret:p})}function A(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d}={}){let p=Ht({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i,ttlMs:d});return{...e,autoSlippage:p,amountOutMinimum:p.minAmountOut}}var ve,ke,R=P(()=>{Ie();Ce();ve=100,ke=2e4});function Re(e){let t=String(e||"").trim();return/^0x[0-9a-fA-F]{40}$/.test(t)?t:$}var $,j=P(()=>{$="0x000000000000000000000000000000000000dEaD"});import{createHash as Vt,createHmac as jt,timingSafeEqual as zn}from"node:crypto";function ae(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ae).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ae(e[r])}`).join(",")}}`}function Te(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Be(e=process.env){return Te(process.env)||Te(e)}function Xt(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...s}=e||{};return s}function Yt(e){let t=Xt(e);return Vt("sha256").update(ae(t)).digest("hex")}function Kt(e,t=Be()){return t?jt("sha256",t).update(String(e)).digest("hex"):""}function T(e,{provider:t,kind:r,env:n=process.env}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let o={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!o.provider)throw new Error("stampPrepared: provider required");if(!o.kind)throw new Error("stampPrepared: kind required");let s=Date.now(),u=s+Gt,i={...o,preparedAt:s,expiresAt:u,prepareVersion:zt},d=Yt(i),p=Be(n),l=p?Kt(d,p):void 0,a={...i,oraclePrepared:!0,prepareHash:d};return l&&(a.prepareMac=l),a}var zt,Gt,Gn,B=P(()=>{zt=2,Gt=300*1e3,Gn=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var ue={};At(ue,{ACROSS_API:()=>lt,HOP_API:()=>dt,RELAY_API:()=>pt,acrossHealth:()=>mn,acrossSuggestedFees:()=>mt,hopHealth:()=>fn,hopQuote:()=>ft,relayHealth:()=>hn,relayPrepare:()=>wn,relayQuote:()=>ce});async function mn(e={}){try{return{ok:!0,estimatedFillTimeSec:(await mt({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 mt(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:s,amount:u}=e;if(!r||o==null||s==null||!u)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let c=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(s),amount:String(u)}),i=(t.baseUrl||process.env.ACROSS_API_URL||lt).replace(/\/$/,"");return y(`${i}/suggested-fees?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function fn(e={}){try{let t=await ft({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 ft(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:s="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let u=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u});if(!c.executable)throw new Error(`hop: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:s,slippage:String(c.selectedBps/100)}),d=(t.baseUrl||process.env.HOP_API_URL||dt).replace(/\/$/,""),p=await y(`${d}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),l=p?.estimatedRecieved||p?.estimatedReceived;return l?A(p,{chainId:Number(e.originChainId||e.chainId||pn[o]||0),venue:p?.tx?.to||"hop",amountOut:l,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u}):{...p,autoSlippagePolicy:c}}async function hn(e={}){try{let t=await ce({user:$,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 ce(e={},t={}){let{user:r=$,originChainId:n,destinationChainId:o,originCurrency:s="0x0000000000000000000000000000000000000000",destinationCurrency:u="0x0000000000000000000000000000000000000000",amount:c,tradeType:i="EXACT_INPUT"}=e;if(n==null||o==null||!c)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`relay: route requires ${d.requiredBps} bps above cap ${d.capBps}`);let p=(t.baseUrl||process.env.RELAY_API_URL||pt).replace(/\/$/,""),l=await y(`${p}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:s,destinationCurrency:u,amount:String(c),tradeType:i,slippageTolerance:String(d.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.details?.currencyOut?.amount;return!a||!/^\d+$/.test(String(a))?{...l,autoSlippagePolicy:d}:A(l,{chainId:Number(n),venue:l?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function wn(e={},t={}){let r=await ce(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(c=>(c.items||[]).filter(i=>i?.data?.to&&i?.data?.data).map(i=>({stepId:c.id,...i.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let s=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(c=>String(c.to).toLowerCase()!==s))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let u=o.map(c=>({chainId:n,from:c.from||e.user,to:c.to,data:c.data,value:c.value??"0x0",...c.gasLimit!=null||c.gas!=null?{gasLimit:c.gasLimit??c.gas}:{},slippageGuard:U(r.autoSlippage,{chainId:n,venue:c.to,data:c.data})}));return T({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:u},{provider:"relay",kind:"relay-tx"})}var lt,dt,pt,pn,le=P(()=>{I();R();j();B();lt="https://across.to/api",dt="https://api.hop.exchange/v1",pt="https://api.relay.link",pn={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var Sn=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),In=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Cn=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var S=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"}),we={1:"coingecko:ethereum",10:"coingecko:ethereum",56:"coingecko:binancecoin",137:"coingecko:matic-network",8453:"coingecko:ethereum",42161:"coingecko:ethereum",43114:"coingecko:avalanche-2",999:"coingecko:ethereum"},q=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}};function he(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:o=null,feeUsd:s=null,oracleFeeBps:u=0,estimatedGas:c=null,liquidityUsd:i=null,error:d=null,executionReady:p=!1,meta:l={}}=e||{};if(d||r==null)return{source:t,quality:S.FAILED,amountOut:null,error:d||"no amountOut returned"};let a=q(r);if(a==null||a<=0n)return{source:t,quality:S.FAILED,amountOut:null,error:"non-positive amountOut"};let m=Number(u);return{source:t,quality:o==null?S.NO_GAS:S.FULL,amountOut:a.toString(),minOut:q(n)?.toString()??null,gasUsd:o,feeUsd:s,oracleFeeBps:Number.isFinite(m)&&m>0?Math.floor(m):0,estimatedGas:c==null?null:String(c),liquidityUsd:i==null?null:Number(i),executionReady:p,meta:l}}async function be(e,t,{divisor:r=1000n}={}){let n=q(t);if(n==null||n<=0n)return null;let o=n/r>0n?n/r:1n;if(o>=n)return null;let s,u;try{[s,u]=await Promise.all([e(o),e(n)])}catch{return null}let c=q(s),i=q(u);if(c==null||i==null||c<=0n)return null;let d=Number(c)/Number(o),p=Number(i)/Number(n);return!Number.isFinite(d)||!Number.isFinite(p)||d<=0?null:{impactPct:(1-p/d)*100,probeAmountIn:o.toString(),probeAmountOut:c.toString(),fullAmountOut:i.toString()}}function ge(e,t,{maxImpactPct:r=25}={}){let n=[],o=[],s=(e.routes??[]).filter(c=>{let i=t?.[c.source];return i?i.impactPct>r?(n.push({source:c.source,impactPct:Number(i.impactPct.toFixed(2)),reason:`price impact ${i.impactPct.toFixed(1)}% exceeds ${r}% ceiling -- the venue cannot absorb this size near the quoted price`}),!1):!0:(o.push(c.source),!0)}),u=[...e.warnings??[]];return n.length&&u.push(`dropped ${n.length} route(s) on price impact: `+n.map(c=>`${c.source} (${c.impactPct}%)`).join(", ")),o.length&&u.push(`price impact NOT measured for: ${o.join(", ")}. These are unproven against thin liquidity, not proven safe.`),{...e,routes:s,best:s[0]??null,impactRejected:n,impactUnmeasured:o,warnings:u}}function te(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:o=50}={}){let s=e.filter(f=>f.quality!==S.FAILED),u=e.filter(f=>f.quality===S.FAILED),c=t!=null&&t>0&&r!=null&&r>=0,i=s.map(f=>{let g=BigInt(f.amountOut),E=0n,k=!1,_=BigInt(f.oracleFeeBps??0),M=_>0n?g*_/10000n:0n;if(c){let fe=(f.gasUsd??0)+(f.feeUsd??0);if(fe>0){let ee=fe/t*10**r;Number.isFinite(ee)&&ee>=0&&(E=BigInt(Math.floor(ee)),k=!0)}else f.gasUsd===0&&(k=!0)}let me=E+M,Et=g>me?g-me:0n;return{...f,grossOut:g.toString(),netOut:Et.toString(),costInDest:E.toString(),oracleFeeInDest:M.toString(),costAccounted:k}}),d=Number(o)>0?Number(o):0,p=i.reduce((f,g)=>BigInt(g.netOut)>f?BigInt(g.netOut):f,0n),l=f=>p>0n?Number((p-BigInt(f))*10000n/p):0,a=[],m=i.slice().sort((f,g)=>BigInt(g.netOut)>BigInt(f.netOut)?1:-1)[0]??null;i.sort((f,g)=>{let E=l(f.netOut)<=d?0:1,k=l(g.netOut)<=d?0:1;if(n&&d>0&&E!==k)return E-k;if(n&&d>0){let _=f.liquidityUsd??-1,M=g.liquidityUsd??-1;if(_!==M)return M-_}return BigInt(g.netOut)>BigInt(f.netOut)?1:-1}),n&&d>0&&m&&i[0]&&i[0].source!==m.source&&a.push(`liquidity-first: chose ${i[0].source} (liquidity $${i[0].liquidityUsd??"unknown"}) over best-price ${m.source} within ${d} bps`);let h=i.filter(f=>!f.costAccounted).map(f=>f.source);c?h.length&&a.push(`gas not reported by: ${h.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 w=null,b=null;if(i.length>=2&&i[0].costAccounted&&i[1].costAccounted){let f=BigInt(i[0].netOut),g=BigInt(i[1].netOut);g>0n&&(w=Number((f-g)*10000n/g),b=`${i[0].source} vs ${i[1].source}`)}return{best:i[0]??null,routes:i,failed:u,improvementBps:w,spreadBasis:b,rankedOn:c?"net-of-cost":"gross",warnings:a}}async function H(e,{timeoutMs:t=12e3}={}){let r=(o,s)=>Promise.race([o,new Promise((u,c)=>setTimeout(()=>c(new Error(`${s}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,s)=>{let u=e[s].source;return o.status==="rejected"?he({source:u,error:String(o.reason?.message||o.reason)}):he({source:u,...o.value})})}I();R();j();B();import{existsSync as or,readFileSync as ar}from"node:fs";import{homedir as ir}from"node:os";import{join as Pe}from"node:path";import{Contract as Qt,JsonRpcProvider as Wt}from"ethers";var Jt="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",Zt=999,er="https://rpc.hyperliquid.xyz/evm",tr=["function balanceOf(address owner) view returns (uint256)"],rr=/^0x[a-fA-F0-9]{40}$/;function nr(e){return rr.test(String(e||""))}async function Ne(e,{contract:t=Jt,rpc:r=er,chainId:n=Zt,balanceOf:o}={}){if(!nr(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let s=new Wt(r,n,{staticNetwork:!0}),u=new Qt(t,tr,s);return BigInt(await u.balanceOf(e))}var sr=100,cr=5,Ue=Object.freeze({swap:5,bridge:5,perps:0,nft:0});function ur(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(Ue,t)?Ue[t]:cr}var lr="ORACLE_INTEGRATOR_FEE_BPS",dr="ORACLE_INTEGRATOR_FEE_RECIPIENT",pr="ORACLE_INTEGRATOR_ID",$e="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",mr="oracle";function fr(e=process.env){if(e[$e])return String(e[$e]);let t=e.ORACLE_CONFIG_DIR||Pe(ir(),".config","oracle");return Pe(t,"fee-recipient")}function hr(e=process.env){try{let t=fr(e);if(!or(t))return"";let r=ar(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function wr(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),sr)}function br({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[dr]||"").trim(),o=String(e[pr]||mr).trim();if(r===!0)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"admin-oracle"};let s=ur(t),u=wr(e[lr],{fallback:n?s:0}),c=Math.min(u,s);if(!c)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"no-recipient"};let i=hr(e);return i&&i!==n.toLowerCase()?{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:c,recipient:n,integrator:o,action:t,applies:!0,reason:"configured"}}async function z({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:o=!1}={}){let s=br({env:t,action:r,admin:o});if(o===!0)return{...s,holderVerificationStatus:"admin-oracle"};let u=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(u))return{...s,holderVerificationStatus:"wallet-required"};try{return BigInt(await Ne(u,n))>0n?{...s,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...s,holderVerificationStatus:"non-holder"}}catch{return{...s,holderVerificationStatus:"unavailable"}}}function Le(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 Fe(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}function De(e){return e?.applies?{partner:e.integrator,partnerFeeBps:String(e.bps),partnerAddress:e.recipient}:{}}var gr="https://li.quest/v1";function Er(e={}){return(e.baseUrl||process.env.LIFI_API_URL||gr).replace(/\/$/,"")}var yr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";async function ie(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=yr,toToken:s,fromAmount:u,fromAddress:c=$}=e;if(r==null||!s||!u)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let i=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:s,fromAmount:String(u),fromAddress:c}),d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`lifi: route requires ${d.requiredBps} bps above cap ${d.capBps}`);i.set("slippage",String(d.selectedBps/1e4));let p=await z({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[b,f]of Object.entries(Fe(p)))i.set(b,f);let l=await y(`${Er(t)}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.estimate?.toAmount||l?.toAmount;if(!a)return{...l,autoSlippagePolicy:d,oracleFee:p};let m=l?.transactionRequest?.to||l?.estimate?.approvalAddress||"lifi",h=A(l,{chainId:Number(r),venue:m,amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),w=l?.estimate?.toAmountMin||l?.toAmountMin;if(w!=null&&BigInt(w)<BigInt(h.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...h,oracleFee:p}}I();R();B();var Ar="https://api.paraswap.io",xr=(e={})=>(e.baseUrl||process.env.PARASWAP_API_URL||Ar).replace(/\/$/,"");function Me(e,t){let r=String(e||"");if(!/^0x[0-9a-fA-F]{40}$/.test(r))throw new Error(`${t} must be a 20-byte token address`);return r.toLowerCase()}async function qe(e={},t={}){let r=Number(e.chainId||e.network||1);if(e.amount==null)throw new Error("amount required");let n=new URLSearchParams({srcToken:Me(e.srcToken,"srcToken"),destToken:Me(e.destToken,"destToken"),amount:String(e.amount),srcDecimals:String(Number(e.srcDecimals)),destDecimals:String(Number(e.destDecimals)),side:String(e.side||"SELL").toUpperCase(),network:String(r),version:String(e.version||"6.2")});e.includeDEXS&&n.set("includeDEXS",String(e.includeDEXS)),e.excludeDEXS&&n.set("excludeDEXS",String(e.excludeDEXS));let o=await z({wallet:e.userAddress||e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[c,i]of Object.entries(De(o)))n.set(c,i);let s=await y(`${xr(t)}/prices?${n}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=s?.priceRoute?.destAmount;return u?{...A(s,{chainId:r,venue:s?.priceRoute?.contractAddress||"paraswap-quote",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,quoteAgeMs:0,requestedCapBps:e.maxSlippageBps??e.slippageBps}),executionReady:!1,executionBlocker:"call prepare to bind the price route to a validated transaction",oracleFee:o}:{...s,executionReady:!1,oracleFee:o}}I();R();var He="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function G({provider:e,defaultUrl:t,hosts:r=[],url:n,strict:o=!1}){let u=(String(n??"").trim()||String(t)).replace(/\/$/,"");if(u===String(t).replace(/\/$/,""))return{baseUrl:u,trusted:!0,host:Ve(t)};let c;try{c=new URL(u)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let i=c.host;if(!i)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Ve(t),...r]).has(i)){let p=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(i);return c.protocol==="http:"&&!p?{baseUrl:u,trusted:!1,host:i,reason:"plaintext http downgrade"}:{baseUrl:u,trusted:!0,host:i}}if(String(process.env[He]||"")==="1")return{baseUrl:u,trusted:!1,host:i};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${i} (set ${He}=1 to permit it)`);return{baseUrl:u,trusted:!1,host:i}}function Ve(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function X(e,t,r){let n={...e};if(!r)return n;for(let[o,s]of Object.entries(t||{}))s&&(n[o]=s);return n}B();var Sr="https://api.0x.org";function je(e={}){return G({provider:"zerox",defaultUrl:Sr,hosts:["api.0x.org"],url:e.baseUrl||process.env.ZEROX_API_URL})}function Ir(e={}){return je(e).baseUrl}function ze(e={}){return e.apiKey||process.env.ZEROX_API_KEY||process.env.OX_API_KEY||process.env["0X_API_KEY"]||""}function Cr(e={}){return X({"0x-version":"v2",accept:"application/json"},{"0x-api-key":ze(e)},je(e).trusted)}async function Ge(e={},t={}){if(!ze(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:s,taker:u}=e;if(!n||!o||!s)throw new Error("zeroxQuote requires sellToken, buyToken, sellAmount");let c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!c.executable)throw new Error(`0x: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(s),slippageBps:String(c.selectedBps)});u&&i.set("taker",u);let d=await y(`${Ir(t)}/swap/allowance-holder/quote?${i}`,{headers:Cr(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),p=d?.buyAmount||d?.grossBuyAmount;return p?A(d,{chainId:r,venue:d?.transaction?.to||d?.to||"0x",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):{...d,autoSlippagePolicy:c}}I();R();B();var vr="https://api.1inch.dev/swap/v6.0";function Xe(e={}){return G({provider:"oneinch",defaultUrl:vr,hosts:["api.1inch.dev"],url:e.baseUrl||process.env.ONEINCH_API_URL})}function kr(e={}){return Xe(e).baseUrl}function Ye(e={}){return e.apiKey||process.env.ONEINCH_API_KEY||process.env.ONE_INCH_API_KEY||""}function _r(e={}){let t=Ye(e);return X({accept:"application/json"},{Authorization:t?`Bearer ${t}`:""},Xe(e).trusted)}async function Ke(e={},t={}){if(!Ye(t))throw new Error("ONEINCH_API_KEY required for 1inch");let r=Number(e.chainId??1),{src:n,dst:o,amount:s}=e;if(!n||!o||!s)throw new Error("oneinchQuote requires src, dst, amount");let u=new URLSearchParams({src:n,dst:o,amount:String(s)}),c=await y(`${kr(t)}/${r}/quote?${u}`,{headers:_r(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3});return c?.dstAmount?A(c,{chainId:r,venue:"1inch-quote",amountOut:c.dstAmount,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):c}I();R();import{TypedDataEncoder as Oo,getAddress as Ro,isAddress as To}from"ethers";var Co=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});j();B();var Or={1:"https://api.cow.fi/mainnet/api/v1",100:"https://api.cow.fi/xdai/api/v1",42161:"https://api.cow.fi/arbitrum_one/api/v1",8453:"https://api.cow.fi/base/api/v1"},Fo=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Do=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"}),Qe={1:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",8453:"0x4200000000000000000000000000000000000006",42161:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"},Rr={1:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",8453:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",42161:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},Mo=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"}]}),qo=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});function Tr(e,t={}){if(t.baseUrl)return t.baseUrl.replace(/\/$/,"");let r=Or[Number(e)];if(!r)throw new Error(`cowswap: unsupported chainId ${e}`);return r}async function We(e={},t={}){let r=Number(e.chainId??1),n=Re(e.from||e.owner),o=e.sellToken||Qe[r],s=e.buyToken||Rr[r],u=String(e.sellAmountBeforeFee||e.sellAmount||"0");if(!o||!s||u==="0")throw new Error("cowQuote requires sellToken, buyToken, sellAmountBeforeFee");if(/eeeeeeee|native|^eth$/i.test(o)&&(o=Qe[r],!o))throw new Error("no WETH mapping for chain");let c={sellToken:o,buyToken:s,from:n,receiver:e.receiver||n,sellAmountBeforeFee:u,kind:e.kind||"sell",signingScheme:e.signingScheme||"eip1271"},i=await y(`${Tr(r,t)}/quote`,{method:"POST",body:c,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),d=i?.quote?.buyAmount||i?.buyAmount;return d?A(i,{chainId:r,venue:"cowswap-order",amountOut:d,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):i}import{Interface as nt,getAddress as Q,isAddress as zr}from"ethers";I();var Je={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}},Br=new Map(Object.values(Je).map(e=>[e.chainId,e]));function Ze(e){return Br.get(Number(e))||null}function et(e,t=process.env){let r=Ze(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as Nr,getAddress as Yo}from"ethers";var Ko=new Nr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Pr={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};function Ur(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=et(e,r);return n||Pr[Number(e)]||null}var $r=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Lr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!$r.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}async function Y(e,t,r=[],n={}){let o=String(t||"");Lr(o);let s=Ur(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let c=await y(s,{method:"POST",body:{jsonrpc:"2.0",id:1,method:t,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3});if(c?.error){let i=new Error(c.error.message||JSON.stringify(c.error));throw i.code=c.error.code,i}return c.result}I();var Fr="https://api.dexscreener.com",Dr=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"}),x=e=>String(e??"").toLowerCase(),Mr=e=>Array.isArray(e)?e:e==null?[]:[e];function qr(e,t,r){let n=x(t),o=x(r),s=x(e?.baseToken?.address),u=x(e?.quoteToken?.address);return s===n&&u===o||s===o&&u===n}function Hr(e){let t=Number(e?.liquidity?.usd);return Number.isFinite(t)&&t>=0?t:null}function Vr(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||Fr).replace(/\/$/,"")}async function jr(e,t={}){if(!e)throw new Error("tokenAddress required");return y(`${Vr(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}async function K({chainId:e,tokenA:t,tokenB:r,dexIds:n=[]}={},o={}){if(e==null||!t||!r)throw new Error("chainId, tokenA, and tokenB required");let s=x(Dr[Number(e)]||e),u=new Set(Mr(n).filter(Boolean).map(x)),c=[...new Set([t,r].map(a=>String(a)).filter(Boolean))],i=await Promise.allSettled(c.map(a=>jr(a,{...o,baseUrl:o.dexscreenerBaseUrl,timeoutMs:o.dexscreenerTimeoutMs??Math.min(Number(o.timeoutMs??4e3),4e3)}))),d=new Set,p=[];for(let a of i)if(a.status==="fulfilled")for(let m of a.value?.pairs||a.value?.data?.pairs||[]){let h=`${x(m?.chainId)}:${x(m?.dexId)}:${x(m?.pairAddress)}`;d.has(h)||(d.add(h),p.push(m))}return p.filter(a=>x(a?.chainId)===s).filter(a=>qr(a,t,r)).filter(a=>!u.size||u.has(x(a?.dexId))).map(a=>({pairAddress:a.pairAddress??null,dexId:a.dexId??null,chainId:a.chainId??null,liquidityUsd:Hr(a),pairCreatedAt:a.pairCreatedAt??null})).filter(a=>a.liquidityUsd!=null).sort((a,m)=>m.liquidityUsd-a.liquidityUsd)[0]??null}R();B();var L={1:{name:"ethereum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},8453:{name:"base",quoter:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",router:"0x2626664c2603336E57B271c5C0b26F421741e481",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},4663:{name:"robinhood",quoter:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",router:"0xcaf681a66d020601342297493863e78c959e5cb2",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"},999:{name:"hyperevm",weth:"0x5555555555555555555555555555555555555555",usdc:"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"},10:{name:"optimism",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",quoter:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",router:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},43114:{name:"avalanche",quoter:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",router:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}},Gr=[100,500,3e3,1e4],tt=new nt(["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)"]),oa=new nt(["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)"]),Xr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Yr="0x0000000000000000000000000000000000000000",se=[100,500,2500,1e4],Kr={56:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},8453:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},42161:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},999:{hyperswap:{name:"hyperswap",quoter:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",router:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D"}}};function Qr(e,t){let r=Number(e),n=L[r];if(!n)throw new Error(`uniswap-v3: unsupported chainId ${e} (supported: ${Object.keys(L).join(", ")})`);let o=Kr[r]||{};if(!t){if(!n.quoter||!n.router){let i=Object.keys(o).join(", ")||"none registered";throw new Error(`uniswap-v3: chain ${r} (${n.name}) has no canonical Uniswap v3 deployment -- name a venue explicitly (known: ${i})`)}return{chainId:r,venue:n.name,...n}}let s=String(t).toLowerCase();if(s===n.name&&n.quoter&&n.router)return{chainId:r,venue:n.name,...n};let u=o,c=u[s];if(!c){let i=[...n.quoter&&n.router?[n.name]:[],...Object.keys(u)].join(", ");throw new Error(`uniswap-v3: unknown venue "${t}" on chain ${r} (known: ${i})`)}return{chainId:r,venue:s,...n,quoter:c.quoter,router:c.router,feeTiers:c.feeTiers||null}}function rt(e,t){let r=L[Number(t)];if(!e||e===Xr||e===Yr||/^eth$/i.test(String(e)))return Q(r.weth);let n=String(e);if(/^weth$/i.test(n))return Q(r.weth);if(/^usdc$/i.test(n))return Q(r.usdc);if(!zr(n))throw new Error(`invalid token address: ${e}`);return Q(n)}function Wr(e){let t=String(e||"uniswap").toLowerCase();return t==="uniswap"?["uniswap-v3","uniswap"]:t==="pancakeswap"?["pancakeswap-v3","pancakeswap"]:t==="hyperswap"?["hyperswap-v3","hyperswap"]:[t,`${t}-v3`]}async function ot(e={},t={}){let{chainId:r,quoter:n,router:o,feeTiers:s}=Qr(e.chainId??8453,e.venue),u=rt(e.tokenIn||"WETH",r),c=rt(e.tokenOut||L[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");let d=s&&s.length?s:Gr,p=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[d[Math.min(2,d.length-1)]]:[...d],l=[],a=null;for(let w of p){let b=tt.encodeFunctionData("quoteExactInputSingle",[{tokenIn:u,tokenOut:c,amountIn:i,fee:w,sqrtPriceLimitX96:0n}]);try{let f=await Y(r,"eth_call",[{to:n,data:b},"latest"],t);if(!f||f==="0x"){l.push({fee:w,ok:!1,error:"empty result"});continue}let g=tt.decodeFunctionResult("quoteExactInputSingle",f),E={fee:w,ok:!0,amountOut:g[0].toString(),sqrtPriceX96After:g[1].toString(),initializedTicksCrossed:Number(g[2]),gasEstimate:g[3].toString()};l.push(E),(!a||BigInt(E.amountOut)>BigInt(a.amountOut))&&(a=E)}catch(f){l.push({fee:w,ok:!1,error:String(f.message||f).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:Wr(e.venue)},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v3",chainId:r,chain:L[r].name,quoter:n,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,sqrtPriceX96After:a.sqrtPriceX96After,initializedTicksCrossed:a.initializedTicksCrossed,triedFees:l,best:!0},{chainId:r,venue:o,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}import{AbiCoder as Jr,Interface as st,getAddress as C,isAddress as W,keccak256 as Zr}from"ethers";R();B();var en=Jr.defaultAbiCoder(),D="0x0000000000000000000000000000000000000000",F={1:{name:"ethereum",poolManager:"0x000000000004444c5dc75cB358380D2e3dE08A90",quoter:"0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203",stateView:"0x7ffe42c4a5deea5b0fec41c94c136cf115597227",universalRouter:"0x66a9893cc07d91d95644aedd05d03f95e1dba8af",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},10:{name:"optimism",poolManager:"0x9a13f98cb987694c9f086b1f5eb990eea8264ec3",quoter:"0x1f3131a13296fb91c90870043742c3cdbff1a8d7",stateView:"0xc18a3169788f4f75a170290584eca6395c75ecdb",universalRouter:"0x851116d9223fabed8e56c0e6b8ad0c31d98b3507",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",poolManager:"0x28e2ea090877bf75740558f6bfb36a5ffee9e9df",quoter:"0x9f75dd27d6664c475b90e105573e550ff69437b0",stateView:"0xd13dd3d6e93f276fafc9db9e6bb47c1180aee0c4",universalRouter:"0x1906c1d672b88cd1b9ac7593301ca990f94eae07",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",poolManager:"0x67366782805870060151383f4bbff9dab53e5cd6",quoter:"0xb3d5c3dfc3a7aebff71895a7191796bffc2c81b9",stateView:"0x5ea1bd7974c8a611cbab0bdcafcb1d9cc9b3ba5a",universalRouter:"0x1095692a6237d83c6a72f3f5efedb9a670c49223",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},8453:{name:"base",poolManager:"0x498581fF718922c3f8e6A244956aF099B2652b2b",quoter:"0x0d5e0f971ed27fbff6c2837bf31316121532048d",stateView:"0xa3c0c9b65bad0b08107aa264b0f3db444b867a71",universalRouter:"0x6ff5693b99212da76ad316178a184ab56d299b43",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",poolManager:"0x360e68faccca8ca495c1b759fd9eee466db9fb32",quoter:"0x3972c00f7ed4885e145823eb7c655375d275a1c5",stateView:"0x76fd297e2d437cd7f76d50f01afe6160f86e9990",universalRouter:"0xa51afafe0263b40edaef0df8781ea9aa03e381a3",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},43114:{name:"avalanche",poolManager:"0x06380c0e0912312b5150364b9dc4542ba0dbbc85",quoter:"0xbe40675bb704506a3c2ccfb762dcfd1e979845c2",stateView:"0xc3c9e198c735a4b97e3e683f391ccbdd60b69286",universalRouter:"0x94b75331ae8d42c1b61065089b7d48fe14aa73b7",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"},4663:{name:"robinhood",poolManager:"0x8366a39cc670b4001a1121b8f6a443a643e40951",quoter:"0x8dc178efb8111bb0973dd9d722ebeff267c98f94",stateView:"0xf3334192d15450cdd385c8b70e03f9a6bd9e673b",universalRouter:"0x8876789976dEcBfCbBbe364623C63652db8C0904",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"}},tn=[{fee:100,tickSpacing:1},{fee:500,tickSpacing:10},{fee:3e3,tickSpacing:60},{fee:1e4,tickSpacing:200},{fee:25e3,tickSpacing:8}],at=new st(["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)"]),da=new st(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);var rn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";function nn(e){let t=Number(e),r=F[t];if(!r)throw new Error(`uniswap-v4: unsupported chainId ${e} (supported: ${Object.keys(F).join(", ")})`);return{chainId:t,...r}}function it(e,t){let r=F[Number(t)];if(!e||e===rn||e===D||/^eth$/i.test(String(e)))return C(r.weth);let n=String(e);if(/^weth$/i.test(n))return C(r.weth);if(/^usdc$/i.test(n)||/^usdg$/i.test(n))return C(r.usdc);if(!W(n))throw new Error(`invalid token address: ${e}`);return C(n)}function on({currency0:e,currency1:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t);if(s.toLowerCase()===u.toLowerCase())throw new Error("poolKey currencies must differ");let[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=o&&W(o)?C(o):D;return Zr(en.encode(["address","address","uint24","int24","address"],[c,i,Number(r),Number(n),d]))}function an({tokenIn:e,tokenOut:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t),[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=s.toLowerCase()===c.toLowerCase();return{poolKey:{currency0:c,currency1:i,fee:Number(r),tickSpacing:Number(n),hooks:o&&W(o)?C(o):D},zeroForOne:d}}var sn=["uniswap-v4","uniswapv4"];async function ct(e={},t={}){let{chainId:r,quoter:n,poolManager:o,universalRouter:s}=nn(e.chainId??8453),u=it(e.tokenIn||"WETH",r),c=it(e.tokenOut||F[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");if(i>0xffffffffffffffffffffffffffffffffn)throw new Error("amountIn exceeds uint128");let d=e.fee!=null&&e.tickSpacing!=null?[{fee:Number(e.fee),tickSpacing:Number(e.tickSpacing)}]:e.tryTiers===!1?[{fee:500,tickSpacing:10}]:[...tn],p=e.hooks||D,l=[],a=null;for(let w of d){let{poolKey:b,zeroForOne:f}=an({tokenIn:u,tokenOut:c,fee:w.fee,tickSpacing:w.tickSpacing,hooks:p}),g=at.encodeFunctionData("quoteExactInputSingle",[{poolKey:b,zeroForOne:f,exactAmount:i,hookData:"0x"}]);try{let E=await Y(r,"eth_call",[{to:n,data:g},"latest"],t);if(!E||E==="0x"){l.push({...w,ok:!1,error:"empty result"});continue}let k=at.decodeFunctionResult("quoteExactInputSingle",E),_={fee:w.fee,tickSpacing:w.tickSpacing,ok:!0,amountOut:k[0].toString(),gasEstimate:k[1].toString(),poolKey:b,zeroForOne:f,poolId:on({...b})};l.push(_),(!a||BigInt(_.amountOut)>BigInt(a.amountOut))&&(a=_)}catch(E){l.push({...w,ok:!1,error:String(E.message||E).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}/${b.tickSpacing}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v4 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:sn},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v4",chainId:r,chain:F[r].name,poolManager:o,quoter:n,universalRouter:s||null,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,tickSpacing:a.tickSpacing,hooks:a.poolKey.hooks,poolId:a.poolId,zeroForOne:a.zeroForOne,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,triedTiers:l,best:!0,executionReady:!1,prepareReady:typeof e.recipient=="string"&&W(e.recipient)&&e.slippageBps!=null},{chainId:r,venue:s||n,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}I();var cn="https://coins.llama.fi",un="https://api.llama.fi";function ln(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||cn).replace(/\/$/,"")}function dn(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||un).replace(/\/$/,"")}async function J(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return y(`${ln(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function ut(e={}){return y(`${dn(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var v=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function Z(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=v(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}async function wt(e,t={}){let r=we[Number(e)];if(!r)return null;try{let n=await J([r],t);return v(n?.coins?.[r]?.price)}catch{return null}}var N=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),ht=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 bn(e={}){try{let t=await ut({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function gn(e,t={}){let r=N(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...ht[r]||[r]),n.push(...ht[N(e)]||[e]),n}function En(e,t,r={}){let n=Array.isArray(e)?e:[],o=gn(t,r).map(N).filter(Boolean);for(let s of o){let u=n.find(i=>N(i?.slug)===s||N(i?.name)===s),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}for(let s of o){let u=n.find(i=>{let d=N(i?.category);return!d.includes("bridge")&&!d.includes("crosschain")?!1:N(i?.slug).includes(s)||N(i?.name).includes(s)}),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}return null}function de({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:s,decimalsIn:u,decimalsOut:c,nativePriceUsd:i=null,destDecimalsPromise:d=null,opts:p={}}){let l=[];return l.push({source:"lifi",run:async()=>{let a=await ie({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n},p),m=a?.estimate??a?.[0]?.estimate;return{amountOut:m?.toAmount,minOut:m?.toAmountMin,gasUsd:Z(m?.gasCosts),feeUsd:Z(m?.feeCosts),oracleFeeBps:a?.oracleFee?.applies?a.oracleFee.bps:0,meta:{tool:a?.tool??a?.toolDetails?.name,oracleFee:a?.oracleFee??null}}}}),u!=null&&l.push({source:"paraswap",run:async()=>{let a=c??(await Promise.resolve(d))?.decimals;if(a==null)throw new Error("paraswap needs destination decimals; none supplied or resolvable");let m=await qe({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:u,destDecimals:a},p),h=m?.priceRoute;return{amountOut:h?.destAmount,gasUsd:v(h?.gasCostUSD),oracleFeeBps:m?.oracleFee?.applies?m.oracleFee.bps:0,meta:{bestRoute:h?.bestRoute?.[0]?.swaps?.[0]?.swapExchanges?.[0]?.exchange,oracleFee:m?.oracleFee??null}}}}),process.env.ZEROX_API_KEY&&l.push({source:"0x",run:async()=>{let a=await Ge({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},p),m=null,h=a?.totalNetworkFee,w=await Promise.resolve(i);return h!=null&&w&&(m=Number(h)/1e18*w),{amountOut:a?.buyAmount,minOut:a?.minBuyAmount,gasUsd:m,meta:{source:a?.route?.fills?.[0]?.source}}}}),process.env.ONEINCH_API_KEY&&l.push({source:"1inch",run:async()=>{let a=await Ke({chainId:e,src:t,dst:r,amount:n},p),m=null;return a?.gas!=null&&i&&(m=null),{amountOut:a?.dstAmount,gasUsd:m,meta:{gasUnits:a?.gas}}}}),l.push({source:"cow",run:async()=>{let a=await We({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},p),m=a?.quote??a,h=m?.feeAmount;return{amountOut:m?.buyAmount,gasUsd:0,meta:{intent:!0,feeAmountInSellToken:h,settlement:"solver-executed"}}}}),L[Number(e)]&&l.push({source:"uniswap-v3",run:async()=>{let a=await ot({chainId:e,tokenIn:t,tokenOut:r,amountIn:n},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,fee:a?.fee,gasUnits:a?.gasEstimate,quoter:a?.quoter}}}}),F[Number(e)]&&l.push({source:"uniswap-v4",run:async()=>{let a=await ct({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:s},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,venue:"uniswap-v4",fee:a?.fee,tickSpacing:a?.tickSpacing,poolId:a?.poolId,hooks:a?.hooks,gasUnits:a?.gasEstimate,quoter:a?.quoter,poolManager:a?.poolManager,prepareReady:a?.prepareReady===!0,executionReady:!1}}}}),l}function bt({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:s,opts:u={}}){let c=[],i=null,d=async(p,l={})=>(i||=bn(u),En(await i,p,l));return c.push({source:"lifi",run:async()=>{let p=await ie({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},u),l=p?.estimate??p?.[0]?.estimate,a={tool:p?.tool??p?.toolDetails?.name,durationSeconds:v(l?.executionDuration)},m=await d("lifi",a);return{amountOut:l?.toAmount,minOut:l?.toAmountMin,gasUsd:Z(l?.gasCosts),feeUsd:Z(l?.feeCosts),oracleFeeBps:p?.oracleFee?.applies?p.oracleFee.bps:0,liquidityUsd:m?.liquidityUsd??null,meta:{...a,liquidityProtocol:m?.protocol,oracleFee:p?.oracleFee??null}}}}),c.push({source:"relay",run:async()=>{let{relayQuote:p}=await Promise.resolve().then(()=>(le(),ue)),a=(await p({user:s,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},u))?.details,m={durationSeconds:v(a?.timeEstimate),rate:a?.rate},h=await d("relay",m);return{amountOut:a?.currencyOut?.amount,minOut:a?.currencyOut?.minimumAmount,gasUsd:v(a?.totalImpact?.usd)!=null?Math.abs(v(a.totalImpact.usd)):null,liquidityUsd:h?.liquidityUsd??null,meta:{...m,liquidityProtocol:h?.protocol}}}}),c.push({source:"across",run:async()=>{let{acrossSuggestedFees:p}=await Promise.resolve().then(()=>(le(),ue)),l=await p({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},u),a=l?.totalRelayFee?.total,m=null;if(a!=null)try{let w=BigInt(String(o))-BigInt(String(a));w>0n&&(m=w.toString())}catch{}let h=await d("across");return{amountOut:m,gasUsd:null,liquidityUsd:h?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:v(l?.estimatedFillTimeSec),limits:l?.limits?{min:l.limits.minDeposit,max:l.limits.maxDeposit}:void 0,liquidityProtocol:h?.protocol}}}}),c}var yn={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function gt(e,t,r){let n=yn[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let u=(await J([o],r))?.coins?.[o],c=Number(u?.price),i=Number(u?.decimals);return{priceUsd:Number.isFinite(c)?c:null,decimals:Number.isFinite(i)?i:null}}catch{return{priceUsd:null,decimals:null}}}async function Pa(e,t={}){let{chainId:r,tokenIn:n,tokenOut:o,amountIn:s}=e;if(r==null||!n||!o||s==null)throw new Error("bestSwapRoute requires chainId, tokenIn, tokenOut, amountIn");let u=wt(r,t),c=gt(r,o,t),i=de({...e,nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??12e3}),c]);u.catch(()=>{});let l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=t.maxImpactPct===void 0?25:t.maxImpactPct;if(a!=null&&l.best){let m=l.best.source,w=await be(async b=>{let f=de({...e,amountIn:b.toString(),nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}).filter(E=>E.source===m);return f.length?(await H(f,{timeoutMs:t.timeoutMs??12e3}))?.[0]?.amountOut??null:null},s);if(w){let b=ge(l,{[m]:w},{maxImpactPct:a});return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...b,sourcesTried:i.length,sourcesAnswered:d.filter(f=>f.quality!==S.FAILED).length,note:pe(b,i.length),priceImpact:{[m]:Number(w.impactPct.toFixed(2))}}}}return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...l,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}async function Ua(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:u}=e;if(r==null||n==null||!o||!s||u==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 c=gt(n,s,t),i=bt({...e,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??15e3}),c]),l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=l.routes.map(m=>({source:m.source,seconds:m.meta?.durationSeconds??null})).filter(m=>m.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:String(u),...l,durations:a,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}function An(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Le(t)}`:""}function pe(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=An(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 o=e.improvementBps,s=o/100;if(o<.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 u=s>=.01?`${s.toFixed(2)}%`:`${o.toFixed(2)}bps`;return`best of ${r} routes, ranked on ${e.rankedOn}: ${u} 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}export{S as QUALITY,Ua as bestBridgeRoute,Pa as bestSwapRoute,pe as formatComparisonNote};
2
+ `),c=xt("sha256").update(u).digest("hex").slice(0,32);return`${e} ${t} ${c}`}function Tt(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ye):Math.min(250*2**e,ye)+Math.floor(Math.random()*100)}async function Nt(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s}){let u=new AbortController,c=setTimeout(()=>u.abort(),s);try{let i=String(e),d={...n||{}};for(let p=0;p<=Ae;p+=1){let l=await t(i,{method:r,headers:d,body:o,signal:u.signal,redirect:"manual"}),a=await l.text(),m=null;if(a)try{m=JSON.parse(a)}catch{m=null}if(Ct.has(l.status)){if(r!=="GET"&&r!=="HEAD"){let w=new Error(`HTTP ${l.status} ${r} ${i} redirected non-idempotent request`);throw w.status=l.status,w.body=m??a.slice(0,300),w}if(p===Ae)throw new Error(`HTTP redirect loop for ${e}`);let h=_t(l.headers?.get?.("location"),i);Ot(h,i)||(d=kt(d)),i=h;continue}if(!l.ok){let h=new Error(`HTTP ${l.status} ${r} ${i}`);throw h.status=l.status,h.retryAfter=l.headers?.get?.("retry-after")??null,h.body=m??a.slice(0,300),h}return m??a}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(c)}}async function y(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,o=(t.method||"GET").toUpperCase(),s={Accept:"application/json",...t.headers||{}},u=t.body;u!=null&&typeof u!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",u=JSON.stringify(u));let c=Number.isInteger(t.retries)?Math.max(t.retries,0):It,i=async()=>{let m;for(let h=0;h<=c;h++)try{return await Nt(e,{fetchImpl:r,method:o,headers:s,body:u,timeoutMs:n})}catch(w){m=w;let b=w?.status,f=w?.name==="AbortError",g=new Set([408,425,429]),E=b!=null?g.has(b)||St.has(b)&&Ee.has(o):!f&&Ee.has(o);if(h===c||!E)throw w;await Bt(Tt(h,w?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&u==null))return i();let p=Rt(o,e,s),l=re.get(p);if(l)return l;let a=i().finally(()=>re.delete(p));return re.set(p,a),a}var St,Ee,It,ye,xe,Ct,Ae,re,Bt,I=P(()=>{St=new Set([408,425,429,500,502,503,504]),Ee=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),It=2,ye=4e3,xe=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ct=new Set([301,302,303,307,308]),Ae=3;re=new Map;Bt=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as Pt}from"node:fs";import{homedir as Ut}from"node:os";import{join as V}from"node:path";function $t(){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=Ut();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||V(t,".config","oracle")).trim();return[e,V(r,"exec.env")].filter(Boolean)}return[e,V(t,".config","oracle","exec.env"),V(t,".config","mad-desk","exec.env")].filter(Boolean)}function Se(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of $t())try{let s=Pt(o,"utf8"),u=s.match(new RegExp(`^${t}=(.*)$`,"m"))||s.match(new RegExp(`^${r}=(.*)$`,"m"));if(u&&(n=u[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 Ie=P(()=>{});var Ce=P(()=>{});import{createHash as Lt,createHmac as Ft,timingSafeEqual as Dn}from"node:crypto";function oe(e){return Array.isArray(e)?`[${e.map(oe).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${oe(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Dt(e,{required:t=!1}={}){try{return Se(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function _e(e){let{signature:t,...r}=e;return r}function Oe(e,{secret:t}={}){let r=Dt(t);return r?{...e,signature:Ft("sha256",r).update(oe(_e(e))).digest("hex")}:e}function Mt(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 Lt("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function U(e,{chainId:t,venue:r,data:n,secret:o}={}){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");return Oe({..._e(e),calldataHash:Mt(n)},{secret:o})}function ne(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function qt(e){let t=e==null?ve: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,ve)}function O({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let s=ne(e,0),u=s>0?s>=25e4?5:s>=1e5?10:s>=5e4?20:s>=1e4?40:70:n?30:10,c=Math.min(60,Math.abs(ne(t,0))*2),i=Math.min(40,Math.floor(Math.max(0,ne(r,0))/5e3)*5),d=Math.max(25,Math.ceil(20+u+c+i)),p=qt(o);return{mode:"auto",requiredBps:d,selectedBps:Math.min(d,p),capBps:p,executable:d<=p}}function Ht({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:s=0,crossChain:u=!1,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d=ke,secret:p}={}){let l=BigInt(r??0);if(l<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let a=O({liquidityUsd:n,priceChange5m:o,quoteAgeMs:s,crossChain:u,requestedCapBps:c});if(!a.executable)throw new Error(`auto-slippage requires ${a.requiredBps} bps above hard/requested cap ${a.capBps}; route blocked`);let m=Number(i);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let h=Math.min(3e4,Math.max(1e3,Number(d)||ke)),w=l*BigInt(1e4-a.selectedBps),b=w/10000n;if(w%10000n!==0n&&(b+=1n),b>l&&(b=l),l>0n&&b<=0n)throw new Error(`auto-slippage: quote ${l} is too small to express a ${a.selectedBps} bps floor without rounding to zero`);let f=Number((l-b)*10000n/(l===0n?1n:l));if(f>a.capBps)throw new Error(`auto-slippage: realised floor implies ${f} bps, above cap ${a.capBps} \u2014 refusing to issue a guard weaker than advertised`);return Oe({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:l.toString(),minAmountOut:b.toString(),requiredBps:a.requiredBps,selectedBps:a.selectedBps,capBps:a.capBps,quotedAtMs:m,expiresAtMs:m+h},{secret:p})}function A(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d}={}){let p=Ht({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i,ttlMs:d});return{...e,autoSlippage:p,amountOutMinimum:p.minAmountOut}}var ve,ke,R=P(()=>{Ie();Ce();ve=100,ke=2e4});function Re(e){let t=String(e||"").trim();return/^0x[0-9a-fA-F]{40}$/.test(t)?t:$}var $,j=P(()=>{$="0x000000000000000000000000000000000000dEaD"});import{createHash as Vt,createHmac as jt,timingSafeEqual as zn}from"node:crypto";function ae(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ae).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ae(e[r])}`).join(",")}}`}function Te(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Be(e=process.env){return Te(process.env)||Te(e)}function Xt(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...s}=e||{};return s}function Yt(e){let t=Xt(e);return Vt("sha256").update(ae(t)).digest("hex")}function Kt(e,t=Be()){return t?jt("sha256",t).update(String(e)).digest("hex"):""}function T(e,{provider:t,kind:r,env:n=process.env}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let o={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!o.provider)throw new Error("stampPrepared: provider required");if(!o.kind)throw new Error("stampPrepared: kind required");let s=Date.now(),u=s+Gt,i={...o,preparedAt:s,expiresAt:u,prepareVersion:zt},d=Yt(i),p=Be(n),l=p?Kt(d,p):void 0,a={...i,oraclePrepared:!0,prepareHash:d};return l&&(a.prepareMac=l),a}var zt,Gt,Gn,B=P(()=>{zt=2,Gt=300*1e3,Gn=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var ue={};At(ue,{ACROSS_API:()=>lt,HOP_API:()=>dt,RELAY_API:()=>pt,acrossHealth:()=>mn,acrossSuggestedFees:()=>mt,hopHealth:()=>fn,hopQuote:()=>ft,relayHealth:()=>hn,relayPrepare:()=>wn,relayQuote:()=>ce});async function mn(e={}){try{return{ok:!0,estimatedFillTimeSec:(await mt({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 mt(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:s,amount:u}=e;if(!r||o==null||s==null||!u)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let c=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(s),amount:String(u)}),i=(t.baseUrl||process.env.ACROSS_API_URL||lt).replace(/\/$/,"");return y(`${i}/suggested-fees?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function fn(e={}){try{let t=await ft({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 ft(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:s="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let u=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u});if(!c.executable)throw new Error(`hop: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:s,slippage:String(c.selectedBps/100)}),d=(t.baseUrl||process.env.HOP_API_URL||dt).replace(/\/$/,""),p=await y(`${d}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),l=p?.estimatedRecieved||p?.estimatedReceived;return l?A(p,{chainId:Number(e.originChainId||e.chainId||pn[o]||0),venue:p?.tx?.to||"hop",amountOut:l,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u}):{...p,autoSlippagePolicy:c}}async function hn(e={}){try{let t=await ce({user:$,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 ce(e={},t={}){let{user:r=$,originChainId:n,destinationChainId:o,originCurrency:s="0x0000000000000000000000000000000000000000",destinationCurrency:u="0x0000000000000000000000000000000000000000",amount:c,tradeType:i="EXACT_INPUT"}=e;if(n==null||o==null||!c)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`relay: route requires ${d.requiredBps} bps above cap ${d.capBps}`);let p=(t.baseUrl||process.env.RELAY_API_URL||pt).replace(/\/$/,""),l=await y(`${p}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:s,destinationCurrency:u,amount:String(c),tradeType:i,slippageTolerance:String(d.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.details?.currencyOut?.amount;return!a||!/^\d+$/.test(String(a))?{...l,autoSlippagePolicy:d}:A(l,{chainId:Number(n),venue:l?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function wn(e={},t={}){let r=await ce(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(c=>(c.items||[]).filter(i=>i?.data?.to&&i?.data?.data).map(i=>({stepId:c.id,...i.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let s=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(c=>String(c.to).toLowerCase()!==s))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let u=o.map(c=>({chainId:n,from:c.from||e.user,to:c.to,data:c.data,value:c.value??"0x0",...c.gasLimit!=null||c.gas!=null?{gasLimit:c.gasLimit??c.gas}:{},slippageGuard:U(r.autoSlippage,{chainId:n,venue:c.to,data:c.data})}));return T({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:u},{provider:"relay",kind:"relay-tx"})}var lt,dt,pt,pn,le=P(()=>{I();R();j();B();lt="https://across.to/api",dt="https://api.hop.exchange/v1",pt="https://api.relay.link",pn={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var Sn=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),In=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Cn=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var S=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"}),we={1:"coingecko:ethereum",10:"coingecko:ethereum",56:"coingecko:binancecoin",137:"coingecko:matic-network",8453:"coingecko:ethereum",42161:"coingecko:ethereum",43114:"coingecko:avalanche-2",999:"coingecko:ethereum"},q=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}};function he(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:o=null,feeUsd:s=null,oracleFeeBps:u=0,estimatedGas:c=null,liquidityUsd:i=null,error:d=null,executionReady:p=!1,meta:l={}}=e||{};if(d||r==null)return{source:t,quality:S.FAILED,amountOut:null,error:d||"no amountOut returned"};let a=q(r);if(a==null||a<=0n)return{source:t,quality:S.FAILED,amountOut:null,error:"non-positive amountOut"};let m=Number(u);return{source:t,quality:o==null?S.NO_GAS:S.FULL,amountOut:a.toString(),minOut:q(n)?.toString()??null,gasUsd:o,feeUsd:s,oracleFeeBps:Number.isFinite(m)&&m>0?Math.floor(m):0,estimatedGas:c==null?null:String(c),liquidityUsd:i==null?null:Number(i),executionReady:p,meta:l}}async function be(e,t,{divisor:r=1000n}={}){let n=q(t);if(n==null||n<=0n)return null;let o=n/r>0n?n/r:1n;if(o>=n)return null;let s,u;try{[s,u]=await Promise.all([e(o),e(n)])}catch{return null}let c=q(s),i=q(u);if(c==null||i==null||c<=0n)return null;let d=Number(c)/Number(o),p=Number(i)/Number(n);return!Number.isFinite(d)||!Number.isFinite(p)||d<=0?null:{impactPct:(1-p/d)*100,probeAmountIn:o.toString(),probeAmountOut:c.toString(),fullAmountOut:i.toString()}}function ge(e,t,{maxImpactPct:r=25}={}){let n=[],o=[],s=(e.routes??[]).filter(c=>{let i=t?.[c.source];return i?i.impactPct>r?(n.push({source:c.source,impactPct:Number(i.impactPct.toFixed(2)),reason:`price impact ${i.impactPct.toFixed(1)}% exceeds ${r}% ceiling -- the venue cannot absorb this size near the quoted price`}),!1):!0:(o.push(c.source),!0)}),u=[...e.warnings??[]];return n.length&&u.push(`dropped ${n.length} route(s) on price impact: `+n.map(c=>`${c.source} (${c.impactPct}%)`).join(", ")),o.length&&u.push(`price impact NOT measured for: ${o.join(", ")}. These are unproven against thin liquidity, not proven safe.`),{...e,routes:s,best:s[0]??null,impactRejected:n,impactUnmeasured:o,warnings:u}}function te(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:o=50}={}){let s=e.filter(f=>f.quality!==S.FAILED),u=e.filter(f=>f.quality===S.FAILED),c=t!=null&&t>0&&r!=null&&r>=0,i=s.map(f=>{let g=BigInt(f.amountOut),E=0n,k=!1,_=BigInt(f.oracleFeeBps??0),M=_>0n?g*_/10000n:0n;if(c){let fe=(f.gasUsd??0)+(f.feeUsd??0);if(fe>0){let ee=fe/t*10**r;Number.isFinite(ee)&&ee>=0&&(E=BigInt(Math.floor(ee)),k=!0)}else f.gasUsd===0&&(k=!0)}let me=E+M,Et=g>me?g-me:0n;return{...f,grossOut:g.toString(),netOut:Et.toString(),costInDest:E.toString(),oracleFeeInDest:M.toString(),costAccounted:k}}),d=Number(o)>0?Number(o):0,p=i.reduce((f,g)=>BigInt(g.netOut)>f?BigInt(g.netOut):f,0n),l=f=>p>0n?Number((p-BigInt(f))*10000n/p):0,a=[],m=i.slice().sort((f,g)=>BigInt(g.netOut)>BigInt(f.netOut)?1:-1)[0]??null;i.sort((f,g)=>{let E=l(f.netOut)<=d?0:1,k=l(g.netOut)<=d?0:1;if(n&&d>0&&E!==k)return E-k;if(n&&d>0){let _=f.liquidityUsd??-1,M=g.liquidityUsd??-1;if(_!==M)return M-_}return BigInt(g.netOut)>BigInt(f.netOut)?1:-1}),n&&d>0&&m&&i[0]&&i[0].source!==m.source&&a.push(`liquidity-first: chose ${i[0].source} (liquidity $${i[0].liquidityUsd??"unknown"}) over best-price ${m.source} within ${d} bps`);let h=i.filter(f=>!f.costAccounted).map(f=>f.source);c?h.length&&a.push(`gas not reported by: ${h.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 w=null,b=null;if(i.length>=2&&i[0].costAccounted&&i[1].costAccounted){let f=BigInt(i[0].netOut),g=BigInt(i[1].netOut);g>0n&&(w=Number((f-g)*10000n/g),b=`${i[0].source} vs ${i[1].source}`)}return{best:i[0]??null,routes:i,failed:u,improvementBps:w,spreadBasis:b,rankedOn:c?"net-of-cost":"gross",warnings:a}}async function H(e,{timeoutMs:t=12e3}={}){let r=(o,s)=>Promise.race([o,new Promise((u,c)=>setTimeout(()=>c(new Error(`${s}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,s)=>{let u=e[s].source;return o.status==="rejected"?he({source:u,error:String(o.reason?.message||o.reason)}):he({source:u,...o.value})})}I();R();j();B();import{existsSync as or,readFileSync as ar}from"node:fs";import{homedir as ir}from"node:os";import{join as Pe}from"node:path";import{Contract as Qt,JsonRpcProvider as Wt}from"ethers";var Jt="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",Zt=999,er="https://rpc.hyperliquid.xyz/evm",tr=["function balanceOf(address owner) view returns (uint256)"],rr=/^0x[a-fA-F0-9]{40}$/;function nr(e){return rr.test(String(e||""))}async function Ne(e,{contract:t=Jt,rpc:r=er,chainId:n=Zt,balanceOf:o}={}){if(!nr(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let s=new Wt(r,n,{staticNetwork:!0}),u=new Qt(t,tr,s);return BigInt(await u.balanceOf(e))}var sr=100,cr=5,Ue=Object.freeze({swap:5,bridge:5,perps:0,nft:0});function ur(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(Ue,t)?Ue[t]:cr}var lr="ORACLE_INTEGRATOR_FEE_BPS",dr="ORACLE_INTEGRATOR_FEE_RECIPIENT",pr="ORACLE_INTEGRATOR_ID",$e="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",mr="oracle";function fr(e=process.env){if(e[$e])return String(e[$e]);let t=e.ORACLE_CONFIG_DIR||Pe(ir(),".config","oracle");return Pe(t,"fee-recipient")}function hr(e=process.env){try{let t=fr(e);if(!or(t))return"";let r=ar(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function wr(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),sr)}function br({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[dr]||"").trim(),o=String(e[pr]||mr).trim();if(r===!0)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"admin-oracle"};let s=ur(t),u=wr(e[lr],{fallback:n?s:0}),c=Math.min(u,s);if(!c)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"no-recipient"};let i=hr(e);return!i||i!==n.toLowerCase()?{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:c,recipient:n,integrator:o,action:t,applies:!0,reason:"configured"}}async function z({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:o=!1}={}){let s=br({env:t,action:r,admin:o});if(o===!0)return{...s,holderVerificationStatus:"admin-oracle"};let u=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(u))return{...s,holderVerificationStatus:"wallet-required"};try{return BigInt(await Ne(u,n))>0n?{...s,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...s,holderVerificationStatus:"non-holder"}}catch{return{...s,holderVerificationStatus:"unavailable"}}}function Le(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 Fe(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}function De(e){return e?.applies?{partner:e.integrator,partnerFeeBps:String(e.bps),partnerAddress:e.recipient}:{}}var gr="https://li.quest/v1";function Er(e={}){return(e.baseUrl||process.env.LIFI_API_URL||gr).replace(/\/$/,"")}var yr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";async function ie(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=yr,toToken:s,fromAmount:u,fromAddress:c=$}=e;if(r==null||!s||!u)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let i=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:s,fromAmount:String(u),fromAddress:c}),d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`lifi: route requires ${d.requiredBps} bps above cap ${d.capBps}`);i.set("slippage",String(d.selectedBps/1e4));let p=await z({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[b,f]of Object.entries(Fe(p)))i.set(b,f);let l=await y(`${Er(t)}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.estimate?.toAmount||l?.toAmount;if(!a)return{...l,autoSlippagePolicy:d,oracleFee:p};let m=l?.transactionRequest?.to||l?.estimate?.approvalAddress||"lifi",h=A(l,{chainId:Number(r),venue:m,amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),w=l?.estimate?.toAmountMin||l?.toAmountMin;if(w!=null&&BigInt(w)<BigInt(h.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...h,oracleFee:p}}I();R();B();var Ar="https://api.paraswap.io",xr=(e={})=>(e.baseUrl||process.env.PARASWAP_API_URL||Ar).replace(/\/$/,"");function Me(e,t){let r=String(e||"");if(!/^0x[0-9a-fA-F]{40}$/.test(r))throw new Error(`${t} must be a 20-byte token address`);return r.toLowerCase()}async function qe(e={},t={}){let r=Number(e.chainId||e.network||1);if(e.amount==null)throw new Error("amount required");let n=new URLSearchParams({srcToken:Me(e.srcToken,"srcToken"),destToken:Me(e.destToken,"destToken"),amount:String(e.amount),srcDecimals:String(Number(e.srcDecimals)),destDecimals:String(Number(e.destDecimals)),side:String(e.side||"SELL").toUpperCase(),network:String(r),version:String(e.version||"6.2")});e.includeDEXS&&n.set("includeDEXS",String(e.includeDEXS)),e.excludeDEXS&&n.set("excludeDEXS",String(e.excludeDEXS));let o=await z({wallet:e.userAddress||e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[c,i]of Object.entries(De(o)))n.set(c,i);let s=await y(`${xr(t)}/prices?${n}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=s?.priceRoute?.destAmount;return u?{...A(s,{chainId:r,venue:s?.priceRoute?.contractAddress||"paraswap-quote",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,quoteAgeMs:0,requestedCapBps:e.maxSlippageBps??e.slippageBps}),executionReady:!1,executionBlocker:"call prepare to bind the price route to a validated transaction",oracleFee:o}:{...s,executionReady:!1,oracleFee:o}}I();R();var He="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function G({provider:e,defaultUrl:t,hosts:r=[],url:n,strict:o=!1}){let u=(String(n??"").trim()||String(t)).replace(/\/$/,"");if(u===String(t).replace(/\/$/,""))return{baseUrl:u,trusted:!0,host:Ve(t)};let c;try{c=new URL(u)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let i=c.host;if(!i)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Ve(t),...r]).has(i)){let p=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(i);return c.protocol==="http:"&&!p?{baseUrl:u,trusted:!1,host:i,reason:"plaintext http downgrade"}:{baseUrl:u,trusted:!0,host:i}}if(String(process.env[He]||"")==="1")return{baseUrl:u,trusted:!1,host:i};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${i} (set ${He}=1 to permit it)`);return{baseUrl:u,trusted:!1,host:i}}function Ve(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function X(e,t,r){let n={...e};if(!r)return n;for(let[o,s]of Object.entries(t||{}))s&&(n[o]=s);return n}B();var Sr="https://api.0x.org";function je(e={}){return G({provider:"zerox",defaultUrl:Sr,hosts:["api.0x.org"],url:e.baseUrl||process.env.ZEROX_API_URL})}function Ir(e={}){return je(e).baseUrl}function ze(e={}){return e.apiKey||process.env.ZEROX_API_KEY||process.env.OX_API_KEY||process.env["0X_API_KEY"]||""}function Cr(e={}){return X({"0x-version":"v2",accept:"application/json"},{"0x-api-key":ze(e)},je(e).trusted)}async function Ge(e={},t={}){if(!ze(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:s,taker:u}=e;if(!n||!o||!s)throw new Error("zeroxQuote requires sellToken, buyToken, sellAmount");let c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!c.executable)throw new Error(`0x: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(s),slippageBps:String(c.selectedBps)});u&&i.set("taker",u);let d=await y(`${Ir(t)}/swap/allowance-holder/quote?${i}`,{headers:Cr(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),p=d?.buyAmount||d?.grossBuyAmount;return p?A(d,{chainId:r,venue:d?.transaction?.to||d?.to||"0x",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):{...d,autoSlippagePolicy:c}}I();R();B();var vr="https://api.1inch.dev/swap/v6.0";function Xe(e={}){return G({provider:"oneinch",defaultUrl:vr,hosts:["api.1inch.dev"],url:e.baseUrl||process.env.ONEINCH_API_URL})}function kr(e={}){return Xe(e).baseUrl}function Ye(e={}){return e.apiKey||process.env.ONEINCH_API_KEY||process.env.ONE_INCH_API_KEY||""}function _r(e={}){let t=Ye(e);return X({accept:"application/json"},{Authorization:t?`Bearer ${t}`:""},Xe(e).trusted)}async function Ke(e={},t={}){if(!Ye(t))throw new Error("ONEINCH_API_KEY required for 1inch");let r=Number(e.chainId??1),{src:n,dst:o,amount:s}=e;if(!n||!o||!s)throw new Error("oneinchQuote requires src, dst, amount");let u=new URLSearchParams({src:n,dst:o,amount:String(s)}),c=await y(`${kr(t)}/${r}/quote?${u}`,{headers:_r(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3});return c?.dstAmount?A(c,{chainId:r,venue:"1inch-quote",amountOut:c.dstAmount,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):c}I();R();import{TypedDataEncoder as Oo,getAddress as Ro,isAddress as To}from"ethers";var Co=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});j();B();var Or={1:"https://api.cow.fi/mainnet/api/v1",100:"https://api.cow.fi/xdai/api/v1",42161:"https://api.cow.fi/arbitrum_one/api/v1",8453:"https://api.cow.fi/base/api/v1"},Fo=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Do=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"}),Qe={1:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",8453:"0x4200000000000000000000000000000000000006",42161:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"},Rr={1:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",8453:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",42161:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},Mo=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"}]}),qo=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});function Tr(e,t={}){if(t.baseUrl)return t.baseUrl.replace(/\/$/,"");let r=Or[Number(e)];if(!r)throw new Error(`cowswap: unsupported chainId ${e}`);return r}async function We(e={},t={}){let r=Number(e.chainId??1),n=Re(e.from||e.owner),o=e.sellToken||Qe[r],s=e.buyToken||Rr[r],u=String(e.sellAmountBeforeFee||e.sellAmount||"0");if(!o||!s||u==="0")throw new Error("cowQuote requires sellToken, buyToken, sellAmountBeforeFee");if(/eeeeeeee|native|^eth$/i.test(o)&&(o=Qe[r],!o))throw new Error("no WETH mapping for chain");let c={sellToken:o,buyToken:s,from:n,receiver:e.receiver||n,sellAmountBeforeFee:u,kind:e.kind||"sell",signingScheme:e.signingScheme||"eip1271"},i=await y(`${Tr(r,t)}/quote`,{method:"POST",body:c,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),d=i?.quote?.buyAmount||i?.buyAmount;return d?A(i,{chainId:r,venue:"cowswap-order",amountOut:d,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):i}import{Interface as nt,getAddress as Q,isAddress as zr}from"ethers";I();var Je={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}},Br=new Map(Object.values(Je).map(e=>[e.chainId,e]));function Ze(e){return Br.get(Number(e))||null}function et(e,t=process.env){let r=Ze(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as Nr,getAddress as Yo}from"ethers";var Ko=new Nr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Pr={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};function Ur(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=et(e,r);return n||Pr[Number(e)]||null}var $r=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Lr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!$r.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}async function Y(e,t,r=[],n={}){let o=String(t||"");Lr(o);let s=Ur(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let c=await y(s,{method:"POST",body:{jsonrpc:"2.0",id:1,method:t,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3});if(c?.error){let i=new Error(c.error.message||JSON.stringify(c.error));throw i.code=c.error.code,i}return c.result}I();var Fr="https://api.dexscreener.com",Dr=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"}),x=e=>String(e??"").toLowerCase(),Mr=e=>Array.isArray(e)?e:e==null?[]:[e];function qr(e,t,r){let n=x(t),o=x(r),s=x(e?.baseToken?.address),u=x(e?.quoteToken?.address);return s===n&&u===o||s===o&&u===n}function Hr(e){let t=Number(e?.liquidity?.usd);return Number.isFinite(t)&&t>=0?t:null}function Vr(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||Fr).replace(/\/$/,"")}async function jr(e,t={}){if(!e)throw new Error("tokenAddress required");return y(`${Vr(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}async function K({chainId:e,tokenA:t,tokenB:r,dexIds:n=[]}={},o={}){if(e==null||!t||!r)throw new Error("chainId, tokenA, and tokenB required");let s=x(Dr[Number(e)]||e),u=new Set(Mr(n).filter(Boolean).map(x)),c=[...new Set([t,r].map(a=>String(a)).filter(Boolean))],i=await Promise.allSettled(c.map(a=>jr(a,{...o,baseUrl:o.dexscreenerBaseUrl,timeoutMs:o.dexscreenerTimeoutMs??Math.min(Number(o.timeoutMs??4e3),4e3)}))),d=new Set,p=[];for(let a of i)if(a.status==="fulfilled")for(let m of a.value?.pairs||a.value?.data?.pairs||[]){let h=`${x(m?.chainId)}:${x(m?.dexId)}:${x(m?.pairAddress)}`;d.has(h)||(d.add(h),p.push(m))}return p.filter(a=>x(a?.chainId)===s).filter(a=>qr(a,t,r)).filter(a=>!u.size||u.has(x(a?.dexId))).map(a=>({pairAddress:a.pairAddress??null,dexId:a.dexId??null,chainId:a.chainId??null,liquidityUsd:Hr(a),pairCreatedAt:a.pairCreatedAt??null})).filter(a=>a.liquidityUsd!=null).sort((a,m)=>m.liquidityUsd-a.liquidityUsd)[0]??null}R();B();var L={1:{name:"ethereum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},8453:{name:"base",quoter:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",router:"0x2626664c2603336E57B271c5C0b26F421741e481",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},4663:{name:"robinhood",quoter:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",router:"0xcaf681a66d020601342297493863e78c959e5cb2",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"},999:{name:"hyperevm",weth:"0x5555555555555555555555555555555555555555",usdc:"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"},10:{name:"optimism",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",quoter:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",router:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},43114:{name:"avalanche",quoter:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",router:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}},Gr=[100,500,3e3,1e4],tt=new nt(["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)"]),oa=new nt(["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)"]),Xr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Yr="0x0000000000000000000000000000000000000000",se=[100,500,2500,1e4],Kr={56:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},8453:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},42161:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},999:{hyperswap:{name:"hyperswap",quoter:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",router:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D"}}};function Qr(e,t){let r=Number(e),n=L[r];if(!n)throw new Error(`uniswap-v3: unsupported chainId ${e} (supported: ${Object.keys(L).join(", ")})`);let o=Kr[r]||{};if(!t){if(!n.quoter||!n.router){let i=Object.keys(o).join(", ")||"none registered";throw new Error(`uniswap-v3: chain ${r} (${n.name}) has no canonical Uniswap v3 deployment -- name a venue explicitly (known: ${i})`)}return{chainId:r,venue:n.name,...n}}let s=String(t).toLowerCase();if(s===n.name&&n.quoter&&n.router)return{chainId:r,venue:n.name,...n};let u=o,c=u[s];if(!c){let i=[...n.quoter&&n.router?[n.name]:[],...Object.keys(u)].join(", ");throw new Error(`uniswap-v3: unknown venue "${t}" on chain ${r} (known: ${i})`)}return{chainId:r,venue:s,...n,quoter:c.quoter,router:c.router,feeTiers:c.feeTiers||null}}function rt(e,t){let r=L[Number(t)];if(!e||e===Xr||e===Yr||/^eth$/i.test(String(e)))return Q(r.weth);let n=String(e);if(/^weth$/i.test(n))return Q(r.weth);if(/^usdc$/i.test(n))return Q(r.usdc);if(!zr(n))throw new Error(`invalid token address: ${e}`);return Q(n)}function Wr(e){let t=String(e||"uniswap").toLowerCase();return t==="uniswap"?["uniswap-v3","uniswap"]:t==="pancakeswap"?["pancakeswap-v3","pancakeswap"]:t==="hyperswap"?["hyperswap-v3","hyperswap"]:[t,`${t}-v3`]}async function ot(e={},t={}){let{chainId:r,quoter:n,router:o,feeTiers:s}=Qr(e.chainId??8453,e.venue),u=rt(e.tokenIn||"WETH",r),c=rt(e.tokenOut||L[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");let d=s&&s.length?s:Gr,p=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[d[Math.min(2,d.length-1)]]:[...d],l=[],a=null;for(let w of p){let b=tt.encodeFunctionData("quoteExactInputSingle",[{tokenIn:u,tokenOut:c,amountIn:i,fee:w,sqrtPriceLimitX96:0n}]);try{let f=await Y(r,"eth_call",[{to:n,data:b},"latest"],t);if(!f||f==="0x"){l.push({fee:w,ok:!1,error:"empty result"});continue}let g=tt.decodeFunctionResult("quoteExactInputSingle",f),E={fee:w,ok:!0,amountOut:g[0].toString(),sqrtPriceX96After:g[1].toString(),initializedTicksCrossed:Number(g[2]),gasEstimate:g[3].toString()};l.push(E),(!a||BigInt(E.amountOut)>BigInt(a.amountOut))&&(a=E)}catch(f){l.push({fee:w,ok:!1,error:String(f.message||f).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:Wr(e.venue)},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v3",chainId:r,chain:L[r].name,quoter:n,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,sqrtPriceX96After:a.sqrtPriceX96After,initializedTicksCrossed:a.initializedTicksCrossed,triedFees:l,best:!0},{chainId:r,venue:o,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}import{AbiCoder as Jr,Interface as st,getAddress as C,isAddress as W,keccak256 as Zr}from"ethers";R();B();var en=Jr.defaultAbiCoder(),D="0x0000000000000000000000000000000000000000",F={1:{name:"ethereum",poolManager:"0x000000000004444c5dc75cB358380D2e3dE08A90",quoter:"0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203",stateView:"0x7ffe42c4a5deea5b0fec41c94c136cf115597227",universalRouter:"0x66a9893cc07d91d95644aedd05d03f95e1dba8af",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},10:{name:"optimism",poolManager:"0x9a13f98cb987694c9f086b1f5eb990eea8264ec3",quoter:"0x1f3131a13296fb91c90870043742c3cdbff1a8d7",stateView:"0xc18a3169788f4f75a170290584eca6395c75ecdb",universalRouter:"0x851116d9223fabed8e56c0e6b8ad0c31d98b3507",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",poolManager:"0x28e2ea090877bf75740558f6bfb36a5ffee9e9df",quoter:"0x9f75dd27d6664c475b90e105573e550ff69437b0",stateView:"0xd13dd3d6e93f276fafc9db9e6bb47c1180aee0c4",universalRouter:"0x1906c1d672b88cd1b9ac7593301ca990f94eae07",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",poolManager:"0x67366782805870060151383f4bbff9dab53e5cd6",quoter:"0xb3d5c3dfc3a7aebff71895a7191796bffc2c81b9",stateView:"0x5ea1bd7974c8a611cbab0bdcafcb1d9cc9b3ba5a",universalRouter:"0x1095692a6237d83c6a72f3f5efedb9a670c49223",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},8453:{name:"base",poolManager:"0x498581fF718922c3f8e6A244956aF099B2652b2b",quoter:"0x0d5e0f971ed27fbff6c2837bf31316121532048d",stateView:"0xa3c0c9b65bad0b08107aa264b0f3db444b867a71",universalRouter:"0x6ff5693b99212da76ad316178a184ab56d299b43",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",poolManager:"0x360e68faccca8ca495c1b759fd9eee466db9fb32",quoter:"0x3972c00f7ed4885e145823eb7c655375d275a1c5",stateView:"0x76fd297e2d437cd7f76d50f01afe6160f86e9990",universalRouter:"0xa51afafe0263b40edaef0df8781ea9aa03e381a3",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},43114:{name:"avalanche",poolManager:"0x06380c0e0912312b5150364b9dc4542ba0dbbc85",quoter:"0xbe40675bb704506a3c2ccfb762dcfd1e979845c2",stateView:"0xc3c9e198c735a4b97e3e683f391ccbdd60b69286",universalRouter:"0x94b75331ae8d42c1b61065089b7d48fe14aa73b7",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"},4663:{name:"robinhood",poolManager:"0x8366a39cc670b4001a1121b8f6a443a643e40951",quoter:"0x8dc178efb8111bb0973dd9d722ebeff267c98f94",stateView:"0xf3334192d15450cdd385c8b70e03f9a6bd9e673b",universalRouter:"0x8876789976dEcBfCbBbe364623C63652db8C0904",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"}},tn=[{fee:100,tickSpacing:1},{fee:500,tickSpacing:10},{fee:3e3,tickSpacing:60},{fee:1e4,tickSpacing:200},{fee:25e3,tickSpacing:8}],at=new st(["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)"]),da=new st(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);var rn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";function nn(e){let t=Number(e),r=F[t];if(!r)throw new Error(`uniswap-v4: unsupported chainId ${e} (supported: ${Object.keys(F).join(", ")})`);return{chainId:t,...r}}function it(e,t){let r=F[Number(t)];if(!e||e===rn||e===D||/^eth$/i.test(String(e)))return C(r.weth);let n=String(e);if(/^weth$/i.test(n))return C(r.weth);if(/^usdc$/i.test(n)||/^usdg$/i.test(n))return C(r.usdc);if(!W(n))throw new Error(`invalid token address: ${e}`);return C(n)}function on({currency0:e,currency1:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t);if(s.toLowerCase()===u.toLowerCase())throw new Error("poolKey currencies must differ");let[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=o&&W(o)?C(o):D;return Zr(en.encode(["address","address","uint24","int24","address"],[c,i,Number(r),Number(n),d]))}function an({tokenIn:e,tokenOut:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t),[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=s.toLowerCase()===c.toLowerCase();return{poolKey:{currency0:c,currency1:i,fee:Number(r),tickSpacing:Number(n),hooks:o&&W(o)?C(o):D},zeroForOne:d}}var sn=["uniswap-v4","uniswapv4"];async function ct(e={},t={}){let{chainId:r,quoter:n,poolManager:o,universalRouter:s}=nn(e.chainId??8453),u=it(e.tokenIn||"WETH",r),c=it(e.tokenOut||F[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");if(i>0xffffffffffffffffffffffffffffffffn)throw new Error("amountIn exceeds uint128");let d=e.fee!=null&&e.tickSpacing!=null?[{fee:Number(e.fee),tickSpacing:Number(e.tickSpacing)}]:e.tryTiers===!1?[{fee:500,tickSpacing:10}]:[...tn],p=e.hooks||D,l=[],a=null;for(let w of d){let{poolKey:b,zeroForOne:f}=an({tokenIn:u,tokenOut:c,fee:w.fee,tickSpacing:w.tickSpacing,hooks:p}),g=at.encodeFunctionData("quoteExactInputSingle",[{poolKey:b,zeroForOne:f,exactAmount:i,hookData:"0x"}]);try{let E=await Y(r,"eth_call",[{to:n,data:g},"latest"],t);if(!E||E==="0x"){l.push({...w,ok:!1,error:"empty result"});continue}let k=at.decodeFunctionResult("quoteExactInputSingle",E),_={fee:w.fee,tickSpacing:w.tickSpacing,ok:!0,amountOut:k[0].toString(),gasEstimate:k[1].toString(),poolKey:b,zeroForOne:f,poolId:on({...b})};l.push(_),(!a||BigInt(_.amountOut)>BigInt(a.amountOut))&&(a=_)}catch(E){l.push({...w,ok:!1,error:String(E.message||E).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}/${b.tickSpacing}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v4 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:sn},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v4",chainId:r,chain:F[r].name,poolManager:o,quoter:n,universalRouter:s||null,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,tickSpacing:a.tickSpacing,hooks:a.poolKey.hooks,poolId:a.poolId,zeroForOne:a.zeroForOne,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,triedTiers:l,best:!0,executionReady:!1,prepareReady:typeof e.recipient=="string"&&W(e.recipient)&&e.slippageBps!=null},{chainId:r,venue:s||n,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}I();var cn="https://coins.llama.fi",un="https://api.llama.fi";function ln(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||cn).replace(/\/$/,"")}function dn(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||un).replace(/\/$/,"")}async function J(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return y(`${ln(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function ut(e={}){return y(`${dn(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var v=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function Z(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=v(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}async function wt(e,t={}){let r=we[Number(e)];if(!r)return null;try{let n=await J([r],t);return v(n?.coins?.[r]?.price)}catch{return null}}var N=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),ht=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 bn(e={}){try{let t=await ut({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function gn(e,t={}){let r=N(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...ht[r]||[r]),n.push(...ht[N(e)]||[e]),n}function En(e,t,r={}){let n=Array.isArray(e)?e:[],o=gn(t,r).map(N).filter(Boolean);for(let s of o){let u=n.find(i=>N(i?.slug)===s||N(i?.name)===s),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}for(let s of o){let u=n.find(i=>{let d=N(i?.category);return!d.includes("bridge")&&!d.includes("crosschain")?!1:N(i?.slug).includes(s)||N(i?.name).includes(s)}),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}return null}function de({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:s,decimalsIn:u,decimalsOut:c,nativePriceUsd:i=null,destDecimalsPromise:d=null,opts:p={}}){let l=[];return l.push({source:"lifi",run:async()=>{let a=await ie({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n},p),m=a?.estimate??a?.[0]?.estimate;return{amountOut:m?.toAmount,minOut:m?.toAmountMin,gasUsd:Z(m?.gasCosts),feeUsd:Z(m?.feeCosts),oracleFeeBps:a?.oracleFee?.applies?a.oracleFee.bps:0,meta:{tool:a?.tool??a?.toolDetails?.name,oracleFee:a?.oracleFee??null}}}}),u!=null&&l.push({source:"paraswap",run:async()=>{let a=c??(await Promise.resolve(d))?.decimals;if(a==null)throw new Error("paraswap needs destination decimals; none supplied or resolvable");let m=await qe({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:u,destDecimals:a},p),h=m?.priceRoute;return{amountOut:h?.destAmount,gasUsd:v(h?.gasCostUSD),oracleFeeBps:m?.oracleFee?.applies?m.oracleFee.bps:0,meta:{bestRoute:h?.bestRoute?.[0]?.swaps?.[0]?.swapExchanges?.[0]?.exchange,oracleFee:m?.oracleFee??null}}}}),process.env.ZEROX_API_KEY&&l.push({source:"0x",run:async()=>{let a=await Ge({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},p),m=null,h=a?.totalNetworkFee,w=await Promise.resolve(i);return h!=null&&w&&(m=Number(h)/1e18*w),{amountOut:a?.buyAmount,minOut:a?.minBuyAmount,gasUsd:m,meta:{source:a?.route?.fills?.[0]?.source}}}}),process.env.ONEINCH_API_KEY&&l.push({source:"1inch",run:async()=>{let a=await Ke({chainId:e,src:t,dst:r,amount:n},p),m=null;return a?.gas!=null&&i&&(m=null),{amountOut:a?.dstAmount,gasUsd:m,meta:{gasUnits:a?.gas}}}}),l.push({source:"cow",run:async()=>{let a=await We({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},p),m=a?.quote??a,h=m?.feeAmount;return{amountOut:m?.buyAmount,gasUsd:0,meta:{intent:!0,feeAmountInSellToken:h,settlement:"solver-executed"}}}}),L[Number(e)]&&l.push({source:"uniswap-v3",run:async()=>{let a=await ot({chainId:e,tokenIn:t,tokenOut:r,amountIn:n},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,fee:a?.fee,gasUnits:a?.gasEstimate,quoter:a?.quoter}}}}),F[Number(e)]&&l.push({source:"uniswap-v4",run:async()=>{let a=await ct({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:s},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,venue:"uniswap-v4",fee:a?.fee,tickSpacing:a?.tickSpacing,poolId:a?.poolId,hooks:a?.hooks,gasUnits:a?.gasEstimate,quoter:a?.quoter,poolManager:a?.poolManager,prepareReady:a?.prepareReady===!0,executionReady:!1}}}}),l}function bt({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:s,opts:u={}}){let c=[],i=null,d=async(p,l={})=>(i||=bn(u),En(await i,p,l));return c.push({source:"lifi",run:async()=>{let p=await ie({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},u),l=p?.estimate??p?.[0]?.estimate,a={tool:p?.tool??p?.toolDetails?.name,durationSeconds:v(l?.executionDuration)},m=await d("lifi",a);return{amountOut:l?.toAmount,minOut:l?.toAmountMin,gasUsd:Z(l?.gasCosts),feeUsd:Z(l?.feeCosts),oracleFeeBps:p?.oracleFee?.applies?p.oracleFee.bps:0,liquidityUsd:m?.liquidityUsd??null,meta:{...a,liquidityProtocol:m?.protocol,oracleFee:p?.oracleFee??null}}}}),c.push({source:"relay",run:async()=>{let{relayQuote:p}=await Promise.resolve().then(()=>(le(),ue)),a=(await p({user:s,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},u))?.details,m={durationSeconds:v(a?.timeEstimate),rate:a?.rate},h=await d("relay",m);return{amountOut:a?.currencyOut?.amount,minOut:a?.currencyOut?.minimumAmount,gasUsd:v(a?.totalImpact?.usd)!=null?Math.abs(v(a.totalImpact.usd)):null,liquidityUsd:h?.liquidityUsd??null,meta:{...m,liquidityProtocol:h?.protocol}}}}),c.push({source:"across",run:async()=>{let{acrossSuggestedFees:p}=await Promise.resolve().then(()=>(le(),ue)),l=await p({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},u),a=l?.totalRelayFee?.total,m=null;if(a!=null)try{let w=BigInt(String(o))-BigInt(String(a));w>0n&&(m=w.toString())}catch{}let h=await d("across");return{amountOut:m,gasUsd:null,liquidityUsd:h?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:v(l?.estimatedFillTimeSec),limits:l?.limits?{min:l.limits.minDeposit,max:l.limits.maxDeposit}:void 0,liquidityProtocol:h?.protocol}}}}),c}var yn={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function gt(e,t,r){let n=yn[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let u=(await J([o],r))?.coins?.[o],c=Number(u?.price),i=Number(u?.decimals);return{priceUsd:Number.isFinite(c)?c:null,decimals:Number.isFinite(i)?i:null}}catch{return{priceUsd:null,decimals:null}}}async function Pa(e,t={}){let{chainId:r,tokenIn:n,tokenOut:o,amountIn:s}=e;if(r==null||!n||!o||s==null)throw new Error("bestSwapRoute requires chainId, tokenIn, tokenOut, amountIn");let u=wt(r,t),c=gt(r,o,t),i=de({...e,nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??12e3}),c]);u.catch(()=>{});let l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=t.maxImpactPct===void 0?25:t.maxImpactPct;if(a!=null&&l.best){let m=l.best.source,w=await be(async b=>{let f=de({...e,amountIn:b.toString(),nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}).filter(E=>E.source===m);return f.length?(await H(f,{timeoutMs:t.timeoutMs??12e3}))?.[0]?.amountOut??null:null},s);if(w){let b=ge(l,{[m]:w},{maxImpactPct:a});return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...b,sourcesTried:i.length,sourcesAnswered:d.filter(f=>f.quality!==S.FAILED).length,note:pe(b,i.length),priceImpact:{[m]:Number(w.impactPct.toFixed(2))}}}}return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...l,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}async function Ua(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:u}=e;if(r==null||n==null||!o||!s||u==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 c=gt(n,s,t),i=bt({...e,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??15e3}),c]),l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=l.routes.map(m=>({source:m.source,seconds:m.meta?.durationSeconds??null})).filter(m=>m.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:String(u),...l,durations:a,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}function An(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Le(t)}`:""}function pe(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=An(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 o=e.improvementBps,s=o/100;if(o<.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 u=s>=.01?`${s.toFixed(2)}%`:`${o.toFixed(2)}bps`;return`best of ${r} routes, ranked on ${e.rankedOn}: ${u} 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}export{S as QUALITY,Ua as bestBridgeRoute,Pa as bestSwapRoute,pe as formatComparisonNote};
@@ -1,2 +1,2 @@
1
1
  var je=Object.defineProperty;var S=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var re=(e,t)=>{for(var r in t)je(e,r,{get:t[r],enumerable:!0})};import{createHash as ze}from"node:crypto";function Ye(e){let t=String(e||"").toLowerCase();return le.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function Qe(e){let t={};for(let[r,n]of Object.entries(e||{}))Ye(r)||(t[r]=n);return t}function We(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 Je(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Ze(e,t,r){let n={};for(let[s,l]of Object.entries(r||{}))n[s.toLowerCase()]=l;let o=Object.keys(n).filter(s=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(s)),i=[...new Set([...le,...o])].sort().map(s=>`${s}=${n[s]??""}`).join(`
2
- `),c=ze("sha256").update(i).digest("hex").slice(0,32);return`${e} ${t} ${c}`}function et(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ce):Math.min(250*2**e,ce)+Math.floor(Math.random()*100)}async function rt(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:a}){let i=new AbortController,c=setTimeout(()=>i.abort(),a);try{let s=String(e),l={...n||{}};for(let d=0;d<=ue;d+=1){let u=await t(s,{method:r,headers:l,body:o,signal:i.signal,redirect:"manual"}),p=await u.text(),m=null;if(p)try{m=JSON.parse(p)}catch{m=null}if(Ke.has(u.status)){if(r!=="GET"&&r!=="HEAD"){let b=new Error(`HTTP ${u.status} ${r} ${s} redirected non-idempotent request`);throw b.status=u.status,b.body=m??p.slice(0,300),b}if(d===ue)throw new Error(`HTTP redirect loop for ${e}`);let w=We(u.headers?.get?.("location"),s);Je(w,s)||(l=Qe(l)),s=w;continue}if(!u.ok){let w=new Error(`HTTP ${u.status} ${r} ${s}`);throw w.status=u.status,w.retryAfter=u.headers?.get?.("retry-after")??null,w.body=m??p.slice(0,300),w}return m??p}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(c)}}async function E(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,o=(t.method||"GET").toUpperCase(),a={Accept:"application/json",...t.headers||{}},i=t.body;i!=null&&typeof i!="string"&&(a["Content-Type"]=a["Content-Type"]||"application/json",i=JSON.stringify(i));let c=Number.isInteger(t.retries)?Math.max(t.retries,0):Xe,s=async()=>{let m;for(let w=0;w<=c;w++)try{return await rt(e,{fetchImpl:r,method:o,headers:a,body:i,timeoutMs:n})}catch(b){m=b;let f=b?.status,h=b?.name==="AbortError",g=new Set([408,425,429]),y=f!=null?g.has(f)||Ge.has(f)&&se.has(o):!h&&se.has(o);if(w===c||!y)throw b;await tt(et(w,b?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&i==null))return s();let d=Ze(o,e,a),u=j.get(d);if(u)return u;let p=s().finally(()=>j.delete(d));return j.set(d,p),p}var Ge,se,Xe,ce,le,Ke,ue,j,tt,I=S(()=>{Ge=new Set([408,425,429,500,502,503,504]),se=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Xe=2,ce=4e3,le=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ke=new Set([301,302,303,307,308]),ue=3;j=new Map;tt=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as nt}from"node:fs";import{homedir as ot}from"node:os";import{join as U}from"node:path";function at(){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=ot();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||U(t,".config","oracle")).trim();return[e,U(r,"exec.env")].filter(Boolean)}return[e,U(t,".config","oracle","exec.env"),U(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 o of at())try{let a=nt(o,"utf8"),i=a.match(new RegExp(`^${t}=(.*)$`,"m"))||a.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 pe=S(()=>{});var me=S(()=>{});import{createHash as it,createHmac as st,timingSafeEqual as $r}from"node:crypto";function G(e){return Array.isArray(e)?`[${e.map(G).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${G(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function ct(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 we(e){let{signature:t,...r}=e;return r}function ge(e,{secret:t}={}){let r=ct(t);return r?{...e,signature:st("sha256",r).update(G(we(e))).digest("hex")}:e}function ut(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 it("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function B(e,{chainId:t,venue:r,data:n,secret:o}={}){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");return ge({...we(e),calldataHash:ut(n)},{secret:o})}function z(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function lt(e){let t=e==null?fe: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,fe)}function T({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let a=z(e,0),i=a>0?a>=25e4?5:a>=1e5?10:a>=5e4?20:a>=1e4?40:70:n?30:10,c=Math.min(60,Math.abs(z(t,0))*2),s=Math.min(40,Math.floor(Math.max(0,z(r,0))/5e3)*5),l=Math.max(25,Math.ceil(20+i+c+s)),d=lt(o);return{mode:"auto",requiredBps:l,selectedBps:Math.min(l,d),capBps:d,executable:l<=d}}function dt({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:a=0,crossChain:i=!1,requestedCapBps:c,quotedAtMs:s=Date.now(),ttlMs:l=he,secret:d}={}){let u=BigInt(r??0);if(u<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let p=T({liquidityUsd:n,priceChange5m:o,quoteAgeMs:a,crossChain:i,requestedCapBps:c});if(!p.executable)throw new Error(`auto-slippage requires ${p.requiredBps} bps above hard/requested cap ${p.capBps}; route blocked`);let m=Number(s);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let w=Math.min(3e4,Math.max(1e3,Number(l)||he)),b=u*BigInt(1e4-p.selectedBps),f=b/10000n;if(b%10000n!==0n&&(f+=1n),f>u&&(f=u),u>0n&&f<=0n)throw new Error(`auto-slippage: quote ${u} is too small to express a ${p.selectedBps} bps floor without rounding to zero`);let h=Number((u-f)*10000n/(u===0n?1n:u));if(h>p.capBps)throw new Error(`auto-slippage: realised floor implies ${h} bps, above cap ${p.capBps} \u2014 refusing to issue a guard weaker than advertised`);return ge({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:u.toString(),minAmountOut:f.toString(),requiredBps:p.requiredBps,selectedBps:p.selectedBps,capBps:p.capBps,quotedAtMs:m,expiresAtMs:m+w},{secret:d})}function x(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:a,crossChain:i,requestedCapBps:c,quotedAtMs:s=Date.now(),ttlMs:l}={}){let d=dt({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:a,crossChain:i,requestedCapBps:c,quotedAtMs:s,ttlMs:l});return{...e,autoSlippage:d,amountOutMinimum:d.minAmountOut}}var fe,he,k=S(()=>{pe();me();fe=100,he=2e4});var P,L=S(()=>{P="0x000000000000000000000000000000000000dEaD"});import{createHash as pt,createHmac as mt,timingSafeEqual as Mr}from"node:crypto";function X(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(X).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${X(e[r])}`).join(",")}}`}function be(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Ee(e=process.env){return be(process.env)||be(e)}function wt(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...a}=e||{};return a}function gt(e){let t=wt(e);return pt("sha256").update(X(t)).digest("hex")}function bt(e,t=Ee()){return t?mt("sha256",t).update(String(e)).digest("hex"):""}function A(e,{provider:t,kind:r,env:n=process.env}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let o={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!o.provider)throw new Error("stampPrepared: provider required");if(!o.kind)throw new Error("stampPrepared: kind required");let a=Date.now(),i=a+ht,s={...o,preparedAt:a,expiresAt:i,prepareVersion:ft},l=gt(s),d=Ee(n),u=d?bt(l,d):void 0,p={...s,oraclePrepared:!0,prepareHash:l};return u&&(p.prepareMac=u),p}var ft,ht,qr,C=S(()=>{ft=2,ht=300*1e3,qr=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});import{Contract as Et,JsonRpcProvider as yt}from"ethers";function vt(e){return Ct.test(String(e||""))}async function ye(e,{contract:t=At,rpc:r=St,chainId:n=xt,balanceOf:o}={}){if(!vt(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let a=new yt(r,n,{staticNetwork:!0}),i=new Et(t,It,a);return BigInt(await i.balanceOf(e))}var At,xt,St,It,Ct,Ae=S(()=>{At="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",xt=999,St="https://rpc.hyperliquid.xyz/evm",It=["function balanceOf(address owner) view returns (uint256)"],Ct=/^0x[a-fA-F0-9]{40}$/});import{existsSync as kt,readFileSync as Ot}from"node:fs";import{homedir as _t}from"node:os";import{join as xe}from"node:path";function Tt(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(Se,t)?Se[t]:Bt}function Lt(e=process.env){if(e[Ie])return String(e[Ie]);let t=e.ORACLE_CONFIG_DIR||xe(_t(),".config","oracle");return xe(t,"fee-recipient")}function Dt(e=process.env){try{let t=Lt(e);if(!kt(t))return"";let r=Ot(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function Ft(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),Rt)}function Mt({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[$t]||"").trim(),o=String(e[Pt]||Ut).trim();if(r===!0)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"admin-oracle"};let a=Tt(t),i=Ft(e[Nt],{fallback:n?a:0}),c=Math.min(i,a);if(!c)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"no-recipient"};let s=Dt(e);return s&&s!==n.toLowerCase()?{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:c,recipient:n,integrator:o,action:t,applies:!0,reason:"configured"}}async function K({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:o=!1}={}){let a=Mt({env:t,action:r,admin:o});if(o===!0)return{...a,holderVerificationStatus:"admin-oracle"};let i=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(i))return{...a,holderVerificationStatus:"wallet-required"};try{return BigInt(await ye(i,n))>0n?{...a,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...a,holderVerificationStatus:"non-holder"}}catch{return{...a,holderVerificationStatus:"unavailable"}}}function Ce(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 ve(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}var Rt,Bt,Se,Nt,$t,Pt,Ie,Ut,D=S(()=>{Ae();Rt=100,Bt=5,Se=Object.freeze({swap:5,bridge:5,perps:0,nft:0});Nt="ORACLE_INTEGRATOR_FEE_BPS",$t="ORACLE_INTEGRATOR_FEE_RECIPIENT",Pt="ORACLE_INTEGRATOR_ID",Ie="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",Ut="oracle"});var _e={};re(_e,{LIFI_API:()=>Oe,lifiChains:()=>zt,lifiHealth:()=>Vt,lifiPrepare:()=>jt,lifiQuote:()=>F});function Q(e={}){return(e.baseUrl||process.env.LIFI_API_URL||Oe).replace(/\/$/,"")}function Ht(e){let t=String(e||Y).toLowerCase();return t===Y.toLowerCase()||t===qt}function ke(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 Vt(e={}){let t=await E(`${Q(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 F(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=Y,toToken:a,fromAmount:i,fromAddress:c=P}=e;if(r==null||!a||!i)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let s=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:a,fromAmount:String(i),fromAddress:c}),l=T({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}`);s.set("slippage",String(l.selectedBps/1e4));let d=await K({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[f,h]of Object.entries(ve(d)))s.set(f,h);let u=await E(`${Q(t)}/quote?${s}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),p=u?.estimate?.toAmount||u?.toAmount;if(!p)return{...u,autoSlippagePolicy:l,oracleFee:d};let m=u?.transactionRequest?.to||u?.estimate?.approvalAddress||"lifi",w=x(u,{chainId:Number(r),venue:m,amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),b=u?.estimate?.toAmountMin||u?.toAmountMin;if(b!=null&&BigInt(b)<BigInt(w.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...w,oracleFee:d}}async function jt(e={},t={}){let r=await F(e,t),n=r?.transactionRequest;if(!n?.to||!n?.data)throw new Error("lifi: quote did not return an executable transactionRequest");let o=Number(e.fromChain);if(n.chainId!=null&&Number(n.chainId)!==o)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 a=null;if(!Ht(e.fromToken)){let i=r?.estimate?.approvalAddress||r?.approvalAddress;if(!i)throw new Error("lifi: ERC20 route missing approvalAddress");let c=r?.action?.fromToken?.address||r?.estimate?.fromToken?.address||e.fromToken;a={token:ke(c,"approval token"),spender:ke(i,"approval spender"),amount:String(e.fromAmount)}}return A({provider:"lifi",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:o,quote:r,autoSlippage:r.autoSlippage,requiresApproval:a,transaction:{chainId:o,from:n.from||e.fromAddress,to:n.to,data:n.data,value:n.value??"0x0",...n.gasLimit!=null?{gasLimit:n.gasLimit}:{},slippageGuard:B(r.autoSlippage,{chainId:o,venue:n.to,data:n.data})}},{provider:"lifi",kind:"lifi-tx"})}async function zt(e={}){return E(`${Q(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3})}var Oe,Y,qt,W=S(()=>{I();k();L();C();D();Oe="https://li.quest/v1";Y="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",qt="0x0000000000000000000000000000000000000000"});var M={};re(M,{ACROSS_API:()=>$e,HOP_API:()=>Pe,RELAY_API:()=>Ue,acrossHealth:()=>nr,acrossSuggestedFees:()=>Le,hopHealth:()=>or,hopQuote:()=>De,relayHealth:()=>ar,relayPrepare:()=>ir,relayQuote:()=>Z});async function nr(e={}){try{return{ok:!0,estimatedFillTimeSec:(await Le({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 Le(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:a,amount:i}=e;if(!r||o==null||a==null||!i)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let c=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(a),amount:String(i)}),s=(t.baseUrl||process.env.ACROSS_API_URL||$e).replace(/\/$/,"");return E(`${s}/suggested-fees?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function or(e={}){try{let t=await De({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 De(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:a="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let i=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),c=T({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==a,requestedCapBps:e.maxSlippageBps??e.slippageBps??i});if(!c.executable)throw new Error(`hop: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let s=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:a,slippage:String(c.selectedBps/100)}),l=(t.baseUrl||process.env.HOP_API_URL||Pe).replace(/\/$/,""),d=await E(`${l}/quote?${s}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),u=d?.estimatedRecieved||d?.estimatedReceived;return u?x(d,{chainId:Number(e.originChainId||e.chainId||rr[o]||0),venue:d?.tx?.to||"hop",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==a,requestedCapBps:e.maxSlippageBps??e.slippageBps??i}):{...d,autoSlippagePolicy:c}}async function ar(e={}){try{let t=await Z({user:P,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 Z(e={},t={}){let{user:r=P,originChainId:n,destinationChainId:o,originCurrency:a="0x0000000000000000000000000000000000000000",destinationCurrency:i="0x0000000000000000000000000000000000000000",amount:c,tradeType:s="EXACT_INPUT"}=e;if(n==null||o==null||!c)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let l=T({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),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||Ue).replace(/\/$/,""),u=await E(`${d}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:a,destinationCurrency:i,amount:String(c),tradeType:s,slippageTolerance:String(l.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),p=u?.details?.currencyOut?.amount;return!p||!/^\d+$/.test(String(p))?{...u,autoSlippagePolicy:l}:x(u,{chainId:Number(n),venue:u?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function ir(e={},t={}){let r=await Z(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(c=>(c.items||[]).filter(s=>s?.data?.to&&s?.data?.data).map(s=>({stepId:c.id,...s.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let a=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(c=>String(c.to).toLowerCase()!==a))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let i=o.map(c=>({chainId:n,from:c.from||e.user,to:c.to,data:c.data,value:c.value??"0x0",...c.gasLimit!=null||c.gas!=null?{gasLimit:c.gasLimit??c.gas}:{},slippageGuard:B(r.autoSlippage,{chainId:n,venue:c.to,data:c.data})}));return A({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 $e,Pe,Ue,rr,q=S(()=>{I();k();L();C();$e="https://across.to/api",Pe="https://api.hop.exchange/v1",Ue="https://api.relay.link",rr={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var br=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),Er=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),yr=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var R=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"});var ne=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:o=null,feeUsd:a=null,oracleFeeBps:i=0,estimatedGas:c=null,liquidityUsd:s=null,error:l=null,executionReady:d=!1,meta:u={}}=e||{};if(l||r==null)return{source:t,quality:R.FAILED,amountOut:null,error:l||"no amountOut returned"};let p=ne(r);if(p==null||p<=0n)return{source:t,quality:R.FAILED,amountOut:null,error:"non-positive amountOut"};let m=Number(i);return{source:t,quality:o==null?R.NO_GAS:R.FULL,amountOut:p.toString(),minOut:ne(n)?.toString()??null,gasUsd:o,feeUsd:a,oracleFeeBps:Number.isFinite(m)&&m>0?Math.floor(m):0,estimatedGas:c==null?null:String(c),liquidityUsd:s==null?null:Number(s),executionReady:d,meta:u}}function ae(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:o=50}={}){let a=e.filter(h=>h.quality!==R.FAILED),i=e.filter(h=>h.quality===R.FAILED),c=t!=null&&t>0&&r!=null&&r>=0,s=a.map(h=>{let g=BigInt(h.amountOut),y=0n,v=!1,O=BigInt(h.oracleFeeBps??0),_=O>0n?g*O/10000n:0n;if(c){let te=(h.gasUsd??0)+(h.feeUsd??0);if(te>0){let V=te/t*10**r;Number.isFinite(V)&&V>=0&&(y=BigInt(Math.floor(V)),v=!0)}else h.gasUsd===0&&(v=!0)}let ee=y+_,Ve=g>ee?g-ee:0n;return{...h,grossOut:g.toString(),netOut:Ve.toString(),costInDest:y.toString(),oracleFeeInDest:_.toString(),costAccounted:v}}),l=Number(o)>0?Number(o):0,d=s.reduce((h,g)=>BigInt(g.netOut)>h?BigInt(g.netOut):h,0n),u=h=>d>0n?Number((d-BigInt(h))*10000n/d):0,p=[],m=s.slice().sort((h,g)=>BigInt(g.netOut)>BigInt(h.netOut)?1:-1)[0]??null;s.sort((h,g)=>{let y=u(h.netOut)<=l?0:1,v=u(g.netOut)<=l?0:1;if(n&&l>0&&y!==v)return y-v;if(n&&l>0){let O=h.liquidityUsd??-1,_=g.liquidityUsd??-1;if(O!==_)return _-O}return BigInt(g.netOut)>BigInt(h.netOut)?1:-1}),n&&l>0&&m&&s[0]&&s[0].source!==m.source&&p.push(`liquidity-first: chose ${s[0].source} (liquidity $${s[0].liquidityUsd??"unknown"}) over best-price ${m.source} within ${l} bps`);let w=s.filter(h=>!h.costAccounted).map(h=>h.source);c?w.length&&p.push(`gas not reported by: ${w.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):p.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let b=null,f=null;if(s.length>=2&&s[0].costAccounted&&s[1].costAccounted){let h=BigInt(s[0].netOut),g=BigInt(s[1].netOut);g>0n&&(b=Number((h-g)*10000n/g),f=`${s[0].source} vs ${s[1].source}`)}return{best:s[0]??null,routes:s,failed:i,improvementBps:b,spreadBasis:f,rankedOn:c?"net-of-cost":"gross",warnings:p}}async function ie(e,{timeoutMs:t=12e3}={}){let r=(o,a)=>Promise.race([o,new Promise((i,c)=>setTimeout(()=>c(new Error(`${a}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,a)=>{let i=e[a].source;return o.status==="rejected"?oe({source:i,error:String(o.reason?.message||o.reason)}):oe({source:i,...o.value})})}W();I();k();C();D();I();k();C();I();k();C();I();k();import{TypedDataEncoder as Cn,getAddress as vn,isAddress as kn}from"ethers";var yn=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});L();C();var $n=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Pn=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"});var Un=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"}]}),Ln=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});import{Interface as Be,getAddress as eo,isAddress as to}from"ethers";I();var Re={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}},Fn=new Map(Object.values(Re).map(e=>[e.chainId,e]));import{Interface as Kt,getAddress as Xn}from"ethers";var Kn=new Kt(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);I();var Wn=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});k();C();var io=new Be(["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)"]),so=new Be(["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 Wt,Interface as Te,getAddress as lo,isAddress as po,keccak256 as mo}from"ethers";k();C();var bo=Wt.defaultAbiCoder();var Eo=new Te(["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)"]),yo=new Te(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);I();var Jt="https://coins.llama.fi",Zt="https://api.llama.fi";function er(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||Jt).replace(/\/$/,"")}function tr(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||Zt).replace(/\/$/,"")}async function J(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return E(`${er(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Ne(e={}){return E(`${tr(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var $=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function Fe(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=$(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}var N=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),Me=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 sr(e={}){try{let t=await Ne({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function cr(e,t={}){let r=N(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...Me[r]||[r]),n.push(...Me[N(e)]||[e]),n}function ur(e,t,r={}){let n=Array.isArray(e)?e:[],o=cr(t,r).map(N).filter(Boolean);for(let a of o){let i=n.find(s=>N(s?.slug)===a||N(s?.name)===a),c=$(i?.tvl);if(c!=null)return{liquidityUsd:c,protocol:i?.name??i?.slug??a}}for(let a of o){let i=n.find(s=>{let l=N(s?.category);return!l.includes("bridge")&&!l.includes("crosschain")?!1:N(s?.slug).includes(a)||N(s?.name).includes(a)}),c=$(i?.tvl);if(c!=null)return{liquidityUsd:c,protocol:i?.name??i?.slug??a}}return null}function qe({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:a,opts:i={}}){let c=[],s=null,l=async(d,u={})=>(s||=sr(i),ur(await s,d,u));return c.push({source:"lifi",run:async()=>{let d=await F({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},i),u=d?.estimate??d?.[0]?.estimate,p={tool:d?.tool??d?.toolDetails?.name,durationSeconds:$(u?.executionDuration)},m=await l("lifi",p);return{amountOut:u?.toAmount,minOut:u?.toAmountMin,gasUsd:Fe(u?.gasCosts),feeUsd:Fe(u?.feeCosts),oracleFeeBps:d?.oracleFee?.applies?d.oracleFee.bps:0,liquidityUsd:m?.liquidityUsd??null,meta:{...p,liquidityProtocol:m?.protocol,oracleFee:d?.oracleFee??null}}}}),c.push({source:"relay",run:async()=>{let{relayQuote:d}=await Promise.resolve().then(()=>(q(),M)),p=(await d({user:a,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},i))?.details,m={durationSeconds:$(p?.timeEstimate),rate:p?.rate},w=await l("relay",m);return{amountOut:p?.currencyOut?.amount,minOut:p?.currencyOut?.minimumAmount,gasUsd:$(p?.totalImpact?.usd)!=null?Math.abs($(p.totalImpact.usd)):null,liquidityUsd:w?.liquidityUsd??null,meta:{...m,liquidityProtocol:w?.protocol}}}}),c.push({source:"across",run:async()=>{let{acrossSuggestedFees:d}=await Promise.resolve().then(()=>(q(),M)),u=await d({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},i),p=u?.totalRelayFee?.total,m=null;if(p!=null)try{let b=BigInt(String(o))-BigInt(String(p));b>0n&&(m=b.toString())}catch{}let w=await l("across");return{amountOut:m,gasUsd:null,liquidityUsd:w?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:$(u?.estimatedFillTimeSec),limits:u?.limits?{min:u.limits.minDeposit,max:u.limits.maxDeposit}:void 0,liquidityProtocol:w?.protocol}}}}),c}D();var lr={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function dr(e,t,r){let n=lr[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let i=(await J([o],r))?.coins?.[o],c=Number(i?.price),s=Number(i?.decimals);return{priceUsd:Number.isFinite(c)?c:null,decimals:Number.isFinite(s)?s:null}}catch{return{priceUsd:null,decimals:null}}}async function He(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:a,amountIn:i}=e;if(r==null||n==null||!o||!a||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 c=dr(n,a,t),s=qe({...e,opts:t}),[l,d]=await Promise.all([ie(s,{timeoutMs:t.timeoutMs??15e3}),c]),u=ae(l,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals,liquidityBandBps:t.liquidityBandBps??50}),p=u.routes.map(m=>({source:m.source,seconds:m.meta?.durationSeconds??null})).filter(m=>m.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:o,tokenOut:a,amountIn:String(i),...u,durations:p,sourcesTried:s.length,sourcesAnswered:l.filter(m=>m.quality!==R.FAILED).length,note:mr(u,s.length)}}function pr(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Ce(t)}`:""}function mr(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=pr(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 o=e.improvementBps,a=o/100;if(o<.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=a>=.01?`${a.toFixed(2)}%`:`${o.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}C();var fr=/^0x[0-9a-fA-F]{40}$/,hr=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),wr=100,H={relay:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:a},i)=>{let{relayPrepare:c}=await Promise.resolve().then(()=>(q(),M)),s=await c({user:a,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},i);return{transactions:s.transactions||[],amountOut:s.quote?.details?.currencyOut?.amount??null,minOut:s.quote?.details?.currencyOut?.minimumAmount??null,durationSeconds:s.quote?.details?.timeEstimate??null}},lifi:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:a,isHolder:i},c)=>{let{lifiPrepare:s}=await Promise.resolve().then(()=>(W(),_e)),l=await s({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o,fromAddress:a,isHolder:i,feeAction:"bridge"},c);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 aa(){return Object.keys(H)}async function ia(e,t={}){let{taker:r,fromChainId:n,toChainId:o}=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(!fr.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(hr.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 a=await He(e,t);if(!a.best)return{ok:!1,reason:"no source returned a usable bridge route",comparison:a};let i=e.source||a.best.source,c=a.routes.find(f=>f.source===i);if(!c)return{ok:!1,reason:`source "${i}" returned no usable route`,comparison:a};let s=H[i];if(!s){let f=a.routes.find(h=>H[h.source]&&h.source!==i);return{ok:!1,reason:`${i} won the comparison but has no bridge prepare path in this build. `+(f?`Next preparable route is ${f.source}; pass source:"${f.source}".`:"No route in this comparison can be prepared."),failureKind:"no-prepare-path",...f?{alternative:f.source}:{},winner:i,comparison:a}}let l;try{l=await s(e,t)}catch(f){let h=typeof f?.body=="string"?f.body:f?.body?JSON.stringify(f.body):"",g=[String(f?.message||f),h].filter(Boolean).join(" :: "),y=/allowance/i.test(g),v=!y&&/not enough|insufficient|balance/i.test(g),O=a.routes.find(_=>H[_.source]&&_.source!==i);return{ok:!1,reason:y?`${i} will not build calldata until the token approval exists on-chain. Approve first, then prepare again. Underlying: ${g}`:v?`${i} refused to build: ${g}. Quoting works for any address; preparing needs the real funded wallet on chain ${n}.`:`${i} bridge prepare failed: ${g}`,failureKind:y?"approval-required-first":v?"taker-not-funded":"provider-error",...O?{alternative:O.source}:{},comparison:a}}let d=l.transactions||[];if(!d.length)return{ok:!1,reason:`${i} returned no executable transaction for this route`,failureKind:"provider-error",comparison:a};let u=d.filter(f=>f.chainId!=null&&Number(f.chainId)!==Number(n));if(u.length)return{ok:!1,reason:`${i} returned a transaction for chain ${u[0].chainId} but the origin chain is ${n}. Refusing to hand over a mismatched artifact.`,failureKind:"chain-mismatch",comparison:a};let p=e.driftToleranceBps??wr,m=null,w=null;if(l.amountOut!=null&&c.grossOut!=null)try{let f=BigInt(c.grossOut),h=BigInt(l.amountOut);f>0n&&(m=Number((h-f)*10000n/f),m<-p&&(w=`route moved ${(m/100).toFixed(2)}% against you since the comparison (tolerance ${(p/100).toFixed(2)}%). Re-compare before signing.`))}catch{}let b=[...w?[w]:[],...a.warnings||[],`Bridging is NOT atomic: the origin transaction succeeding does not mean funds arrived on chain ${o}. 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&&b.push(`This route needs ${d.length} transactions signed IN ORDER. Signing only the first leaves funds approved but not bridged.`),A({ok:!0,chosen:{source:i,wasWinner:i===a.best.source,netOut:c.netOut,grossOut:c.grossOut,gasUsd:c.gasUsd},artifactKind:"unsigned-transaction-sequence",fromChainId:Number(n),toChainId:Number(o),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:m,warnings:b,runnersUp:a.routes.filter(f=>f.source!==i).map(f=>({source:f.source,netOut:f.netOut,gasUsd:f.gasUsd})),comparison:{rankedOn:a.rankedOn,sourcesAnswered:a.sourcesAnswered,sourcesTried:a.sourcesTried,improvementBps:a.improvementBps},note:`UNSIGNED. ${d.length} transaction(s) on chain ${n}, crediting chain ${o}. Verify every destination address before signing.`},{provider:"router",kind:"best-bridge"})}export{ia as prepareBestBridgeRoute,aa as supportedBridgePreparers};
2
+ `),c=ze("sha256").update(i).digest("hex").slice(0,32);return`${e} ${t} ${c}`}function et(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ce):Math.min(250*2**e,ce)+Math.floor(Math.random()*100)}async function rt(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:a}){let i=new AbortController,c=setTimeout(()=>i.abort(),a);try{let s=String(e),l={...n||{}};for(let d=0;d<=ue;d+=1){let u=await t(s,{method:r,headers:l,body:o,signal:i.signal,redirect:"manual"}),p=await u.text(),m=null;if(p)try{m=JSON.parse(p)}catch{m=null}if(Ke.has(u.status)){if(r!=="GET"&&r!=="HEAD"){let b=new Error(`HTTP ${u.status} ${r} ${s} redirected non-idempotent request`);throw b.status=u.status,b.body=m??p.slice(0,300),b}if(d===ue)throw new Error(`HTTP redirect loop for ${e}`);let w=We(u.headers?.get?.("location"),s);Je(w,s)||(l=Qe(l)),s=w;continue}if(!u.ok){let w=new Error(`HTTP ${u.status} ${r} ${s}`);throw w.status=u.status,w.retryAfter=u.headers?.get?.("retry-after")??null,w.body=m??p.slice(0,300),w}return m??p}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(c)}}async function E(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,o=(t.method||"GET").toUpperCase(),a={Accept:"application/json",...t.headers||{}},i=t.body;i!=null&&typeof i!="string"&&(a["Content-Type"]=a["Content-Type"]||"application/json",i=JSON.stringify(i));let c=Number.isInteger(t.retries)?Math.max(t.retries,0):Xe,s=async()=>{let m;for(let w=0;w<=c;w++)try{return await rt(e,{fetchImpl:r,method:o,headers:a,body:i,timeoutMs:n})}catch(b){m=b;let f=b?.status,h=b?.name==="AbortError",g=new Set([408,425,429]),y=f!=null?g.has(f)||Ge.has(f)&&se.has(o):!h&&se.has(o);if(w===c||!y)throw b;await tt(et(w,b?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&i==null))return s();let d=Ze(o,e,a),u=j.get(d);if(u)return u;let p=s().finally(()=>j.delete(d));return j.set(d,p),p}var Ge,se,Xe,ce,le,Ke,ue,j,tt,I=S(()=>{Ge=new Set([408,425,429,500,502,503,504]),se=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Xe=2,ce=4e3,le=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ke=new Set([301,302,303,307,308]),ue=3;j=new Map;tt=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as nt}from"node:fs";import{homedir as ot}from"node:os";import{join as U}from"node:path";function at(){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=ot();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||U(t,".config","oracle")).trim();return[e,U(r,"exec.env")].filter(Boolean)}return[e,U(t,".config","oracle","exec.env"),U(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 o of at())try{let a=nt(o,"utf8"),i=a.match(new RegExp(`^${t}=(.*)$`,"m"))||a.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 pe=S(()=>{});var me=S(()=>{});import{createHash as it,createHmac as st,timingSafeEqual as $r}from"node:crypto";function G(e){return Array.isArray(e)?`[${e.map(G).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${G(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function ct(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 we(e){let{signature:t,...r}=e;return r}function ge(e,{secret:t}={}){let r=ct(t);return r?{...e,signature:st("sha256",r).update(G(we(e))).digest("hex")}:e}function ut(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 it("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function B(e,{chainId:t,venue:r,data:n,secret:o}={}){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");return ge({...we(e),calldataHash:ut(n)},{secret:o})}function z(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function lt(e){let t=e==null?fe: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,fe)}function T({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let a=z(e,0),i=a>0?a>=25e4?5:a>=1e5?10:a>=5e4?20:a>=1e4?40:70:n?30:10,c=Math.min(60,Math.abs(z(t,0))*2),s=Math.min(40,Math.floor(Math.max(0,z(r,0))/5e3)*5),l=Math.max(25,Math.ceil(20+i+c+s)),d=lt(o);return{mode:"auto",requiredBps:l,selectedBps:Math.min(l,d),capBps:d,executable:l<=d}}function dt({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:a=0,crossChain:i=!1,requestedCapBps:c,quotedAtMs:s=Date.now(),ttlMs:l=he,secret:d}={}){let u=BigInt(r??0);if(u<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let p=T({liquidityUsd:n,priceChange5m:o,quoteAgeMs:a,crossChain:i,requestedCapBps:c});if(!p.executable)throw new Error(`auto-slippage requires ${p.requiredBps} bps above hard/requested cap ${p.capBps}; route blocked`);let m=Number(s);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let w=Math.min(3e4,Math.max(1e3,Number(l)||he)),b=u*BigInt(1e4-p.selectedBps),f=b/10000n;if(b%10000n!==0n&&(f+=1n),f>u&&(f=u),u>0n&&f<=0n)throw new Error(`auto-slippage: quote ${u} is too small to express a ${p.selectedBps} bps floor without rounding to zero`);let h=Number((u-f)*10000n/(u===0n?1n:u));if(h>p.capBps)throw new Error(`auto-slippage: realised floor implies ${h} bps, above cap ${p.capBps} \u2014 refusing to issue a guard weaker than advertised`);return ge({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:u.toString(),minAmountOut:f.toString(),requiredBps:p.requiredBps,selectedBps:p.selectedBps,capBps:p.capBps,quotedAtMs:m,expiresAtMs:m+w},{secret:d})}function x(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:a,crossChain:i,requestedCapBps:c,quotedAtMs:s=Date.now(),ttlMs:l}={}){let d=dt({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:a,crossChain:i,requestedCapBps:c,quotedAtMs:s,ttlMs:l});return{...e,autoSlippage:d,amountOutMinimum:d.minAmountOut}}var fe,he,k=S(()=>{pe();me();fe=100,he=2e4});var P,L=S(()=>{P="0x000000000000000000000000000000000000dEaD"});import{createHash as pt,createHmac as mt,timingSafeEqual as Mr}from"node:crypto";function X(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(X).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${X(e[r])}`).join(",")}}`}function be(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Ee(e=process.env){return be(process.env)||be(e)}function wt(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...a}=e||{};return a}function gt(e){let t=wt(e);return pt("sha256").update(X(t)).digest("hex")}function bt(e,t=Ee()){return t?mt("sha256",t).update(String(e)).digest("hex"):""}function A(e,{provider:t,kind:r,env:n=process.env}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let o={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!o.provider)throw new Error("stampPrepared: provider required");if(!o.kind)throw new Error("stampPrepared: kind required");let a=Date.now(),i=a+ht,s={...o,preparedAt:a,expiresAt:i,prepareVersion:ft},l=gt(s),d=Ee(n),u=d?bt(l,d):void 0,p={...s,oraclePrepared:!0,prepareHash:l};return u&&(p.prepareMac=u),p}var ft,ht,qr,C=S(()=>{ft=2,ht=300*1e3,qr=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});import{Contract as Et,JsonRpcProvider as yt}from"ethers";function vt(e){return Ct.test(String(e||""))}async function ye(e,{contract:t=At,rpc:r=St,chainId:n=xt,balanceOf:o}={}){if(!vt(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let a=new yt(r,n,{staticNetwork:!0}),i=new Et(t,It,a);return BigInt(await i.balanceOf(e))}var At,xt,St,It,Ct,Ae=S(()=>{At="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",xt=999,St="https://rpc.hyperliquid.xyz/evm",It=["function balanceOf(address owner) view returns (uint256)"],Ct=/^0x[a-fA-F0-9]{40}$/});import{existsSync as kt,readFileSync as Ot}from"node:fs";import{homedir as _t}from"node:os";import{join as xe}from"node:path";function Tt(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(Se,t)?Se[t]:Bt}function Lt(e=process.env){if(e[Ie])return String(e[Ie]);let t=e.ORACLE_CONFIG_DIR||xe(_t(),".config","oracle");return xe(t,"fee-recipient")}function Dt(e=process.env){try{let t=Lt(e);if(!kt(t))return"";let r=Ot(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function Ft(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),Rt)}function Mt({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[$t]||"").trim(),o=String(e[Pt]||Ut).trim();if(r===!0)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"admin-oracle"};let a=Tt(t),i=Ft(e[Nt],{fallback:n?a:0}),c=Math.min(i,a);if(!c)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"no-recipient"};let s=Dt(e);return!s||s!==n.toLowerCase()?{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:c,recipient:n,integrator:o,action:t,applies:!0,reason:"configured"}}async function K({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:o=!1}={}){let a=Mt({env:t,action:r,admin:o});if(o===!0)return{...a,holderVerificationStatus:"admin-oracle"};let i=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(i))return{...a,holderVerificationStatus:"wallet-required"};try{return BigInt(await ye(i,n))>0n?{...a,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...a,holderVerificationStatus:"non-holder"}}catch{return{...a,holderVerificationStatus:"unavailable"}}}function Ce(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 ve(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}var Rt,Bt,Se,Nt,$t,Pt,Ie,Ut,D=S(()=>{Ae();Rt=100,Bt=5,Se=Object.freeze({swap:5,bridge:5,perps:0,nft:0});Nt="ORACLE_INTEGRATOR_FEE_BPS",$t="ORACLE_INTEGRATOR_FEE_RECIPIENT",Pt="ORACLE_INTEGRATOR_ID",Ie="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",Ut="oracle"});var _e={};re(_e,{LIFI_API:()=>Oe,lifiChains:()=>zt,lifiHealth:()=>Vt,lifiPrepare:()=>jt,lifiQuote:()=>F});function Q(e={}){return(e.baseUrl||process.env.LIFI_API_URL||Oe).replace(/\/$/,"")}function Ht(e){let t=String(e||Y).toLowerCase();return t===Y.toLowerCase()||t===qt}function ke(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 Vt(e={}){let t=await E(`${Q(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 F(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=Y,toToken:a,fromAmount:i,fromAddress:c=P}=e;if(r==null||!a||!i)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let s=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:a,fromAmount:String(i),fromAddress:c}),l=T({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}`);s.set("slippage",String(l.selectedBps/1e4));let d=await K({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[f,h]of Object.entries(ve(d)))s.set(f,h);let u=await E(`${Q(t)}/quote?${s}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),p=u?.estimate?.toAmount||u?.toAmount;if(!p)return{...u,autoSlippagePolicy:l,oracleFee:d};let m=u?.transactionRequest?.to||u?.estimate?.approvalAddress||"lifi",w=x(u,{chainId:Number(r),venue:m,amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),b=u?.estimate?.toAmountMin||u?.toAmountMin;if(b!=null&&BigInt(b)<BigInt(w.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...w,oracleFee:d}}async function jt(e={},t={}){let r=await F(e,t),n=r?.transactionRequest;if(!n?.to||!n?.data)throw new Error("lifi: quote did not return an executable transactionRequest");let o=Number(e.fromChain);if(n.chainId!=null&&Number(n.chainId)!==o)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 a=null;if(!Ht(e.fromToken)){let i=r?.estimate?.approvalAddress||r?.approvalAddress;if(!i)throw new Error("lifi: ERC20 route missing approvalAddress");let c=r?.action?.fromToken?.address||r?.estimate?.fromToken?.address||e.fromToken;a={token:ke(c,"approval token"),spender:ke(i,"approval spender"),amount:String(e.fromAmount)}}return A({provider:"lifi",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:o,quote:r,autoSlippage:r.autoSlippage,requiresApproval:a,transaction:{chainId:o,from:n.from||e.fromAddress,to:n.to,data:n.data,value:n.value??"0x0",...n.gasLimit!=null?{gasLimit:n.gasLimit}:{},slippageGuard:B(r.autoSlippage,{chainId:o,venue:n.to,data:n.data})}},{provider:"lifi",kind:"lifi-tx"})}async function zt(e={}){return E(`${Q(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3})}var Oe,Y,qt,W=S(()=>{I();k();L();C();D();Oe="https://li.quest/v1";Y="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",qt="0x0000000000000000000000000000000000000000"});var M={};re(M,{ACROSS_API:()=>$e,HOP_API:()=>Pe,RELAY_API:()=>Ue,acrossHealth:()=>nr,acrossSuggestedFees:()=>Le,hopHealth:()=>or,hopQuote:()=>De,relayHealth:()=>ar,relayPrepare:()=>ir,relayQuote:()=>Z});async function nr(e={}){try{return{ok:!0,estimatedFillTimeSec:(await Le({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 Le(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:a,amount:i}=e;if(!r||o==null||a==null||!i)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let c=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(a),amount:String(i)}),s=(t.baseUrl||process.env.ACROSS_API_URL||$e).replace(/\/$/,"");return E(`${s}/suggested-fees?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function or(e={}){try{let t=await De({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 De(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:a="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let i=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),c=T({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==a,requestedCapBps:e.maxSlippageBps??e.slippageBps??i});if(!c.executable)throw new Error(`hop: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let s=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:a,slippage:String(c.selectedBps/100)}),l=(t.baseUrl||process.env.HOP_API_URL||Pe).replace(/\/$/,""),d=await E(`${l}/quote?${s}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),u=d?.estimatedRecieved||d?.estimatedReceived;return u?x(d,{chainId:Number(e.originChainId||e.chainId||rr[o]||0),venue:d?.tx?.to||"hop",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==a,requestedCapBps:e.maxSlippageBps??e.slippageBps??i}):{...d,autoSlippagePolicy:c}}async function ar(e={}){try{let t=await Z({user:P,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 Z(e={},t={}){let{user:r=P,originChainId:n,destinationChainId:o,originCurrency:a="0x0000000000000000000000000000000000000000",destinationCurrency:i="0x0000000000000000000000000000000000000000",amount:c,tradeType:s="EXACT_INPUT"}=e;if(n==null||o==null||!c)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let l=T({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),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||Ue).replace(/\/$/,""),u=await E(`${d}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:a,destinationCurrency:i,amount:String(c),tradeType:s,slippageTolerance:String(l.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),p=u?.details?.currencyOut?.amount;return!p||!/^\d+$/.test(String(p))?{...u,autoSlippagePolicy:l}:x(u,{chainId:Number(n),venue:u?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function ir(e={},t={}){let r=await Z(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(c=>(c.items||[]).filter(s=>s?.data?.to&&s?.data?.data).map(s=>({stepId:c.id,...s.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let a=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(c=>String(c.to).toLowerCase()!==a))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let i=o.map(c=>({chainId:n,from:c.from||e.user,to:c.to,data:c.data,value:c.value??"0x0",...c.gasLimit!=null||c.gas!=null?{gasLimit:c.gasLimit??c.gas}:{},slippageGuard:B(r.autoSlippage,{chainId:n,venue:c.to,data:c.data})}));return A({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 $e,Pe,Ue,rr,q=S(()=>{I();k();L();C();$e="https://across.to/api",Pe="https://api.hop.exchange/v1",Ue="https://api.relay.link",rr={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var br=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),Er=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),yr=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var R=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"});var ne=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:o=null,feeUsd:a=null,oracleFeeBps:i=0,estimatedGas:c=null,liquidityUsd:s=null,error:l=null,executionReady:d=!1,meta:u={}}=e||{};if(l||r==null)return{source:t,quality:R.FAILED,amountOut:null,error:l||"no amountOut returned"};let p=ne(r);if(p==null||p<=0n)return{source:t,quality:R.FAILED,amountOut:null,error:"non-positive amountOut"};let m=Number(i);return{source:t,quality:o==null?R.NO_GAS:R.FULL,amountOut:p.toString(),minOut:ne(n)?.toString()??null,gasUsd:o,feeUsd:a,oracleFeeBps:Number.isFinite(m)&&m>0?Math.floor(m):0,estimatedGas:c==null?null:String(c),liquidityUsd:s==null?null:Number(s),executionReady:d,meta:u}}function ae(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:o=50}={}){let a=e.filter(h=>h.quality!==R.FAILED),i=e.filter(h=>h.quality===R.FAILED),c=t!=null&&t>0&&r!=null&&r>=0,s=a.map(h=>{let g=BigInt(h.amountOut),y=0n,v=!1,O=BigInt(h.oracleFeeBps??0),_=O>0n?g*O/10000n:0n;if(c){let te=(h.gasUsd??0)+(h.feeUsd??0);if(te>0){let V=te/t*10**r;Number.isFinite(V)&&V>=0&&(y=BigInt(Math.floor(V)),v=!0)}else h.gasUsd===0&&(v=!0)}let ee=y+_,Ve=g>ee?g-ee:0n;return{...h,grossOut:g.toString(),netOut:Ve.toString(),costInDest:y.toString(),oracleFeeInDest:_.toString(),costAccounted:v}}),l=Number(o)>0?Number(o):0,d=s.reduce((h,g)=>BigInt(g.netOut)>h?BigInt(g.netOut):h,0n),u=h=>d>0n?Number((d-BigInt(h))*10000n/d):0,p=[],m=s.slice().sort((h,g)=>BigInt(g.netOut)>BigInt(h.netOut)?1:-1)[0]??null;s.sort((h,g)=>{let y=u(h.netOut)<=l?0:1,v=u(g.netOut)<=l?0:1;if(n&&l>0&&y!==v)return y-v;if(n&&l>0){let O=h.liquidityUsd??-1,_=g.liquidityUsd??-1;if(O!==_)return _-O}return BigInt(g.netOut)>BigInt(h.netOut)?1:-1}),n&&l>0&&m&&s[0]&&s[0].source!==m.source&&p.push(`liquidity-first: chose ${s[0].source} (liquidity $${s[0].liquidityUsd??"unknown"}) over best-price ${m.source} within ${l} bps`);let w=s.filter(h=>!h.costAccounted).map(h=>h.source);c?w.length&&p.push(`gas not reported by: ${w.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):p.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let b=null,f=null;if(s.length>=2&&s[0].costAccounted&&s[1].costAccounted){let h=BigInt(s[0].netOut),g=BigInt(s[1].netOut);g>0n&&(b=Number((h-g)*10000n/g),f=`${s[0].source} vs ${s[1].source}`)}return{best:s[0]??null,routes:s,failed:i,improvementBps:b,spreadBasis:f,rankedOn:c?"net-of-cost":"gross",warnings:p}}async function ie(e,{timeoutMs:t=12e3}={}){let r=(o,a)=>Promise.race([o,new Promise((i,c)=>setTimeout(()=>c(new Error(`${a}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,a)=>{let i=e[a].source;return o.status==="rejected"?oe({source:i,error:String(o.reason?.message||o.reason)}):oe({source:i,...o.value})})}W();I();k();C();D();I();k();C();I();k();C();I();k();import{TypedDataEncoder as Cn,getAddress as vn,isAddress as kn}from"ethers";var yn=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});L();C();var $n=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Pn=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"});var Un=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"}]}),Ln=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});import{Interface as Be,getAddress as eo,isAddress as to}from"ethers";I();var Re={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}},Fn=new Map(Object.values(Re).map(e=>[e.chainId,e]));import{Interface as Kt,getAddress as Xn}from"ethers";var Kn=new Kt(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);I();var Wn=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});k();C();var io=new Be(["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)"]),so=new Be(["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 Wt,Interface as Te,getAddress as lo,isAddress as po,keccak256 as mo}from"ethers";k();C();var bo=Wt.defaultAbiCoder();var Eo=new Te(["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)"]),yo=new Te(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);I();var Jt="https://coins.llama.fi",Zt="https://api.llama.fi";function er(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||Jt).replace(/\/$/,"")}function tr(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||Zt).replace(/\/$/,"")}async function J(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return E(`${er(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Ne(e={}){return E(`${tr(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var $=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function Fe(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=$(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}var N=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),Me=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 sr(e={}){try{let t=await Ne({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function cr(e,t={}){let r=N(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...Me[r]||[r]),n.push(...Me[N(e)]||[e]),n}function ur(e,t,r={}){let n=Array.isArray(e)?e:[],o=cr(t,r).map(N).filter(Boolean);for(let a of o){let i=n.find(s=>N(s?.slug)===a||N(s?.name)===a),c=$(i?.tvl);if(c!=null)return{liquidityUsd:c,protocol:i?.name??i?.slug??a}}for(let a of o){let i=n.find(s=>{let l=N(s?.category);return!l.includes("bridge")&&!l.includes("crosschain")?!1:N(s?.slug).includes(a)||N(s?.name).includes(a)}),c=$(i?.tvl);if(c!=null)return{liquidityUsd:c,protocol:i?.name??i?.slug??a}}return null}function qe({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:a,opts:i={}}){let c=[],s=null,l=async(d,u={})=>(s||=sr(i),ur(await s,d,u));return c.push({source:"lifi",run:async()=>{let d=await F({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},i),u=d?.estimate??d?.[0]?.estimate,p={tool:d?.tool??d?.toolDetails?.name,durationSeconds:$(u?.executionDuration)},m=await l("lifi",p);return{amountOut:u?.toAmount,minOut:u?.toAmountMin,gasUsd:Fe(u?.gasCosts),feeUsd:Fe(u?.feeCosts),oracleFeeBps:d?.oracleFee?.applies?d.oracleFee.bps:0,liquidityUsd:m?.liquidityUsd??null,meta:{...p,liquidityProtocol:m?.protocol,oracleFee:d?.oracleFee??null}}}}),c.push({source:"relay",run:async()=>{let{relayQuote:d}=await Promise.resolve().then(()=>(q(),M)),p=(await d({user:a,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},i))?.details,m={durationSeconds:$(p?.timeEstimate),rate:p?.rate},w=await l("relay",m);return{amountOut:p?.currencyOut?.amount,minOut:p?.currencyOut?.minimumAmount,gasUsd:$(p?.totalImpact?.usd)!=null?Math.abs($(p.totalImpact.usd)):null,liquidityUsd:w?.liquidityUsd??null,meta:{...m,liquidityProtocol:w?.protocol}}}}),c.push({source:"across",run:async()=>{let{acrossSuggestedFees:d}=await Promise.resolve().then(()=>(q(),M)),u=await d({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},i),p=u?.totalRelayFee?.total,m=null;if(p!=null)try{let b=BigInt(String(o))-BigInt(String(p));b>0n&&(m=b.toString())}catch{}let w=await l("across");return{amountOut:m,gasUsd:null,liquidityUsd:w?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:$(u?.estimatedFillTimeSec),limits:u?.limits?{min:u.limits.minDeposit,max:u.limits.maxDeposit}:void 0,liquidityProtocol:w?.protocol}}}}),c}D();var lr={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function dr(e,t,r){let n=lr[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let i=(await J([o],r))?.coins?.[o],c=Number(i?.price),s=Number(i?.decimals);return{priceUsd:Number.isFinite(c)?c:null,decimals:Number.isFinite(s)?s:null}}catch{return{priceUsd:null,decimals:null}}}async function He(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:a,amountIn:i}=e;if(r==null||n==null||!o||!a||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 c=dr(n,a,t),s=qe({...e,opts:t}),[l,d]=await Promise.all([ie(s,{timeoutMs:t.timeoutMs??15e3}),c]),u=ae(l,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals,liquidityBandBps:t.liquidityBandBps??50}),p=u.routes.map(m=>({source:m.source,seconds:m.meta?.durationSeconds??null})).filter(m=>m.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:o,tokenOut:a,amountIn:String(i),...u,durations:p,sourcesTried:s.length,sourcesAnswered:l.filter(m=>m.quality!==R.FAILED).length,note:mr(u,s.length)}}function pr(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Ce(t)}`:""}function mr(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=pr(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 o=e.improvementBps,a=o/100;if(o<.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=a>=.01?`${a.toFixed(2)}%`:`${o.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}C();var fr=/^0x[0-9a-fA-F]{40}$/,hr=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),wr=100,H={relay:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:a},i)=>{let{relayPrepare:c}=await Promise.resolve().then(()=>(q(),M)),s=await c({user:a,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},i);return{transactions:s.transactions||[],amountOut:s.quote?.details?.currencyOut?.amount??null,minOut:s.quote?.details?.currencyOut?.minimumAmount??null,durationSeconds:s.quote?.details?.timeEstimate??null}},lifi:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:a,isHolder:i},c)=>{let{lifiPrepare:s}=await Promise.resolve().then(()=>(W(),_e)),l=await s({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o,fromAddress:a,isHolder:i,feeAction:"bridge"},c);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 aa(){return Object.keys(H)}async function ia(e,t={}){let{taker:r,fromChainId:n,toChainId:o}=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(!fr.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(hr.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 a=await He(e,t);if(!a.best)return{ok:!1,reason:"no source returned a usable bridge route",comparison:a};let i=e.source||a.best.source,c=a.routes.find(f=>f.source===i);if(!c)return{ok:!1,reason:`source "${i}" returned no usable route`,comparison:a};let s=H[i];if(!s){let f=a.routes.find(h=>H[h.source]&&h.source!==i);return{ok:!1,reason:`${i} won the comparison but has no bridge prepare path in this build. `+(f?`Next preparable route is ${f.source}; pass source:"${f.source}".`:"No route in this comparison can be prepared."),failureKind:"no-prepare-path",...f?{alternative:f.source}:{},winner:i,comparison:a}}let l;try{l=await s(e,t)}catch(f){let h=typeof f?.body=="string"?f.body:f?.body?JSON.stringify(f.body):"",g=[String(f?.message||f),h].filter(Boolean).join(" :: "),y=/allowance/i.test(g),v=!y&&/not enough|insufficient|balance/i.test(g),O=a.routes.find(_=>H[_.source]&&_.source!==i);return{ok:!1,reason:y?`${i} will not build calldata until the token approval exists on-chain. Approve first, then prepare again. Underlying: ${g}`:v?`${i} refused to build: ${g}. Quoting works for any address; preparing needs the real funded wallet on chain ${n}.`:`${i} bridge prepare failed: ${g}`,failureKind:y?"approval-required-first":v?"taker-not-funded":"provider-error",...O?{alternative:O.source}:{},comparison:a}}let d=l.transactions||[];if(!d.length)return{ok:!1,reason:`${i} returned no executable transaction for this route`,failureKind:"provider-error",comparison:a};let u=d.filter(f=>f.chainId!=null&&Number(f.chainId)!==Number(n));if(u.length)return{ok:!1,reason:`${i} returned a transaction for chain ${u[0].chainId} but the origin chain is ${n}. Refusing to hand over a mismatched artifact.`,failureKind:"chain-mismatch",comparison:a};let p=e.driftToleranceBps??wr,m=null,w=null;if(l.amountOut!=null&&c.grossOut!=null)try{let f=BigInt(c.grossOut),h=BigInt(l.amountOut);f>0n&&(m=Number((h-f)*10000n/f),m<-p&&(w=`route moved ${(m/100).toFixed(2)}% against you since the comparison (tolerance ${(p/100).toFixed(2)}%). Re-compare before signing.`))}catch{}let b=[...w?[w]:[],...a.warnings||[],`Bridging is NOT atomic: the origin transaction succeeding does not mean funds arrived on chain ${o}. 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&&b.push(`This route needs ${d.length} transactions signed IN ORDER. Signing only the first leaves funds approved but not bridged.`),A({ok:!0,chosen:{source:i,wasWinner:i===a.best.source,netOut:c.netOut,grossOut:c.grossOut,gasUsd:c.gasUsd},artifactKind:"unsigned-transaction-sequence",fromChainId:Number(n),toChainId:Number(o),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:m,warnings:b,runnersUp:a.routes.filter(f=>f.source!==i).map(f=>({source:f.source,netOut:f.netOut,gasUsd:f.gasUsd})),comparison:{rankedOn:a.rankedOn,sourcesAnswered:a.sourcesAnswered,sourcesTried:a.sourcesTried,improvementBps:a.improvementBps},note:`UNSIGNED. ${d.length} transaction(s) on chain ${n}, crediting chain ${o}. Verify every destination address before signing.`},{provider:"router",kind:"best-bridge"})}export{ia as prepareBestBridgeRoute,aa as supportedBridgePreparers};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oracle-agent/oracle",
3
- "version": "0.22.16",
3
+ "version": "0.23.0",
4
4
  "description": "Oracle: standalone prepare-only multichain agent control plane. Runs its own agent loop, or plugs into any MCP-compatible harness. Policy-bounded intents for a user-signed wallet; the public package never takes your key.",
5
5
  "license": "BUSL-1.1",
6
6
  "type": "module",
@@ -50,6 +50,7 @@
50
50
  "./address-book": "./dist/address-book.mjs",
51
51
  "./names": "./dist/data/names.mjs",
52
52
  "./nft-gas-war": "./dist/nft-gas-war-guard.mjs",
53
+ "./nft-trait-sniper": "./dist/nft/index.mjs",
53
54
  "./prepare-envelope": "./dist/prepare-envelope.mjs",
54
55
  "./connect": "./dist/onboarding/harness-configs.mjs",
55
56
  "./receipts": "./dist/action-receipts.mjs",
@@ -57,8 +58,7 @@
57
58
  "./watch": "./dist/watch-preferences.mjs",
58
59
  "./signals": "./dist/signals/index.mjs",
59
60
  "./strategy": "./dist/strategy/index.mjs",
60
- "./agent-grants": "./dist/public-api/agent-grants.mjs",
61
- "./local-vault": "./dist/local-vault/index.mjs"
61
+ "./agent-grants": "./dist/public-api/agent-grants.mjs"
62
62
  },
63
63
  "dependencies": {
64
64
  "@msgpack/msgpack": "^3.1.3",