@oracle-agent/oracle 0.12.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/README.md +31 -4
  2. package/SETUP.md +5 -2
  3. package/artifacts/specialist-packs/oracle-full-crypto.json +3 -0
  4. package/dist/address-book.mjs +2 -2
  5. package/dist/assets/profiles/_template/SOUL.md +54 -0
  6. package/dist/assets/profiles/_template/profile.json +22 -0
  7. package/dist/assets/profiles/bitcoin-agent/SOUL.md +31 -0
  8. package/dist/assets/profiles/bitcoin-agent/profile.json +32 -0
  9. package/dist/assets/profiles/hyperliquid-agent/SOUL.md +34 -0
  10. package/dist/assets/profiles/hyperliquid-agent/profile.json +38 -0
  11. package/dist/assets/profiles/oracle/SOUL.md +134 -0
  12. package/dist/assets/profiles/oracle/profile.json +40 -0
  13. package/dist/assets/profiles/polymarket-agent/SOUL.md +35 -0
  14. package/dist/assets/profiles/polymarket-agent/profile.json +34 -0
  15. package/dist/assets/profiles/profile.schema.json +90 -0
  16. package/dist/assets/profiles/protocol-builder/SOUL.md +57 -0
  17. package/dist/assets/profiles/protocol-builder/profile.json +39 -0
  18. package/dist/assets/profiles/robinhood-agent/SOUL.md +53 -0
  19. package/dist/assets/profiles/robinhood-agent/profile.json +41 -0
  20. package/dist/assets/profiles/solana-agent/SOUL.md +37 -0
  21. package/dist/assets/profiles/solana-agent/profile.json +38 -0
  22. package/dist/assets/profiles/stable-agent/SOUL.md +43 -0
  23. package/dist/assets/profiles/stable-agent/profile.json +38 -0
  24. package/dist/assets/skills/balance/SKILL.md +176 -0
  25. package/dist/assets/skills/bitcoin-l1.md +33 -0
  26. package/dist/assets/skills/chain-defi-ecosystem-profiling.md +27 -0
  27. package/dist/assets/skills/evm-contract-research.md +27 -0
  28. package/dist/assets/skills/hyperliquid.md +26 -0
  29. package/dist/assets/skills/multichain-exec-desk.md +33 -0
  30. package/dist/assets/skills/oracle-action-semantics/SKILL.md +40 -0
  31. package/dist/assets/skills/oracle-best-execution/SKILL.md +127 -0
  32. package/dist/assets/skills/oracle-best-execution.md +27 -0
  33. package/dist/assets/skills/oracle-bitcoin/SKILL.md +53 -0
  34. package/dist/assets/skills/oracle-chain-graphs-telegram-cards/SKILL.md +59 -0
  35. package/dist/assets/skills/oracle-chat/SKILL.md +61 -0
  36. package/dist/assets/skills/oracle-chat/chain.SKILL.md +31 -0
  37. package/dist/assets/skills/oracle-chat/setup.SKILL.md +37 -0
  38. package/dist/assets/skills/oracle-circuit-breaker/SKILL.md +51 -0
  39. package/dist/assets/skills/oracle-contract-research/SKILL.md +55 -0
  40. package/dist/assets/skills/oracle-desk/SKILL.md +58 -0
  41. package/dist/assets/skills/oracle-desk.md +27 -0
  42. package/dist/assets/skills/oracle-dex-launch/SKILL.md +38 -0
  43. package/dist/assets/skills/oracle-equities/SKILL.md +62 -0
  44. package/dist/assets/skills/oracle-grants/SKILL.md +69 -0
  45. package/dist/assets/skills/oracle-hypercore-staking/SKILL.md +57 -0
  46. package/dist/assets/skills/oracle-hyperliquid/SKILL.md +56 -0
  47. package/dist/assets/skills/oracle-meme-token-sniper/SKILL.md +73 -0
  48. package/dist/assets/skills/oracle-multichain-nft-launch/SKILL.md +338 -0
  49. package/dist/assets/skills/oracle-multichain-token-launch/SKILL.md +300 -0
  50. package/dist/assets/skills/oracle-nft-gacha-launch/SKILL.md +48 -0
  51. package/dist/assets/skills/oracle-nft-mint-gas-war/SKILL.md +63 -0
  52. package/dist/assets/skills/oracle-polymarket/SKILL.md +60 -0
  53. package/dist/assets/skills/oracle-protocol-builder/SKILL.md +59 -0
  54. package/dist/assets/skills/oracle-protocol-security/SKILL.md +60 -0
  55. package/dist/assets/skills/oracle-public-product/SKILL.md +44 -0
  56. package/dist/assets/skills/oracle-receipts/SKILL.md +52 -0
  57. package/dist/assets/skills/oracle-receipts.md +29 -0
  58. package/dist/assets/skills/oracle-rfq-tokenized-assets/SKILL.md +69 -0
  59. package/dist/assets/skills/oracle-smart-wallet-scanner/SKILL.md +49 -0
  60. package/dist/assets/skills/oracle-solana/SKILL.md +65 -0
  61. package/dist/assets/skills/oracle-solana-nft/SKILL.md +54 -0
  62. package/dist/assets/skills/oracle-token-research/SKILL.md +67 -0
  63. package/dist/assets/skills/solana.md +22 -0
  64. package/dist/bin/desk-server.mjs +56 -11
  65. package/dist/bin/oracle-data-mcp.mjs +6 -6
  66. package/dist/bin/oracle-equities.mjs +20 -0
  67. package/dist/bin/oracle-init.mjs +19 -19
  68. package/dist/bin/oracle-public-server.mjs +4 -4
  69. package/dist/bin/oracle-route.mjs +13 -13
  70. package/dist/bin/oracle-scan.mjs +10 -10
  71. package/dist/bin/oracle.mjs +35 -27
  72. package/dist/cli/commands/auth.mjs +11 -11
  73. package/dist/cli/commands/bootstrap.mjs +6 -6
  74. package/dist/cli/commands/chain.mjs +12 -12
  75. package/dist/cli/commands/chat.mjs +39 -29
  76. package/dist/cli/commands/data-mcp.mjs +2 -2
  77. package/dist/cli/commands/data.mjs +5 -5
  78. package/dist/cli/commands/doctor.mjs +3 -3
  79. package/dist/cli/commands/equities.mjs +15 -0
  80. package/dist/cli/commands/farm.mjs +59 -0
  81. package/dist/cli/commands/follow.mjs +28 -0
  82. package/dist/cli/commands/gate.mjs +4 -4
  83. package/dist/cli/commands/harness.mjs +15 -0
  84. package/dist/cli/commands/init.mjs +3 -3
  85. package/dist/cli/commands/mcp.mjs +50 -23
  86. package/dist/cli/commands/model.mjs +44 -34
  87. package/dist/cli/commands/plugins.mjs +38 -0
  88. package/dist/cli/commands/prepare.mjs +2 -2
  89. package/dist/cli/commands/public.mjs +3 -3
  90. package/dist/cli/commands/resolve.mjs +23 -0
  91. package/dist/cli/commands/route.mjs +2 -2
  92. package/dist/cli/commands/scan.mjs +2 -2
  93. package/dist/cli/commands/setup.mjs +12 -12
  94. package/dist/cli/commands/sign.mjs +19 -2
  95. package/dist/cli/commands/swap.mjs +36 -0
  96. package/dist/cli/commands/upgrade.mjs +2 -2
  97. package/dist/cli/commands/version.mjs +2 -2
  98. package/dist/data/desk-data.mjs +53 -10
  99. package/dist/data/names.mjs +2 -0
  100. package/dist/data/providers/farming.mjs +2 -0
  101. package/dist/equities/index.mjs +1 -0
  102. package/dist/index.mjs +58 -15
  103. package/dist/public-api/agent-grants.mjs +3 -0
  104. package/dist/router/index.mjs +2 -2
  105. package/dist/scanner/index.mjs +3 -3
  106. package/package.json +8 -3
  107. package/public/oracle-splash/_variants/ice.html +2073 -0
  108. package/public/oracle-splash/_variants/ivory.html +2075 -0
  109. package/public/oracle-splash/assets/agents/claude.png +0 -0
  110. package/public/oracle-splash/assets/agents/codex.png +0 -0
  111. package/public/oracle-splash/assets/desktop-app.jpg +0 -0
  112. package/public/oracle-splash/assets/hero/cli-session-poster.jpg +0 -0
  113. package/public/oracle-splash/assets/hero/cli-session.mp4 +0 -0
  114. package/public/oracle-splash/assets/hero/cli-session.webm +0 -0
  115. package/public/oracle-splash/assets/hero/orb-poster.jpg +0 -0
  116. package/public/oracle-splash/assets/hero/orb.webm +0 -0
  117. package/public/oracle-splash/assets/hero/risk-session-poster.jpg +0 -0
  118. package/public/oracle-splash/assets/hero/risk-session.mp4 +0 -0
  119. package/public/oracle-splash/assets/hero/risk-session.webm +0 -0
  120. package/public/oracle-splash/assets/hero/route-session-poster.jpg +0 -0
  121. package/public/oracle-splash/assets/hero/route-session.mp4 +0 -0
  122. package/public/oracle-splash/assets/hero/route-session.webm +0 -0
  123. package/public/oracle-splash/downloads/index.html +241 -0
  124. package/public/oracle-splash/index.html +1211 -242
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- var uo=Object.defineProperty;var E=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var O=(e,t)=>{for(var r in t)uo(e,r,{get:t[r],enumerable:!0})};var ir={};O(ir,{DEFAULT_CROSS_CHAIN_SOURCES:()=>Zt,DEFAULT_SAME_CHAIN_SOURCES:()=>Jt,NATIVE_TOKEN:()=>Ye,canonicalJson:()=>tr,hashFirmQuote:()=>or,hashRfqIntent:()=>nr,normalizeFirmQuote:()=>Je,normalizeRfqIntent:()=>So,sha256Hex:()=>le});import{createHash as yo}from"node:crypto";import{getAddress as Xt,isAddress as Xe}from"ethers";function A(e,t="invalid"){throw new Error(`rfq: ${e} ${t}`)}function Qt(e,t){let r=Number(e);return(!Number.isSafeInteger(r)||r<=0)&&A(t,"must be a positive chainId"),r}function Ae(e,t){let r=String(e??"").trim();return(!wo.test(r)||BigInt(r)<=0n)&&A(t,"must be a positive integer string"),r}function Eo(e,t){return e==null||e===""?null:Ae(e,t)}function Wt(e,t){let r=String(e??"").trim();return r.toLowerCase()===Ye.toLowerCase()?Ye:(Xe(r)||A(t,"must be an EVM address or native token sentinel"),Xt(r))}function er(e,t){let r=String(e??"").trim();return Xe(r)||A(t,"must be an EVM address"),Xt(r)}function vo(e,t){return e==null||e===""?null:er(e,t)}function Yt(e,t,r){return e===void 0?[...r]:(Array.isArray(e)||A(t,"must be an array"),e.map(n=>String(n).trim()).filter(Boolean))}function Ao(e,{nowMs:t,maxDeadlineMs:r},n){let o=Number(e);return Number.isFinite(o)||A(n,"must be a finite millisecond timestamp"),o<=t&&A(n,"expired"),o>t+r&&A(n,"exceeds maxDeadlineMs"),Math.floor(o)}function Y(e){if(Array.isArray(e))return e.map(Y);if(e&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())e[r]!==void 0&&(t[r]=Y(e[r]));return t}return e}function tr(e){return JSON.stringify(Y(e))}function le(e){return`0x${yo("sha256").update(tr(e)).digest("hex")}`}function rr(e,t){let r={...e};for(let n of t)delete r[n];return r}function nr(e){return le(rr(e,["intentHash"]))}function or(e){return le(rr(e,["firmQuoteHash"]))}function So(e={},t={}){let r=Number(t.nowMs??Date.now()),n=Number(t.maxDeadlineMs??1800*1e3);(!Number.isFinite(r)||!Number.isFinite(n)||n<=0)&&A("time","is invalid");let o=Qt(e.fromChainId??e.fromChain,"fromChainId"),i=Qt(e.toChainId??e.toChain,"toChainId"),a=o===i?Jt:Zt,c={kind:"rfq-intent",version:1,fromChainId:o,toChainId:i,sellToken:Wt(e.sellToken??e.tokenIn??e.fromToken,"sellToken"),buyToken:Wt(e.buyToken??e.tokenOut??e.toToken,"buyToken"),sellAmount:Ae(e.sellAmount??e.amountIn??e.fromAmount,"sellAmount"),receiver:er(e.receiver??e.recipient??e.to,"receiver"),deadlineMs:Ao(e.deadlineMs??e.deadline??e.expiresAtMs,{nowMs:r,maxDeadlineMs:n},"deadline"),minBuyAmount:Eo(e.minBuyAmount??e.minOut??e.amountOutMin,"minBuyAmount"),allowedSources:Yt(e.allowedSources,"allowedSources",a),allowedRouters:Yt(e.allowedRouters,"allowedRouters",[]),slippageBps:Number.isFinite(Number(e.slippageBps))?Number(e.slippageBps):null,partialFill:e.partialFill===!0,metadata:e.metadata&&typeof e.metadata=="object"&&!Array.isArray(e.metadata)?Y(e.metadata):{}};return c.slippageBps!=null&&(!Number.isInteger(c.slippageBps)||c.slippageBps<0||c.slippageBps>1e4)&&A("slippageBps","must be 0 to 10000"),c.intentId=e.intentId?String(e.intentId):le({seed:"rfq-intent",intent:c}).slice(0,34),c.intentHash=nr(c),Object.freeze(c)}function xo(e){return(!e||typeof e!="object"||Array.isArray(e))&&A("artifact","required"),e.typedDataHash!=null&&!Gt.test(String(e.typedDataHash))&&A("artifact.typedDataHash","must be bytes32"),e.calldataHash!=null&&!Gt.test(String(e.calldataHash))&&A("artifact.calldataHash","must be bytes32"),e.to!=null&&!Xe(String(e.to))&&A("artifact.to","must be an address"),e.data!=null&&!/^0x(?:[0-9a-fA-F]{2})*$/.test(String(e.data))&&A("artifact.data","must be hex"),Y(e)}function Je(e,t={},r={}){(!e||e.kind!=="rfq-intent")&&A("intent","required");let n=Number(r.nowMs??Date.now()),o=Number(t.expiryMs??t.expiresAtMs??t.validUntilMs);Number.isFinite(o)||A("quote expiry","required"),o<=n&&A("quote","expired"),o>e.deadlineMs&&A("quote expiry","exceeds intent deadline");let i=String(t.source??t.provider??"").trim();i||A("source","required"),e.allowedSources.includes(i)||A("source","not allowed by intent");let s=Ae(t.amountOut??t.buyAmount,"amountOut"),a=Ae(t.minBuyAmount??t.minOut??s,"minBuyAmount");BigInt(a)>BigInt(s)&&A("minBuyAmount","exceeds amountOut");let c=xo(t.artifact??t.executableArtifact??t.transaction??t.typedData),u=Number(t.quotedAtMs??t.timestampMs??r.nowMs??Date.now());Number.isFinite(u)||A("quotedAtMs","must be finite");let d=vo(t.router??t.settlementRouter??c.to,"router"),p={kind:"rfq-firm-quote",provider:"rfq",surface:"rfq",version:1,quoteId:String(t.quoteId??t.id??"").trim(),source:i,intentHash:e.intentHash,fromChainId:e.fromChainId,toChainId:e.toChainId,sellToken:e.sellToken,buyToken:e.buyToken,sellAmount:e.sellAmount,receiver:e.receiver,router:d,amountOut:s,minBuyAmount:a,quotedAtMs:Math.floor(u),expiryMs:Math.floor(o),artifact:c,maker:t.maker?String(t.maker):null,metadata:t.metadata&&typeof t.metadata=="object"&&!Array.isArray(t.metadata)?Y(t.metadata):{}};return p.quoteId||(p.quoteId=le({seed:"rfq-quote",out:p}).slice(0,34)),p.firmQuoteHash=or(p),Object.freeze(p)}var Ye,Jt,Zt,Gt,wo,Ze=E(()=>{Ye="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Jt=Object.freeze(["lifi","paraswap","0x","cow","uniswap-v3"]),Zt=Object.freeze(["lifi"]),Gt=/^0x[0-9a-fA-F]{64}$/,wo=/^\d+$/});import{createHash as Io}from"node:crypto";function Oo(e){let t=String(e||"").toLowerCase();return ur.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function Ro(e){let t={};for(let[r,n]of Object.entries(e||{}))Oo(r)||(t[r]=n);return t}function No(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 To(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Bo(e,t,r){let n={};for(let[c,u]of Object.entries(r||{}))n[c.toLowerCase()]=u;let o=Object.keys(n).filter(c=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(c)),s=[...new Set([...ur,...o])].sort().map(c=>`${c}=${n[c]??""}`).join(`
3
- `),a=Io("sha256").update(s).digest("hex").slice(0,32);return`${e} ${t} ${a}`}function Lo(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,sr):Math.min(250*2**e,sr)+Math.floor(Math.random()*100)}async function Uo(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i}){let s=new AbortController,a=setTimeout(()=>s.abort(),i);try{let c=String(e),u={...n||{}};for(let d=0;d<=cr;d+=1){let p=await t(c,{method:r,headers:u,body:o,signal:s.signal,redirect:"manual"}),l=await p.text(),m=null;if(l)try{m=JSON.parse(l)}catch{m=null}if(_o.has(p.status)){if(r!=="GET"&&r!=="HEAD"){let b=new Error(`HTTP ${p.status} ${r} ${c} redirected non-idempotent request`);throw b.status=p.status,b.body=m??l.slice(0,300),b}if(d===cr)throw new Error(`HTTP redirect loop for ${e}`);let f=No(p.headers?.get?.("location"),c);To(f,c)||(u=Ro(u)),c=f;continue}if(!p.ok){let f=new Error(`HTTP ${p.status} ${r} ${c}`);throw f.status=p.status,f.retryAfter=p.headers?.get?.("retry-after")??null,f.body=m??l.slice(0,300),f}return m??l}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(a)}}async function v(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(),i={Accept:"application/json",...t.headers||{}},s=t.body;s!=null&&typeof s!="string"&&(i["Content-Type"]=i["Content-Type"]||"application/json",s=JSON.stringify(s));let a=Number.isInteger(t.retries)?Math.max(t.retries,0):ko,c=async()=>{let m;for(let f=0;f<=a;f++)try{return await Uo(e,{fetchImpl:r,method:o,headers:i,body:s,timeoutMs:n})}catch(b){m=b;let h=b?.status,g=b?.name==="AbortError",S=new Set([408,425,429]),C=h!=null?S.has(h)||Co.has(h)&&ar.has(o):!g&&ar.has(o);if(f===a||!C)throw b;await Do(Lo(f,b?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&s==null))return c();let d=Bo(o,e,i),p=et.get(d);if(p)return p;let l=c().finally(()=>et.delete(d));return et.set(d,l),l}var Co,ar,ko,sr,ur,_o,cr,et,Do,L=E(()=>{Co=new Set([408,425,429,500,502,503,504]),ar=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),ko=2,sr=4e3,ur=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],_o=new Set([301,302,303,307,308]),cr=3;et=new Map;Do=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as Po}from"node:fs";import{homedir as qo}from"node:os";import{join as lr}from"node:path";function $o(){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=qo();return[e,lr(t,".config","oracle","exec.env"),lr(t,".config","mad-desk","exec.env")].filter(Boolean)}function dr(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of $o())try{let i=Po(o,"utf8"),s=i.match(new RegExp(`^${t}=(.*)$`,"m"))||i.match(new RegExp(`^${r}=(.*)$`,"m"));if(s&&(n=s[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 pr=E(()=>{});var mr=E(()=>{});import{createHash as Fo,createHmac as Mo,timingSafeEqual as rs}from"node:crypto";function rt(e){return Array.isArray(e)?`[${e.map(rt).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${rt(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function jo(e,{required:t=!1}={}){try{return dr(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function br(e){let{signature:t,...r}=e;return r}function gr(e,{secret:t}={}){let r=jo(t);return r?{...e,signature:Mo("sha256",r).update(rt(br(e))).digest("hex")}:e}function Vo(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 Fo("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function N(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 gr({...br(e),calldataHash:Vo(n)},{secret:o})}function tt(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function Ho(e){let t=e==null?fr: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,fr)}function U({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let i=tt(e,0),s=i>0?i>=25e4?5:i>=1e5?10:i>=5e4?20:i>=1e4?40:70:n?30:10,a=Math.min(60,Math.abs(tt(t,0))*2),c=Math.min(40,Math.floor(Math.max(0,tt(r,0))/5e3)*5),u=Math.max(25,Math.ceil(20+s+a+c)),d=Ho(o);return{mode:"auto",requiredBps:u,selectedBps:Math.min(u,d),capBps:d,executable:u<=d}}function Ko({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:i=0,crossChain:s=!1,requestedCapBps:a,quotedAtMs:c=Date.now(),ttlMs:u=hr,secret:d}={}){let p=BigInt(r??0);if(p<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let l=U({liquidityUsd:n,priceChange5m:o,quoteAgeMs:i,crossChain:s,requestedCapBps:a});if(!l.executable)throw new Error(`auto-slippage requires ${l.requiredBps} bps above hard/requested cap ${l.capBps}; route blocked`);let m=Number(c);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let f=Math.min(3e4,Math.max(1e3,Number(u)||hr)),b=p*BigInt(1e4-l.selectedBps),h=b/10000n;if(b%10000n!==0n&&(h+=1n),h>p&&(h=p),p>0n&&h<=0n)throw new Error(`auto-slippage: quote ${p} is too small to express a ${l.selectedBps} bps floor without rounding to zero`);let g=Number((p-h)*10000n/(p===0n?1n:p));if(g>l.capBps)throw new Error(`auto-slippage: realised floor implies ${g} bps, above cap ${l.capBps} \u2014 refusing to issue a guard weaker than advertised`);return gr({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:p.toString(),minAmountOut:h.toString(),requiredBps:l.requiredBps,selectedBps:l.selectedBps,capBps:l.capBps,quotedAtMs:m,expiresAtMs:m+f},{secret:d})}function I(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:i,crossChain:s,requestedCapBps:a,quotedAtMs:c=Date.now(),ttlMs:u}={}){let d=Ko({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:i,crossChain:s,requestedCapBps:a,quotedAtMs:c,ttlMs:u});return{...e,autoSlippage:d,amountOutMinimum:d.minAmountOut}}var fr,hr,P=E(()=>{pr();mr();fr=100,hr=2e4});function nt(e){let t=String(e||"").trim();return/^0x[0-9a-fA-F]{40}$/.test(t)?t:F}var F,Se=E(()=>{F="0x000000000000000000000000000000000000dEaD"});import{createHash as zo,createHmac as Go,timingSafeEqual as cs}from"node:crypto";function ot(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ot).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ot(e[r])}`).join(",")}}`}function yr(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function wr(e=process.env){return yr(process.env)||yr(e)}function Yo(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...i}=e||{};return i}function Xo(e){let t=Yo(e);return zo("sha256").update(ot(t)).digest("hex")}function Jo(e,t=wr()){return t?Go("sha256",t).update(String(e)).digest("hex"):""}function x(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 i=Date.now(),s=i+Wo,c={...o,preparedAt:i,expiresAt:s,prepareVersion:Qo},u=Xo(c),d=wr(n),p=d?Jo(u,d):void 0,l={...c,oraclePrepared:!0,prepareHash:u};return p&&(l.prepareMac=p),l}var Qo,Wo,us,T=E(()=>{Qo=2,Wo=300*1e3,us=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var st={};O(st,{LIFI_API:()=>vr,lifiChains:()=>ni,lifiHealth:()=>ti,lifiPrepare:()=>ri,lifiQuote:()=>V});function at(e={}){return(e.baseUrl||process.env.LIFI_API_URL||vr).replace(/\/$/,"")}function ei(e){let t=String(e||it).toLowerCase();return t===it.toLowerCase()||t===Zo}function Er(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 ti(e={}){let t=await v(`${at(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 V(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=it,toToken:i,fromAmount:s,fromAddress:a=F}=e;if(r==null||!i||!s)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let c=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:i,fromAmount:String(s),fromAddress:a}),u=U({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!u.executable)throw new Error(`lifi: route requires ${u.requiredBps} bps above cap ${u.capBps}`);c.set("slippage",String(u.selectedBps/1e4));let d=await v(`${at(t)}/quote?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),p=d?.estimate?.toAmount||d?.toAmount;if(!p)return{...d,autoSlippagePolicy:u};let l=d?.transactionRequest?.to||d?.estimate?.approvalAddress||"lifi",m=I(d,{chainId:Number(r),venue:l,amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),f=d?.estimate?.toAmountMin||d?.toAmountMin;if(f!=null&&BigInt(f)<BigInt(m.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return m}async function ri(e={},t={}){let r=await V(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 i=null;if(!ei(e.fromToken)){let s=r?.estimate?.approvalAddress||r?.approvalAddress;if(!s)throw new Error("lifi: ERC20 route missing approvalAddress");i={token:Er(e.fromToken,"approval token"),spender:Er(s,"approval spender"),amount:String(e.fromAmount)}}return x({provider:"lifi",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:o,quote:r,autoSlippage:r.autoSlippage,requiresApproval:i,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:N(r.autoSlippage,{chainId:o,venue:n.to,data:n.data})}},{provider:"lifi",kind:"lifi-tx"})}async function ni(e={}){return v(`${at(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3})}var vr,it,Zo,de=E(()=>{L();P();Se();T();vr="https://li.quest/v1";it="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Zo="0x0000000000000000000000000000000000000000"});var xr={};O(xr,{PARASWAP_API:()=>Ar,paraswapHealth:()=>ii,paraswapPrepare:()=>oi,paraswapPrice:()=>J,paraswapTokens:()=>Sr});function X(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 Sr(e={},t={}){let r=Number(e.chainId||1);return v(`${ct(t)}/tokens/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function J(e={},t={}){let r=Number(e.chainId||e.network||1);if(e.amount==null)throw new Error("amount required");let n=new URLSearchParams({srcToken:X(e.srcToken,"srcToken"),destToken:X(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 v(`${ct(t)}/prices?${n}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),i=o?.priceRoute?.destAmount;return i?{...I(o,{chainId:r,venue:o?.priceRoute?.contractAddress||"paraswap-quote",amountOut:i,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"}:{...o,executionReady:!1}}async function oi(e={},t={}){if(String(e.side||"SELL").toUpperCase()!=="SELL")throw new Error("paraswap: agentic prepare currently supports exact-input SELL only");let r=Number(e.chainId||e.network||1),n=X(e.userAddress,"userAddress"),o=await J(e,t),i=o?.priceRoute,s=String(i?.contractAddress||"").toLowerCase();if(!s)throw new Error("paraswap: price route missing contractAddress");let a={srcToken:X(e.srcToken,"srcToken"),destToken:X(e.destToken,"destToken"),srcAmount:String(i.srcAmount||e.amount),destAmount:String(o.amountOutMinimum),priceRoute:i,userAddress:n,ignoreChecks:!1,ignoreGasEstimate:!1};e.receiver&&(a.receiver=X(e.receiver,"receiver"));let c=await v(`${ct(t)}/transactions/${r}`,{method:"POST",body:a,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??25e3});if(Number(c.chainId??r)!==r)throw new Error("paraswap: transaction chain mismatch");if(String(c.to||"").toLowerCase()!==s)throw new Error("paraswap: transaction target mismatch");if(c.from&&String(c.from).toLowerCase()!==n)throw new Error("paraswap: transaction sender mismatch");return x({provider:"paraswap",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:r,quote:o,autoSlippage:o.autoSlippage,requiresApproval:a.srcToken!=="0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"?{token:a.srcToken,spender:i.tokenTransferProxy||s,amount:a.srcAmount}:null,transaction:{chainId:r,from:c.from||n,to:c.to,data:c.data,value:c.value??"0x0",...c.gas!=null?{gasLimit:c.gas}:{},slippageGuard:N(o.autoSlippage,{chainId:r,venue:c.to,data:c.data})}},{provider:"paraswap",kind:"paraswap-tx"})}async function ii(e={}){let t=await Sr({chainId:1},e),r=Array.isArray(t?.tokens)?t.tokens.length:Object.keys(t?.tokens||{}).length;return{ok:r>0,tokenSample:r}}var Ar,ct,xe=E(()=>{L();P();T();Ar="https://api.paraswap.io",ct=(e={})=>(e.baseUrl||process.env.PARASWAP_API_URL||Ar).replace(/\/$/,"")});function Ie({provider:e,defaultUrl:t,hosts:r=[],url:n,strict:o=!1}){let s=(String(n??"").trim()||String(t)).replace(/\/$/,"");if(s===String(t).replace(/\/$/,""))return{baseUrl:s,trusted:!0,host:Cr(t)};let a;try{a=new URL(s)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(a.protocol!=="http:"&&a.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let c=a.host;if(!c)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Cr(t),...r]).has(c)){let d=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(c);return a.protocol==="http:"&&!d?{baseUrl:s,trusted:!1,host:c,reason:"plaintext http downgrade"}:{baseUrl:s,trusted:!0,host:c}}if(String(process.env[Ir]||"")==="1")return{baseUrl:s,trusted:!1,host:c};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${c} (set ${Ir}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:c}}function Cr(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function Ce(e,t,r){let n={...e};if(!r)return n;for(let[o,i]of Object.entries(t||{}))i&&(n[o]=i);return n}var Ir,ut=E(()=>{Ir="ORACLE_ALLOW_CUSTOM_PROVIDER_URL"});var Tr={};O(Tr,{ZEROX_API:()=>kr,zeroxHealth:()=>ai,zeroxPrepare:()=>si,zeroxPrice:()=>Nr,zeroxQuote:()=>Z});function _r(e={}){return Ie({provider:"zerox",defaultUrl:kr,hosts:["api.0x.org"],url:e.baseUrl||process.env.ZEROX_API_URL})}function Or(e={}){return _r(e).baseUrl}function ke(e={}){return e.apiKey||process.env.ZEROX_API_KEY||process.env.OX_API_KEY||process.env["0X_API_KEY"]||""}function Rr(e={}){return Ce({"0x-version":"v2",accept:"application/json"},{"0x-api-key":ke(e)},_r(e).trusted)}async function ai(e={}){if(!ke(e))return{ok:!1,configured:!1,error:"ZEROX_API_KEY not set"};try{let t=await Nr({chainId:8453,sellToken:"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",buyToken:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",sellAmount:"1000000000000000"},e);return{ok:!0,configured:!0,buyAmount:t.buyAmount||t.grossBuyAmount}}catch(t){return{ok:!1,configured:!0,error:String(t.message||t).slice(0,160)}}}async function Nr(e={},t={}){if(!ke(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:i,taker:s}=e;if(!n||!o||!i)throw new Error("zeroxPrice requires sellToken, buyToken, sellAmount");let a=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(i)});return s&&a.set("taker",s),v(`${Or(t)}/swap/allowance-holder/price?${a}`,{headers:Rr(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Z(e={},t={}){if(!ke(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:i,taker:s}=e;if(!n||!o||!i)throw new Error("zeroxQuote requires sellToken, buyToken, sellAmount");let a=U({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!a.executable)throw new Error(`0x: route requires ${a.requiredBps} bps above cap ${a.capBps}`);let c=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(i),slippageBps:String(a.selectedBps)});s&&c.set("taker",s);let u=await v(`${Or(t)}/swap/allowance-holder/quote?${c}`,{headers:Rr(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),d=u?.buyAmount||u?.grossBuyAmount;return d?I(u,{chainId:r,venue:u?.transaction?.to||u?.to||"0x",amountOut:d,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):{...u,autoSlippagePolicy:a}}async function si(e={},t={}){if(!e.taker)throw new Error("0x: taker required for executable prepare");let r=await Z(e,t),n=r?.transaction;if(!n?.to||!n?.data)throw new Error("0x: firm quote returned no transaction");let o=Number(e.chainId??8453),i=r?.issues?.allowance?.spender||r?.allowanceTarget;return x({provider:"zerox",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:o,quote:r,autoSlippage:r.autoSlippage,requiresApproval:r?.issues?.allowance?.actual!=null&&BigInt(r.issues.allowance.actual)<BigInt(e.sellAmount)?{token:e.sellToken,spender:i,amount:String(e.sellAmount)}:null,transaction:{chainId:o,from:e.taker,to:n.to,data:n.data,value:n.value??"0x0",...n.gas!=null?{gasLimit:n.gas}:{},slippageGuard:N(r.autoSlippage,{chainId:o,venue:n.to,data:n.data})}},{provider:"zerox",kind:"zerox-tx"})}var kr,_e=E(()=>{L();P();ut();T();kr="https://api.0x.org"});var xs,Is,Br=E(()=>{xs=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"}),Is=Object.freeze({"evm:prepare":["ORACLE_EVM_ADDRESS","EVM_KEYSTORE_FILE","ORACLE_SIGNER_ADDRESS"],"evm:execute":["EVM_KEYSTORE_FILE","ORACLE_KEYSTORE_FILE"],"btc:execute":["BTC_WIF_FILE","ORACLE_BTC_WIF_FILE"],"solana:execute":["SOLANA_KEYPAIR_FILE","ORACLE_SOLANA_KEYPAIR_FILE"],"nft:buy":[],"nft:mint":[],"cow:submit":[]})});var Vr={};O(Vr,{COW_CANCEL_TYPES:()=>qr,COW_HOSTS:()=>dt,COW_ORDER_TYPES:()=>Oe,COW_SETTLEMENT:()=>Dr,COW_VAULT_RELAYER:()=>Ur,cowCancelOrders:()=>wi,cowChains:()=>Ai,cowHealth:()=>pi,cowOrder:()=>jr,cowOrderStatus:()=>Mr,cowOrderUid:()=>fi,cowPrepareCancel:()=>gi,cowPrepareOrder:()=>mi,cowQuote:()=>H,cowSignCancel:()=>yi,cowSignOrder:()=>hi,cowSubmitSignedOrder:()=>bi,cowVerifyOrderFill:()=>vi});import{TypedDataEncoder as Lr,getAddress as pe,isAddress as ci}from"ethers";function Re(e,t={}){if(t.baseUrl)return t.baseUrl.replace(/\/$/,"");let r=dt[Number(e)];if(!r)throw new Error(`cowswap: unsupported chainId ${e}`);return r}function ui(e,t="v1",r={}){let n=Re(e,r);return t==="v1"?n:n.replace(/\/api\/v1$/,`/api/${t}`)}function M(e,t){let r=String(e||"").trim();if(!ci(r))throw new Error(`cowswap: ${t} must be an address`);return pe(r).toLowerCase()}function ee(e,t){try{let r=BigInt(String(e));if(r<0n)throw new Error("negative");return r.toString()}catch{throw new Error(`cowswap: ${t} must be a non-negative integer string`)}}function $r(e,t){let r=String(e||"").trim();if(!/^0x[0-9a-fA-F]{64}$/.test(r))throw new Error(`cowswap: ${t} must be bytes32 hex`);return r.toLowerCase()}function Fr(e,t="uid"){let r=String(e||"").trim();if(!/^0x[0-9a-fA-F]{112}$/.test(r))throw new Error(`cowswap: ${t} must be 56-byte order UID hex`);return r.toLowerCase()}function li({digest:e,owner:t,validTo:r}={}){let n=$r(e,"order digest").slice(2),o=M(t,"owner").slice(2).toLowerCase(),i=Number(r);if(!Number.isInteger(i)||i<0||i>4294967295)throw new Error("cowswap: validTo must fit uint32");return`0x${n}${o}${i.toString(16).padStart(8,"0")}`.toLowerCase()}function pt(e){let t=Dr[Number(e)];if(!t)throw new Error(`cowswap: settlement contract not registered for chain ${e}`);return{name:"Gnosis Protocol",version:"v2",chainId:Number(e),verifyingContract:pe(t)}}function di(e={},t,r){let n=M(e.sellToken,"sellToken"),o=M(e.buyToken,"buyToken"),i=M(e.receiver||r,"receiver"),s=Number(e.validTo);if(!Number.isInteger(s)||s<=0)throw new Error("cowswap: quote.validTo required");let a=$r(e.appData||e.appDataHash||`0x${"0".repeat(64)}`,"appData");return{sellToken:n,buyToken:o,receiver:i,sellAmount:ee(e.sellAmount,"sellAmount"),buyAmount:ee(e.buyAmount,"buyAmount"),validTo:s,appData:a,feeAmount:ee(e.feeAmount??"0","feeAmount"),kind:String(e.kind||"sell"),partiallyFillable:!!e.partiallyFillable,sellTokenBalance:String(e.sellTokenBalance||"erc20"),buyTokenBalance:String(e.buyTokenBalance||"erc20")}}async function pi(e={}){try{let t=await H({chainId:1,sellToken:lt[1],buyToken:Pr[1],sellAmountBeforeFee:"1000000000000000",from:F},e);return{ok:!0,buyAmount:t.quote?.buyAmount||t.buyAmount}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function H(e={},t={}){let r=Number(e.chainId??1),n=nt(e.from||e.owner),o=e.sellToken||lt[r],i=e.buyToken||Pr[r],s=String(e.sellAmountBeforeFee||e.sellAmount||"0");if(!o||!i||s==="0")throw new Error("cowQuote requires sellToken, buyToken, sellAmountBeforeFee");if(/eeeeeeee|native|^eth$/i.test(o)&&(o=lt[r],!o))throw new Error("no WETH mapping for chain");let a={sellToken:o,buyToken:i,from:n,receiver:e.receiver||n,sellAmountBeforeFee:s,kind:e.kind||"sell",signingScheme:e.signingScheme||"eip1271"},c=await v(`${Re(r,t)}/quote`,{method:"POST",body:a,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),u=c?.quote?.buyAmount||c?.buyAmount;return u?I(c,{chainId:r,venue:"cowswap-order",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):c}async function mi(e={},t={}){let r=Number(e.chainId??1),n=M(nt(e.from||e.owner||e.signer),"owner"),o=await H({...e,chainId:r,from:n,signingScheme:e.signingScheme||"eip712"},t),i=di(o?.quote||o,r,n),s=pt(r),a={domain:s,types:Oe,primaryType:"Order",message:i},c=Lr.hash(s,Oe,i),u=Ur[r];if(!u)throw new Error(`cowswap: vault relayer not registered for chain ${r}`);return x({provider:"cowswap",orderReady:!0,executionReady:!1,chainId:r,owner:n,signingScheme:"eip712",settlement:s.verifyingContract.toLowerCase(),vaultRelayer:pe(u).toLowerCase(),quote:o,quoteId:o?.id??e.quoteId??null,typedData:a,cowGuard:{mode:"cow-order",version:1,provider:"cowswap",chainId:r,owner:n,settlement:s.verifyingContract.toLowerCase(),vaultRelayer:pe(u).toLowerCase(),sellToken:i.sellToken,buyToken:i.buyToken,sellAmount:i.sellAmount,buyAmount:i.buyAmount,validTo:i.validTo,quoteId:o?.id??e.quoteId??null,typedDataHash:c,issuedAtMs:Date.now(),expiresAtMs:Math.min(i.validTo*1e3,Date.now()+2e4)},requiresApproval:{token:i.sellToken,spender:pe(u).toLowerCase(),amount:i.sellAmount}},{provider:"cowswap",kind:"cow-order"})}async function Mr(e={},t={}){let r=Number(e.chainId??1),n=String(e.uid||e.orderUid||"").trim();if(!n)throw new Error("cowOrderStatus requires uid");return v(`${Re(r,t)}/orders/${encodeURIComponent(n)}/status`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function jr(e={},t={}){let r=Number(e.chainId??1),n=String(e.uid||e.orderUid||"").trim();if(!n)throw new Error("cowOrder requires uid");return v(`${Re(r,t)}/orders/${encodeURIComponent(n)}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}function fi(e={}){let t=e.typedData||e,r=Number(e.chainId??t?.domain?.chainId),n=t?.message||e.order||e.message;if(!n)throw new Error("cowswap: typed order message required");let o=e.cowGuard?.typedDataHash||Lr.hash(pt(r),Oe,n),i=e.owner||e.from||e.signer||n.receiver;return li({digest:o,owner:i,validTo:n.validTo})}async function hi(e={},t={}){throw new Error("cowswap.cowSignOrder refused: @oracle-agent/oracle is prepare-only. Sign with the user wallet; do not pass private keys here.")}async function bi(e={},t={}){throw new Error("cowswap.cowSubmitSignedOrder refused: @oracle-agent/oracle is prepare-only. Submit signed orders from the user wallet or local operator.")}function gi(e={}){let t=Number(e.chainId??1),r=M(e.owner||e.from||e.signer,"owner"),n=(e.orderUids||e.uids||[e.uid]).filter(Boolean).map((s,a)=>Fr(s,`orderUids[${a}]`));if(!n.length)throw new Error("cowswap: orderUids required");let o=pt(t);return x({provider:"cowswap",chainId:t,owner:r,orderUids:n,signingScheme:"eip712",typedData:{domain:o,types:qr,primaryType:"OrderCancellations",message:{orderUids:n}},cancelReady:!0,executableArtifact:!0},{provider:"cowswap",kind:"cow-cancel"})}async function yi(e={},t={}){throw new Error("cowswap.cowSignCancel refused: @oracle-agent/oracle is prepare-only. Cancel-sign with the user wallet.")}async function wi(e={},t={}){throw new Error("cowswap.cowCancelOrders refused: @oracle-agent/oracle is prepare-only. Cancel from the user wallet or local operator.")}function Ei(e={}){return ee(e.buyAmount??e.executedBuyAmount??"0","trade.buyAmount")}async function vi(e={},t={}){let r=Number(e.chainId??1),n=Fr(e.uid||e.orderUid),o=t.order||await jr({chainId:r,uid:n},t),i=t.status||o.status||await Mr({chainId:r,uid:n},t).catch(()=>null),s=t.trades||await v(`${ui(r,"v2",t)}/trades?orderUid=${encodeURIComponent(n)}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),a=Array.isArray(s)?s:[],c=e.expectedOwner?M(e.expectedOwner,"expectedOwner"):null;if(c&&M(o.owner||a[0]?.owner||c,"owner")!==c)return{ok:!1,provider:"cowswap",chainId:r,uid:n,reason:"owner mismatch",order:o,status:i,trades:a};let u=0n;for(let l of a.filter(m=>String(m.orderUid||"").toLowerCase()===n))u+=BigInt(Ei(l));u===0n&&o.executedBuyAmount!=null&&(u=BigInt(ee(o.executedBuyAmount,"executedBuyAmount")));let d=e.minBuyAmount!=null?BigInt(ee(e.minBuyAmount,"minBuyAmount")):0n,p=u>=d&&String(o.status||i?.status||"").toLowerCase()!=="expired";return{ok:p,provider:"cowswap",chainId:r,uid:n,status:o.status||i?.status||null,executedBuyAmount:u.toString(),minBuyAmount:e.minBuyAmount??null,trades:a,settlementTxs:[...new Set(a.map(l=>l.txHash).filter(Boolean))],order:o,orderStatus:i,reason:p?null:"insufficient fill or expired order"}}function Ai(){return Object.keys(dt).map(Number)}var dt,Dr,Ur,lt,Pr,Oe,qr,Ne=E(()=>{L();P();Br();Se();T();dt={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"},Dr=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Ur=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"}),lt={1:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",8453:"0x4200000000000000000000000000000000000006",42161:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"},Pr={1:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",8453:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",42161:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},Oe=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"}]}),qr=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]})});function Kr(e){return Si.get(Number(e))||null}function zr(e,t=process.env){let r=Kr(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}var Hr,Si,Gr=E(()=>{Hr={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}},Si=new Map(Object.values(Hr).map(e=>[e.chainId,e]))});import{Interface as xi,getAddress as Ii}from"ethers";function Wr(e,t){try{return Ii(e).toLowerCase()}catch{throw new Error(`${t} must be a valid EVM address`)}}function ki(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=zr(e,r);return n||Ci[Number(e)]||null}function Oi(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!_i.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 k(e,t,r=[],n={}){let o=String(t||"");Oi(o);let i=ki(e,n);if(!i)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let a=await v(i,{method:"POST",body:{jsonrpc:"2.0",id:1,method:t,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3});if(a?.error){let c=new Error(a.error.message||JSON.stringify(a.error));throw c.code=a.error.code,c}return a.result}async function Yr(e,t={}){let r=await k(e,"eth_blockNumber",[],t);return parseInt(r,16)}async function Xr(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await k(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function Jr(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=Wr(e.token||e.tokenAddress,"token"),o=Wr(e.account||e.owner||e.address,"account"),i=Qr.encodeFunctionData("balanceOf",[o]),s=await k(r,"eth_call",[{to:n,data:i},e.blockTag||"latest"],t),a=Qr.decodeFunctionResult("balanceOf",s),c=BigInt(a[0]);return{chainId:r,token:n,account:o,balance:c.toString(),balanceHex:`0x${c.toString(16)}`,blockTag:e.blockTag||"latest"}}var Qr,Ci,_i,te=E(()=>{L();Gr();Qr=new xi(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);Ci={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"};_i=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/});var an={};O(an,{UNI_V3_CHAINS:()=>_,UNI_V3_FEE_TIERS:()=>tn,uniV3Chains:()=>Di,uniV3EthUsdc:()=>on,uniV3Health:()=>Li,uniV3PrepareExactIn:()=>Bi,uniV3QuoteExactIn:()=>K,uniV3QuoteExactInPath:()=>Ti});import{Interface as en,getAddress as me,isAddress as Ri}from"ethers";function ft(e){let t=Number(e),r=_[t];if(!r)throw new Error(`uniswap-v3: unsupported chainId ${e} (supported: ${Object.keys(_).join(", ")})`);return{chainId:t,...r}}function mt(e,t){let r=_[Number(t)];if(!e||e===rn||e===nn||/^eth$/i.test(String(e)))return me(r.weth);let n=String(e);if(/^weth$/i.test(n))return me(r.weth);if(/^usdc$/i.test(n))return me(r.usdc);if(!Ri(n))throw new Error(`invalid token address: ${e}`);return me(n)}function Ni(e,t){if(e.length!==t.length+1)throw new Error("path: fees.length must be tokens.length - 1");let r="0x";for(let n=0;n<t.length;n++)r+=e[n].slice(2).toLowerCase(),r+=Number(t[n]).toString(16).padStart(6,"0");return r+=e[e.length-1].slice(2).toLowerCase(),r}async function K(e={},t={}){let{chainId:r,quoter:n,router:o}=ft(e.chainId??8453),i=mt(e.tokenIn||"WETH",r),s=mt(e.tokenOut||_[r].usdc,r),a=BigInt(e.amountIn??0);if(a<=0n)throw new Error("amountIn required (raw base units)");let c=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[3e3]:[...tn],u=[],d=null;for(let p of c){let l=Te.encodeFunctionData("quoteExactInputSingle",[{tokenIn:i,tokenOut:s,amountIn:a,fee:p,sqrtPriceLimitX96:0n}]);try{let m=await k(r,"eth_call",[{to:n,data:l},"latest"],t);if(!m||m==="0x"){u.push({fee:p,ok:!1,error:"empty result"});continue}let f=Te.decodeFunctionResult("quoteExactInputSingle",m),b={fee:p,ok:!0,amountOut:f[0].toString(),sqrtPriceX96After:f[1].toString(),initializedTicksCrossed:Number(f[2]),gasEstimate:f[3].toString()};u.push(b),(!d||BigInt(b.amountOut)>BigInt(d.amountOut))&&(d=b)}catch(m){u.push({fee:p,ok:!1,error:String(m.message||m).slice(0,160)})}}if(!d){let p=u.map(l=>`${l.fee}:${l.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${p}`)}return I({venue:"uniswap-v3",chainId:r,chain:_[r].name,quoter:n,tokenIn:i,tokenOut:s,amountIn:a.toString(),fee:d.fee,amountOut:d.amountOut,gasEstimate:d.gasEstimate,sqrtPriceX96After:d.sqrtPriceX96After,initializedTicksCrossed:d.initializedTicksCrossed,triedFees:u,best:!0},{chainId:r,venue:o,amountOut:d.amountOut,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function Ti(e={},t={}){let{chainId:r,quoter:n,router:o}=ft(e.chainId??8453),i=(e.tokens||[]).map(l=>mt(l,r)),s=(e.fees||[]).map(Number);if(i.length<2)throw new Error("tokens[] need at least 2 addresses");let a=BigInt(e.amountIn??0);if(a<=0n)throw new Error("amountIn required");let c=Ni(i,s),u=Te.encodeFunctionData("quoteExactInput",[c,a]),d=await k(r,"eth_call",[{to:n,data:u},"latest"],t),p=Te.decodeFunctionResult("quoteExactInput",d);return I({venue:"uniswap-v3",chainId:r,chain:_[r].name,quoter:n,tokens:i,fees:s,path:c,amountIn:a.toString(),amountOut:p[0].toString(),gasEstimate:p[3].toString()},{chainId:r,venue:o,amountOut:p[0].toString(),liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function on(e={},t={}){let r=Number(e.chainId??8453),n=e.amountIn??"1000000000000000",o=await K({chainId:r,tokenIn:_[r].weth,tokenOut:_[r].usdc,amountIn:n,fee:e.fee},t),i=Number(o.amountOut)/1e6;return{...o,amountOutUsdc:i,pair:"WETH/USDC"}}async function Bi(e={},t={}){let r=Number(e.chainId??8453),n=ft(r),o=me(e.recipient),i=String(e.tokenIn||"WETH"),s=!e.tokenIn||i===rn||i===nn||/^eth$/i.test(i),a=await K(e,t),c=Zr.encodeFunctionData("exactInputSingle",[{tokenIn:a.tokenIn,tokenOut:a.tokenOut,fee:a.fee,recipient:o,amountIn:BigInt(a.amountIn),amountOutMinimum:BigInt(a.amountOutMinimum),sqrtPriceLimitX96:0n}]),u=Math.min(600,Math.max(30,Number(e.deadlineSeconds??300))),p=Number(t.nowSeconds??Math.floor(Date.now()/1e3))+u,l=Zr.encodeFunctionData("multicall",[p,[c]]);return x({provider:"uniswap-v3",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:r,deadline:p,quote:a,autoSlippage:a.autoSlippage,requiresApproval:s?null:{token:a.tokenIn,spender:n.router,amount:a.amountIn},transaction:{chainId:r,from:o,to:n.router,data:l,value:s?a.amountIn:"0",slippageGuard:N(a.autoSlippage,{chainId:r,venue:n.router,data:l})}},{provider:"uniswap-v3",kind:"univ3-swap-tx"})}async function Li(e={}){let t=Number(e.chainId??8453);try{let r=await on({chainId:t,amountIn:"1000000000000000"},e);return{ok:!0,chainId:t,fee:r.fee,amountOutUsdc:r.amountOutUsdc,midPxHint:r.amountOutUsdc/.001}}catch(r){return{ok:!1,chainId:t,error:String(r.message||r).slice(0,200)}}}async function Di(){return Object.entries(_).map(([e,t])=>({chainId:Number(e),name:t.name,quoter:t.quoter,weth:t.weth,usdc:t.usdc}))}var _,tn,Te,Zr,rn,nn,Be=E(()=>{te();P();T();_={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"},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"}},tn=[100,500,3e3,1e4],Te=new en(["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)"]),Zr=new en(["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)"]),rn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",nn="0x0000000000000000000000000000000000000000"});var dn={};O(dn,{executeRfqCandidates:()=>un,rankRfqQuotes:()=>ln,requestRfqQuotes:()=>qi,sourceCandidates:()=>cn});function fe(e,t){return Array.isArray(e?.allowedSources)&&e.allowedSources.includes(t)}function sn(e,t){return String(e?.[t]??"").trim()}function he(e,t){return Object.freeze({source:e,run:t})}function cn(e,t={}){if(!e||e.kind!=="rfq-intent")throw new Error("rfq: intent required");let r=t.env??process.env,n=t.providers??{},o=t.supportedUniV3Chains??_,i=Number(e.fromChainId)===Number(e.toChainId),s=[];return fe(e,"lifi")&&s.push(he("lifi",async()=>{let c=await(n.lifiQuote??V)({fromChain:e.fromChainId,toChain:e.toChainId,fromToken:e.sellToken,toToken:e.buyToken,fromAmount:e.sellAmount,fromAddress:e.receiver},t),u=c?.estimate??c?.[0]?.estimate??c;return{quoteId:c?.id??c?.routeId??null,amountOut:u?.toAmount??c?.toAmount,minBuyAmount:u?.toAmountMin??c?.toAmountMin??u?.toAmount??c?.toAmount,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"lifi-route",calldataHash:c?.transactionRequest?.data?await Ui(t,c.transactionRequest.data):void 0,route:c},metadata:{tool:c?.tool??c?.toolDetails?.name??null}}})),i&&(fe(e,"paraswap")&&s.push(he("paraswap",async()=>{let c=await(n.paraswapPrice??J)({chainId:e.fromChainId,srcToken:e.sellToken,destToken:e.buyToken,amount:e.sellAmount,srcDecimals:t.decimalsIn,destDecimals:t.decimalsOut},t),u=c?.priceRoute??c;return{quoteId:u?.id??null,amountOut:u?.destAmount,minBuyAmount:c?.amountOutMinimum??u?.destAmount,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"paraswap-price-route",route:u},metadata:{contractAddress:u?.contractAddress??null}}})),fe(e,"0x")&&(sn(r,"ZEROX_API_KEY")||sn(r,"0X_API_KEY")||n.zeroxQuote)&&s.push(he("0x",async()=>{let c=await(n.zeroxQuote??Z)({chainId:e.fromChainId,sellToken:e.sellToken,buyToken:e.buyToken,sellAmount:e.sellAmount,taker:e.receiver},t);return{quoteId:c?.id??null,amountOut:c?.buyAmount??c?.grossBuyAmount,minBuyAmount:c?.minBuyAmount??c?.buyAmount,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"0x-transaction",to:c?.transaction?.to,data:c?.transaction?.data,value:c?.transaction?.value??"0"},metadata:{route:c?.route??null}}})),fe(e,"cow")&&s.push(he("cow",async()=>{let c=await(n.cowQuote??H)({chainId:e.fromChainId,sellToken:e.sellToken,buyToken:e.buyToken,sellAmountBeforeFee:e.sellAmount,from:e.receiver,signingScheme:"eip712"},t),u=c?.quote??c;return{quoteId:c?.id??null,amountOut:u?.buyAmount,minBuyAmount:u?.buyAmount,expiryMs:Math.min(Number(u?.validTo??0)*1e3||Date.now()+Number(t.defaultQuoteTtlMs??2e4),e.deadlineMs),artifact:{type:"cow-order",order:u},metadata:{solver:!0}}})),fe(e,"uniswap-v3")&&o[Number(e.fromChainId)]&&s.push(he("uniswap-v3",async()=>{let c=await(n.uniV3QuoteExactIn??K)({chainId:e.fromChainId,tokenIn:e.sellToken,tokenOut:e.buyToken,amountIn:e.sellAmount},t);return{quoteId:c?.id??null,amountOut:c?.amountOut,minBuyAmount:c?.minOut??c?.amountOutMinimum??c?.amountOut,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"uniswap-v3-quote",quoter:c?.quoter,fee:c?.fee},metadata:{onchain:!0}}}))),s}async function Ui(e,t){return`0x${(await import("node:crypto")).createHash("sha256").update(String(t)).digest("hex")}`}async function Pi(e,t){return Promise.race([Promise.resolve().then(e.run),new Promise((r,n)=>setTimeout(()=>n(new Error(`${e.source}: timeout`)),t))])}async function un(e,t,r={}){let n=Number(r.timeoutMs??12e3),o=await Promise.allSettled(t.map(a=>Pi(a,n))),i=[],s=[];for(let a=0;a<o.length;a++){let c=t[a],u=o[a];if(u.status==="rejected"){s.push({source:c.source,error:String(u.reason?.message||u.reason)});continue}try{i.push(Je(e,{...u.value,source:c.source},r))}catch(d){s.push({source:c.source,error:String(d?.message||d)})}}return{quotes:i,failed:s}}function ln(e=[],t={}){let r=Number(t.nowMs??Date.now()),n=e.filter(s=>Number(s.expiryMs??0)>r);n.sort((s,a)=>{let c=BigInt(a.minBuyAmount??0)-BigInt(s.minBuyAmount??0);if(c!==0n)return c>0n?1:-1;let u=BigInt(a.amountOut??0)-BigInt(s.amountOut??0);return u>0n?1:u<0n?-1:0});let o=n.map(s=>({...s,scoreBasis:"minBuyAmount"})),i=[];return o.length||i.push("no RFQ source returned a usable firm quote"),e.length!==o.length&&i.push("expired RFQ quotes were excluded from ranking"),{best:o[0]??null,quotes:o,failed:[],warnings:i}}async function qi(e,t={}){let r=cn(e,t),{quotes:n,failed:o}=await un(e,r,t),i=ln(n,t);return{kind:"rfq-result",intent:e,best:i.best,quotes:i.quotes,failed:o,warnings:[...i.warnings],sourcesTried:r.length,sourcesAnswered:n.length}}var pn=E(()=>{de();xe();_e();Ne();Be();Ze()});function mn(e={}){let t=[],r=[];if(!e||typeof e!="object")return{ok:!1,errors:["definition must be an object"],warnings:r};if((!Number.isInteger(e.chainId)||e.chainId<=0)&&t.push("chainId must be a positive integer"),(typeof e.key!="string"||!/^[a-z][a-z0-9-]*$/.test(e.key||""))&&t.push('key must be a lowercase slug (e.g. "base")'),(typeof e.name!="string"||!e.name.trim())&&t.push("name is required"),!Array.isArray(e.rpcEnv)||e.rpcEnv.length===0)t.push("rpcEnv must list at least one environment variable name");else for(let o of e.rpcEnv)(typeof o!="string"||!/^[A-Z][A-Z0-9_]*$/.test(o))&&t.push(`rpcEnv entry "${o}" should be an UPPER_SNAKE env var name`);if(e.nativeCurrency){let o=e.nativeCurrency;(typeof o.symbol!="string"||!o.symbol)&&t.push("nativeCurrency.symbol is required when nativeCurrency is set"),Number.isInteger(o.decimals)||t.push("nativeCurrency.decimals must be an integer")}for(let[o,i]of(e.venues||[]).entries()){let s=`venues[${o}]`;if(!i||typeof i!="object"){t.push(`${s} must be an object`);continue}$i.test(i.address||"")||t.push(`${s}.address is not a valid 20-byte address`),/^0x0{40}$/.test(i.address||"")&&t.push(`${s}.address is the zero address -- placeholder left in place?`),i.kind||t.push(`${s}.kind is required (router|quoter|factory|...)`),i.verified?(i.verified.method||t.push(`${s}.verified.method is required`),i.verified.source||t.push(`${s}.verified.source is required`),i.verified.date||r.push(`${s}.verified.date missing -- add one so staleness is visible`)):t.push(`${s} must record verification: { verified: { method, source, date } }. An unverified venue stays blocked.`)}let n=e.capabilities||{};for(let o of Object.keys(n))re.includes(o)?typeof n[o]!="function"&&t.push(`capability "${o}" must be a function`):t.push(`unknown capability "${o}"`);return Object.keys(n).length===0&&r.push("scanner implements no capabilities -- it can only be registered, not used"),n.prepareUnsignedTx&&!n.quote&&r.push("prepareUnsignedTx without quote: no priced expectation to validate the built tx against"),n.prepareUnsignedTx&&!n.sellSimulation&&r.push("prepareUnsignedTx without sellSimulation: cannot prove an asset is exitable before buying"),{ok:t.length===0,errors:t,warnings:r}}function fn(e){let{ok:t,errors:r,warnings:n}=mn(e);if(!t)throw new Error(`invalid scanner for ${e?.key??"<unknown>"}:
2
+ var Ga=Object.defineProperty;var w=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var _=(e,t)=>{for(var r in t)Ga(e,r,{get:t[r],enumerable:!0})};var Xn={};_(Xn,{DEFAULT_CROSS_CHAIN_SOURCES:()=>Vn,DEFAULT_SAME_CHAIN_SOURCES:()=>Hn,NATIVE_TOKEN:()=>wr,canonicalJson:()=>Kn,hashFirmQuote:()=>Gn,hashRfqIntent:()=>Wn,normalizeFirmQuote:()=>vr,normalizeRfqIntent:()=>cc,sha256Hex:()=>We});import{createHash as nc}from"node:crypto";import{getAddress as jn,isAddress as Sr}from"ethers";function R(e,t="invalid"){throw new Error(`rfq: ${e} ${t}`)}function Ln(e,t){let r=Number(e);return(!Number.isSafeInteger(r)||r<=0)&&R(t,"must be a positive chainId"),r}function ht(e,t){let r=String(e??"").trim();return(!oc.test(r)||BigInt(r)<=0n)&&R(t,"must be a positive integer string"),r}function sc(e,t){return e==null||e===""?null:ht(e,t)}function Fn(e,t){let r=String(e??"").trim();return r.toLowerCase()===wr.toLowerCase()?wr:(Sr(r)||R(t,"must be an EVM address or native token sentinel"),jn(r))}function zn(e,t){let r=String(e??"").trim();return Sr(r)||R(t,"must be an EVM address"),jn(r)}function ic(e,t){return e==null||e===""?null:zn(e,t)}function Mn(e,t,r){return e===void 0?[...r]:(Array.isArray(e)||R(t,"must be an array"),e.map(n=>String(n).trim()).filter(Boolean))}function ac(e,{nowMs:t,maxDeadlineMs:r},n){let o=Number(e);return Number.isFinite(o)||R(n,"must be a finite millisecond timestamp"),o<=t&&R(n,"expired"),o>t+r&&R(n,"exceeds maxDeadlineMs"),Math.floor(o)}function Oe(e){if(Array.isArray(e))return e.map(Oe);if(e&&typeof e=="object"){let t={};for(let r of Object.keys(e).sort())e[r]!==void 0&&(t[r]=Oe(e[r]));return t}return e}function Kn(e){return JSON.stringify(Oe(e))}function We(e){return`0x${nc("sha256").update(Kn(e)).digest("hex")}`}function Qn(e,t){let r={...e};for(let n of t)delete r[n];return r}function Wn(e){return We(Qn(e,["intentHash"]))}function Gn(e){return We(Qn(e,["firmQuoteHash"]))}function cc(e={},t={}){let r=Number(t.nowMs??Date.now()),n=Number(t.maxDeadlineMs??1800*1e3);(!Number.isFinite(r)||!Number.isFinite(n)||n<=0)&&R("time","is invalid");let o=Ln(e.fromChainId??e.fromChain,"fromChainId"),s=Ln(e.toChainId??e.toChain,"toChainId"),i=o===s?Hn:Vn,c={kind:"rfq-intent",version:1,fromChainId:o,toChainId:s,sellToken:Fn(e.sellToken??e.tokenIn??e.fromToken,"sellToken"),buyToken:Fn(e.buyToken??e.tokenOut??e.toToken,"buyToken"),sellAmount:ht(e.sellAmount??e.amountIn??e.fromAmount,"sellAmount"),receiver:zn(e.receiver??e.recipient??e.to,"receiver"),deadlineMs:ac(e.deadlineMs??e.deadline??e.expiresAtMs,{nowMs:r,maxDeadlineMs:n},"deadline"),minBuyAmount:sc(e.minBuyAmount??e.minOut??e.amountOutMin,"minBuyAmount"),allowedSources:Mn(e.allowedSources,"allowedSources",i),allowedRouters:Mn(e.allowedRouters,"allowedRouters",[]),slippageBps:Number.isFinite(Number(e.slippageBps))?Number(e.slippageBps):null,partialFill:e.partialFill===!0,metadata:e.metadata&&typeof e.metadata=="object"&&!Array.isArray(e.metadata)?Oe(e.metadata):{}};return c.slippageBps!=null&&(!Number.isInteger(c.slippageBps)||c.slippageBps<0||c.slippageBps>1e4)&&R("slippageBps","must be 0 to 10000"),c.intentId=e.intentId?String(e.intentId):We({seed:"rfq-intent",intent:c}).slice(0,34),c.intentHash=Wn(c),Object.freeze(c)}function uc(e){return(!e||typeof e!="object"||Array.isArray(e))&&R("artifact","required"),e.typedDataHash!=null&&!Un.test(String(e.typedDataHash))&&R("artifact.typedDataHash","must be bytes32"),e.calldataHash!=null&&!Un.test(String(e.calldataHash))&&R("artifact.calldataHash","must be bytes32"),e.to!=null&&!Sr(String(e.to))&&R("artifact.to","must be an address"),e.data!=null&&!/^0x(?:[0-9a-fA-F]{2})*$/.test(String(e.data))&&R("artifact.data","must be hex"),Oe(e)}function vr(e,t={},r={}){(!e||e.kind!=="rfq-intent")&&R("intent","required");let n=Number(r.nowMs??Date.now()),o=Number(t.expiryMs??t.expiresAtMs??t.validUntilMs);Number.isFinite(o)||R("quote expiry","required"),o<=n&&R("quote","expired"),o>e.deadlineMs&&R("quote expiry","exceeds intent deadline");let s=String(t.source??t.provider??"").trim();s||R("source","required"),e.allowedSources.includes(s)||R("source","not allowed by intent");let a=ht(t.amountOut??t.buyAmount,"amountOut"),i=ht(t.minBuyAmount??t.minOut??a,"minBuyAmount");BigInt(i)>BigInt(a)&&R("minBuyAmount","exceeds amountOut");let c=uc(t.artifact??t.executableArtifact??t.transaction??t.typedData),u=Number(t.quotedAtMs??t.timestampMs??r.nowMs??Date.now());Number.isFinite(u)||R("quotedAtMs","must be finite");let d=ic(t.router??t.settlementRouter??c.to,"router"),p={kind:"rfq-firm-quote",provider:"rfq",surface:"rfq",version:1,quoteId:String(t.quoteId??t.id??"").trim(),source:s,intentHash:e.intentHash,fromChainId:e.fromChainId,toChainId:e.toChainId,sellToken:e.sellToken,buyToken:e.buyToken,sellAmount:e.sellAmount,receiver:e.receiver,router:d,amountOut:a,minBuyAmount:i,quotedAtMs:Math.floor(u),expiryMs:Math.floor(o),artifact:c,maker:t.maker?String(t.maker):null,metadata:t.metadata&&typeof t.metadata=="object"&&!Array.isArray(t.metadata)?Oe(t.metadata):{}};return p.quoteId||(p.quoteId=We({seed:"rfq-quote",out:p}).slice(0,34)),p.firmQuoteHash=Gn(p),Object.freeze(p)}var wr,Hn,Vn,Un,oc,xr=w(()=>{wr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Hn=Object.freeze(["lifi","paraswap","0x","cow","uniswap-v3"]),Vn=Object.freeze(["lifi"]),Un=/^0x[0-9a-fA-F]{64}$/,oc=/^\d+$/});import{createHash as lc}from"node:crypto";function fc(e){let t=String(e||"").toLowerCase();return eo.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function hc(e){let t={};for(let[r,n]of Object.entries(e||{}))fc(r)||(t[r]=n);return t}function bc(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 gc(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function yc(e,t,r){let n={};for(let[c,u]of Object.entries(r||{}))n[c.toLowerCase()]=u;let o=Object.keys(n).filter(c=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(c)),a=[...new Set([...eo,...o])].sort().map(c=>`${c}=${n[c]??""}`).join(`
3
+ `),i=lc("sha256").update(a).digest("hex").slice(0,32);return`${e} ${t} ${i}`}function wc(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,Jn):Math.min(250*2**e,Jn)+Math.floor(Math.random()*100)}async function vc(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s}){let a=new AbortController,i=setTimeout(()=>a.abort(),s);try{let c=String(e),u={...n||{}};for(let d=0;d<=Zn;d+=1){let p=await t(c,{method:r,headers:u,body:o,signal:a.signal,redirect:"manual"}),l=await p.text(),m=null;if(l)try{m=JSON.parse(l)}catch{m=null}if(mc.has(p.status)){if(r!=="GET"&&r!=="HEAD"){let g=new Error(`HTTP ${p.status} ${r} ${c} redirected non-idempotent request`);throw g.status=p.status,g.body=m??l.slice(0,300),g}if(d===Zn)throw new Error(`HTTP redirect loop for ${e}`);let f=bc(p.headers?.get?.("location"),c);gc(f,c)||(u=hc(u)),c=f;continue}if(!p.ok){let f=new Error(`HTTP ${p.status} ${r} ${c}`);throw f.status=p.status,f.retryAfter=p.headers?.get?.("retry-after")??null,f.body=m??l.slice(0,300),f}return m??l}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(i)}}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||{}},a=t.body;a!=null&&typeof a!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",a=JSON.stringify(a));let i=Number.isInteger(t.retries)?Math.max(t.retries,0):pc,c=async()=>{let m;for(let f=0;f<=i;f++)try{return await vc(e,{fetchImpl:r,method:o,headers:s,body:a,timeoutMs:n})}catch(g){m=g;let b=g?.status,S=g?.name==="AbortError",I=new Set([408,425,429]),N=b!=null?I.has(b)||dc.has(b)&&Yn.has(o):!S&&Yn.has(o);if(f===i||!N)throw g;await Sc(wc(f,g?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&a==null))return c();let d=yc(o,e,s),p=Ar.get(d);if(p)return p;let l=c().finally(()=>Ar.delete(d));return Ar.set(d,l),l}async function bt(e,t,r){let n=Array.from(e),o=Math.max(1,Math.min(Number(t)||1,n.length||1)),s=new Array(n.length),a=0;return await Promise.all(Array.from({length:o},async()=>{for(;a<n.length;){let i=a++;s[i]=await r(n[i],i)}})),s}var dc,Yn,pc,Jn,eo,mc,Zn,Ar,Sc,C=w(()=>{dc=new Set([408,425,429,500,502,503,504]),Yn=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),pc=2,Jn=4e3,eo=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],mc=new Set([301,302,303,307,308]),Zn=3;Ar=new Map;Sc=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as xc}from"node:fs";import{homedir as Ac}from"node:os";import{join as gt}from"node:path";function Ec(){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=Ac();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||gt(t,".config","oracle")).trim();return[e,gt(r,"exec.env")].filter(Boolean)}return[e,gt(t,".config","oracle","exec.env"),gt(t,".config","mad-desk","exec.env")].filter(Boolean)}function to(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of Ec())try{let s=xc(o,"utf8"),a=s.match(new RegExp(`^${t}=(.*)$`,"m"))||s.match(new RegExp(`^${r}=(.*)$`,"m"));if(a&&(n=a[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}var ro=w(()=>{});var no=w(()=>{});import{createHash as kc,createHmac as Ic,timingSafeEqual as Xm}from"node:crypto";function kr(e){return Array.isArray(e)?`[${e.map(kr).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${kr(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Cc(e,{required:t=!1}={}){try{return to(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function io(e){let{signature:t,...r}=e;return r}function ao(e,{secret:t}={}){let r=Cc(t);return r?{...e,signature:Ic("sha256",r).update(kr(io(e))).digest("hex")}:e}function _c(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 kc("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function Q(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 ao({...io(e),calldataHash:_c(n)},{secret:o})}function Er(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function Oc(e){let t=e==null?oo: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,oo)}function ne({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let s=Er(e,0),a=s>0?s>=25e4?5:s>=1e5?10:s>=5e4?20:s>=1e4?40:70:n?30:10,i=Math.min(60,Math.abs(Er(t,0))*2),c=Math.min(40,Math.floor(Math.max(0,Er(r,0))/5e3)*5),u=Math.max(25,Math.ceil(20+a+i+c)),d=Oc(o);return{mode:"auto",requiredBps:u,selectedBps:Math.min(u,d),capBps:d,executable:u<=d}}function Rc({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:s=0,crossChain:a=!1,requestedCapBps:i,quotedAtMs:c=Date.now(),ttlMs:u=so,secret:d}={}){let p=BigInt(r??0);if(p<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let l=ne({liquidityUsd:n,priceChange5m:o,quoteAgeMs:s,crossChain:a,requestedCapBps:i});if(!l.executable)throw new Error(`auto-slippage requires ${l.requiredBps} bps above hard/requested cap ${l.capBps}; route blocked`);let m=Number(c);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let f=Math.min(3e4,Math.max(1e3,Number(u)||so)),g=p*BigInt(1e4-l.selectedBps),b=g/10000n;if(g%10000n!==0n&&(b+=1n),b>p&&(b=p),p>0n&&b<=0n)throw new Error(`auto-slippage: quote ${p} is too small to express a ${l.selectedBps} bps floor without rounding to zero`);let S=Number((p-b)*10000n/(p===0n?1n:p));if(S>l.capBps)throw new Error(`auto-slippage: realised floor implies ${S} bps, above cap ${l.capBps} \u2014 refusing to issue a guard weaker than advertised`);return ao({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:p.toString(),minAmountOut:b.toString(),requiredBps:l.requiredBps,selectedBps:l.selectedBps,capBps:l.capBps,quotedAtMs:m,expiresAtMs:m+f},{secret:d})}function D(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:a,requestedCapBps:i,quotedAtMs:c=Date.now(),ttlMs:u}={}){let d=Rc({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:a,requestedCapBps:i,quotedAtMs:c,ttlMs:u});return{...e,autoSlippage:d,amountOutMinimum:d.minAmountOut}}var oo,so,oe=w(()=>{ro();no();oo=100,so=2e4});function Ir(e){let t=String(e||"").trim();return/^0x[0-9a-fA-F]{40}$/.test(t)?t:ue}var ue,yt=w(()=>{ue="0x000000000000000000000000000000000000dEaD"});import{createHash as Tc,createHmac as Nc,timingSafeEqual as rf}from"node:crypto";function Cr(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(Cr).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${Cr(e[r])}`).join(",")}}`}function co(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function uo(e=process.env){return co(process.env)||co(e)}function qc(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...s}=e||{};return s}function Dc(e){let t=qc(e);return Tc("sha256").update(Cr(t)).digest("hex")}function Pc(e,t=uo()){return t?Nc("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(),a=s+$c,c={...o,preparedAt:s,expiresAt:a,prepareVersion:Bc},u=Dc(c),d=uo(n),p=d?Pc(u,d):void 0,l={...c,oraclePrepared:!0,prepareHash:u};return p&&(l.prepareMac=p),l}var Bc,$c,nf,j=w(()=>{Bc=2,$c=300*1e3,nf=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});function Uc(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(lo,t)?lo[t]:10}function Hc(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),100)}function wt({env:e=process.env,isHolder:t=!1,action:r="swap"}={}){let n=String(e[Fc]||"").trim(),o=Hc(e[Lc],{fallback:n?Uc(r):0}),s=String(e[Mc]||jc).trim();return t?{bps:0,recipient:n,integrator:s,action:r,applies:!1,reason:"locals-only-holder"}:o?/^0x[a-fA-F0-9]{40}$/.test(n)?{bps:o,recipient:n,integrator:s,action:r,applies:!0,reason:"configured"}:{bps:0,recipient:"",integrator:s,action:r,applies:!1,reason:"no-recipient"}:{bps:0,recipient:"",integrator:s,action:r,applies:!1,reason:"not-configured"}}function po(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}function mo(e){return e?.applies?{partner:e.integrator,partnerFeeBps:String(e.bps),partnerAddress:e.recipient}:{}}var lo,Lc,Fc,Mc,jc,_r=w(()=>{lo=Object.freeze({swap:10,bridge:15,perps:5,nft:0});Lc="ORACLE_INTEGRATOR_FEE_BPS",Fc="ORACLE_INTEGRATOR_FEE_RECIPIENT",Mc="ORACLE_INTEGRATOR_ID",jc="oracle"});var Tr={};_(Tr,{LIFI_API:()=>ho,lifiChains:()=>Wc,lifiHealth:()=>Kc,lifiPrepare:()=>Qc,lifiQuote:()=>ge});function Rr(e={}){return(e.baseUrl||process.env.LIFI_API_URL||ho).replace(/\/$/,"")}function zc(e){let t=String(e||Or).toLowerCase();return t===Or.toLowerCase()||t===Vc}function fo(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 Kc(e={}){let t=await y(`${Rr(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 ge(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=Or,toToken:s,fromAmount:a,fromAddress:i=ue}=e;if(r==null||!s||!a)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let c=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:s,fromAmount:String(a),fromAddress:i}),u=ne({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!u.executable)throw new Error(`lifi: route requires ${u.requiredBps} bps above cap ${u.capBps}`);c.set("slippage",String(u.selectedBps/1e4));let d=wt({isHolder:e.isHolder,action:e.feeAction||"swap"});for(let[b,S]of Object.entries(po(d)))c.set(b,S);let p=await y(`${Rr(t)}/quote?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),l=p?.estimate?.toAmount||p?.toAmount;if(!l)return{...p,autoSlippagePolicy:u,oracleFee:d};let m=p?.transactionRequest?.to||p?.estimate?.approvalAddress||"lifi",f=D(p,{chainId:Number(r),venue:m,amountOut:l,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),g=p?.estimate?.toAmountMin||p?.toAmountMin;if(g!=null&&BigInt(g)<BigInt(f.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...f,oracleFee:d}}async function Qc(e={},t={}){let r=await ge(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 s=null;if(!zc(e.fromToken)){let a=r?.estimate?.approvalAddress||r?.approvalAddress;if(!a)throw new Error("lifi: ERC20 route missing approvalAddress");let i=r?.action?.fromToken?.address||r?.estimate?.fromToken?.address||e.fromToken;s={token:fo(i,"approval token"),spender:fo(a,"approval spender"),amount:String(e.fromAmount)}}return T({provider:"lifi",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:o,quote:r,autoSlippage:r.autoSlippage,requiresApproval:s,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:Q(r.autoSlippage,{chainId:o,venue:n.to,data:n.data})}},{provider:"lifi",kind:"lifi-tx"})}async function Wc(e={}){return y(`${Rr(e)}/chains`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??12e3})}var ho,Or,Vc,Ge=w(()=>{C();oe();yt();j();_r();ho="https://li.quest/v1";Or="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Vc="0x0000000000000000000000000000000000000000"});var yo={};_(yo,{PARASWAP_API:()=>bo,paraswapHealth:()=>Xc,paraswapPrepare:()=>Gc,paraswapPrice:()=>Te,paraswapTokens:()=>go});function Re(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 go(e={},t={}){let r=Number(e.chainId||1);return y(`${Nr(t)}/tokens/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Te(e={},t={}){let r=Number(e.chainId||e.network||1);if(e.amount==null)throw new Error("amount required");let n=new URLSearchParams({srcToken:Re(e.srcToken,"srcToken"),destToken:Re(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=wt({isHolder:e.isHolder});for(let[i,c]of Object.entries(mo(o)))n.set(i,c);let s=await y(`${Nr(t)}/prices?${n}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=s?.priceRoute?.destAmount;return a?{...D(s,{chainId:r,venue:s?.priceRoute?.contractAddress||"paraswap-quote",amountOut:a,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}}async function Gc(e={},t={}){if(String(e.side||"SELL").toUpperCase()!=="SELL")throw new Error("paraswap: agentic prepare currently supports exact-input SELL only");let r=Number(e.chainId||e.network||1),n=Re(e.userAddress,"userAddress"),o=await Te(e,t),s=o?.priceRoute,a=String(s?.contractAddress||"").toLowerCase();if(!a)throw new Error("paraswap: price route missing contractAddress");let i={srcToken:Re(e.srcToken,"srcToken"),destToken:Re(e.destToken,"destToken"),srcAmount:String(s.srcAmount||e.amount),destAmount:String(o.amountOutMinimum),priceRoute:s,userAddress:n,ignoreChecks:!1,ignoreGasEstimate:!1};e.receiver&&(i.receiver=Re(e.receiver,"receiver"));let c=await y(`${Nr(t)}/transactions/${r}`,{method:"POST",body:i,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??25e3});if(Number(c.chainId??r)!==r)throw new Error("paraswap: transaction chain mismatch");if(String(c.to||"").toLowerCase()!==a)throw new Error("paraswap: transaction target mismatch");if(c.from&&String(c.from).toLowerCase()!==n)throw new Error("paraswap: transaction sender mismatch");return T({provider:"paraswap",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:r,quote:o,autoSlippage:o.autoSlippage,requiresApproval:i.srcToken!=="0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"?{token:i.srcToken,spender:s.tokenTransferProxy||a,amount:i.srcAmount}:null,transaction:{chainId:r,from:c.from||n,to:c.to,data:c.data,value:c.value??"0x0",...c.gas!=null?{gasLimit:c.gas}:{},slippageGuard:Q(o.autoSlippage,{chainId:r,venue:c.to,data:c.data})}},{provider:"paraswap",kind:"paraswap-tx"})}async function Xc(e={}){let t=await go({chainId:1},e),r=Array.isArray(t?.tokens)?t.tokens.length:Object.keys(t?.tokens||{}).length;return{ok:r>0,tokenSample:r}}var bo,Nr,St=w(()=>{C();oe();j();_r();bo="https://api.paraswap.io",Nr=(e={})=>(e.baseUrl||process.env.PARASWAP_API_URL||bo).replace(/\/$/,"")});function vt({provider:e,defaultUrl:t,hosts:r=[],url:n,strict:o=!1}){let a=(String(n??"").trim()||String(t)).replace(/\/$/,"");if(a===String(t).replace(/\/$/,""))return{baseUrl:a,trusted:!0,host:So(t)};let i;try{i=new URL(a)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(i.protocol!=="http:"&&i.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let c=i.host;if(!c)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([So(t),...r]).has(c)){let d=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(c);return i.protocol==="http:"&&!d?{baseUrl:a,trusted:!1,host:c,reason:"plaintext http downgrade"}:{baseUrl:a,trusted:!0,host:c}}if(String(process.env[wo]||"")==="1")return{baseUrl:a,trusted:!1,host:c};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${c} (set ${wo}=1 to permit it)`);return{baseUrl:a,trusted:!1,host:c}}function So(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function xt(e,t,r){let n={...e};if(!r)return n;for(let[o,s]of Object.entries(t||{}))s&&(n[o]=s);return n}var wo,Br=w(()=>{wo="ORACLE_ALLOW_CUSTOM_PROVIDER_URL"});var Io={};_(Io,{ZEROX_API:()=>vo,zeroxHealth:()=>Yc,zeroxPrepare:()=>Jc,zeroxPrice:()=>ko,zeroxQuote:()=>Ne});function xo(e={}){return vt({provider:"zerox",defaultUrl:vo,hosts:["api.0x.org"],url:e.baseUrl||process.env.ZEROX_API_URL})}function Ao(e={}){return xo(e).baseUrl}function At(e={}){return e.apiKey||process.env.ZEROX_API_KEY||process.env.OX_API_KEY||process.env["0X_API_KEY"]||""}function Eo(e={}){return xt({"0x-version":"v2",accept:"application/json"},{"0x-api-key":At(e)},xo(e).trusted)}async function Yc(e={}){if(!At(e))return{ok:!1,configured:!1,error:"ZEROX_API_KEY not set"};try{let t=await ko({chainId:8453,sellToken:"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",buyToken:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",sellAmount:"1000000000000000"},e);return{ok:!0,configured:!0,buyAmount:t.buyAmount||t.grossBuyAmount}}catch(t){return{ok:!1,configured:!0,error:String(t.message||t).slice(0,160)}}}async function ko(e={},t={}){if(!At(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:s,taker:a}=e;if(!n||!o||!s)throw new Error("zeroxPrice requires sellToken, buyToken, sellAmount");let i=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(s)});return a&&i.set("taker",a),y(`${Ao(t)}/swap/allowance-holder/price?${i}`,{headers:Eo(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Ne(e={},t={}){if(!At(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:s,taker:a}=e;if(!n||!o||!s)throw new Error("zeroxQuote requires sellToken, buyToken, sellAmount");let i=ne({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!i.executable)throw new Error(`0x: route requires ${i.requiredBps} bps above cap ${i.capBps}`);let c=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(s),slippageBps:String(i.selectedBps)});a&&c.set("taker",a);let u=await y(`${Ao(t)}/swap/allowance-holder/quote?${c}`,{headers:Eo(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),d=u?.buyAmount||u?.grossBuyAmount;return d?D(u,{chainId:r,venue:u?.transaction?.to||u?.to||"0x",amountOut:d,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):{...u,autoSlippagePolicy:i}}async function Jc(e={},t={}){if(!e.taker)throw new Error("0x: taker required for executable prepare");let r=await Ne(e,t),n=r?.transaction;if(!n?.to||!n?.data)throw new Error("0x: firm quote returned no transaction");let o=Number(e.chainId??8453),s=r?.issues?.allowance?.spender||r?.allowanceTarget;return T({provider:"zerox",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:o,quote:r,autoSlippage:r.autoSlippage,requiresApproval:r?.issues?.allowance?.actual!=null&&BigInt(r.issues.allowance.actual)<BigInt(e.sellAmount)?{token:e.sellToken,spender:s,amount:String(e.sellAmount)}:null,transaction:{chainId:o,from:e.taker,to:n.to,data:n.data,value:n.value??"0x0",...n.gas!=null?{gasLimit:n.gas}:{},slippageGuard:Q(r.autoSlippage,{chainId:o,venue:n.to,data:n.data})}},{provider:"zerox",kind:"zerox-tx"})}var vo,Et=w(()=>{C();oe();Br();j();vo="https://api.0x.org"});var xf,Af,Co=w(()=>{xf=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"}),Af=Object.freeze({"evm:prepare":["ORACLE_EVM_ADDRESS","EVM_KEYSTORE_FILE","ORACLE_SIGNER_ADDRESS"],"evm:execute":["EVM_KEYSTORE_FILE","ORACLE_KEYSTORE_FILE"],"btc:execute":["BTC_WIF_FILE","ORACLE_BTC_WIF_FILE"],"solana:execute":["SOLANA_KEYPAIR_FILE","ORACLE_SOLANA_KEYPAIR_FILE"],"nft:buy":[],"nft:mint":[],"cow:submit":[]})});var Po={};_(Po,{COW_CANCEL_TYPES:()=>No,COW_HOSTS:()=>qr,COW_ORDER_TYPES:()=>kt,COW_SETTLEMENT:()=>Oo,COW_VAULT_RELAYER:()=>Ro,cowCancelOrders:()=>lu,cowChains:()=>mu,cowHealth:()=>nu,cowOrder:()=>Do,cowOrderStatus:()=>qo,cowOrderUid:()=>su,cowPrepareCancel:()=>cu,cowPrepareOrder:()=>ou,cowQuote:()=>ye,cowSignCancel:()=>uu,cowSignOrder:()=>iu,cowSubmitSignedOrder:()=>au,cowVerifyOrderFill:()=>pu});import{TypedDataEncoder as _o,getAddress as Xe,isAddress as Zc}from"ethers";function It(e,t={}){if(t.baseUrl)return t.baseUrl.replace(/\/$/,"");let r=qr[Number(e)];if(!r)throw new Error(`cowswap: unsupported chainId ${e}`);return r}function eu(e,t="v1",r={}){let n=It(e,r);return t==="v1"?n:n.replace(/\/api\/v1$/,`/api/${t}`)}function le(e,t){let r=String(e||"").trim();if(!Zc(r))throw new Error(`cowswap: ${t} must be an address`);return Xe(r).toLowerCase()}function Be(e,t){try{let r=BigInt(String(e));if(r<0n)throw new Error("negative");return r.toString()}catch{throw new Error(`cowswap: ${t} must be a non-negative integer string`)}}function Bo(e,t){let r=String(e||"").trim();if(!/^0x[0-9a-fA-F]{64}$/.test(r))throw new Error(`cowswap: ${t} must be bytes32 hex`);return r.toLowerCase()}function $o(e,t="uid"){let r=String(e||"").trim();if(!/^0x[0-9a-fA-F]{112}$/.test(r))throw new Error(`cowswap: ${t} must be 56-byte order UID hex`);return r.toLowerCase()}function tu({digest:e,owner:t,validTo:r}={}){let n=Bo(e,"order digest").slice(2),o=le(t,"owner").slice(2).toLowerCase(),s=Number(r);if(!Number.isInteger(s)||s<0||s>4294967295)throw new Error("cowswap: validTo must fit uint32");return`0x${n}${o}${s.toString(16).padStart(8,"0")}`.toLowerCase()}function Dr(e){let t=Oo[Number(e)];if(!t)throw new Error(`cowswap: settlement contract not registered for chain ${e}`);return{name:"Gnosis Protocol",version:"v2",chainId:Number(e),verifyingContract:Xe(t)}}function ru(e={},t,r){let n=le(e.sellToken,"sellToken"),o=le(e.buyToken,"buyToken"),s=le(e.receiver||r,"receiver"),a=Number(e.validTo);if(!Number.isInteger(a)||a<=0)throw new Error("cowswap: quote.validTo required");let i=Bo(e.appData||e.appDataHash||`0x${"0".repeat(64)}`,"appData");return{sellToken:n,buyToken:o,receiver:s,sellAmount:Be(e.sellAmount,"sellAmount"),buyAmount:Be(e.buyAmount,"buyAmount"),validTo:a,appData:i,feeAmount:Be(e.feeAmount??"0","feeAmount"),kind:String(e.kind||"sell"),partiallyFillable:!!e.partiallyFillable,sellTokenBalance:String(e.sellTokenBalance||"erc20"),buyTokenBalance:String(e.buyTokenBalance||"erc20")}}async function nu(e={}){try{let t=await ye({chainId:1,sellToken:$r[1],buyToken:To[1],sellAmountBeforeFee:"1000000000000000",from:ue},e);return{ok:!0,buyAmount:t.quote?.buyAmount||t.buyAmount}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function ye(e={},t={}){let r=Number(e.chainId??1),n=Ir(e.from||e.owner),o=e.sellToken||$r[r],s=e.buyToken||To[r],a=String(e.sellAmountBeforeFee||e.sellAmount||"0");if(!o||!s||a==="0")throw new Error("cowQuote requires sellToken, buyToken, sellAmountBeforeFee");if(/eeeeeeee|native|^eth$/i.test(o)&&(o=$r[r],!o))throw new Error("no WETH mapping for chain");let i={sellToken:o,buyToken:s,from:n,receiver:e.receiver||n,sellAmountBeforeFee:a,kind:e.kind||"sell",signingScheme:e.signingScheme||"eip1271"},c=await y(`${It(r,t)}/quote`,{method:"POST",body:i,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),u=c?.quote?.buyAmount||c?.buyAmount;return u?D(c,{chainId:r,venue:"cowswap-order",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):c}async function ou(e={},t={}){let r=Number(e.chainId??1),n=le(Ir(e.from||e.owner||e.signer),"owner"),o=await ye({...e,chainId:r,from:n,signingScheme:e.signingScheme||"eip712"},t),s=ru(o?.quote||o,r,n),a=Dr(r),i={domain:a,types:kt,primaryType:"Order",message:s},c=_o.hash(a,kt,s),u=Ro[r];if(!u)throw new Error(`cowswap: vault relayer not registered for chain ${r}`);return T({provider:"cowswap",orderReady:!0,executionReady:!1,chainId:r,owner:n,signingScheme:"eip712",settlement:a.verifyingContract.toLowerCase(),vaultRelayer:Xe(u).toLowerCase(),quote:o,quoteId:o?.id??e.quoteId??null,typedData:i,cowGuard:{mode:"cow-order",version:1,provider:"cowswap",chainId:r,owner:n,settlement:a.verifyingContract.toLowerCase(),vaultRelayer:Xe(u).toLowerCase(),sellToken:s.sellToken,buyToken:s.buyToken,sellAmount:s.sellAmount,buyAmount:s.buyAmount,validTo:s.validTo,quoteId:o?.id??e.quoteId??null,typedDataHash:c,issuedAtMs:Date.now(),expiresAtMs:Math.min(s.validTo*1e3,Date.now()+2e4)},requiresApproval:{token:s.sellToken,spender:Xe(u).toLowerCase(),amount:s.sellAmount}},{provider:"cowswap",kind:"cow-order"})}async function qo(e={},t={}){let r=Number(e.chainId??1),n=String(e.uid||e.orderUid||"").trim();if(!n)throw new Error("cowOrderStatus requires uid");return y(`${It(r,t)}/orders/${encodeURIComponent(n)}/status`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Do(e={},t={}){let r=Number(e.chainId??1),n=String(e.uid||e.orderUid||"").trim();if(!n)throw new Error("cowOrder requires uid");return y(`${It(r,t)}/orders/${encodeURIComponent(n)}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}function su(e={}){let t=e.typedData||e,r=Number(e.chainId??t?.domain?.chainId),n=t?.message||e.order||e.message;if(!n)throw new Error("cowswap: typed order message required");let o=e.cowGuard?.typedDataHash||_o.hash(Dr(r),kt,n),s=e.owner||e.from||e.signer||n.receiver;return tu({digest:o,owner:s,validTo:n.validTo})}async function iu(e={},t={}){throw new Error("cowswap.cowSignOrder refused: @oracle-agent/oracle is prepare-only. Sign with the user wallet; do not pass private keys here.")}async function au(e={},t={}){throw new Error("cowswap.cowSubmitSignedOrder refused: @oracle-agent/oracle is prepare-only. Submit signed orders from the user wallet or local operator.")}function cu(e={}){let t=Number(e.chainId??1),r=le(e.owner||e.from||e.signer,"owner"),n=(e.orderUids||e.uids||[e.uid]).filter(Boolean).map((a,i)=>$o(a,`orderUids[${i}]`));if(!n.length)throw new Error("cowswap: orderUids required");let o=Dr(t);return T({provider:"cowswap",chainId:t,owner:r,orderUids:n,signingScheme:"eip712",typedData:{domain:o,types:No,primaryType:"OrderCancellations",message:{orderUids:n}},cancelReady:!0,executableArtifact:!0},{provider:"cowswap",kind:"cow-cancel"})}async function uu(e={},t={}){throw new Error("cowswap.cowSignCancel refused: @oracle-agent/oracle is prepare-only. Cancel-sign with the user wallet.")}async function lu(e={},t={}){throw new Error("cowswap.cowCancelOrders refused: @oracle-agent/oracle is prepare-only. Cancel from the user wallet or local operator.")}function du(e={}){return Be(e.buyAmount??e.executedBuyAmount??"0","trade.buyAmount")}async function pu(e={},t={}){let r=Number(e.chainId??1),n=$o(e.uid||e.orderUid),o=t.order||await Do({chainId:r,uid:n},t),s=t.status||o.status||await qo({chainId:r,uid:n},t).catch(()=>null),a=t.trades||await y(`${eu(r,"v2",t)}/trades?orderUid=${encodeURIComponent(n)}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),i=Array.isArray(a)?a:[],c=e.expectedOwner?le(e.expectedOwner,"expectedOwner"):null;if(c&&le(o.owner||i[0]?.owner||c,"owner")!==c)return{ok:!1,provider:"cowswap",chainId:r,uid:n,reason:"owner mismatch",order:o,status:s,trades:i};let u=0n;for(let l of i.filter(m=>String(m.orderUid||"").toLowerCase()===n))u+=BigInt(du(l));u===0n&&o.executedBuyAmount!=null&&(u=BigInt(Be(o.executedBuyAmount,"executedBuyAmount")));let d=e.minBuyAmount!=null?BigInt(Be(e.minBuyAmount,"minBuyAmount")):0n,p=u>=d&&String(o.status||s?.status||"").toLowerCase()!=="expired";return{ok:p,provider:"cowswap",chainId:r,uid:n,status:o.status||s?.status||null,executedBuyAmount:u.toString(),minBuyAmount:e.minBuyAmount??null,trades:i,settlementTxs:[...new Set(i.map(l=>l.txHash).filter(Boolean))],order:o,orderStatus:s,reason:p?null:"insufficient fill or expired order"}}function mu(){return Object.keys(qr).map(Number)}var qr,Oo,Ro,$r,To,kt,No,Ct=w(()=>{C();oe();Co();yt();j();qr={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"},Oo=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Ro=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"}),$r={1:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",8453:"0x4200000000000000000000000000000000000006",42161:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"},To={1:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",8453:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",42161:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},kt=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"}]}),No=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]})});function Lo(e){return fu.get(Number(e))||null}function Fo(e,t=process.env){let r=Lo(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}var Uo,fu,Mo=w(()=>{Uo={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}},fu=new Map(Object.values(Uo).map(e=>[e.chainId,e]))});import{Interface as hu,getAddress as bu}from"ethers";function Ye(e,t){try{return bu(e).toLowerCase()}catch{throw new Error(`${t} must be a valid EVM address`)}}function yu(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=Fo(e,r);return n||gu[Number(e)]||null}function Su(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!wu.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 B(e,t,r=[],n={}){let o=String(t||"");Su(o);let s=yu(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let i=await y(s,{method:"POST",body:{jsonrpc:"2.0",id:1,method:t,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3});if(i?.error){let c=new Error(i.error.message||JSON.stringify(i.error));throw c.code=i.error.code,c}return i.result}async function Ot(e,t={}){let r=await B(e,"eth_blockNumber",[],t);return parseInt(r,16)}async function jo(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await B(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function Ho(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=Ye(e.token||e.tokenAddress,"token"),o=Ye(e.owner,"owner"),s=Ye(e.spender,"spender"),a=_t.encodeFunctionData("allowance",[o,s]),i=await B(r,"eth_call",[{to:n,data:a},e.blockTag||"latest"],t),c=_t.decodeFunctionResult("allowance",i),u=BigInt(c[0]);return{chainId:r,token:n,owner:o,spender:s,allowance:u.toString(),allowanceHex:`0x${u.toString(16)}`,blockTag:e.blockTag||"latest"}}async function Vo(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=Ye(e.token||e.tokenAddress,"token"),o=Ye(e.account||e.owner||e.address,"account"),s=_t.encodeFunctionData("balanceOf",[o]),a=await B(r,"eth_call",[{to:n,data:s},e.blockTag||"latest"],t),i=_t.decodeFunctionResult("balanceOf",a),c=BigInt(i[0]);return{chainId:r,token:n,account:o,balance:c.toString(),balanceHex:`0x${c.toString(16)}`,blockTag:e.blockTag||"latest"}}var _t,gu,wu,we=w(()=>{C();Mo();_t=new hu(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);gu={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"};wu=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/});var Jo={};_(Jo,{PANCAKE_FEE_TIERS:()=>Rt,UNI_V3_CHAINS:()=>L,UNI_V3_FEE_TIERS:()=>Qo,UNI_V3_VENUES:()=>Xo,uniV3Chains:()=>Iu,uniV3EthUsdc:()=>Yo,uniV3Health:()=>ku,uniV3PrepareExactIn:()=>Eu,uniV3QuoteExactIn:()=>Se,uniV3QuoteExactInPath:()=>Au});import{Interface as Ko,getAddress as Je,isAddress as vu}from"ethers";function Ur(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=Xo[r]||{};if(!t){if(!n.quoter||!n.router){let c=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: ${c})`)}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 a=o,i=a[s];if(!i){let c=[...n.quoter&&n.router?[n.name]:[],...Object.keys(a)].join(", ");throw new Error(`uniswap-v3: unknown venue "${t}" on chain ${r} (known: ${c})`)}return{chainId:r,venue:s,...n,quoter:i.quoter,router:i.router,feeTiers:i.feeTiers||null}}function Pr(e,t){let r=L[Number(t)];if(!e||e===Wo||e===Go||/^eth$/i.test(String(e)))return Je(r.weth);let n=String(e);if(/^weth$/i.test(n))return Je(r.weth);if(/^usdc$/i.test(n))return Je(r.usdc);if(!vu(n))throw new Error(`invalid token address: ${e}`);return Je(n)}function xu(e,t){if(e.length!==t.length+1)throw new Error("path: fees.length must be tokens.length - 1");let r="0x";for(let n=0;n<t.length;n++)r+=e[n].slice(2).toLowerCase(),r+=Number(t[n]).toString(16).padStart(6,"0");return r+=e[e.length-1].slice(2).toLowerCase(),r}async function Se(e={},t={}){let{chainId:r,quoter:n,router:o,feeTiers:s}=Ur(e.chainId??8453,e.venue),a=Pr(e.tokenIn||"WETH",r),i=Pr(e.tokenOut||L[r].usdc,r),c=BigInt(e.amountIn??0);if(c<=0n)throw new Error("amountIn required (raw base units)");let u=s&&s.length?s:Qo,d=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[u[Math.min(2,u.length-1)]]:[...u],p=[],l=null;for(let m of d){let f=Tt.encodeFunctionData("quoteExactInputSingle",[{tokenIn:a,tokenOut:i,amountIn:c,fee:m,sqrtPriceLimitX96:0n}]);try{let g=await B(r,"eth_call",[{to:n,data:f},"latest"],t);if(!g||g==="0x"){p.push({fee:m,ok:!1,error:"empty result"});continue}let b=Tt.decodeFunctionResult("quoteExactInputSingle",g),S={fee:m,ok:!0,amountOut:b[0].toString(),sqrtPriceX96After:b[1].toString(),initializedTicksCrossed:Number(b[2]),gasEstimate:b[3].toString()};p.push(S),(!l||BigInt(S.amountOut)>BigInt(l.amountOut))&&(l=S)}catch(g){p.push({fee:m,ok:!1,error:String(g.message||g).slice(0,160)})}}if(!l){let m=p.map(f=>`${f.fee}:${f.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${m}`)}return D({venue:"uniswap-v3",chainId:r,chain:L[r].name,quoter:n,tokenIn:a,tokenOut:i,amountIn:c.toString(),fee:l.fee,amountOut:l.amountOut,gasEstimate:l.gasEstimate,sqrtPriceX96After:l.sqrtPriceX96After,initializedTicksCrossed:l.initializedTicksCrossed,triedFees:p,best:!0},{chainId:r,venue:o,amountOut:l.amountOut,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function Au(e={},t={}){let{chainId:r,quoter:n,router:o}=Ur(e.chainId??8453),s=(e.tokens||[]).map(l=>Pr(l,r)),a=(e.fees||[]).map(Number);if(s.length<2)throw new Error("tokens[] need at least 2 addresses");let i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required");let c=xu(s,a),u=Tt.encodeFunctionData("quoteExactInput",[c,i]),d=await B(r,"eth_call",[{to:n,data:u},"latest"],t),p=Tt.decodeFunctionResult("quoteExactInput",d);return D({venue:"uniswap-v3",chainId:r,chain:L[r].name,quoter:n,tokens:s,fees:a,path:c,amountIn:i.toString(),amountOut:p[0].toString(),gasEstimate:p[3].toString()},{chainId:r,venue:o,amountOut:p[0].toString(),liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function Yo(e={},t={}){let r=Number(e.chainId??8453),n=e.amountIn??"1000000000000000",o=await Se({chainId:r,tokenIn:L[r].weth,tokenOut:L[r].usdc,amountIn:n,fee:e.fee},t),s=Number(o.amountOut)/1e6;return{...o,amountOutUsdc:s,pair:"WETH/USDC"}}async function Eu(e={},t={}){let r=Number(e.chainId??8453),n=Ur(r,e.venue),o=Je(e.recipient),s=String(e.tokenIn||"WETH"),a=!e.tokenIn||s===Wo||s===Go||/^eth$/i.test(s),i=await Se(e,t),c=zo.encodeFunctionData("exactInputSingle",[{tokenIn:i.tokenIn,tokenOut:i.tokenOut,fee:i.fee,recipient:o,amountIn:BigInt(i.amountIn),amountOutMinimum:BigInt(i.amountOutMinimum),sqrtPriceLimitX96:0n}]),u=Math.min(600,Math.max(30,Number(e.deadlineSeconds??300))),p=Number(t.nowSeconds??Math.floor(Date.now()/1e3))+u,l=zo.encodeFunctionData("multicall",[p,[c]]);return T({provider:"uniswap-v3",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:r,deadline:p,quote:i,autoSlippage:i.autoSlippage,requiresApproval:a?null:{token:i.tokenIn,spender:n.router,amount:i.amountIn},transaction:{chainId:r,from:o,to:n.router,data:l,value:a?i.amountIn:"0",slippageGuard:Q(i.autoSlippage,{chainId:r,venue:n.router,data:l})}},{provider:"uniswap-v3",kind:"univ3-swap-tx"})}async function ku(e={}){let t=Number(e.chainId??8453);try{let r=await Yo({chainId:t,amountIn:"1000000000000000"},e);return{ok:!0,chainId:t,fee:r.fee,amountOutUsdc:r.amountOutUsdc,midPxHint:r.amountOutUsdc/.001}}catch(r){return{ok:!1,chainId:t,error:String(r.message||r).slice(0,200)}}}async function Iu(){return Object.entries(L).map(([e,t])=>({chainId:Number(e),name:t.name,quoter:t.quoter,weth:t.weth,usdc:t.usdc}))}var L,Qo,Tt,zo,Wo,Go,Rt,Xo,Nt=w(()=>{we();oe();j();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"}},Qo=[100,500,3e3,1e4],Tt=new Ko(["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)"]),zo=new Ko(["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)"]),Wo="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Go="0x0000000000000000000000000000000000000000",Rt=[100,500,2500,1e4],Xo={56:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:Rt}},8453:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:Rt}},42161:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:Rt}},999:{hyperswap:{name:"hyperswap",quoter:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",router:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D"}}}});var ns={};_(ns,{executeRfqCandidates:()=>ts,rankRfqQuotes:()=>rs,requestRfqQuotes:()=>Ou,sourceCandidates:()=>es});function Ze(e,t){return Array.isArray(e?.allowedSources)&&e.allowedSources.includes(t)}function Zo(e,t){return String(e?.[t]??"").trim()}function et(e,t){return Object.freeze({source:e,run:t})}function es(e,t={}){if(!e||e.kind!=="rfq-intent")throw new Error("rfq: intent required");let r=t.env??process.env,n=t.providers??{},o=t.supportedUniV3Chains??L,s=Number(e.fromChainId)===Number(e.toChainId),a=[];return Ze(e,"lifi")&&a.push(et("lifi",async()=>{let c=await(n.lifiQuote??ge)({fromChain:e.fromChainId,toChain:e.toChainId,fromToken:e.sellToken,toToken:e.buyToken,fromAmount:e.sellAmount,fromAddress:e.receiver},t),u=c?.estimate??c?.[0]?.estimate??c;return{quoteId:c?.id??c?.routeId??null,amountOut:u?.toAmount??c?.toAmount,minBuyAmount:u?.toAmountMin??c?.toAmountMin??u?.toAmount??c?.toAmount,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"lifi-route",calldataHash:c?.transactionRequest?.data?await Cu(t,c.transactionRequest.data):void 0,route:c},metadata:{tool:c?.tool??c?.toolDetails?.name??null}}})),s&&(Ze(e,"paraswap")&&a.push(et("paraswap",async()=>{let c=await(n.paraswapPrice??Te)({chainId:e.fromChainId,srcToken:e.sellToken,destToken:e.buyToken,amount:e.sellAmount,srcDecimals:t.decimalsIn,destDecimals:t.decimalsOut},t),u=c?.priceRoute??c;return{quoteId:u?.id??null,amountOut:u?.destAmount,minBuyAmount:c?.amountOutMinimum??u?.destAmount,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"paraswap-price-route",route:u},metadata:{contractAddress:u?.contractAddress??null}}})),Ze(e,"0x")&&(Zo(r,"ZEROX_API_KEY")||Zo(r,"0X_API_KEY")||n.zeroxQuote)&&a.push(et("0x",async()=>{let c=await(n.zeroxQuote??Ne)({chainId:e.fromChainId,sellToken:e.sellToken,buyToken:e.buyToken,sellAmount:e.sellAmount,taker:e.receiver},t);return{quoteId:c?.id??null,amountOut:c?.buyAmount??c?.grossBuyAmount,minBuyAmount:c?.minBuyAmount??c?.buyAmount,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"0x-transaction",to:c?.transaction?.to,data:c?.transaction?.data,value:c?.transaction?.value??"0"},metadata:{route:c?.route??null}}})),Ze(e,"cow")&&a.push(et("cow",async()=>{let c=await(n.cowQuote??ye)({chainId:e.fromChainId,sellToken:e.sellToken,buyToken:e.buyToken,sellAmountBeforeFee:e.sellAmount,from:e.receiver,signingScheme:"eip712"},t),u=c?.quote??c;return{quoteId:c?.id??null,amountOut:u?.buyAmount,minBuyAmount:u?.buyAmount,expiryMs:Math.min(Number(u?.validTo??0)*1e3||Date.now()+Number(t.defaultQuoteTtlMs??2e4),e.deadlineMs),artifact:{type:"cow-order",order:u},metadata:{solver:!0}}})),Ze(e,"uniswap-v3")&&o[Number(e.fromChainId)]&&a.push(et("uniswap-v3",async()=>{let c=await(n.uniV3QuoteExactIn??Se)({chainId:e.fromChainId,tokenIn:e.sellToken,tokenOut:e.buyToken,amountIn:e.sellAmount},t);return{quoteId:c?.id??null,amountOut:c?.amountOut,minBuyAmount:c?.minOut??c?.amountOutMinimum??c?.amountOut,expiryMs:Date.now()+Number(t.defaultQuoteTtlMs??2e4),artifact:{type:"uniswap-v3-quote",quoter:c?.quoter,fee:c?.fee},metadata:{onchain:!0}}}))),a}async function Cu(e,t){return`0x${(await import("node:crypto")).createHash("sha256").update(String(t)).digest("hex")}`}async function _u(e,t){return Promise.race([Promise.resolve().then(e.run),new Promise((r,n)=>setTimeout(()=>n(new Error(`${e.source}: timeout`)),t))])}async function ts(e,t,r={}){let n=Number(r.timeoutMs??12e3),o=await Promise.allSettled(t.map(i=>_u(i,n))),s=[],a=[];for(let i=0;i<o.length;i++){let c=t[i],u=o[i];if(u.status==="rejected"){a.push({source:c.source,error:String(u.reason?.message||u.reason)});continue}try{s.push(vr(e,{...u.value,source:c.source},r))}catch(d){a.push({source:c.source,error:String(d?.message||d)})}}return{quotes:s,failed:a}}function rs(e=[],t={}){let r=Number(t.nowMs??Date.now()),n=e.filter(a=>Number(a.expiryMs??0)>r);n.sort((a,i)=>{let c=BigInt(i.minBuyAmount??0)-BigInt(a.minBuyAmount??0);if(c!==0n)return c>0n?1:-1;let u=BigInt(i.amountOut??0)-BigInt(a.amountOut??0);return u>0n?1:u<0n?-1:0});let o=n.map(a=>({...a,scoreBasis:"minBuyAmount"})),s=[];return o.length||s.push("no RFQ source returned a usable firm quote"),e.length!==o.length&&s.push("expired RFQ quotes were excluded from ranking"),{best:o[0]??null,quotes:o,failed:[],warnings:s}}async function Ou(e,t={}){let r=es(e,t),{quotes:n,failed:o}=await ts(e,r,t),s=rs(n,t);return{kind:"rfq-result",intent:e,best:s.best,quotes:s.quotes,failed:o,warnings:[...s.warnings],sourcesTried:r.length,sourcesAnswered:n.length}}var os=w(()=>{Ge();St();Et();Ct();Nt();xr()});function ss(e={}){let t=[],r=[];if(!e||typeof e!="object")return{ok:!1,errors:["definition must be an object"],warnings:r};if((!Number.isInteger(e.chainId)||e.chainId<=0)&&t.push("chainId must be a positive integer"),(typeof e.key!="string"||!/^[a-z][a-z0-9-]*$/.test(e.key||""))&&t.push('key must be a lowercase slug (e.g. "base")'),(typeof e.name!="string"||!e.name.trim())&&t.push("name is required"),!Array.isArray(e.rpcEnv)||e.rpcEnv.length===0)t.push("rpcEnv must list at least one environment variable name");else for(let o of e.rpcEnv)(typeof o!="string"||!/^[A-Z][A-Z0-9_]*$/.test(o))&&t.push(`rpcEnv entry "${o}" should be an UPPER_SNAKE env var name`);if(e.nativeCurrency){let o=e.nativeCurrency;(typeof o.symbol!="string"||!o.symbol)&&t.push("nativeCurrency.symbol is required when nativeCurrency is set"),Number.isInteger(o.decimals)||t.push("nativeCurrency.decimals must be an integer")}for(let[o,s]of(e.venues||[]).entries()){let a=`venues[${o}]`;if(!s||typeof s!="object"){t.push(`${a} must be an object`);continue}Ru.test(s.address||"")||t.push(`${a}.address is not a valid 20-byte address`),/^0x0{40}$/.test(s.address||"")&&t.push(`${a}.address is the zero address -- placeholder left in place?`),s.kind||t.push(`${a}.kind is required (router|quoter|factory|...)`),s.verified?(s.verified.method||t.push(`${a}.verified.method is required`),s.verified.source||t.push(`${a}.verified.source is required`),s.verified.date||r.push(`${a}.verified.date missing -- add one so staleness is visible`)):t.push(`${a} must record verification: { verified: { method, source, date } }. An unverified venue stays blocked.`)}let n=e.capabilities||{};for(let o of Object.keys(n))$e.includes(o)?typeof n[o]!="function"&&t.push(`capability "${o}" must be a function`):t.push(`unknown capability "${o}"`);return Object.keys(n).length===0&&r.push("scanner implements no capabilities -- it can only be registered, not used"),n.prepareUnsignedTx&&!n.quote&&r.push("prepareUnsignedTx without quote: no priced expectation to validate the built tx against"),n.prepareUnsignedTx&&!n.sellSimulation&&r.push("prepareUnsignedTx without sellSimulation: cannot prove an asset is exitable before buying"),{ok:t.length===0,errors:t,warnings:r}}function is(e){let{ok:t,errors:r,warnings:n}=ss(e);if(!t)throw new Error(`invalid scanner for ${e?.key??"<unknown>"}:
4
4
  - ${r.join(`
5
- - `)}`);let o=e.capabilities||{},i=re.filter(a=>typeof o[a]=="function"),s={key:e.key,chainId:e.chainId,name:e.name,rpcEnv:[...e.rpcEnv],nativeCurrency:e.nativeCurrency?{...e.nativeCurrency}:null,explorer:e.explorer||null,venues:(e.venues||[]).map(a=>({...a})),warnings:n,capabilities(){return{chainId:e.chainId,key:e.key,supported:[...i],unsupported:re.filter(a=>!i.includes(a))}},supports(a){return i.includes(a)}};for(let a of re)i.includes(a)?s[a]=async(...c)=>o[a](...c,{scanner:s}):s[a]=async()=>{throw new Error(`${e.key} (chain ${e.chainId}) does not implement "${a}". Supported: ${i.join(", ")||"none"}. An unimplemented capability is absent, not assumed -- implement it or treat this chain as fail-closed for that operation.`)};return Object.freeze(s)}function Le(e){let t=fn(e);return ne.set(t.chainId,t),t}function Fi(e){return ne.get(Number(e))||null}function Mi(){return[...ne.values()]}function ji(){ne.clear()}function Vi(){let e={};for(let t of ne.values())e[t.chainId]={key:t.key,name:t.name,...t.capabilities(),venueCount:t.venues.length,failClosed:t.venues.length===0};return{generatedAt:new Date().toISOString(),chainCount:ne.size,capabilities:[...re],chains:e}}var re,w,y,$i,ne,z=E(()=>{re=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),w=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),y=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"}),$i=/^0x[0-9a-fA-F]{40}$/;ne=new Map});function hn(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:o=null,feeUsd:i=null,estimatedGas:s=null,error:a=null,executionReady:c=!1,meta:u={}}=e||{};if(a||r==null)return{source:t,quality:D.FAILED,amountOut:null,error:a||"no amountOut returned"};let d=be(r);return d==null||d<=0n?{source:t,quality:D.FAILED,amountOut:null,error:"non-positive amountOut"}:{source:t,quality:o==null?D.NO_GAS:D.FULL,amountOut:d.toString(),minOut:be(n)?.toString()??null,gasUsd:o,feeUsd:i,estimatedGas:s==null?null:String(s),executionReady:c,meta:u}}async function gn(e,t,{divisor:r=1000n}={}){let n=be(t);if(n==null||n<=0n)return null;let o=n/r>0n?n/r:1n;if(o>=n)return null;let i,s;try{[i,s]=await Promise.all([e(o),e(n)])}catch{return null}let a=be(i),c=be(s);if(a==null||c==null||a<=0n)return null;let u=Number(a)/Number(o),d=Number(c)/Number(n);return!Number.isFinite(u)||!Number.isFinite(d)||u<=0?null:{impactPct:(1-d/u)*100,probeAmountIn:o.toString(),probeAmountOut:a.toString(),fullAmountOut:c.toString()}}function yn(e,t,{maxImpactPct:r=25}={}){let n=[],o=[],i=(e.routes??[]).filter(a=>{let c=t?.[a.source];return c?c.impactPct>r?(n.push({source:a.source,impactPct:Number(c.impactPct.toFixed(2)),reason:`price impact ${c.impactPct.toFixed(1)}% exceeds ${r}% ceiling -- the venue cannot absorb this size near the quoted price`}),!1):!0:(o.push(a.source),!0)}),s=[...e.warnings??[]];return n.length&&s.push(`dropped ${n.length} route(s) on price impact: `+n.map(a=>`${a.source} (${a.impactPct}%)`).join(", ")),o.length&&s.push(`price impact NOT measured for: ${o.join(", ")}. These are unproven against thin liquidity, not proven safe.`),{...e,routes:i,best:i[0]??null,impactRejected:n,impactUnmeasured:o,warnings:s}}function ht(e,{destPriceUsd:t=null,destDecimals:r=null}={}){let n=e.filter(p=>p.quality!==D.FAILED),o=e.filter(p=>p.quality===D.FAILED),i=t!=null&&t>0&&r!=null&&r>=0,s=n.map(p=>{let l=BigInt(p.amountOut),m=0n,f=!1;if(i){let h=(p.gasUsd??0)+(p.feeUsd??0);if(h>0){let g=h/t*10**r;Number.isFinite(g)&&g>=0&&(m=BigInt(Math.floor(g)),f=!0)}else p.gasUsd===0&&(f=!0)}let b=l>m?l-m:0n;return{...p,grossOut:l.toString(),netOut:b.toString(),costInDest:m.toString(),costAccounted:f}});s.sort((p,l)=>BigInt(l.netOut)>BigInt(p.netOut)?1:-1);let a=s.filter(p=>!p.costAccounted).map(p=>p.source),c=[];i?a.length&&c.push(`gas not reported by: ${a.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):c.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let u=null,d=null;if(s.length>=2&&s[0].costAccounted&&s[1].costAccounted){let p=BigInt(s[0].netOut),l=BigInt(s[1].netOut);l>0n&&(u=Number((p-l)*10000n/l),d=`${s[0].source} vs ${s[1].source}`)}return{best:s[0]??null,routes:s,failed:o,improvementBps:u,spreadBasis:d,rankedOn:i?"net-of-cost":"gross",warnings:c}}async function De(e,{timeoutMs:t=12e3}={}){let r=(o,i)=>Promise.race([o,new Promise((s,a)=>setTimeout(()=>a(new Error(`${i}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,i)=>{let s=e[i].source;return o.status==="rejected"?hn({source:s,error:String(o.reason?.message||o.reason)}):hn({source:s,...o.value})})}var D,bn,be,bt=E(()=>{z();D=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"}),bn={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"},be=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}}});function wn(e={}){return Ie({provider:"oneinch",defaultUrl:Hi,hosts:["api.1inch.dev"],url:e.baseUrl||process.env.ONEINCH_API_URL})}function Ki(e={}){return wn(e).baseUrl}function En(e={}){return e.apiKey||process.env.ONEINCH_API_KEY||process.env.ONE_INCH_API_KEY||""}function zi(e={}){let t=En(e);return Ce({accept:"application/json"},{Authorization:t?`Bearer ${t}`:""},wn(e).trusted)}async function vn(e={},t={}){if(!En(t))throw new Error("ONEINCH_API_KEY required for 1inch");let r=Number(e.chainId??1),{src:n,dst:o,amount:i}=e;if(!n||!o||!i)throw new Error("oneinchQuote requires src, dst, amount");let s=new URLSearchParams({src:n,dst:o,amount:String(i)}),a=await v(`${Ki(t)}/${r}/quote?${s}`,{headers:zi(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3});return a?.dstAmount?I(a,{chainId:r,venue:"1inch-quote",amountOut:a.dstAmount,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):a}var Hi,An=E(()=>{L();P();ut();T();Hi="https://api.1inch.dev/swap/v6.0"});var On={};O(On,{UNI_V4_CHAINS:()=>q,UNI_V4_FEE_TIERS:()=>Cn,computeV4PoolId:()=>_n,uniV4Chains:()=>ta,uniV4Health:()=>ra,uniV4PrepareExactIn:()=>ea,uniV4QuoteExactIn:()=>Pe});import{AbiCoder as Gi,Interface as In,getAddress as B,isAddress as Ue,keccak256 as Qi}from"ethers";function gt(e){let t=Number(e),r=q[t];if(!r)throw new Error(`uniswap-v4: unsupported chainId ${e} (supported: ${Object.keys(q).join(", ")})`);return{chainId:t,...r}}function xn(e,t){let r=q[Number(t)];if(!e||e===kn||e===G||/^eth$/i.test(String(e)))return B(r.weth);let n=String(e);if(/^weth$/i.test(n))return B(r.weth);if(/^usdc$/i.test(n)||/^usdg$/i.test(n))return B(r.usdc);if(!Ue(n))throw new Error(`invalid token address: ${e}`);return B(n)}function _n({currency0:e,currency1:t,fee:r,tickSpacing:n,hooks:o=G}){let i=B(e),s=B(t);if(i.toLowerCase()===s.toLowerCase())throw new Error("poolKey currencies must differ");let[a,c]=i.toLowerCase()<s.toLowerCase()?[i,s]:[s,i],u=o&&Ue(o)?B(o):G;return Qi(ge.encode(["address","address","uint24","int24","address"],[a,c,Number(r),Number(n),u]))}function Zi({tokenIn:e,tokenOut:t,fee:r,tickSpacing:n,hooks:o=G}){let i=B(e),s=B(t),[a,c]=i.toLowerCase()<s.toLowerCase()?[i,s]:[s,i],u=i.toLowerCase()===a.toLowerCase();return{poolKey:{currency0:a,currency1:c,fee:Number(r),tickSpacing:Number(n),hooks:o&&Ue(o)?B(o):G},zeroForOne:u}}async function Pe(e={},t={}){let{chainId:r,quoter:n,poolManager:o,universalRouter:i}=gt(e.chainId??8453),s=xn(e.tokenIn||"WETH",r),a=xn(e.tokenOut||q[r].usdc,r),c=BigInt(e.amountIn??0);if(c<=0n)throw new Error("amountIn required (raw base units)");if(c>0xffffffffffffffffffffffffffffffffn)throw new Error("amountIn exceeds uint128");let u=e.fee!=null&&e.tickSpacing!=null?[{fee:Number(e.fee),tickSpacing:Number(e.tickSpacing)}]:e.tryTiers===!1?[{fee:500,tickSpacing:10}]:[...Cn],d=e.hooks||G,p=[],l=null;for(let m of u){let{poolKey:f,zeroForOne:b}=Zi({tokenIn:s,tokenOut:a,fee:m.fee,tickSpacing:m.tickSpacing,hooks:d}),h=Sn.encodeFunctionData("quoteExactInputSingle",[{poolKey:f,zeroForOne:b,exactAmount:c,hookData:"0x"}]);try{let g=await k(r,"eth_call",[{to:n,data:h},"latest"],t);if(!g||g==="0x"){p.push({...m,ok:!1,error:"empty result"});continue}let S=Sn.decodeFunctionResult("quoteExactInputSingle",g),C={fee:m.fee,tickSpacing:m.tickSpacing,ok:!0,amountOut:S[0].toString(),gasEstimate:S[1].toString(),poolKey:f,zeroForOne:b,poolId:_n({...f})};p.push(C),(!l||BigInt(C.amountOut)>BigInt(l.amountOut))&&(l=C)}catch(g){p.push({...m,ok:!1,error:String(g.message||g).slice(0,160)})}}if(!l){let m=p.map(f=>`${f.fee}/${f.tickSpacing}:${f.error||"fail"}`).join("; ");throw new Error(`uniswap-v4 quote failed chain=${r}: ${m}`)}return I({venue:"uniswap-v4",chainId:r,chain:q[r].name,poolManager:o,quoter:n,universalRouter:i||null,tokenIn:s,tokenOut:a,amountIn:c.toString(),fee:l.fee,tickSpacing:l.tickSpacing,hooks:l.poolKey.hooks,poolId:l.poolId,zeroForOne:l.zeroForOne,amountOut:l.amountOut,gasEstimate:l.gasEstimate,triedTiers:p,best:!0,executionReady:!1,prepareReady:typeof e.recipient=="string"&&Ue(e.recipient)&&e.slippageBps!=null},{chainId:r,venue:i||n,amountOut:l.amountOut,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function ea(e={},t={}){let r=Number(e.chainId??8453),n=gt(r);if(!e.recipient)throw new Error("uniswap-v4 prepare requires recipient");let o=B(e.recipient);if(e.slippageBps==null)throw new Error("uniswap-v4 prepare requires explicit slippageBps");let i=Number(e.slippageBps);if(!Number.isInteger(i)||i<0||i>=1e4)throw new Error("slippageBps must be an integer from 0 through 9999");let s=String(e.tokenIn||"");if(!s||s===kn||s===G||/^eth$/i.test(s))throw new Error("uniswap-v4 prepare currently requires an ERC-20 tokenIn; native input is not inferred");let a=await Pe(e,t);if(!n.universalRouter)throw new Error(`uniswap-v4: no Universal Router on chain ${r}`);let c=BigInt(a.amountOut)*BigInt(1e4-i)/10000n,u={currency0:a.zeroForOne?a.tokenIn:a.tokenOut,currency1:a.zeroForOne?a.tokenOut:a.tokenIn,fee:a.fee,tickSpacing:a.tickSpacing,hooks:a.hooks},p=ge.encode(["tuple(tuple(address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 amountIn,uint128 amountOutMinimum,uint256 minHopPriceX36,bytes hookData)"],[[u,a.zeroForOne,BigInt(a.amountIn),c,0n,"0x"]]),l=ge.encode(["address","uint256"],[a.tokenIn,BigInt(a.amountIn)]),m=ge.encode(["address","uint256"],[a.tokenOut,c]),f=ge.encode(["bytes","bytes[]"],[Xi,[p,l,m]]),b=Math.min(600,Math.max(30,Number(e.deadlineSeconds??300))),g=Number(t.nowSeconds??Math.floor(Date.now()/1e3))+b,S=Wi.encodeFunctionData("execute",[Yi,[f],g]);return x({provider:"uniswap-v4",prepareReady:!0,calldataReady:!0,executionReady:!1,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:r,deadline:g,quote:{...a,amountOutMinimum:c.toString(),slippageBps:i},requiresApproval:{token:a.tokenIn,spender:Ji,amount:a.amountIn,note:"Universal Router V4 settlement uses Permit2; Permit2 authorization for the Universal Router is also required"},transaction:{chainId:r,from:o,to:n.universalRouter,data:S,value:"0"}},{provider:"uniswap-v4",kind:"univ4-swap-tx"})}async function ta(){return Object.entries(q).map(([e,t])=>({chainId:Number(e),name:t.name,poolManager:t.poolManager,quoter:t.quoter,stateView:t.stateView||null,universalRouter:t.universalRouter||null,weth:t.weth,usdc:t.usdc}))}async function ra(e={}){let t=gt(e.chainId??8453),r=await k(t.chainId,"eth_getCode",[t.quoter,"latest"],e),n=typeof r=="string"&&r!=="0x"&&r.length>4;return{ok:n,chainId:t.chainId,quoter:t.quoter,poolManager:t.poolManager,codeBytes:n?(r.length-2)/2:0}}var ge,G,q,Cn,Sn,Wi,Yi,Xi,Ji,kn,yt=E(()=>{te();P();T();ge=Gi.defaultAbiCoder(),G="0x0000000000000000000000000000000000000000",q={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"}},Cn=[{fee:100,tickSpacing:1},{fee:500,tickSpacing:10},{fee:3e3,tickSpacing:60},{fee:1e4,tickSpacing:200},{fee:25e3,tickSpacing:8}],Sn=new In(["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)"]),Wi=new In(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]),Yi="0x10",Xi="0x060c0f",Ji="0x000000000022D473030F116dDEE9F6B43aC78BA3",kn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"});function oa(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||na).replace(/\/$/,"")}async function qe(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return v(`${oa(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}var na,wt=E(()=>{L();na="https://coins.llama.fi"});var $e={};O($e,{ACROSS_API:()=>Rn,HOP_API:()=>Nn,RELAY_API:()=>Tn,acrossHealth:()=>aa,acrossSuggestedFees:()=>Bn,hopHealth:()=>sa,hopQuote:()=>Ln,relayHealth:()=>ca,relayPrepare:()=>ua,relayQuote:()=>Et});async function aa(e={}){try{return{ok:!0,estimatedFillTimeSec:(await Bn({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 Bn(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:i,amount:s}=e;if(!r||o==null||i==null||!s)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let a=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(i),amount:String(s)}),c=(t.baseUrl||process.env.ACROSS_API_URL||Rn).replace(/\/$/,"");return v(`${c}/suggested-fees?${a}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function sa(e={}){try{let t=await Ln({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 Ln(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:i="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let s=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),a=U({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==i,requestedCapBps:e.maxSlippageBps??e.slippageBps??s});if(!a.executable)throw new Error(`hop: route requires ${a.requiredBps} bps above cap ${a.capBps}`);let c=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:i,slippage:String(a.selectedBps/100)}),u=(t.baseUrl||process.env.HOP_API_URL||Nn).replace(/\/$/,""),d=await v(`${u}/quote?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),p=d?.estimatedRecieved||d?.estimatedReceived;return p?I(d,{chainId:Number(e.originChainId||e.chainId||ia[o]||0),venue:d?.tx?.to||"hop",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==i,requestedCapBps:e.maxSlippageBps??e.slippageBps??s}):{...d,autoSlippagePolicy:a}}async function ca(e={}){try{let t=await Et({user:F,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 Et(e={},t={}){let{user:r=F,originChainId:n,destinationChainId:o,originCurrency:i="0x0000000000000000000000000000000000000000",destinationCurrency:s="0x0000000000000000000000000000000000000000",amount:a,tradeType:c="EXACT_INPUT"}=e;if(n==null||o==null||!a)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let u=U({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!u.executable)throw new Error(`relay: route requires ${u.requiredBps} bps above cap ${u.capBps}`);let d=(t.baseUrl||process.env.RELAY_API_URL||Tn).replace(/\/$/,""),p=await v(`${d}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:i,destinationCurrency:s,amount:String(a),tradeType:c,slippageTolerance:String(u.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),l=p?.details?.currencyOut?.amount;return!l||!/^\d+$/.test(String(l))?{...p,autoSlippagePolicy:u}:I(p,{chainId:Number(n),venue:p?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:l,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function ua(e={},t={}){let r=await Et(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(a=>(a.items||[]).filter(c=>c?.data?.to&&c?.data?.data).map(c=>({stepId:a.id,...c.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let i=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(a=>String(a.to).toLowerCase()!==i))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let s=o.map(a=>({chainId:n,from:a.from||e.user,to:a.to,data:a.data,value:a.value??"0x0",...a.gasLimit!=null||a.gas!=null?{gasLimit:a.gasLimit??a.gas}:{},slippageGuard:N(r.autoSlippage,{chainId:n,venue:a.to,data:a.data})}));return x({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:s},{provider:"relay",kind:"relay-tx"})}var Rn,Nn,Tn,ia,Fe=E(()=>{L();P();Se();T();Rn="https://across.to/api",Nn="https://api.hop.exchange/v1",Tn="https://api.relay.link",ia={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});function Me(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=j(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}async function Dn(e,t={}){let r=bn[Number(e)];if(!r)return null;try{let n=await qe([r],t);return j(n?.coins?.[r]?.price)}catch{return null}}function vt({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:i,decimalsIn:s,decimalsOut:a,nativePriceUsd:c=null,destDecimalsPromise:u=null,opts:d={}}){let p=[];return p.push({source:"lifi",run:async()=>{let l=await V({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n},d),m=l?.estimate??l?.[0]?.estimate;return{amountOut:m?.toAmount,minOut:m?.toAmountMin,gasUsd:Me(m?.gasCosts),feeUsd:Me(m?.feeCosts),meta:{tool:l?.tool??l?.toolDetails?.name}}}}),s!=null&&p.push({source:"paraswap",run:async()=>{let l=a??(await Promise.resolve(u))?.decimals;if(l==null)throw new Error("paraswap needs destination decimals; none supplied or resolvable");let f=(await J({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:s,destDecimals:l},d))?.priceRoute;return{amountOut:f?.destAmount,gasUsd:j(f?.gasCostUSD),meta:{bestRoute:f?.bestRoute?.[0]?.swaps?.[0]?.swapExchanges?.[0]?.exchange}}}}),process.env.ZEROX_API_KEY&&p.push({source:"0x",run:async()=>{let l=await Z({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},d),m=null,f=l?.totalNetworkFee,b=await Promise.resolve(c);return f!=null&&b&&(m=Number(f)/1e18*b),{amountOut:l?.buyAmount,minOut:l?.minBuyAmount,gasUsd:m,meta:{source:l?.route?.fills?.[0]?.source}}}}),process.env.ONEINCH_API_KEY&&p.push({source:"1inch",run:async()=>{let l=await vn({chainId:e,src:t,dst:r,amount:n},d),m=null;return l?.gas!=null&&c&&(m=null),{amountOut:l?.dstAmount,gasUsd:m,meta:{gasUnits:l?.gas}}}}),p.push({source:"cow",run:async()=>{let l=await H({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},d),m=l?.quote??l,f=m?.feeAmount;return{amountOut:m?.buyAmount,gasUsd:0,meta:{intent:!0,feeAmountInSellToken:f,settlement:"solver-executed"}}}}),_[Number(e)]&&p.push({source:"uniswap-v3",run:async()=>{let l=await K({chainId:e,tokenIn:t,tokenOut:r,amountIn:n},d);return{amountOut:l?.amountOut,minOut:l?.minOut??l?.amountOutMinimum??null,gasUsd:null,meta:{onchain:!0,fee:l?.fee,gasUnits:l?.gasEstimate,quoter:l?.quoter}}}}),q[Number(e)]&&p.push({source:"uniswap-v4",run:async()=>{let l=await Pe({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:i},d);return{amountOut:l?.amountOut,minOut:l?.minOut??l?.amountOutMinimum??null,gasUsd:null,meta:{onchain:!0,venue:"uniswap-v4",fee:l?.fee,tickSpacing:l?.tickSpacing,poolId:l?.poolId,hooks:l?.hooks,gasUnits:l?.gasEstimate,quoter:l?.quoter,poolManager:l?.poolManager,prepareReady:l?.prepareReady===!0,executionReady:!1}}}}),p}function Un({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:i,opts:s={}}){let a=[];return a.push({source:"lifi",run:async()=>{let c=await V({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},s),u=c?.estimate??c?.[0]?.estimate;return{amountOut:u?.toAmount,minOut:u?.toAmountMin,gasUsd:Me(u?.gasCosts),feeUsd:Me(u?.feeCosts),meta:{tool:c?.tool??c?.toolDetails?.name,durationSeconds:j(u?.executionDuration)}}}}),a.push({source:"relay",run:async()=>{let{relayQuote:c}=await Promise.resolve().then(()=>(Fe(),$e)),d=(await c({user:i,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},s))?.details;return{amountOut:d?.currencyOut?.amount,minOut:d?.currencyOut?.minimumAmount,gasUsd:j(d?.totalImpact?.usd)!=null?Math.abs(j(d.totalImpact.usd)):null,meta:{durationSeconds:j(d?.timeEstimate),rate:d?.rate}}}}),a.push({source:"across",run:async()=>{let{acrossSuggestedFees:c}=await Promise.resolve().then(()=>(Fe(),$e)),u=await c({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},s),d=u?.totalRelayFee?.total,p=null;if(d!=null)try{let l=BigInt(String(o))-BigInt(String(d));l>0n&&(p=l.toString())}catch{}return{amountOut:p,gasUsd:null,meta:{derivedFromFees:!0,durationSeconds:j(u?.estimatedFillTimeSec),limits:u?.limits?{min:u.limits.minDeposit,max:u.limits.maxDeposit}:void 0}}}}),a}var j,Pn=E(()=>{de();xe();_e();An();Ne();Be();yt();wt();bt();j=e=>{let t=Number(e);return Number.isFinite(t)?t:null}});var Fn={};O(Fn,{QUALITY:()=>D,bestBridgeRoute:()=>St,bestSwapRoute:()=>At});async function qn(e,t,r){let n=la[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let s=(await qe([o],r))?.coins?.[o],a=Number(s?.price),c=Number(s?.decimals);return{priceUsd:Number.isFinite(a)?a:null,decimals:Number.isFinite(c)?c:null}}catch{return{priceUsd:null,decimals:null}}}async function At(e,t={}){let{chainId:r,tokenIn:n,tokenOut:o,amountIn:i}=e;if(r==null||!n||!o||i==null)throw new Error("bestSwapRoute requires chainId, tokenIn, tokenOut, amountIn");let s=Dn(r,t),a=qn(r,o,t),c=vt({...e,nativePriceUsd:s,decimalsOut:e.decimalsOut,destDecimalsPromise:a,opts:t}),[u,d]=await Promise.all([De(c,{timeoutMs:t.timeoutMs??12e3}),a]);s.catch(()=>{});let p=ht(u,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals}),l=t.maxImpactPct===void 0?25:t.maxImpactPct;if(l!=null&&p.best){let m=p.best.source,b=await gn(async h=>{let g=vt({...e,amountIn:h.toString(),nativePriceUsd:s,decimalsOut:e.decimalsOut,destDecimalsPromise:a,opts:t}).filter(C=>C.source===m);return g.length?(await De(g,{timeoutMs:t.timeoutMs??12e3}))?.[0]?.amountOut??null:null},i);if(b){let h=yn(p,{[m]:b},{maxImpactPct:l});return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(i),...h,priceImpact:{[m]:Number(b.impactPct.toFixed(2))}}}}return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(i),...p,sourcesTried:c.length,sourcesAnswered:u.filter(m=>m.quality!==D.FAILED).length,note:$n(p,c.length)}}async function St(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:i,amountIn:s}=e;if(r==null||n==null||!o||!i||s==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 a=qn(n,i,t),c=Un({...e,opts:t}),[u,d]=await Promise.all([De(c,{timeoutMs:t.timeoutMs??15e3}),a]),p=ht(u,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals}),l=p.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:i,amountIn:String(s),...p,durations:l,sourcesTried:c.length,sourcesAnswered:u.filter(m=>m.quality!==D.FAILED).length,note:$n(p,c.length)}}function $n(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length;return r===1?`only 1 of ${t} sources answered, so this is the ONLY route, not a proven best one. Treat it as unbenchmarked.`:e.improvementBps!=null?`best of ${r} routes, ranked on ${e.rankedOn}: ${(e.improvementBps/100).toFixed(2)}% better than the runner-up (${e.spreadBasis})`:`best of ${r} routes, ranked on ${e.rankedOn}. No spread quoted: the top routes report cost differently, so the margin is not comparable.`}var la,je=E(()=>{bt();Pn();wt();la={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"}});var Mn={};O(Mn,{ARTIFACT:()=>$,prepareBestRoute:()=>ha,supportedPreparers:()=>pa});function pa(){return Object.keys(Ve)}async function ha(e,t={}){let{taker:r}=e;if(!r)throw new Error("prepareBestRoute requires taker: a prepared transaction is built FOR an address, and the quote-only placeholder must never end up in one");if(!fa.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(ma.has(r.toLowerCase()))throw new Error(`taker "${r}" is a placeholder/burn address. It is valid for quoting but not for preparing -- that would build a transaction for an address nobody controls. Pass the real wallet that will sign.`);let n=await At(e,t);if(!n.best){let l=n.impactRejected??[];return{ok:!1,reason:l.length?l[0].reason:"no source returned a usable route",priceImpactBlocked:l.length>0,impactRejected:l,comparison:n}}let o=e.source||n.best.source,i=n.routes.find(l=>l.source===o);if(!i)return{ok:!1,reason:`source "${o}" did not return a usable route`,comparison:n};let s=Ve[o];if(!s){let l=n.routes.find(m=>Ve[m.source]&&m.source!==o);return{ok:!1,reason:`${o} won the comparison but has no prepare path in this build. `+(l?`Next preparable route is ${l.source}; pass source:"${l.source}" to use it.`:"No route in this comparison can be prepared."),comparison:n,winner:o}}let a;try{a=await s(e,t)}catch(l){let m=typeof l?.body=="string"?l.body:l?.body?JSON.stringify(l.body):"",f=[String(l?.message||l),m].filter(Boolean).join(" :: "),b=/allowance/i.test(f),h=!b&&/not enough|insufficient|balance/i.test(f),g,S;b?(S="approval-required-first",g=`${o} will not build swap calldata until the token approval exists on-chain. Approve the spender first, then prepare again. Underlying: ${f}`):h?(S="taker-not-funded",g=`${o} refused to build the transaction: ${f}. This venue verifies the taker holds the input token. Quoting works for any address; preparing needs the real funded wallet.`):(S="provider-error",g=`${o} prepare failed: ${f}`);let C=n.routes.find(ae=>Ve[ae.source]&&ae.source!==o);return{ok:!1,reason:g,failureKind:S,...C?{alternative:C.source}:{},comparison:n}}let c=e.driftToleranceBps??da,u=null,d=null;if(a.amountOut!=null&&i.grossOut!=null)try{let l=BigInt(i.grossOut),m=BigInt(a.amountOut);l>0n&&(u=Number((m-l)*10000n/l),u<-c&&(d=`route moved ${(u/100).toFixed(2)}% against you between the comparison and this prepare (tolerance ${(c/100).toFixed(2)}%). The ranking may no longer hold -- re-run the comparison before signing.`))}catch{}let p=n.routes.filter(l=>l.source!==o).map(l=>({source:l.source,netOut:l.netOut,gasUsd:l.gasUsd}));return x({ok:!0,chosen:{source:o,wasWinner:o===n.best.source,netOut:i.netOut,grossOut:i.grossOut,gasUsd:i.gasUsd},priceImpact:n.priceImpact??null,impactUnmeasured:n.impactUnmeasured??[],...a,unsigned:!0,signedBy:"user-wallet",destination:a.artifactKind===$.TRANSACTION?a.transaction?.to??null:a.settlement??null,driftBps:u,warnings:[...d?[d]:[],...n.warnings||[],...a.artifactKind===$.TYPED_DATA_ORDER?["This is an ORDER to sign, not a transaction to broadcast. Signing it authorizes a solver to settle on your behalf."]:[]],runnersUp:p,comparison:{rankedOn:n.rankedOn,sourcesAnswered:n.sourcesAnswered,sourcesTried:n.sourcesTried,improvementBps:n.improvementBps},note:"UNSIGNED. Verify the destination address and minOut against a fresh quote immediately before signing -- a quote-time minimum is not a minimum at broadcast time."},{provider:"router",kind:"best-route"})}var $,da,Ve,ma,fa,jn=E(()=>{je();T();$=Object.freeze({TRANSACTION:"unsigned-transaction",TYPED_DATA_ORDER:"typed-data-order"}),da=100,Ve={"uniswap-v3":async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},i)=>{let{uniV3PrepareExactIn:s}=await Promise.resolve().then(()=>(Be(),an)),a=await s({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o},i);return{artifactKind:$.TRANSACTION,transaction:a.transaction,requiresApproval:a.requiresApproval??null,amountOut:a.quote?.amountOut??null,minOut:a.quote?.amountOutMinimum??null}},"uniswap-v4":async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:i,fee:s,tickSpacing:a,hooks:c},u)=>{let{uniV4PrepareExactIn:d}=await Promise.resolve().then(()=>(yt(),On)),p=await d({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:i,fee:s,tickSpacing:a,hooks:c},u);return{artifactKind:$.TRANSACTION,transaction:p.transaction,requiresApproval:p.requiresApproval,amountOut:p.quote?.amountOut??null,minOut:p.quote?.amountOutMinimum??null,prepareReady:!0,executionReady:!1}},lifi:async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},i)=>{let{lifiPrepare:s}=await Promise.resolve().then(()=>(de(),st)),a=await s({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n,fromAddress:o},i);return{artifactKind:$.TRANSACTION,transaction:a.transaction,requiresApproval:a.requiresApproval??null,amountOut:a.quote?.estimate?.toAmount??null,minOut:a.quote?.estimate?.toAmountMin??null}},paraswap:async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,decimalsIn:i,decimalsOut:s},a)=>{let{paraswapPrepare:c}=await Promise.resolve().then(()=>(xe(),xr)),u=await c({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:i,destDecimals:s,userAddress:o,side:"SELL"},a);return{artifactKind:$.TRANSACTION,transaction:u.transaction,requiresApproval:u.requiresApproval??null,amountOut:u.quote?.priceRoute?.destAmount??null,minOut:u.quote?.amountOutMinimum??null}},"0x":async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},i)=>{let{zeroxPrepare:s}=await Promise.resolve().then(()=>(_e(),Tr)),a=await s({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},i);return{artifactKind:$.TRANSACTION,transaction:a.transaction,requiresApproval:a.requiresApproval??null,amountOut:a.quote?.buyAmount??null,minOut:a.quote?.minBuyAmount??null}},cow:async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},i)=>{let{cowPrepareOrder:s}=await Promise.resolve().then(()=>(Ne(),Vr)),a=await s({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},i);return{artifactKind:$.TYPED_DATA_ORDER,typedData:a.typedData,requiresApproval:{token:t,spender:a.vaultRelayer,amount:String(n),note:"CoW pulls funds via the vault relayer, not the settlement contract"},settlement:a.settlement,amountOut:a.quote?.quote?.buyAmount??null,minOut:null,submission:"sign the typed data, then submit the order to the CoW API"}}};ma=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),fa=/^0x[0-9a-fA-F]{40}$/});var Vn={};O(Vn,{prepareBestBridgeRoute:()=>Ea,supportedBridgePreparers:()=>wa});function wa(){return Object.keys(He)}async function Ea(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(!ba.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(ga.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 i=await St(e,t);if(!i.best)return{ok:!1,reason:"no source returned a usable bridge route",comparison:i};let s=e.source||i.best.source,a=i.routes.find(h=>h.source===s);if(!a)return{ok:!1,reason:`source "${s}" returned no usable route`,comparison:i};let c=He[s];if(!c){let h=i.routes.find(g=>He[g.source]&&g.source!==s);return{ok:!1,reason:`${s} won the comparison but has no bridge prepare path in this build. `+(h?`Next preparable route is ${h.source}; pass source:"${h.source}".`:"No route in this comparison can be prepared."),failureKind:"no-prepare-path",...h?{alternative:h.source}:{},winner:s,comparison:i}}let u;try{u=await c(e,t)}catch(h){let g=typeof h?.body=="string"?h.body:h?.body?JSON.stringify(h.body):"",S=[String(h?.message||h),g].filter(Boolean).join(" :: "),C=/allowance/i.test(S),ae=!C&&/not enough|insufficient|balance/i.test(S),Bt=i.routes.find(Lt=>He[Lt.source]&&Lt.source!==s);return{ok:!1,reason:C?`${s} will not build calldata until the token approval exists on-chain. Approve first, then prepare again. Underlying: ${S}`:ae?`${s} refused to build: ${S}. Quoting works for any address; preparing needs the real funded wallet on chain ${n}.`:`${s} bridge prepare failed: ${S}`,failureKind:C?"approval-required-first":ae?"taker-not-funded":"provider-error",...Bt?{alternative:Bt.source}:{},comparison:i}}let d=u.transactions||[];if(!d.length)return{ok:!1,reason:`${s} returned no executable transaction for this route`,failureKind:"provider-error",comparison:i};let p=d.filter(h=>h.chainId!=null&&Number(h.chainId)!==Number(n));if(p.length)return{ok:!1,reason:`${s} returned a transaction for chain ${p[0].chainId} but the origin chain is ${n}. Refusing to hand over a mismatched artifact.`,failureKind:"chain-mismatch",comparison:i};let l=e.driftToleranceBps??ya,m=null,f=null;if(u.amountOut!=null&&a.grossOut!=null)try{let h=BigInt(a.grossOut),g=BigInt(u.amountOut);h>0n&&(m=Number((g-h)*10000n/h),m<-l&&(f=`route moved ${(m/100).toFixed(2)}% against you since the comparison (tolerance ${(l/100).toFixed(2)}%). Re-compare before signing.`))}catch{}let b=[...f?[f]:[],...i.warnings||[],`Bridging is NOT atomic: the origin transaction succeeding does not mean funds arrived on chain ${o}. Expect ~${u.durationSeconds!=null?`${u.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.`),x({ok:!0,chosen:{source:s,wasWinner:s===i.best.source,netOut:a.netOut,grossOut:a.grossOut,gasUsd:a.gasUsd},artifactKind:"unsigned-transaction-sequence",fromChainId:Number(n),toChainId:Number(o),transactionCount:d.length,transactions:d,requiresApproval:u.requiresApproval??null,minOut:u.minOut??null,durationSeconds:u.durationSeconds??null,destination:d[0]?.to??null,unsigned:!0,signedBy:"user-wallet",driftBps:m,warnings:b,runnersUp:i.routes.filter(h=>h.source!==s).map(h=>({source:h.source,netOut:h.netOut,gasUsd:h.gasUsd})),comparison:{rankedOn:i.rankedOn,sourcesAnswered:i.sourcesAnswered,sourcesTried:i.sourcesTried,improvementBps:i.improvementBps},note:`UNSIGNED. ${d.length} transaction(s) on chain ${n}, crediting chain ${o}. Verify every destination address before signing.`},{provider:"router",kind:"best-bridge"})}var ba,ga,ya,He,Hn=E(()=>{je();T();ba=/^0x[0-9a-fA-F]{40}$/,ga=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),ya=100,He={relay:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:i},s)=>{let{relayPrepare:a}=await Promise.resolve().then(()=>(Fe(),$e)),c=await a({user:i,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},s);return{transactions:c.transactions||[],amountOut:c.quote?.details?.currencyOut?.amount??null,minOut:c.quote?.details?.currencyOut?.minimumAmount??null,durationSeconds:c.quote?.details?.timeEstimate??null}},lifi:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:i},s)=>{let{lifiPrepare:a}=await Promise.resolve().then(()=>(de(),st)),c=await a({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o,fromAddress:i},s);return{transactions:c.transaction?[c.transaction]:[],requiresApproval:c.requiresApproval??null,amountOut:c.quote?.estimate?.toAmount??null,minOut:c.quote?.estimate?.toAmountMin??null,durationSeconds:c.quote?.estimate?.executionDuration??null}}}});function Aa(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||va).replace(/\/$/,"")}async function Kn(e,t={}){if(!e)throw new Error("tokenAddress required");return v(`${Aa(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}var va,zn=E(()=>{L();va="https://api.dexscreener.com"});function Sa(e,t){return`0x${It.getAmountsOut}`+R(e)+R(64)+R(t.length)+t.map(ye).join("")}function xa(e){if(!e||e==="0x")return null;let t=e.slice(2);if(t.length<128)return null;let r=Number(BigInt(`0x${t.slice(64,128)}`));if(!Number.isFinite(r)||r<1||r>16)return null;let n=[];for(let o=0;o<r;o++){let i=128+o*64;if(t.length<i+64)return null;n.push(BigInt(`0x${t.slice(i,i+64)}`))}return n}function xt(e,t="router"){return(e?.venues||[]).find(n=>n.kind===t)?.address??null}function Ia(e,t){let r=Number(t);if(!Number.isFinite(r)||r<0)throw new Error("slippageBps must be a non-negative number");if(r>Ct)throw new Error(`slippageBps ${r} exceeds the ${Ct} bps ceiling. Block and requote or split the order -- do not widen the guard to force a fill.`);return BigInt(e)*BigInt(1e4-Math.floor(r))/10000n}function Gn(e){let{chainId:t,wrappedNative:r}=e;async function n(o,i,s,a){let c=await k(t,"eth_call",[{to:o,data:Sa(i,s)},"latest"],a);return xa(c?.result??c)}return{async quote({tokenIn:o,tokenOut:i,amountIn:s,path:a},c={}){let u=xt(c.scanner);if(!u)return{chainId:t,evidence:w.UNAVAILABLE,reason:"no verified router configured for this chain; quoting stays fail-closed rather than guessing a venue address"};let d=a||[o,i];if(d.some(l=>!/^0x[0-9a-fA-F]{40}$/.test(l||"")))throw new Error("quote requires valid 20-byte addresses");let p=await n(u,s,d,c);return p?{chainId:t,router:u,path:d,amountIn:String(s),amountOut:p[p.length-1].toString(),hops:d.length-1,evidence:w.LIVE,note:"exact-input quote at current reserves; not a guaranteed fill"}:{chainId:t,router:u,path:d,evidence:w.UNKNOWN,reason:"router returned no amounts -- no pool for this path, or the call reverted"}},async sellSimulation({token:o,amountIn:i,base:s},a={}){let c=xt(a.scanner),u=s||r;if(!c||!u)return{chainId:t,token:o,verdict:y.UNKNOWN,evidence:w.UNAVAILABLE,reason:c?"no wrappedNative configured for this chain, so no base asset to round-trip against":"no verified router configured for this chain"};let d=await n(c,i,[u,o],a);if(!d)return{chainId:t,token:o,verdict:y.FAIL,evidence:w.LIVE,leg:"buy",reason:"buy leg returned no amounts -- no route in"};let p=d[d.length-1];if(p===0n)return{chainId:t,token:o,verdict:y.FAIL,evidence:w.LIVE,leg:"buy",reason:"buy leg quotes zero output"};let l=await n(c,p,[o,u],a);if(!l)return{chainId:t,token:o,verdict:y.FAIL,evidence:w.LIVE,leg:"sell",bought:p.toString(),reason:"SELL LEG FAILED while the buy leg quoted fine. This is the honeypot signature: do not trade."};let m=l[l.length-1],f=Number(m*10000n/BigInt(i)),b=y.PASS,h="round trip completes with expected fee/impact loss";return f<5e3?(b=y.FAIL,h=`round trip returns only ${(f/100).toFixed(2)}% -- punitive tax or no real liquidity`):f<9e3&&(b=y.CAUTION,h=`round trip returns ${(f/100).toFixed(2)}% -- transfer tax or thin liquidity at this size`),{chainId:t,token:o,base:u,router:c,verdict:b,reason:h,amountIn:String(i),bought:p.toString(),returned:m.toString(),retentionBps:f,evidence:w.LIVE,note:"Quote-level round trip. It does not prove transfer hooks absent at execution time."}},async prepareUnsignedTx({tokenIn:o,tokenOut:i,amountIn:s,recipient:a,slippageBps:c=50,deadlineSeconds:u=900,path:d},p={}){let l=p.scanner,m=xt(l);if(!m)throw new Error(`chain ${t} has no verified router; preparing a swap stays fail-closed. Add a venue with recorded provenance first (see docs/adding-a-chain.md).`);if(!/^0x[0-9a-fA-F]{40}$/.test(a||""))throw new Error("prepareUnsignedTx requires a valid recipient address");let f=d||[o,i],b=await this.quote({tokenIn:o,tokenOut:i,amountIn:s,path:f},p);if(b.evidence!==w.LIVE)throw new Error(`cannot prepare without a live quote (${b.evidence}: ${b.reason??"no reason given"})`);let h=Ia(b.amountOut,c);if(h<=0n)throw new Error("computed minOut is zero -- refusing to prepare");let g=BigInt(Math.floor(Date.now()/1e3)+Number(u)),S=r&&f[0].toLowerCase()===r.toLowerCase()&&p.useNative,C=S?`0x${It.swapExactETHForTokens}`+R(h)+R(128)+ye(a)+R(g)+R(f.length)+f.map(ye).join(""):`0x${It.swapExactTokensForTokens}`+R(s)+R(h)+R(160)+ye(a)+R(g)+R(f.length)+f.map(ye).join("");return{unsigned:!0,signedBy:"user-wallet",chainId:t,tx:{to:m,data:C,value:S?`0x${BigInt(s).toString(16)}`:"0x0"},guard:{quotedOut:b.amountOut,minOut:h.toString(),slippageBps:c,maxSlippageBps:Ct,deadline:g.toString()},requires:S?[]:[{step:"approve",token:f[0],spender:m,amount:String(s)}],note:"UNSIGNED. Re-verify the guard against a fresh quote immediately before signing -- a quote-time minimum is not a minimum at broadcast time."}}}}var It,R,ye,Ct,Qn=E(()=>{te();z();It={getAmountsOut:"d06ca61f",swapExactTokensForTokens:"38ed1739",swapExactETHForTokens:"7ff36ab5"},R=e=>BigInt(e).toString(16).padStart(64,"0"),ye=e=>e.slice(2).toLowerCase().padStart(64,"0");Ct=100});function ka(e,t){let r=Number(t);if(!Number.isFinite(r)||r<0)throw new Error("slippageBps must be a non-negative number");if(r>_t)throw new Error(`slippageBps ${r} exceeds the ${_t} bps ceiling. Block and requote or split the order -- do not widen the guard to force a fill.`);return BigInt(e)*BigInt(1e4-Math.floor(r))/10000n}function kt(e,t){return(e?.venues||[]).find(r=>r.kind===t)?.address??null}function Xn(e){let{chainId:t,wrappedNative:r}=e;async function n({quoter:i,tokenIn:s,tokenOut:a,amountIn:c,fee:u},d){let p=`0x${Wn.quoteExactInputSingle}`+we(s)+we(a)+Q(c)+Q(u)+Q(0),l=await k(t,"eth_call",[{to:i,data:p},"latest"],d).catch(()=>null),m=l?.result??l;if(!m||m==="0x"||m.length<66)return null;let f=BigInt(`0x${m.slice(2,66)}`);return f>0n?f:null}async function o({quoter:i,tokenIn:s,tokenOut:a,amountIn:c},u){let d=[],p=null;for(let l of Ca){let m=await n({quoter:i,tokenIn:s,tokenOut:a,amountIn:c,fee:l},u);d.push({fee:l,amountOut:m?m.toString():null}),m&&(!p||m>p.amountOut)&&(p={fee:l,amountOut:m})}return{best:p,tried:d}}return{async quote({tokenIn:i,tokenOut:s,amountIn:a},c={}){let u=kt(c.scanner,"quoter");if(!u)return{chainId:t,evidence:w.UNAVAILABLE,reason:"no verified quoter configured for this chain; quoting stays fail-closed rather than guessing a venue address"};for(let l of[i,s])if(!Yn.test(l||""))throw new Error("quote requires valid 20-byte addresses");let{best:d,tried:p}=await o({quoter:u,tokenIn:i,tokenOut:s,amountIn:a},c);return d?{chainId:t,venue:"uniswap-v3",quoter:u,tokenIn:i,tokenOut:s,amountIn:String(a),amountOut:d.amountOut.toString(),fee:d.fee,triedFeeTiers:p,evidence:w.LIVE,note:"exact-input single-hop quote at current tick; not a guaranteed fill"}:{chainId:t,quoter:u,tokenIn:i,tokenOut:s,triedFeeTiers:p,evidence:w.UNKNOWN,reason:"no fee tier returned a quote -- no V3 pool for this pair, or no liquidity"}},async sellSimulation({token:i,amountIn:s,base:a},c={}){let u=kt(c.scanner,"quoter"),d=a||r;if(!u||!d)return{chainId:t,token:i,verdict:y.UNKNOWN,evidence:w.UNAVAILABLE,reason:u?"no wrappedNative configured, so there is no base asset to round-trip against":"no verified quoter configured for this chain"};let p=await o({quoter:u,tokenIn:d,tokenOut:i,amountIn:s},c);if(!p.best)return{chainId:t,token:i,verdict:y.FAIL,evidence:w.LIVE,leg:"buy",reason:"no V3 pool priced the buy leg on any fee tier"};let l=await o({quoter:u,tokenIn:i,tokenOut:d,amountIn:p.best.amountOut},c);if(!l.best)return{chainId:t,token:i,verdict:y.FAIL,evidence:w.LIVE,leg:"sell",bought:p.best.amountOut.toString(),reason:"SELL LEG FAILED while the buy leg quoted fine. This is the honeypot signature: do not trade."};let m=l.best.amountOut,f=Number(m*10000n/BigInt(s)),b=y.PASS,h="round trip completes with expected fee/impact loss";return f<5e3?(b=y.FAIL,h=`round trip returns only ${(f/100).toFixed(2)}% -- punitive tax or no real liquidity`):f<9e3&&(b=y.CAUTION,h=`round trip returns ${(f/100).toFixed(2)}% -- transfer tax or thin liquidity at this size`),{chainId:t,venue:"uniswap-v3",token:i,base:d,verdict:b,reason:h,amountIn:String(s),bought:p.best.amountOut.toString(),returned:m.toString(),retentionBps:f,buyFee:p.best.fee,sellFee:l.best.fee,evidence:w.LIVE,note:"Quote-level round trip. It does not prove transfer hooks absent at execution time."}},async prepareUnsignedTx({tokenIn:i,tokenOut:s,amountIn:a,recipient:c,slippageBps:u=50,fee:d},p={}){let l=kt(p.scanner,"router");if(!l)throw new Error(`chain ${t} has no verified V3 router; preparing a swap stays fail-closed. Add a venue with recorded provenance first (see docs/adding-a-chain.md).`);if(!Yn.test(c||""))throw new Error("prepareUnsignedTx requires a valid recipient address");let m=await this.quote({tokenIn:i,tokenOut:s,amountIn:a},p);if(m.evidence!==w.LIVE)throw new Error(`cannot prepare without a live quote (${m.evidence}: ${m.reason??"no reason given"})`);let f=d??m.fee,b=ka(m.amountOut,u);if(b<=0n)throw new Error("computed minOut is zero -- refusing to prepare");let h=`0x${Wn.exactInputSingle}`+we(i)+we(s)+Q(f)+we(c)+Q(a)+Q(b)+Q(0);return{unsigned:!0,signedBy:"user-wallet",chainId:t,venue:"uniswap-v3",tx:{to:l,data:h,value:"0x0"},guard:{quotedOut:m.amountOut,minOut:b.toString(),slippageBps:u,maxSlippageBps:_t,fee:f},requires:[{step:"approve",token:i,spender:l,amount:String(a)}],note:"UNSIGNED. Re-verify the guard against a fresh quote immediately before signing -- a quote-time minimum is not a minimum at broadcast time."}}}}var Ca,Wn,Q,we,Yn,_t,Jn=E(()=>{te();z();Ca=[100,500,3e3,1e4],Wn={quoteExactInputSingle:"c6a5026a",exactInputSingle:"04e45aaf"},Q=e=>BigInt(e).toString(16).padStart(64,"0"),we=e=>e.slice(2).toLowerCase().padStart(64,"0"),Yn=/^0x[0-9a-fA-F]{40}$/,_t=100});function Zn(e){if(!e||e==="0x")return null;try{return BigInt(e)}catch{return null}}function eo(e){if(!e||e==="0x")return null;let t=e.slice(2);if(t.length>=128){let n=Number(BigInt(`0x${t.slice(64,128)}`));if(n>0&&n<=256&&t.length>=128+n*2){let o=t.slice(128,128+n*2),i=Buffer.from(o,"hex").toString("utf8").replace(/\0+$/,"");if(i)return i}}return Buffer.from(t.slice(0,64),"hex").toString("utf8").replace(/\0+$/,"")||null}function _a(e){let{chainId:t}=e;async function r(n,o,i){return k(t,"eth_call",[{to:n,data:o},"latest"],i)}return{async blockNumber(n={}){let o=await Yr(t,n);return{chainId:t,blockNumber:o?.blockNumber??o,evidence:w.LIVE}},async nativeBalance(n,o={}){let i=await Xr(t,n,o);return{chainId:t,address:n,wei:i?.wei??i?.balance??null,symbol:e.nativeCurrency?.symbol??null,decimals:e.nativeCurrency?.decimals??18,evidence:w.LIVE}},async tokenBalance({token:n,owner:o},i={}){let s=await Jr({chainId:t,token:n,owner:o},i);return{chainId:t,token:n,owner:o,raw:s?.balance??s,evidence:w.LIVE}},async resolveToken(n,o={}){if(!/^0x[0-9a-fA-F]{40}$/.test(n||""))return{chainId:t,token:n,evidence:w.UNKNOWN,error:"resolveToken needs a 20-byte address; symbol lookup is a market-data concern"};let[i,s,a,c]=await Promise.all([r(n,Ke.decimals,o).catch(()=>null),r(n,Ke.symbol,o).catch(()=>null),r(n,Ke.name,o).catch(()=>null),r(n,Ke.totalSupply,o).catch(()=>null)]),u=Zn(i?.result??i),d=u!==null||s?.result||a?.result;return{chainId:t,address:n,decimals:u===null?null:Number(u),symbol:eo(s?.result??s),name:eo(a?.result??a),totalSupply:(Zn(c?.result??c)??null)?.toString()??null,evidence:d?w.LIVE:w.UNKNOWN,warning:d?void 0:"no ERC-20 metadata returned -- may not be a token contract"}},async resolvePools(n,o={}){let i=e.dexscreenerSlug;if(!i)return{chainId:t,token:n,pools:[],evidence:w.UNAVAILABLE,reason:"no dexscreenerSlug configured for this chain; pool discovery is unavailable rather than guessed"};let s=await Kn(n,o).catch(()=>null),c=(s?.pairs||s?.data?.pairs||[]).filter(u=>String(u.chainId).toLowerCase()===String(i).toLowerCase()).map(u=>({pair:u.pairAddress,dex:u.dexId,base:u.baseToken?.address,quote:u.quoteToken?.address,liquidityUsd:u.liquidity?.usd??null,priceUsd:u.priceUsd??null,volume24hUsd:u.volume?.h24??null,createdAt:u.pairCreatedAt??null})).sort((u,d)=>(d.liquidityUsd??0)-(u.liquidityUsd??0));return{chainId:t,token:n,pools:c,evidence:c.length?w.LIVE:w.UNKNOWN}},async scanBlocks({fromBlock:n,toBlock:o,address:i,topics:s,chunkSize:a=2e3}={},c={}){if(!Number.isInteger(n)||!Number.isInteger(o))throw new Error("scanBlocks requires integer fromBlock and toBlock");if(o<n)throw new Error("toBlock must be >= fromBlock");let u=[],d=[];for(let p=n;p<=o;p+=a){let l=Math.min(p+a-1,o);d.push([p,l])}for(let[p,l]of d){let m={fromBlock:`0x${p.toString(16)}`,toBlock:`0x${l.toString(16)}`};i&&(m.address=i),s&&(m.topics=s);let f=await k(t,"eth_getLogs",[m],c).catch(b=>({error:String(b?.message||b)}));if(f?.error)return{chainId:t,fromBlock:n,toBlock:o,logs:u,complete:!1,failedAt:[p,l],error:f.error,evidence:w.UNKNOWN};for(let b of f?.result??f??[])u.push(b)}return{chainId:t,fromBlock:n,toBlock:o,logs:u,complete:!0,chunks:d.length,evidence:w.LIVE}},async scoreRisk(n,o={}){let i=[],s=y.PASS,a=d=>{let p={[y.PASS]:0,[y.CAUTION]:1,[y.UNKNOWN]:2,[y.FAIL]:3};p[d]>p[s]&&(s=d)},c=await this.resolveToken(n,o);c.evidence!==w.LIVE?(i.push({check:"erc20-metadata",result:y.UNKNOWN,detail:c.warning}),a(y.UNKNOWN)):i.push({check:"erc20-metadata",result:y.PASS,detail:`${c.symbol} / ${c.decimals}d`});let u=await this.resolvePools(n,o);if(u.evidence===w.UNAVAILABLE)i.push({check:"liquidity",result:y.UNKNOWN,detail:u.reason}),a(y.UNKNOWN);else if(!u.pools.length)i.push({check:"liquidity",result:y.FAIL,detail:"no pool with liquidity found"}),a(y.FAIL);else{let d=u.pools[0],p=d.liquidityUsd??0;p<5e3?(i.push({check:"liquidity",result:y.CAUTION,detail:`top pool only $${p}`}),a(y.CAUTION)):i.push({check:"liquidity",result:y.PASS,detail:`$${p} on ${d.dex}`}),d.createdAt&&Date.now()-d.createdAt<24*3600*1e3&&(i.push({check:"age",result:y.CAUTION,detail:"pool under 24h old"}),a(y.CAUTION))}if(typeof this.sellSimulation=="function"){let d=await this.sellSimulation({token:n,amountIn:(10n**16n).toString()},o).catch(p=>({verdict:y.UNKNOWN,reason:String(p?.message||p)}));i.push({check:"sellability",result:d.verdict,detail:d.retentionBps!=null?`round trip returns ${(d.retentionBps/100).toFixed(2)}% -- ${d.reason}`:d.reason}),a(d.verdict)}else i.push({check:"sellability",result:y.UNKNOWN,detail:"no verified router on this chain, so a round-trip sell simulation cannot run. Treat as unproven -- a buy path is not an exit path."}),a(y.UNKNOWN);return{chainId:t,token:n,verdict:s,checks:i,note:"Structural checks only. UNKNOWN is not PASS. A token is not tradeable until a sell simulation succeeds."}}}}function Ot(e){let r={..._a(e)},n=new Set((e.venues||[]).map(i=>i.kind));e.venueKind==="uniswap-v3"&&n.has("quoter")&&n.has("router")?Object.assign(r,Xn({chainId:e.chainId,wrappedNative:e.wrappedNative})):e.venueKind==="uniswap-v2"&&n.has("router")&&Object.assign(r,Gn({chainId:e.chainId,wrappedNative:e.wrappedNative}));let o={};for(let[i,s]of Object.entries(r))o[i]=s.bind(r);return{key:e.key,chainId:e.chainId,name:e.name,rpcEnv:e.rpcEnv,nativeCurrency:e.nativeCurrency,explorer:e.explorer,venues:e.venues||[],capabilities:o}}var Ke,to=E(()=>{te();zn();z();Qn();Jn();Ke={decimals:"0x313ce567",symbol:"0x95d89b41",name:"0x06fdde03",totalSupply:"0x18160ddd",owner:"0x8da5cb5b"}});function ro(){return Rt.map(e=>Le(Ot(e)))}function no(e){return Le(Ot(e))}var Rt,oo=E(()=>{to();z();Rt=Object.freeze([{key:"ethereum",chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://etherscan.io",dexscreenerSlug:"ethereum",venueKind:"uniswap-v3",wrappedNative:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.71 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}}]},{key:"optimism",chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://optimistic.etherscan.io",dexscreenerSlug:"optimism",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1905.23 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}}]},{key:"bsc",chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],nativeCurrency:{symbol:"BNB",decimals:18},explorer:"https://bscscan.com",dexscreenerSlug:"bsc",venueKind:"uniswap-v3",wrappedNative:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",venues:[{kind:"quoter",address:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WBNB->USDC fee 500 quoted 413.86 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}},{kind:"router",address:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}}]},{key:"polygon",chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],nativeCurrency:{symbol:"POL",decimals:18},explorer:"https://polygonscan.com",dexscreenerSlug:"polygon",venueKind:"uniswap-v3",wrappedNative:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WMATIC->USDC fee 500 quoted 0.0720 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}}]},{key:"stable",chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],nativeCurrency:{symbol:"USDT0",decimals:18},venues:[]},{key:"hyperevm",chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],nativeCurrency:{symbol:"HYPE",decimals:18},dexscreenerSlug:"hyperevm",venues:[]},{key:"abstract",chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},venues:[]},{key:"robinhood",chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC","ROBINHOOD_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},dexscreenerSlug:"robinhood",venueKind:"uniswap-v3",wrappedNative:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",venues:[{kind:"quoter",address:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDG fee 100 quoted 1866.58 USDG, and USDG->CASHCAT fee 10000 quoted a live amount). A contract that correctly prices known pairs IS a working V3 quoter",source:"live eth_call against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"router",address:"0xcaf681a66d020601342297493863e78c959e5cb2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode (24497 bytes) on this chain and the paired quoter at the same deployment passed a live functional quote",source:"live eth_getCode against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"factory",address:"0x1f7d7550b1b028f7571e69a784071f0205fd2efa",label:"Uniswap V3 Factory",verified:{method:"eth_getCode returned real bytecode (24535 bytes) and a PoolCreated log scan over this factory returned 76 pools in ~9000 recent blocks",source:"live eth_getLogs against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}}]},{key:"base",chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://basescan.org",dexscreenerSlug:"base",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",venues:[{kind:"quoter",address:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",label:"Uniswap V3 QuoterV2 (Base)",verified:{method:"functional probe: quoteExactInputSingle returned WETH->USDC at fee 500 = 1908.44 USDC, a live sane price. The canonical mainnet quoter address also has bytecode on Base but does NOT price this pair, which is exactly the false positive a codesize-only check accepts",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router",address:"0x2626664c2603336E57B271c5C0b26F421741e481",label:"Uniswap V3 SwapRouter02 (Base)",verified:{method:"eth_getCode returned real bytecode and the paired Base quoter passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router-v2",address:"0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",label:"Uniswap V2 Router02 (Base)",verified:{method:"eth_getCode returned 17891 bytes; live getAmountsOut on WETH->USDC round-tripped to 98.75% (2x0.30% fee + impact)",source:"https://docs.uniswap.org/contracts/v2/reference/smart-contracts/v2-deployments",date:"2026-07-30",chainId:8453}}]},{key:"arbitrum",chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://arbiscan.io",dexscreenerSlug:"arbitrum",venueKind:"uniswap-v3",wrappedNative:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.72 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}}]},{key:"avalanche",chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],nativeCurrency:{symbol:"AVAX",decimals:18},explorer:"https://snowtrace.io",dexscreenerSlug:"avalanche",venueKind:"uniswap-v3",wrappedNative:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",venues:[{kind:"quoter",address:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WAVAX->USDC fee 500 quoted 6.48 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}},{kind:"router",address:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}}]}])});var ze={};O(ze,{CHAIN_CONFIGS:()=>Rt,EVIDENCE:()=>w,RISK:()=>y,SCANNER_CAPABILITIES:()=>re,__clearScanners:()=>ji,createScanner:()=>fn,getScanner:()=>Fi,listScanners:()=>Mi,registerBuiltinScanners:()=>ro,registerCustomChain:()=>no,registerScanner:()=>Le,scannerCoverage:()=>Vi,validateScanner:()=>mn});var Ge=E(()=>{z();oo()});import io from"node:fs";import ie from"node:process";import{fileURLToPath as Oa}from"node:url";import{homedir as Dt}from"node:os";import{join as Ut}from"node:path";var Pt=Ut(Dt(),".config","oracle"),$a=Ut(Dt(),".config","mad-desk");function se(e,t,r=""){let n=process.env[e];if(n!=null&&String(n).trim()!=="")return n;let o=t?process.env[t]:void 0;return o!=null&&String(o).trim()!==""?o:r}import ce from"node:fs";import ue from"node:path";var $t=/^0x[0-9a-fA-F]{40}$/,lo=new Set(["privatekey","private_key","secret","seed","mnemonic","passphrase","signature","keystore"]),po=["privatekey","privkey","secretkey","secret","seedphrase","seed","mnemonic","passphrase","password","keystore","keymaterial","signature","wif","xprv","xpriv","apikey","bearer","credential"],mo=[/\b[5KL][1-9A-HJ-NP-Za-km-z]{50,51}\b/,/\bxprv[0-9A-Za-z]{50,}\b/,/\b(?:[a-z]{3,8}\s+){11,}[a-z]{3,8}\b/i],fo=/^\s*(?:0x)?[0-9a-fA-F]{64}\s*$/;function ho(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function bo(e,t){let r=ho(e);if(lo.has(String(e).toLowerCase())||po.some(n=>r.includes(n)))throw new Error(`address-book: ${t} is forbidden; the book stores labels, never key material`)}function go(e,t){if(typeof e=="string"&&(mo.some(r=>r.test(e))||fo.test(e)))throw new Error(`address-book: ${t} looks like key material; the book stores labels, never key material`)}function Ft(){let e=se("ORACLE_ADDRESS_BOOK","MAD_ADDRESS_BOOK","");if(e)return ue.resolve(e);let t=se("ORACLE_CONFIG_DIR","MAD_CONFIG_DIR",Pt);return ue.join(t,"address-book.json")}function Qe(e,t="field"){if(Array.isArray(e)){e.forEach((r,n)=>Qe(r,`${t}[${n}]`));return}if(!e||typeof e!="object"){go(e,t);return}for(let[r,n]of Object.entries(e))bo(r,r),Qe(n,r)}function We(e){let t=String(e||"").trim();if(!$t.test(t))throw new Error("address-book: address must be 0x + 40 hex characters");return t.toLowerCase()}function W(e,t){return e==null||e===""?null:String(e).slice(0,t)}function qt(){return{version:1,updatedAt:null,entries:[]}}function Mt(e){return{address:String(e.address).toLowerCase(),label:W(e.label,80)||"unknown",who:W(e.who,120),role:W(e.role,40),chainIds:Array.isArray(e.chainIds)?e.chainIds.map(Number).filter(Number.isFinite):[],notes:W(e.notes,500),source:W(e.source,80),firstSeenAt:e.firstSeenAt||null,lastSeenAt:e.lastSeenAt||null}}function ve(){try{let e=JSON.parse(ce.readFileSync(Ft(),"utf8"));if(!e||typeof e!="object")return qt();let t=Array.isArray(e.entries)?e.entries:[];return{version:1,updatedAt:e.updatedAt||null,entries:t.filter(r=>r&&typeof r=="object"&&$t.test(String(r.address||""))).map(Mt)}}catch{return qt()}}function jt(e){let t=Ft();ce.mkdirSync(ue.dirname(t),{recursive:!0,mode:448});let r={...e,version:1,updatedAt:new Date().toISOString()},n=ue.join(ue.dirname(t),`.address-book.${process.pid}.tmp`);ce.writeFileSync(n,`${JSON.stringify(r,null,2)}
6
- `,{mode:384}),ce.renameSync(n,t);try{ce.chmodSync(t,384)}catch{}return r}function Vt(e={}){let t=ve(),r=t.entries;if(e.role&&(r=r.filter(n=>n.role===String(e.role))),e.who){let n=String(e.who).toLowerCase();r=r.filter(o=>(o.who||"").toLowerCase().includes(n)||(o.label||"").toLowerCase().includes(n))}if(e.q){let n=String(e.q).toLowerCase();r=r.filter(o=>o.address.includes(n)||(o.label||"").toLowerCase().includes(n)||(o.who||"").toLowerCase().includes(n)||(o.notes||"").toLowerCase().includes(n))}return{updatedAt:t.updatedAt,count:r.length,entries:r}}function Ht(e){let t=We(e),r=ve().entries.filter(n=>n.address===t);return{address:t,found:r.length>0,entries:r}}function Kt(e={}){Qe(e);let t=We(e.address),r=W(e.label??e.role,80)||"wallet",n=new Date().toISOString(),o=ve(),i=o.entries.findIndex(u=>u.address===t&&u.label===r),s=Mt({address:t,label:r,who:e.who,role:e.role,chainIds:e.chainIds,notes:e.notes,source:e.source||"agent",firstSeenAt:i>=0&&o.entries[i].firstSeenAt||n,lastSeenAt:n});i>=0?o.entries[i]=s:o.entries.push(s);let a=u=>u==="agent"?0:u==="owner"?1:2;o.entries.sort((u,d)=>a(u.role)-a(d.role)||u.label.localeCompare(d.label)||u.address.localeCompare(d.address));let c=jt(o);return{ok:!0,entry:s,count:c.entries.length}}function zt(e,t=null){let r=We(e),n=ve(),o=n.entries.length;return n.entries=n.entries.filter(i=>i.address!==r?!0:t==null?!1:i.label!==String(t)),jt(n),{ok:!0,removed:o-n.entries.length,count:n.entries.length}}var Nt=se("ORACLE_DATA_URL","MAD_DESK_URL","http://127.0.0.1:8787").replace(/\/$/,""),Ra=[{name:"data_catalog",description:"List every read-plane provider the desk exposes (id, venue, chainIds, ops). Use this to discover what public APIs are available before calling data_call. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"data_health",description:"Health of every read-plane provider (which public APIs are up / configured). Read-only.",inputSchema:{type:"object",properties:{}}},{name:"data_call",description:"Generic escape hatch: call any provider/op from the catalog. provider+op are required; args is a free-form object matching that op. Read-only. Use data_catalog first to see valid provider/op pairs.",inputSchema:{type:"object",required:["provider","op"],properties:{provider:{type:"string",description:"provider id, e.g. defillama, dexscreener, lifi, evm-rpc"},op:{type:"string",description:"op name for that provider, e.g. protocols, search, quote"},args:{type:"object",description:"op arguments (free-form)"}}}},{name:"llama_protocols",description:"DeFiLlama: full protocol list with TVL, chain(s), category, 1d/7d change. The primary cross-chain protocol scanner. Read-only. Large payload \u2014 filter client-side.",inputSchema:{type:"object",properties:{}}},{name:"llama_prices",description:"DeFiLlama current prices for coins keyed 'chain:address' or 'coingecko:id' (comma-joined or array). Read-only.",inputSchema:{type:"object",required:["coins"],properties:{coins:{type:"string",description:"comma-joined coin keys, e.g. 'ethereum:0x...,coingecko:bitcoin'"}}}},{name:"dex_search",description:"DexScreener search across all chains by symbol/name/address. Returns matching pairs with price, liquidity, volume, chain. Read-only.",inputSchema:{type:"object",required:["q"],properties:{q:{type:"string",description:"query: symbol, name, or token address"}}}},{name:"dex_token",description:"DexScreener pairs for a specific token address (any chain). Price, liquidity, volume, pair addresses. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"lifi_quote",description:"LI.FI cross-chain / DEX aggregator quote (no key). Best route + expected out for a swap or bridge. Read-only.",inputSchema:{type:"object",required:["fromChain","toChain","fromToken","toToken","fromAmount"],properties:{fromChain:{type:"number"},toChain:{type:"number"},fromToken:{type:"string"},toToken:{type:"string"},fromAmount:{type:"string",description:"raw integer amount (wei-scale)"},fromAddress:{type:"string",description:"optional; defaults to operator wallet"}}}},{name:"portfolio_balance",description:"Read-only balance aggregation across every configured EVM chain plus Solana, Bitcoin, and Hyperliquid. Reports native assets, supported token/collectible reads, failed or missing providers, unverified assets, timestamps, and known priced value without pretending it is a complete total. Public addresses only; never signs or broadcasts.",inputSchema:{type:"object",properties:{addresses:{type:"object",description:"Optional public wallet addresses by family. Omit configured families to use ORACLE_*_ADDRESS defaults.",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},evmChainIds:{type:"array",items:{type:"number"},description:"Optional EVM chain subset. Default is every configured EVM chain."},includeTokens:{type:"boolean",description:"Include supported token reads. Default true."},includeCollectibles:{type:"boolean",description:"Include supported collectible reads. Default true."},includePrices:{type:"boolean",description:"Fetch current DeFiLlama native prices. Default true."}}}},{name:"portfolio_snapshot",description:"Query the current multichain balance and NFT inventory, then append one compact profile-local observation for historical tracking. Stores public-address fingerprint, coverage, breakdown, and known priced value only; no keys, signatures, executable payloads, or raw NFT metadata. Returns the live balance, NFT result, and recorded snapshot.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},evmChainIds:{type:"array",items:{type:"number"}},includeTokens:{type:"boolean"},includeCollectibles:{type:"boolean"},includePrices:{type:"boolean"},includeNfts:{type:"boolean",description:"Include provider-estimated NFT value. Default true."}}}},{name:"portfolio_history",description:"Read profile-local portfolio observations in a time range. Unknown or unavailable values remain null and are never converted to zero. Defaults to the configured public-address portfolio fingerprint.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},portfolioId:{type:"string"},allPortfolios:{type:"boolean",description:"Return observations for every public-address fingerprint in this profile."},since:{type:"string",description:"Inclusive ISO 8601 lower bound."},until:{type:"string",description:"Inclusive ISO 8601 upper bound."},limit:{type:"number",description:"1-1000, default 100."},order:{type:"string",enum:["asc","desc"]}}}},{name:"portfolio_value_graph",description:"Render a static SVG line graph from profile-local portfolio snapshots. Plots known priced value only, labels incomplete coverage, includes provider-estimated NFT values when recorded, and omits unavailable observations instead of plotting fake zeroes.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},portfolioId:{type:"string"},allPortfolios:{type:"boolean"},since:{type:"string"},until:{type:"string"},limit:{type:"number",description:"Historical observations to consider, max 1000."},maxPoints:{type:"number",description:"Rendered point cap, 2-500, default 200."}}}},{name:"nft_inventory",description:"Read all discoverable NFTs for configured EVM, Solana, and Bitcoin addresses. Returns normalized assets, image URLs, estimated values, per-chain partial failures, flagged/NSFW items separated from visible items, listing coverage, and explicit unsupported chains. Read-only.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"}}},chains:{type:"array",items:{type:"string"},description:"Optional chain slug subset."},pageSize:{type:"number",description:"OpenSea items per page, max 200."},maxPages:{type:"number",description:"Maximum pages per chain, max 25."},bitcoinLimit:{type:"number"},includePnl:{type:"boolean",description:"Include OpenSea-indexed account PnL when available. Default true."},costBasis:{type:"object",description:"Optional user-supplied assetKey -> {costUsd,feesUsd,acquiredAt,source}. Missing basis stays unavailable, never zero."}}}},{name:"nft_gallery",description:"Generate one static NFT contact-sheet image page from wallet inventory or supplied normalized items. External metadata is never rendered as HTML; only allowlisted JPEG/PNG/WebP bytes are embedded and unsafe or missing media becomes a placeholder.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"}}},chains:{type:"array",items:{type:"string"}},items:{type:"array",items:{type:"object"},description:"Optional normalized inventory items. Omit to scan configured wallets."},page:{type:"number",description:"1-based gallery page."},pageSize:{type:"number",description:"1-12 items per page."}}}},{name:"nft_pnl",description:"NFT PnL with explicit methodology. Returns OpenSea-indexed account-level PnL where available plus per-item unrealized estimates only when both user-supplied acquisition cost and provider estimated current value exist. Missing history is unavailable, never zero.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"}}},chains:{type:"array",items:{type:"string"}},costBasis:{type:"object"}}}},{name:"nft_prepare_list",description:"Prepare an NFT listing for OpenSea EVM, Magic Eden Solana, or Satflow Bitcoin after explicit user review. Requires userConfirmed=true plus asset, marketplace, price, currency where applicable, and future expiry. Magic Eden Solana also requires confirmation exactly: list <tokenMint> on magiceden-sol for <priceSol> SOL until <expiry>. Returns approval/signing actions, an unsigned Solana transaction, or an unsigned Bitcoin PSBT. Never signs, submits, or broadcasts.",inputSchema:{type:"object",required:["marketplace","userConfirmed"],properties:{marketplace:{type:"string",enum:["opensea","magiceden","magiceden-sol","satflow"]},userConfirmed:{type:"boolean"},chain:{type:"string"},seller:{type:"string"},contract:{type:"string"},tokenId:{type:"string"},quantity:{type:"number"},priceAmount:{type:"string"},currency:{type:"string"},endTime:{type:"string"},useCreatorFee:{type:"boolean"},taker:{type:"string"},tokenMint:{type:"string"},tokenATA:{type:"string"},auctionHouse:{type:"string"},priceSol:{type:"string"},expiry:{description:"Future ISO 8601 timestamp or Unix seconds. Magic Eden Solana listings require finite future expiry; no-expiry is refused."},confirmation:{type:"string",description:"Required for Magic Eden Solana listings. Exact phrase: list <tokenMint> on magiceden-sol for <priceSol> SOL until <expiry>."},inscriptionId:{type:"string"},runesOutput:{type:"string"},ordAddress:{type:"string"},receiveAddress:{type:"string"},priceSats:{type:"string"},tapKey:{type:"string"},collectionSlug:{type:"string"}}}},{name:"rpc_balance",description:"Native token balance of an address on a chain via public RPC. Read-only. Omit address to read the operator wallet.",inputSchema:{type:"object",required:["chainId"],properties:{chainId:{type:"number"},address:{type:"string"}}}},{name:"rpc_block",description:"Latest block number on a chain via public RPC. Read-only.",inputSchema:{type:"object",required:["chainId"],properties:{chainId:{type:"number"}}}},{name:"solana_balance",description:"Solana mainnet SOL balance for a base58 public key. Read-only; no signing or broadcast.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},commitment:{type:"string"}}}},{name:"solana_token_accounts",description:"Solana SPL token accounts for an owner, optionally filtered by mint. Read-only.",inputSchema:{type:"object",required:["owner"],properties:{owner:{type:"string"},mint:{type:"string"},commitment:{type:"string"}}}},{name:"solana_simulate",description:"Simulate a base64 Solana transaction through RPC. Read-only; never signs or broadcasts.",inputSchema:{type:"object",required:["transaction"],properties:{transaction:{type:"string"},sigVerify:{type:"boolean"},replaceRecentBlockhash:{type:"boolean"}}}},{name:"jupiter_venues",description:"Jupiter Solana venue map, optionally verified on-chain against executable BPF loader ownership. Read-only.",inputSchema:{type:"object",properties:{verify:{type:"boolean"},rpc:{type:"string"}}}},{name:"jupiter_quote",description:"Jupiter Solana Swap API quote with a hard <=100 bps slippage cap. Read-only.",inputSchema:{type:"object",required:["inputMint","outputMint","amount"],properties:{inputMint:{type:"string"},outputMint:{type:"string"},amount:{type:"string"},slippageBps:{type:"number"}}}},{name:"jupiter_prepare",description:"Prepare an unsigned Jupiter swap transaction for the user's Solana wallet to sign. No local signer, no broadcast.",inputSchema:{type:"object",required:["userPublicKey"],properties:{userPublicKey:{type:"string"},quoteResponse:{type:"object"},inputMint:{type:"string"},outputMint:{type:"string"},amount:{type:"string"},slippageBps:{type:"number"}}}},{name:"btc_health",description:"Bitcoin L1 Esplora health + tip height (mempool.space by default). No Core RPC, no keys. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"btc_fees",description:"Recommended Bitcoin fee rates (sats/vB). Read-only.",inputSchema:{type:"object",properties:{}}},{name:"btc_balance",description:"Bitcoin address balance in sats via Esplora. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string",description:"bc1\u2026/1\u2026/3\u2026 address"}}}},{name:"btc_utxos",description:"UTXOs for a Bitcoin address via Esplora. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"btc_tx",description:"Lookup a Bitcoin transaction by txid via Esplora. Read-only.",inputSchema:{type:"object",required:["txid"],properties:{txid:{type:"string"}}}},{name:"btc_meta_health",description:"Ordinals/runes indexer health. Reports whether BTC_META_API_URL / vendor API keys are configured. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"btc_rune_balance",description:"Rune balances for a Bitcoin address (requires configured indexer + optional API key). Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"btc_inscriptions",description:"Inscriptions controlled by an address. REQUIRES a keyed indexer (ordinals.com has no address index). Returns unknownNotEmpty:true when unconfigured \u2014 that means UNKNOWN, never 'wallet holds none'. Protect these UTXOs from fee spends.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},limit:{type:"number"}}}},{name:"btc_inscription_info",description:"Inscription metadata by inscription id (content type/length, height, sat, fee). KEYLESS via ordinals.com recursive. Read-only.",inputSchema:{type:"object",required:["inscriptionId"],properties:{inscriptionId:{type:"string",description:"<64-hex-txid>i<index>"}}}},{name:"btc_inscription_children",description:"Child inscriptions of a parent (collections). KEYLESS via ordinals.com recursive. Read-only.",inputSchema:{type:"object",required:["inscriptionId"],properties:{inscriptionId:{type:"string",description:"<64-hex-txid>i<index>"},page:{type:"number"}}}},{name:"btc_ord_block_info",description:"Ord node block info / indexer tip. KEYLESS. Use to confirm the ordinals indexer is at the same tip as Esplora before trusting metaprotocol reads.",inputSchema:{type:"object",properties:{height:{type:"number",description:"omit for current tip"}}}},{name:"satflow_health",description:"Satflow marketplace health (primary BTC ordinals/runes market after Magic Eden BTC sunset). Needs SATFLOW_API_KEY. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"satflow_floors",description:"Satflow collection floor prices. type=ordinals|runes. Read-only.",inputSchema:{type:"object",properties:{type:{type:"string",description:"ordinals or runes"},ids:{type:"string",description:"optional comma-separated collection ids"}}}},{name:"satflow_wallet",description:"Satflow wallet contents (ordinals/runes) for an address. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},type:{type:"string"},limit:{type:"number"}}}},{name:"satflow_item",description:"Satflow item detail for an inscription id (listing + bids + meta). Read-only.",inputSchema:{type:"object",required:["inscriptionId"],properties:{inscriptionId:{type:"string"}}}},{name:"satflow_floor_listings",description:"Satflow floor listings for collection id(s). Read-only.",inputSchema:{type:"object",required:["collectionIds"],properties:{collectionIds:{type:"string"},limit:{type:"number"}}}},{name:"scanner_coverage",description:"Which chains the on-chain scanner supports and which capabilities each one has (blockNumber, nativeBalance, tokenBalance, resolveToken, resolvePools, scanBlocks, scoreRisk, quote, sellSimulation, prepareUnsignedTx). Read-only.",inputSchema:{type:"object",properties:{}}},{name:"scan_token",description:"Resolve a token on an EVM chain: metadata, its pools, and a risk score. Works on chains no indexer covers because it reads the chain directly. Read-only.",inputSchema:{type:"object",properties:{chainId:{type:"number",description:"EVM chain id, e.g. 4663 for Robinhood Chain"},token:{type:"string",description:"token contract address"}},required:["chainId","token"]}},{name:"wallet_balances",description:"Native balance for an address on an EVM chain, plus one token balance when a token address is supplied. Read-only; never signs.",inputSchema:{type:"object",properties:{chainId:{type:"number"},address:{type:"string",description:"wallet address to inspect"},token:{type:"string",description:"optional token contract for a token balance"}},required:["chainId","address"]}},{name:"address_book_remember",description:"Remember a wallet address with a label. Call this whenever someone states their address or an agent/counterparty wallet is discovered, so it survives the conversation. Stores labels only \u2014 never private keys, seeds, or passphrases.",inputSchema:{type:"object",required:["address","label"],properties:{address:{type:"string",description:"0x address"},label:{type:"string",description:"short name, e.g. research-agent"},who:{type:"string",description:"person or entity the wallet belongs to"},role:{type:"string",description:"agent | owner | person | counterparty | venue"},chainIds:{type:"array",items:{type:"number"}},notes:{type:"string"}}}},{name:"address_book_list",description:"List remembered wallets (owner, agent, people, counterparties). Read-only. Check this before sending or bridging to a person.",inputSchema:{type:"object",properties:{q:{type:"string",description:"search across label, who, address, notes"},role:{type:"string"},who:{type:"string"}}}},{name:"address_book_lookup",description:"Look up one 0x address in the durable address book. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"address_book_forget",description:"Remove a remembered address, optionally only one label for it.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},label:{type:"string"}}}},{name:"rfq_quote",description:"Create a cross-chain RFQ intent and fan it out to reviewed solver or venue sources. Returns firm quote objects with intentHash, firmQuoteHash, expiry, min receive, and unsigned executable artifacts. Never signs or broadcasts.",inputSchema:{type:"object",required:["fromChainId","toChainId","sellToken","buyToken","sellAmount","receiver","deadlineMs"],properties:{fromChainId:{type:"number"},toChainId:{type:"number"},sellToken:{type:"string"},buyToken:{type:"string"},sellAmount:{type:"string"},receiver:{type:"string"},deadlineMs:{type:"number"},minBuyAmount:{type:"string"},allowedSources:{type:"array",items:{type:"string"}},allowedRouters:{type:"array",items:{type:"string"}},slippageBps:{type:"number"},decimalsIn:{type:"number"},decimalsOut:{type:"number"}}}},{name:"best_swap_route",description:"Compare swap routes across every available aggregator and rank by NET output (after gas and fees), not headline quote. Returns the winner plus all runners-up so the ranking can be checked rather than trusted.",inputSchema:{type:"object",properties:{chainId:{type:"number",description:"EVM chain id, e.g. 8453 for Base"},tokenIn:{type:"string",description:"sell token address"},tokenOut:{type:"string",description:"buy token address"},amountIn:{type:"string",description:"raw units of tokenIn (wei-scale)"},taker:{type:"string",description:"address used for quoting only; nothing is signed"},decimalsIn:{type:"number"},decimalsOut:{type:"number"}},required:["chainId","tokenIn","tokenOut","amountIn"]}},{name:"best_bridge_route",description:"Compare cross-chain bridge routes and rank by NET output. Also reports each route's expected duration, which is NOT folded into the score -- a route that saves $2 but takes 30 minutes is a trade-off for the caller to make.",inputSchema:{type:"object",properties:{fromChainId:{type:"number"},toChainId:{type:"number"},tokenIn:{type:"string",description:"token on the origin chain"},tokenOut:{type:"string",description:"token on the destination chain"},amountIn:{type:"string",description:"raw units of tokenIn"},taker:{type:"string",description:"address used for quoting only"},decimalsOut:{type:"number"}},required:["fromChainId","toChainId","tokenIn","tokenOut","amountIn"]}},{name:"prepare_best_route",description:"Compare routes, then build the SIGNABLE artifact for the winner. Returns an unsigned transaction (LI.FI/ParaSwap/0x) or EIP-712 typed data for an off-chain order (CoW) -- the artifactKind field says which, and they require different wallet actions. Re-quotes before preparing and reports drift against the comparison. Never signs or broadcasts.",inputSchema:{type:"object",properties:{chainId:{type:"number"},tokenIn:{type:"string"},tokenOut:{type:"string"},amountIn:{type:"string",description:"raw units of tokenIn"},taker:{type:"string",description:"the REAL wallet that will sign. Placeholder/burn addresses are rejected: quoting is anonymous, preparing is not."},decimalsIn:{type:"number"},decimalsOut:{type:"number"},source:{type:"string",description:"force a specific source instead of the winner (flagged in the result)"},driftToleranceBps:{type:"number",description:"default 100"}},required:["chainId","tokenIn","tokenOut","amountIn","taker"]}},{name:"prepare_best_bridge_route",description:"Compare cross-chain bridge routes, then build the signable transaction sequence for the winner. Returns a LIST of unsigned transactions -- some routes need an approval and a deposit signed in order, and signing only the first leaves funds approved but not bridged. Reports the destination chain and expected credit time. Bridging is not atomic. Never signs or broadcasts.",inputSchema:{type:"object",properties:{fromChainId:{type:"number"},toChainId:{type:"number"},tokenIn:{type:"string",description:"token on the origin chain"},tokenOut:{type:"string",description:"token on the destination chain"},amountIn:{type:"string",description:"raw units of tokenIn"},taker:{type:"string",description:"the REAL wallet that will sign; placeholders rejected"},source:{type:"string",description:"force a source instead of the winner"},driftToleranceBps:{type:"number",description:"default 100"}},required:["fromChainId","toChainId","tokenIn","tokenOut","amountIn","taker"]}}],ao=String(ie.env.ORACLE_DEFAULT_ADDRESS||ie.env.MAD_OPERATOR_ADDRESS||"").trim(),Na={llama_protocols:()=>({provider:"defillama",op:"protocols",args:{}}),llama_prices:e=>({provider:"defillama",op:"prices",args:{coins:e.coins}}),dex_search:e=>({provider:"dexscreener",op:"search",args:{q:e.q}}),dex_token:e=>({provider:"dexscreener",op:"token",args:{address:e.address}}),lifi_quote:e=>({provider:"lifi",op:"quote",args:{fromChain:e.fromChain,toChain:e.toChain,fromToken:e.fromToken,toToken:e.toToken,fromAmount:e.fromAmount,fromAddress:e.fromAddress||ao||void 0}}),portfolio_balance:e=>({provider:"portfolio",op:"balances",args:{addresses:e.addresses,evmChainIds:e.evmChainIds,includeTokens:e.includeTokens,includeCollectibles:e.includeCollectibles,includePrices:e.includePrices}}),portfolio_snapshot:e=>({provider:"portfolio",op:"snapshot",args:e}),portfolio_history:e=>({provider:"portfolio",op:"history",args:e}),portfolio_value_graph:e=>({provider:"portfolio",op:"valueGraph",args:e}),nft_inventory:e=>({provider:"nft-portfolio",op:"inventory",args:e}),nft_gallery:e=>({provider:"nft-portfolio",op:"gallery",args:e}),nft_pnl:e=>({provider:"nft-portfolio",op:"pnl",args:e}),nft_prepare_list:e=>({provider:"nft-portfolio",op:"prepareList",args:e}),rpc_balance:e=>{let t=e.address||ao;if(!t)throw new Error("address required (set ORACLE_DEFAULT_ADDRESS to supply a default)");return{provider:"evm-rpc",op:"getBalance",args:{chainId:e.chainId,address:t}}},rpc_block:e=>({provider:"evm-rpc",op:"blockNumber",args:{chainId:e.chainId}}),solana_balance:e=>({provider:"solana-rpc",op:"getBalance",args:{address:e.address,commitment:e.commitment}}),solana_token_accounts:e=>({provider:"solana-rpc",op:"tokenAccounts",args:{owner:e.owner,mint:e.mint,commitment:e.commitment}}),solana_simulate:e=>({provider:"solana-rpc",op:"simulate",args:{transaction:e.transaction,sigVerify:e.sigVerify,replaceRecentBlockhash:e.replaceRecentBlockhash}}),jupiter_venues:e=>({provider:"jupiter",op:"venues",args:{verify:e.verify,rpc:e.rpc}}),jupiter_quote:e=>({provider:"jupiter",op:"quote",args:{inputMint:e.inputMint,outputMint:e.outputMint,amount:e.amount,slippageBps:e.slippageBps}}),jupiter_prepare:e=>({provider:"jupiter",op:"prepare",args:{userPublicKey:e.userPublicKey,quoteResponse:e.quoteResponse,inputMint:e.inputMint,outputMint:e.outputMint,amount:e.amount,slippageBps:e.slippageBps}}),btc_health:()=>({provider:"bitcoin-esplora",op:"health",args:{}}),btc_fees:()=>({provider:"bitcoin-esplora",op:"fees",args:{}}),btc_balance:e=>({provider:"bitcoin-esplora",op:"address",args:{address:e.address}}),btc_utxos:e=>({provider:"bitcoin-esplora",op:"utxos",args:{address:e.address}}),btc_tx:e=>({provider:"bitcoin-esplora",op:"tx",args:{txid:e.txid}}),btc_meta_health:()=>({provider:"bitcoin-meta",op:"health",args:{}}),btc_rune_balance:e=>({provider:"bitcoin-meta",op:"runeBalances",args:{address:e.address}}),btc_inscriptions:e=>({provider:"bitcoin-meta",op:"inscriptions",args:{address:e.address,limit:e.limit}}),btc_inscription_info:e=>({provider:"bitcoin-meta",op:"inscriptionInfo",args:{inscriptionId:e.inscriptionId}}),btc_inscription_children:e=>({provider:"bitcoin-meta",op:"inscriptionChildren",args:{inscriptionId:e.inscriptionId,page:e.page}}),btc_ord_block_info:e=>({provider:"bitcoin-meta",op:"ordBlockInfo",args:{height:e.height}}),satflow_health:()=>({provider:"satflow",op:"health",args:{}}),satflow_floors:e=>({provider:"satflow",op:"collectionFloors",args:{type:e.type,ids:e.ids}}),satflow_wallet:e=>({provider:"satflow",op:"walletContents",args:{address:e.address,type:e.type,limit:e.limit}}),satflow_item:e=>({provider:"satflow",op:"item",args:{inscriptionId:e.inscriptionId||e.id}}),satflow_floor_listings:e=>({provider:"satflow",op:"floorListings",args:{collectionIds:e.collectionIds||e.ids,limit:e.limit}})};function oe(e){ie.stdout.write(`${JSON.stringify(e)}
7
- `)}function co(e,t,r){oe({jsonrpc:"2.0",id:e,error:{code:t,message:r}})}async function Tt(e,{method:t="GET",body:r}={}){let n=await fetch(e,{method:t,headers:{"content-type":"application/json"},body:r?JSON.stringify(r):void 0}),o=await n.json().catch(()=>({}));if(!n.ok)throw new Error(o.error||`HTTP ${n.status}`);return o}async function so(e,t,r={}){return Tt(`${Nt}/data/call`,{method:"POST",body:{provider:e,op:t,args:r}})}async function Ta(e,t={}){if(e==="rfq_quote"){let{normalizeRfqIntent:n}=await Promise.resolve().then(()=>(Ze(),ir)),{requestRfqQuotes:o}=await Promise.resolve().then(()=>(pn(),dn)),i=n({...t,sources:t.sources??t.allowedSources});return o(i,{decimalsIn:t.decimalsIn,decimalsOut:t.decimalsOut})}if(e==="best_swap_route"||e==="best_bridge_route"){let{bestSwapRoute:n,bestBridgeRoute:o}=await Promise.resolve().then(()=>(je(),Fn));return e==="best_swap_route"?n(t):o(t)}if(e==="prepare_best_route"){let{prepareBestRoute:n}=await Promise.resolve().then(()=>(jn(),Mn));return n(t)}if(e==="prepare_best_bridge_route"){let{prepareBestBridgeRoute:n}=await Promise.resolve().then(()=>(Hn(),Vn));return n(t)}if(e==="scanner_coverage"){let n=await Promise.resolve().then(()=>(Ge(),ze));return n.registerBuiltinScanners?.(),n.scannerCoverage()}if(e==="scan_token"){let n=await Promise.resolve().then(()=>(Ge(),ze));n.registerBuiltinScanners?.();let o=n.getScanner(Number(t.chainId));if(!o)throw new Error(`no scanner registered for chainId ${t.chainId}`);let i=await o.resolveToken(t.token),s=o.supports?.("resolvePools")?await o.resolvePools(t.token).catch(()=>null):null,a=o.supports?.("scoreRisk")?await o.scoreRisk({token:t.token}).catch(()=>null):null;return{chainId:Number(t.chainId),token:i,pools:s,risk:a}}if(e==="wallet_balances"){let n=await Promise.resolve().then(()=>(Ge(),ze));n.registerBuiltinScanners?.();let o=n.getScanner(Number(t.chainId));if(!o)throw new Error(`no scanner registered for chainId ${t.chainId}`);let i=await o.nativeBalance(t.address),s=t.token?await o.tokenBalance(t.address,t.token).catch(()=>null):null;return{chainId:Number(t.chainId),address:t.address,native:i,token:s}}if(e==="address_book_remember")return Kt({address:t.address,label:t.label,who:t.who,role:t.role,chainIds:t.chainIds,notes:t.notes,source:"oracle-data-mcp"});if(e==="address_book_list")return Vt({q:t.q,role:t.role,who:t.who});if(e==="address_book_lookup")return Ht(t.address);if(e==="address_book_forget")return zt(t.address,t.label||null);if(e==="data_catalog")return Tt(`${Nt}/data/catalog`);if(e==="data_health")return Tt(`${Nt}/data/health`);if(e==="data_call"){if(!t.provider||!t.op)throw new Error("provider and op are required");return so(t.provider,t.op,t.args||{})}let r=Na[e];if(r){let{provider:n,op:o,args:i}=r(t);return so(n,o,i)}throw new Error(`Unknown tool: ${e}`)}async function Ba(e){let{id:t,method:r,params:n}=e;if(r==="initialize"){oe({jsonrpc:"2.0",id:t,result:{protocolVersion:n?.protocolVersion||"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"oracle-data-mcp",version:"0.1.0"}}});return}if(r!=="notifications/initialized"){if(r==="tools/list"){oe({jsonrpc:"2.0",id:t,result:{tools:Ra}});return}if(r==="tools/call"){try{let o=await Ta(n?.name,n?.arguments||{});if(o?.dataBase64&&/^image\/(?:svg\+xml|png|jpeg|webp)$/.test(String(o.mimeType||""))){let{dataBase64:i,...s}=o;oe({jsonrpc:"2.0",id:t,result:{content:[{type:"image",data:i,mimeType:o.mimeType},{type:"text",text:JSON.stringify(s,null,2)}]}})}else oe({jsonrpc:"2.0",id:t,result:{content:[{type:"text",text:JSON.stringify(o,null,2)}]}})}catch(o){oe({jsonrpc:"2.0",id:t,result:{isError:!0,content:[{type:"text",text:o.message}]}})}return}t!==void 0&&co(t,-32601,`Method not found: ${r}`)}}var Ee="";function La(){ie.stdin.setEncoding("utf8"),ie.stdin.on("data",e=>{Ee+=e;let t;for(;(t=Ee.indexOf(`
8
- `))>=0;){let r=Ee.slice(0,t).trim();if(Ee=Ee.slice(t+1),!!r)try{Ba(JSON.parse(r))}catch(n){co(null,-32700,n.message)}}})}function Da(){let e=ie.argv[1];if(!e)return!1;try{return io.realpathSync(e)===io.realpathSync(Oa(import.meta.url))}catch{return!1}}Da()&&La();export{Ta as callTool,Ba as handle,Ra as tools};
5
+ - `)}`);let o=e.capabilities||{},s=$e.filter(i=>typeof o[i]=="function"),a={key:e.key,chainId:e.chainId,name:e.name,rpcEnv:[...e.rpcEnv],nativeCurrency:e.nativeCurrency?{...e.nativeCurrency}:null,explorer:e.explorer||null,venues:(e.venues||[]).map(i=>({...i})),warnings:n,capabilities(){return{chainId:e.chainId,key:e.key,supported:[...s],unsupported:$e.filter(i=>!s.includes(i))}},supports(i){return s.includes(i)}};for(let i of $e)s.includes(i)?a[i]=async(...c)=>o[i](...c,{scanner:a}):a[i]=async()=>{throw new Error(`${e.key} (chain ${e.chainId}) does not implement "${i}". Supported: ${s.join(", ")||"none"}. An unimplemented capability is absent, not assumed -- implement it or treat this chain as fail-closed for that operation.`)};return Object.freeze(a)}function Bt(e){let t=is(e);return qe.set(t.chainId,t),t}function Tu(e){return qe.get(Number(e))||null}function Nu(){return[...qe.values()]}function Bu(){qe.clear()}function $u(){let e={};for(let t of qe.values())e[t.chainId]={key:t.key,name:t.name,...t.capabilities(),venueCount:t.venues.length,failClosed:t.venues.length===0};return{generatedAt:new Date().toISOString(),chainCount:qe.size,capabilities:[...$e],chains:e}}var $e,A,v,Ru,qe,ve=w(()=>{$e=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),A=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),v=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"}),Ru=/^0x[0-9a-fA-F]{40}$/;qe=new Map});function as(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:o=null,feeUsd:s=null,estimatedGas:a=null,error:i=null,executionReady:c=!1,meta:u={}}=e||{};if(i||r==null)return{source:t,quality:W.FAILED,amountOut:null,error:i||"no amountOut returned"};let d=tt(r);return d==null||d<=0n?{source:t,quality:W.FAILED,amountOut:null,error:"non-positive amountOut"}:{source:t,quality:o==null?W.NO_GAS:W.FULL,amountOut:d.toString(),minOut:tt(n)?.toString()??null,gasUsd:o,feeUsd:s,estimatedGas:a==null?null:String(a),executionReady:c,meta:u}}async function us(e,t,{divisor:r=1000n}={}){let n=tt(t);if(n==null||n<=0n)return null;let o=n/r>0n?n/r:1n;if(o>=n)return null;let s,a;try{[s,a]=await Promise.all([e(o),e(n)])}catch{return null}let i=tt(s),c=tt(a);if(i==null||c==null||i<=0n)return null;let u=Number(i)/Number(o),d=Number(c)/Number(n);return!Number.isFinite(u)||!Number.isFinite(d)||u<=0?null:{impactPct:(1-d/u)*100,probeAmountIn:o.toString(),probeAmountOut:i.toString(),fullAmountOut:c.toString()}}function ls(e,t,{maxImpactPct:r=25}={}){let n=[],o=[],s=(e.routes??[]).filter(i=>{let c=t?.[i.source];return c?c.impactPct>r?(n.push({source:i.source,impactPct:Number(c.impactPct.toFixed(2)),reason:`price impact ${c.impactPct.toFixed(1)}% exceeds ${r}% ceiling -- the venue cannot absorb this size near the quoted price`}),!1):!0:(o.push(i.source),!0)}),a=[...e.warnings??[]];return n.length&&a.push(`dropped ${n.length} route(s) on price impact: `+n.map(i=>`${i.source} (${i.impactPct}%)`).join(", ")),o.length&&a.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:a}}function Lr(e,{destPriceUsd:t=null,destDecimals:r=null}={}){let n=e.filter(p=>p.quality!==W.FAILED),o=e.filter(p=>p.quality===W.FAILED),s=t!=null&&t>0&&r!=null&&r>=0,a=n.map(p=>{let l=BigInt(p.amountOut),m=0n,f=!1;if(s){let b=(p.gasUsd??0)+(p.feeUsd??0);if(b>0){let S=b/t*10**r;Number.isFinite(S)&&S>=0&&(m=BigInt(Math.floor(S)),f=!0)}else p.gasUsd===0&&(f=!0)}let g=l>m?l-m:0n;return{...p,grossOut:l.toString(),netOut:g.toString(),costInDest:m.toString(),costAccounted:f}});a.sort((p,l)=>BigInt(l.netOut)>BigInt(p.netOut)?1:-1);let i=a.filter(p=>!p.costAccounted).map(p=>p.source),c=[];s?i.length&&c.push(`gas not reported by: ${i.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):c.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let u=null,d=null;if(a.length>=2&&a[0].costAccounted&&a[1].costAccounted){let p=BigInt(a[0].netOut),l=BigInt(a[1].netOut);l>0n&&(u=Number((p-l)*10000n/l),d=`${a[0].source} vs ${a[1].source}`)}return{best:a[0]??null,routes:a,failed:o,improvementBps:u,spreadBasis:d,rankedOn:s?"net-of-cost":"gross",warnings:c}}async function $t(e,{timeoutMs:t=12e3}={}){let r=(o,s)=>Promise.race([o,new Promise((a,i)=>setTimeout(()=>i(new Error(`${s}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,s)=>{let a=e[s].source;return o.status==="rejected"?as({source:a,error:String(o.reason?.message||o.reason)}):as({source:a,...o.value})})}var W,cs,tt,Fr=w(()=>{ve();W=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"}),cs={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"},tt=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}}});function ds(e={}){return vt({provider:"oneinch",defaultUrl:qu,hosts:["api.1inch.dev"],url:e.baseUrl||process.env.ONEINCH_API_URL})}function Du(e={}){return ds(e).baseUrl}function ps(e={}){return e.apiKey||process.env.ONEINCH_API_KEY||process.env.ONE_INCH_API_KEY||""}function Pu(e={}){let t=ps(e);return xt({accept:"application/json"},{Authorization:t?`Bearer ${t}`:""},ds(e).trusted)}async function ms(e={},t={}){if(!ps(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 a=new URLSearchParams({src:n,dst:o,amount:String(s)}),i=await y(`${Du(t)}/${r}/quote?${a}`,{headers:Pu(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3});return i?.dstAmount?D(i,{chainId:r,venue:"1inch-quote",amountOut:i.dstAmount,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):i}var qu,fs=w(()=>{C();oe();Br();j();qu="https://api.1inch.dev/swap/v6.0"});var vs={};_(vs,{UNI_V4_CHAINS:()=>se,UNI_V4_FEE_TIERS:()=>ys,computeV4PoolId:()=>Ss,uniV4Chains:()=>Ku,uniV4Health:()=>Qu,uniV4PrepareExactIn:()=>zu,uniV4QuoteExactIn:()=>Dt});import{AbiCoder as Uu,Interface as gs,getAddress as G,isAddress as qt,keccak256 as Lu}from"ethers";function Mr(e){let t=Number(e),r=se[t];if(!r)throw new Error(`uniswap-v4: unsupported chainId ${e} (supported: ${Object.keys(se).join(", ")})`);return{chainId:t,...r}}function bs(e,t){let r=se[Number(t)];if(!e||e===ws||e===xe||/^eth$/i.test(String(e)))return G(r.weth);let n=String(e);if(/^weth$/i.test(n))return G(r.weth);if(/^usdc$/i.test(n)||/^usdg$/i.test(n))return G(r.usdc);if(!qt(n))throw new Error(`invalid token address: ${e}`);return G(n)}function Ss({currency0:e,currency1:t,fee:r,tickSpacing:n,hooks:o=xe}){let s=G(e),a=G(t);if(s.toLowerCase()===a.toLowerCase())throw new Error("poolKey currencies must differ");let[i,c]=s.toLowerCase()<a.toLowerCase()?[s,a]:[a,s],u=o&&qt(o)?G(o):xe;return Lu(rt.encode(["address","address","uint24","int24","address"],[i,c,Number(r),Number(n),u]))}function Vu({tokenIn:e,tokenOut:t,fee:r,tickSpacing:n,hooks:o=xe}){let s=G(e),a=G(t),[i,c]=s.toLowerCase()<a.toLowerCase()?[s,a]:[a,s],u=s.toLowerCase()===i.toLowerCase();return{poolKey:{currency0:i,currency1:c,fee:Number(r),tickSpacing:Number(n),hooks:o&&qt(o)?G(o):xe},zeroForOne:u}}async function Dt(e={},t={}){let{chainId:r,quoter:n,poolManager:o,universalRouter:s}=Mr(e.chainId??8453),a=bs(e.tokenIn||"WETH",r),i=bs(e.tokenOut||se[r].usdc,r),c=BigInt(e.amountIn??0);if(c<=0n)throw new Error("amountIn required (raw base units)");if(c>0xffffffffffffffffffffffffffffffffn)throw new Error("amountIn exceeds uint128");let u=e.fee!=null&&e.tickSpacing!=null?[{fee:Number(e.fee),tickSpacing:Number(e.tickSpacing)}]:e.tryTiers===!1?[{fee:500,tickSpacing:10}]:[...ys],d=e.hooks||xe,p=[],l=null;for(let m of u){let{poolKey:f,zeroForOne:g}=Vu({tokenIn:a,tokenOut:i,fee:m.fee,tickSpacing:m.tickSpacing,hooks:d}),b=hs.encodeFunctionData("quoteExactInputSingle",[{poolKey:f,zeroForOne:g,exactAmount:c,hookData:"0x"}]);try{let S=await B(r,"eth_call",[{to:n,data:b},"latest"],t);if(!S||S==="0x"){p.push({...m,ok:!1,error:"empty result"});continue}let I=hs.decodeFunctionResult("quoteExactInputSingle",S),N={fee:m.fee,tickSpacing:m.tickSpacing,ok:!0,amountOut:I[0].toString(),gasEstimate:I[1].toString(),poolKey:f,zeroForOne:g,poolId:Ss({...f})};p.push(N),(!l||BigInt(N.amountOut)>BigInt(l.amountOut))&&(l=N)}catch(S){p.push({...m,ok:!1,error:String(S.message||S).slice(0,160)})}}if(!l){let m=p.map(f=>`${f.fee}/${f.tickSpacing}:${f.error||"fail"}`).join("; ");throw new Error(`uniswap-v4 quote failed chain=${r}: ${m}`)}return D({venue:"uniswap-v4",chainId:r,chain:se[r].name,poolManager:o,quoter:n,universalRouter:s||null,tokenIn:a,tokenOut:i,amountIn:c.toString(),fee:l.fee,tickSpacing:l.tickSpacing,hooks:l.poolKey.hooks,poolId:l.poolId,zeroForOne:l.zeroForOne,amountOut:l.amountOut,gasEstimate:l.gasEstimate,triedTiers:p,best:!0,executionReady:!1,prepareReady:typeof e.recipient=="string"&&qt(e.recipient)&&e.slippageBps!=null},{chainId:r,venue:s||n,amountOut:l.amountOut,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function zu(e={},t={}){let r=Number(e.chainId??8453),n=Mr(r);if(!e.recipient)throw new Error("uniswap-v4 prepare requires recipient");let o=G(e.recipient);if(e.slippageBps==null)throw new Error("uniswap-v4 prepare requires explicit slippageBps");let s=Number(e.slippageBps);if(!Number.isInteger(s)||s<0||s>=1e4)throw new Error("slippageBps must be an integer from 0 through 9999");let a=String(e.tokenIn||"");if(!a||a===ws||a===xe||/^eth$/i.test(a))throw new Error("uniswap-v4 prepare currently requires an ERC-20 tokenIn; native input is not inferred");let i=await Dt(e,t);if(!n.universalRouter)throw new Error(`uniswap-v4: no Universal Router on chain ${r}`);let c=BigInt(i.amountOut)*BigInt(1e4-s)/10000n,u={currency0:i.zeroForOne?i.tokenIn:i.tokenOut,currency1:i.zeroForOne?i.tokenOut:i.tokenIn,fee:i.fee,tickSpacing:i.tickSpacing,hooks:i.hooks},p=rt.encode(["tuple(tuple(address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 amountIn,uint128 amountOutMinimum,uint256 minHopPriceX36,bytes hookData)"],[[u,i.zeroForOne,BigInt(i.amountIn),c,0n,"0x"]]),l=rt.encode(["address","uint256"],[i.tokenIn,BigInt(i.amountIn)]),m=rt.encode(["address","uint256"],[i.tokenOut,c]),f=rt.encode(["bytes","bytes[]"],[ju,[p,l,m]]),g=Math.min(600,Math.max(30,Number(e.deadlineSeconds??300))),S=Number(t.nowSeconds??Math.floor(Date.now()/1e3))+g,I=Fu.encodeFunctionData("execute",[Mu,[f],S]);return T({provider:"uniswap-v4",prepareReady:!0,calldataReady:!0,executionReady:!1,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:r,deadline:S,quote:{...i,amountOutMinimum:c.toString(),slippageBps:s},requiresApproval:{token:i.tokenIn,spender:Hu,amount:i.amountIn,note:"Universal Router V4 settlement uses Permit2; Permit2 authorization for the Universal Router is also required"},transaction:{chainId:r,from:o,to:n.universalRouter,data:I,value:"0"}},{provider:"uniswap-v4",kind:"univ4-swap-tx"})}async function Ku(){return Object.entries(se).map(([e,t])=>({chainId:Number(e),name:t.name,poolManager:t.poolManager,quoter:t.quoter,stateView:t.stateView||null,universalRouter:t.universalRouter||null,weth:t.weth,usdc:t.usdc}))}async function Qu(e={}){let t=Mr(e.chainId??8453),r=await B(t.chainId,"eth_getCode",[t.quoter,"latest"],e),n=typeof r=="string"&&r!=="0x"&&r.length>4;return{ok:n,chainId:t.chainId,quoter:t.quoter,poolManager:t.poolManager,codeBytes:n?(r.length-2)/2:0}}var rt,xe,se,ys,hs,Fu,Mu,ju,Hu,ws,jr=w(()=>{we();oe();j();rt=Uu.defaultAbiCoder(),xe="0x0000000000000000000000000000000000000000",se={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"}},ys=[{fee:100,tickSpacing:1},{fee:500,tickSpacing:10},{fee:3e3,tickSpacing:60},{fee:1e4,tickSpacing:200},{fee:25e3,tickSpacing:8}],hs=new gs(["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)"]),Fu=new gs(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]),Mu="0x10",ju="0x060c0f",Hu="0x000000000022D473030F116dDEE9F6B43aC78BA3",ws="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"});function Gu(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||Wu).replace(/\/$/,"")}async function Pt(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return y(`${Gu(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}var Wu,Hr=w(()=>{C();Wu="https://coins.llama.fi"});var Ut={};_(Ut,{ACROSS_API:()=>xs,HOP_API:()=>As,RELAY_API:()=>Es,acrossHealth:()=>Yu,acrossSuggestedFees:()=>ks,hopHealth:()=>Ju,hopQuote:()=>Is,relayHealth:()=>Zu,relayPrepare:()=>el,relayQuote:()=>Vr});async function Yu(e={}){try{return{ok:!0,estimatedFillTimeSec:(await ks({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 ks(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:s,amount:a}=e;if(!r||o==null||s==null||!a)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let i=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(s),amount:String(a)}),c=(t.baseUrl||process.env.ACROSS_API_URL||xs).replace(/\/$/,"");return y(`${c}/suggested-fees?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Ju(e={}){try{let t=await Is({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 Is(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:s="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let a=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),i=ne({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??a});if(!i.executable)throw new Error(`hop: route requires ${i.requiredBps} bps above cap ${i.capBps}`);let c=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:s,slippage:String(i.selectedBps/100)}),u=(t.baseUrl||process.env.HOP_API_URL||As).replace(/\/$/,""),d=await y(`${u}/quote?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),p=d?.estimatedRecieved||d?.estimatedReceived;return p?D(d,{chainId:Number(e.originChainId||e.chainId||Xu[o]||0),venue:d?.tx?.to||"hop",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??a}):{...d,autoSlippagePolicy:i}}async function Zu(e={}){try{let t=await Vr({user:ue,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 Vr(e={},t={}){let{user:r=ue,originChainId:n,destinationChainId:o,originCurrency:s="0x0000000000000000000000000000000000000000",destinationCurrency:a="0x0000000000000000000000000000000000000000",amount:i,tradeType:c="EXACT_INPUT"}=e;if(n==null||o==null||!i)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let u=ne({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!u.executable)throw new Error(`relay: route requires ${u.requiredBps} bps above cap ${u.capBps}`);let d=(t.baseUrl||process.env.RELAY_API_URL||Es).replace(/\/$/,""),p=await y(`${d}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:s,destinationCurrency:a,amount:String(i),tradeType:c,slippageTolerance:String(u.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),l=p?.details?.currencyOut?.amount;return!l||!/^\d+$/.test(String(l))?{...p,autoSlippagePolicy:u}:D(p,{chainId:Number(n),venue:p?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:l,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function el(e={},t={}){let r=await Vr(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(i=>(i.items||[]).filter(c=>c?.data?.to&&c?.data?.data).map(c=>({stepId:i.id,...c.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let s=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(i=>String(i.to).toLowerCase()!==s))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let a=o.map(i=>({chainId:n,from:i.from||e.user,to:i.to,data:i.data,value:i.value??"0x0",...i.gasLimit!=null||i.gas!=null?{gasLimit:i.gasLimit??i.gas}:{},slippageGuard:Q(r.autoSlippage,{chainId:n,venue:i.to,data:i.data})}));return T({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:a},{provider:"relay",kind:"relay-tx"})}var xs,As,Es,Xu,Lt=w(()=>{C();oe();yt();j();xs="https://across.to/api",As="https://api.hop.exchange/v1",Es="https://api.relay.link",Xu={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});function Ft(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=de(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}async function Cs(e,t={}){let r=cs[Number(e)];if(!r)return null;try{let n=await Pt([r],t);return de(n?.coins?.[r]?.price)}catch{return null}}function zr({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:s,decimalsIn:a,decimalsOut:i,nativePriceUsd:c=null,destDecimalsPromise:u=null,opts:d={}}){let p=[];return p.push({source:"lifi",run:async()=>{let l=await ge({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n},d),m=l?.estimate??l?.[0]?.estimate;return{amountOut:m?.toAmount,minOut:m?.toAmountMin,gasUsd:Ft(m?.gasCosts),feeUsd:Ft(m?.feeCosts),meta:{tool:l?.tool??l?.toolDetails?.name}}}}),a!=null&&p.push({source:"paraswap",run:async()=>{let l=i??(await Promise.resolve(u))?.decimals;if(l==null)throw new Error("paraswap needs destination decimals; none supplied or resolvable");let f=(await Te({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:a,destDecimals:l},d))?.priceRoute;return{amountOut:f?.destAmount,gasUsd:de(f?.gasCostUSD),meta:{bestRoute:f?.bestRoute?.[0]?.swaps?.[0]?.swapExchanges?.[0]?.exchange}}}}),process.env.ZEROX_API_KEY&&p.push({source:"0x",run:async()=>{let l=await Ne({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},d),m=null,f=l?.totalNetworkFee,g=await Promise.resolve(c);return f!=null&&g&&(m=Number(f)/1e18*g),{amountOut:l?.buyAmount,minOut:l?.minBuyAmount,gasUsd:m,meta:{source:l?.route?.fills?.[0]?.source}}}}),process.env.ONEINCH_API_KEY&&p.push({source:"1inch",run:async()=>{let l=await ms({chainId:e,src:t,dst:r,amount:n},d),m=null;return l?.gas!=null&&c&&(m=null),{amountOut:l?.dstAmount,gasUsd:m,meta:{gasUnits:l?.gas}}}}),p.push({source:"cow",run:async()=>{let l=await ye({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},d),m=l?.quote??l,f=m?.feeAmount;return{amountOut:m?.buyAmount,gasUsd:0,meta:{intent:!0,feeAmountInSellToken:f,settlement:"solver-executed"}}}}),L[Number(e)]&&p.push({source:"uniswap-v3",run:async()=>{let l=await Se({chainId:e,tokenIn:t,tokenOut:r,amountIn:n},d);return{amountOut:l?.amountOut,minOut:l?.minOut??l?.amountOutMinimum??null,gasUsd:null,meta:{onchain:!0,fee:l?.fee,gasUnits:l?.gasEstimate,quoter:l?.quoter}}}}),se[Number(e)]&&p.push({source:"uniswap-v4",run:async()=>{let l=await Dt({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:s},d);return{amountOut:l?.amountOut,minOut:l?.minOut??l?.amountOutMinimum??null,gasUsd:null,meta:{onchain:!0,venue:"uniswap-v4",fee:l?.fee,tickSpacing:l?.tickSpacing,poolId:l?.poolId,hooks:l?.hooks,gasUnits:l?.gasEstimate,quoter:l?.quoter,poolManager:l?.poolManager,prepareReady:l?.prepareReady===!0,executionReady:!1}}}}),p}function _s({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:s,opts:a={}}){let i=[];return i.push({source:"lifi",run:async()=>{let c=await ge({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},a),u=c?.estimate??c?.[0]?.estimate;return{amountOut:u?.toAmount,minOut:u?.toAmountMin,gasUsd:Ft(u?.gasCosts),feeUsd:Ft(u?.feeCosts),meta:{tool:c?.tool??c?.toolDetails?.name,durationSeconds:de(u?.executionDuration)}}}}),i.push({source:"relay",run:async()=>{let{relayQuote:c}=await Promise.resolve().then(()=>(Lt(),Ut)),d=(await c({user:s,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},a))?.details;return{amountOut:d?.currencyOut?.amount,minOut:d?.currencyOut?.minimumAmount,gasUsd:de(d?.totalImpact?.usd)!=null?Math.abs(de(d.totalImpact.usd)):null,meta:{durationSeconds:de(d?.timeEstimate),rate:d?.rate}}}}),i.push({source:"across",run:async()=>{let{acrossSuggestedFees:c}=await Promise.resolve().then(()=>(Lt(),Ut)),u=await c({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},a),d=u?.totalRelayFee?.total,p=null;if(d!=null)try{let l=BigInt(String(o))-BigInt(String(d));l>0n&&(p=l.toString())}catch{}return{amountOut:p,gasUsd:null,meta:{derivedFromFees:!0,durationSeconds:de(u?.estimatedFillTimeSec),limits:u?.limits?{min:u.limits.minDeposit,max:u.limits.maxDeposit}:void 0}}}}),i}var de,Os=w(()=>{Ge();St();Et();fs();Ct();Nt();jr();Hr();Fr();de=e=>{let t=Number(e);return Number.isFinite(t)?t:null}});var Ts={};_(Ts,{QUALITY:()=>W,bestBridgeRoute:()=>nt,bestSwapRoute:()=>De,formatComparisonNote:()=>Mt});async function Rs(e,t,r){let n=tl[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let a=(await Pt([o],r))?.coins?.[o],i=Number(a?.price),c=Number(a?.decimals);return{priceUsd:Number.isFinite(i)?i:null,decimals:Number.isFinite(c)?c:null}}catch{return{priceUsd:null,decimals:null}}}async function De(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 a=Cs(r,t),i=Rs(r,o,t),c=zr({...e,nativePriceUsd:a,decimalsOut:e.decimalsOut,destDecimalsPromise:i,opts:t}),[u,d]=await Promise.all([$t(c,{timeoutMs:t.timeoutMs??12e3}),i]);a.catch(()=>{});let p=Lr(u,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals}),l=t.maxImpactPct===void 0?25:t.maxImpactPct;if(l!=null&&p.best){let m=p.best.source,g=await us(async b=>{let S=zr({...e,amountIn:b.toString(),nativePriceUsd:a,decimalsOut:e.decimalsOut,destDecimalsPromise:i,opts:t}).filter(N=>N.source===m);return S.length?(await $t(S,{timeoutMs:t.timeoutMs??12e3}))?.[0]?.amountOut??null:null},s);if(g){let b=ls(p,{[m]:g},{maxImpactPct:l});return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...b,sourcesTried:c.length,sourcesAnswered:u.filter(S=>S.quality!==W.FAILED).length,note:Mt(b,c.length),priceImpact:{[m]:Number(g.impactPct.toFixed(2))}}}}return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...p,sourcesTried:c.length,sourcesAnswered:u.filter(m=>m.quality!==W.FAILED).length,note:Mt(p,c.length)}}async function nt(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:a}=e;if(r==null||n==null||!o||!s||a==null)throw new Error("bestBridgeRoute requires fromChainId, toChainId, tokenIn, tokenOut, amountIn");if(Number(r)===Number(n))throw new Error("bestBridgeRoute is for cross-chain; use bestSwapRoute for same-chain");let i=Rs(n,s,t),c=_s({...e,opts:t}),[u,d]=await Promise.all([$t(c,{timeoutMs:t.timeoutMs??15e3}),i]),p=Lr(u,{destPriceUsd:d.priceUsd,destDecimals:e.decimalsOut??d.decimals}),l=p.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(a),...p,durations:l,sourcesTried:c.length,sourcesAnswered:u.filter(m=>m.quality!==W.FAILED).length,note:Mt(p,c.length)}}function Mt(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length;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.`;if(e.improvementBps!=null){let n=e.improvementBps,o=n/100;if(n<.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.`;let s=o>=.01?`${o.toFixed(2)}%`:`${n.toFixed(2)}bps`;return`best of ${r} routes, ranked on ${e.rankedOn}: ${s} better than the runner-up (${e.spreadBasis})`}return`best of ${r} routes, ranked on ${e.rankedOn}. No spread quoted: the top routes report cost differently, so the margin is not comparable.`}var tl,Pe=w(()=>{Fr();Os();Hr();tl={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"}});var Ns={};_(Ns,{ARTIFACT:()=>ie,prepareBestRoute:()=>il,supportedPreparers:()=>nl});function nl(){return Object.keys(jt)}async function il(e,t={}){let{taker:r}=e;if(!r)throw new Error("prepareBestRoute requires taker: a prepared transaction is built FOR an address, and the quote-only placeholder must never end up in one");if(!sl.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(ol.has(r.toLowerCase()))throw new Error(`taker "${r}" is a placeholder/burn address. It is valid for quoting but not for preparing -- that would build a transaction for an address nobody controls. Pass the real wallet that will sign.`);let n=await De(e,t);if(!n.best){let l=n.impactRejected??[];return{ok:!1,reason:l.length?l[0].reason:"no source returned a usable route",priceImpactBlocked:l.length>0,impactRejected:l,comparison:n}}let o=e.source||n.best.source,s=n.routes.find(l=>l.source===o);if(!s)return{ok:!1,reason:`source "${o}" did not return a usable route`,comparison:n};let a=jt[o];if(!a){let l=n.routes.find(m=>jt[m.source]&&m.source!==o);return{ok:!1,reason:`${o} won the comparison but has no prepare path in this build. `+(l?`Next preparable route is ${l.source}; pass source:"${l.source}" to use it.`:"No route in this comparison can be prepared."),comparison:n,winner:o}}let i;try{i=await a(e,t)}catch(l){let m=typeof l?.body=="string"?l.body:l?.body?JSON.stringify(l.body):"",f=[String(l?.message||l),m].filter(Boolean).join(" :: "),g=/allowance/i.test(f),b=!g&&/not enough|insufficient|balance/i.test(f),S,I;g?(I="approval-required-first",S=`${o} will not build swap calldata until the token approval exists on-chain. Approve the spender first, then prepare again. Underlying: ${f}`):b?(I="taker-not-funded",S=`${o} refused to build the transaction: ${f}. This venue verifies the taker holds the input token. Quoting works for any address; preparing needs the real funded wallet.`):(I="provider-error",S=`${o} prepare failed: ${f}`);let N=n.routes.find(re=>jt[re.source]&&re.source!==o);return{ok:!1,reason:S,failureKind:I,...N?{alternative:N.source}:{},comparison:n}}let c=e.driftToleranceBps??rl,u=null,d=null;if(i.amountOut!=null&&s.grossOut!=null)try{let l=BigInt(s.grossOut),m=BigInt(i.amountOut);l>0n&&(u=Number((m-l)*10000n/l),u<-c&&(d=`route moved ${(u/100).toFixed(2)}% against you between the comparison and this prepare (tolerance ${(c/100).toFixed(2)}%). The ranking may no longer hold -- re-run the comparison before signing.`))}catch{}let p=n.routes.filter(l=>l.source!==o).map(l=>({source:l.source,netOut:l.netOut,gasUsd:l.gasUsd}));return T({ok:!0,chosen:{source:o,wasWinner:o===n.best.source,netOut:s.netOut,grossOut:s.grossOut,gasUsd:s.gasUsd},priceImpact:n.priceImpact??null,impactUnmeasured:n.impactUnmeasured??[],...i,unsigned:!0,signedBy:"user-wallet",destination:i.artifactKind===ie.TRANSACTION?i.transaction?.to??null:i.settlement??null,driftBps:u,warnings:[...d?[d]:[],...n.warnings||[],...i.artifactKind===ie.TYPED_DATA_ORDER?["This is an ORDER to sign, not a transaction to broadcast. Signing it authorizes a solver to settle on your behalf."]:[]],runnersUp:p,comparison:{rankedOn:n.rankedOn,sourcesAnswered:n.sourcesAnswered,sourcesTried:n.sourcesTried,improvementBps:n.improvementBps},note:"UNSIGNED. Verify the destination address and minOut against a fresh quote immediately before signing -- a quote-time minimum is not a minimum at broadcast time."},{provider:"router",kind:"best-route"})}var ie,rl,jt,ol,sl,Bs=w(()=>{Pe();j();ie=Object.freeze({TRANSACTION:"unsigned-transaction",TYPED_DATA_ORDER:"typed-data-order"}),rl=100,jt={"uniswap-v3":async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},s)=>{let{uniV3PrepareExactIn:a}=await Promise.resolve().then(()=>(Nt(),Jo)),i=await a({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o},s);return{artifactKind:ie.TRANSACTION,transaction:i.transaction,requiresApproval:i.requiresApproval??null,amountOut:i.quote?.amountOut??null,minOut:i.quote?.amountOutMinimum??null}},"uniswap-v4":async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:s,fee:a,tickSpacing:i,hooks:c},u)=>{let{uniV4PrepareExactIn:d}=await Promise.resolve().then(()=>(jr(),vs)),p=await d({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:s,fee:a,tickSpacing:i,hooks:c},u);return{artifactKind:ie.TRANSACTION,transaction:p.transaction,requiresApproval:p.requiresApproval,amountOut:p.quote?.amountOut??null,minOut:p.quote?.amountOutMinimum??null,prepareReady:!0,executionReady:!1}},lifi:async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},s)=>{let{lifiPrepare:a}=await Promise.resolve().then(()=>(Ge(),Tr)),i=await a({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n,fromAddress:o},s);return{artifactKind:ie.TRANSACTION,transaction:i.transaction,requiresApproval:i.requiresApproval??null,amountOut:i.quote?.estimate?.toAmount??null,minOut:i.quote?.estimate?.toAmountMin??null}},paraswap:async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,decimalsIn:s,decimalsOut:a},i)=>{let{paraswapPrepare:c}=await Promise.resolve().then(()=>(St(),yo)),u=await c({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:s,destDecimals:a,userAddress:o,side:"SELL"},i);return{artifactKind:ie.TRANSACTION,transaction:u.transaction,requiresApproval:u.requiresApproval??null,amountOut:u.quote?.priceRoute?.destAmount??null,minOut:u.quote?.amountOutMinimum??null}},"0x":async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},s)=>{let{zeroxPrepare:a}=await Promise.resolve().then(()=>(Et(),Io)),i=await a({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},s);return{artifactKind:ie.TRANSACTION,transaction:i.transaction,requiresApproval:i.requiresApproval??null,amountOut:i.quote?.buyAmount??null,minOut:i.quote?.minBuyAmount??null}},cow:async({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o},s)=>{let{cowPrepareOrder:a}=await Promise.resolve().then(()=>(Ct(),Po)),i=await a({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},s);return{artifactKind:ie.TYPED_DATA_ORDER,typedData:i.typedData,requiresApproval:{token:t,spender:i.vaultRelayer,amount:String(n),note:"CoW pulls funds via the vault relayer, not the settlement contract"},settlement:i.settlement,amountOut:i.quote?.quote?.buyAmount??null,minOut:null,submission:"sign the typed data, then submit the order to the CoW API"}}};ol=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),sl=/^0x[0-9a-fA-F]{40}$/});var $s={};_($s,{prepareBestBridgeRoute:()=>dl,supportedBridgePreparers:()=>ll});function ll(){return Object.keys(Ht)}async function dl(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(!al.test(r))throw new Error(`taker must be a valid 20-byte address, got "${r}"`);if(cl.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 s=await nt(e,t);if(!s.best)return{ok:!1,reason:"no source returned a usable bridge route",comparison:s};let a=e.source||s.best.source,i=s.routes.find(b=>b.source===a);if(!i)return{ok:!1,reason:`source "${a}" returned no usable route`,comparison:s};let c=Ht[a];if(!c){let b=s.routes.find(S=>Ht[S.source]&&S.source!==a);return{ok:!1,reason:`${a} won the comparison but has no bridge prepare path in this build. `+(b?`Next preparable route is ${b.source}; pass source:"${b.source}".`:"No route in this comparison can be prepared."),failureKind:"no-prepare-path",...b?{alternative:b.source}:{},winner:a,comparison:s}}let u;try{u=await c(e,t)}catch(b){let S=typeof b?.body=="string"?b.body:b?.body?JSON.stringify(b.body):"",I=[String(b?.message||b),S].filter(Boolean).join(" :: "),N=/allowance/i.test(I),re=!N&&/not enough|insufficient|balance/i.test(I),be=s.routes.find(Ce=>Ht[Ce.source]&&Ce.source!==a);return{ok:!1,reason:N?`${a} will not build calldata until the token approval exists on-chain. Approve first, then prepare again. Underlying: ${I}`:re?`${a} refused to build: ${I}. Quoting works for any address; preparing needs the real funded wallet on chain ${n}.`:`${a} bridge prepare failed: ${I}`,failureKind:N?"approval-required-first":re?"taker-not-funded":"provider-error",...be?{alternative:be.source}:{},comparison:s}}let d=u.transactions||[];if(!d.length)return{ok:!1,reason:`${a} returned no executable transaction for this route`,failureKind:"provider-error",comparison:s};let p=d.filter(b=>b.chainId!=null&&Number(b.chainId)!==Number(n));if(p.length)return{ok:!1,reason:`${a} returned a transaction for chain ${p[0].chainId} but the origin chain is ${n}. Refusing to hand over a mismatched artifact.`,failureKind:"chain-mismatch",comparison:s};let l=e.driftToleranceBps??ul,m=null,f=null;if(u.amountOut!=null&&i.grossOut!=null)try{let b=BigInt(i.grossOut),S=BigInt(u.amountOut);b>0n&&(m=Number((S-b)*10000n/b),m<-l&&(f=`route moved ${(m/100).toFixed(2)}% against you since the comparison (tolerance ${(l/100).toFixed(2)}%). Re-compare before signing.`))}catch{}let g=[...f?[f]:[],...s.warnings||[],`Bridging is NOT atomic: the origin transaction succeeding does not mean funds arrived on chain ${o}. Expect ~${u.durationSeconds!=null?`${u.durationSeconds}s`:"minutes"} before the destination credits, and do not re-send if it is pending.`];return d.length>1&&g.push(`This route needs ${d.length} transactions signed IN ORDER. Signing only the first leaves funds approved but not bridged.`),T({ok:!0,chosen:{source:a,wasWinner:a===s.best.source,netOut:i.netOut,grossOut:i.grossOut,gasUsd:i.gasUsd},artifactKind:"unsigned-transaction-sequence",fromChainId:Number(n),toChainId:Number(o),transactionCount:d.length,transactions:d,requiresApproval:u.requiresApproval??null,minOut:u.minOut??null,durationSeconds:u.durationSeconds??null,destination:d[0]?.to??null,unsigned:!0,signedBy:"user-wallet",driftBps:m,warnings:g,runnersUp:s.routes.filter(b=>b.source!==a).map(b=>({source:b.source,netOut:b.netOut,gasUsd:b.gasUsd})),comparison:{rankedOn:s.rankedOn,sourcesAnswered:s.sourcesAnswered,sourcesTried:s.sourcesTried,improvementBps:s.improvementBps},note:`UNSIGNED. ${d.length} transaction(s) on chain ${n}, crediting chain ${o}. Verify every destination address before signing.`},{provider:"router",kind:"best-bridge"})}var al,cl,ul,Ht,qs=w(()=>{Pe();j();al=/^0x[0-9a-fA-F]{40}$/,cl=new Set(["0x0000000000000000000000000000000000000000","0x000000000000000000000000000000000000dead","0x0000000000000000000000000000000000000001","0x00000000000000000000000000000000000a1ce5"].map(e=>e.toLowerCase())),ul=100,Ht={relay:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:s},a)=>{let{relayPrepare:i}=await Promise.resolve().then(()=>(Lt(),Ut)),c=await i({user:s,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},a);return{transactions:c.transactions||[],amountOut:c.quote?.details?.currencyOut?.amount??null,minOut:c.quote?.details?.currencyOut?.minimumAmount??null,durationSeconds:c.quote?.details?.timeEstimate??null}},lifi:async({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:s,isHolder:a},i)=>{let{lifiPrepare:c}=await Promise.resolve().then(()=>(Ge(),Tr)),u=await c({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o,fromAddress:s,isHolder:a,feeAction:"bridge"},i);return{transactions:u.transaction?[u.transaction]:[],requiresApproval:u.requiresApproval??null,amountOut:u.quote?.estimate?.toAmount??null,minOut:u.quote?.estimate?.toAmountMin??null,durationSeconds:u.quote?.estimate?.executionDuration??null}}}});var Us={};_(Us,{buildTwapSchedule:()=>Ps,normalizeTwapParams:()=>Ds,prepareTwapChunk:()=>gl,simulateTwap:()=>yl});function Ds(e={}){let t=Math.max(pl,Math.min(ml,Number(e.splits)||hl)),r=Math.max(.1,Number(e.windowHours)||bl),n=Math.max(fl,r*3600),o=BigInt(e.amount)/BigInt(t),s=Math.floor(n/t),a=Number(e.slippageBps)||100;if(!e.chainId)throw new Error("twap requires chainId");if(!e.tokenIn||!e.tokenOut)throw new Error("twap requires tokenIn and tokenOut");if(!e.taker)throw new Error("twap requires taker address");if(BigInt(e.amount)<=0n)throw new Error("twap amount must be positive");return{chainId:Number(e.chainId),tokenIn:String(e.tokenIn),tokenOut:String(e.tokenOut),amount:String(e.amount),splits:t,chunkSize:String(o),windowHours:r,windowSec:n,intervalSec:s,taker:String(e.taker),slippageBps:a,status:"planned",createdAt:new Date().toISOString()}}function Ps(e){let t=Ds(e),r=Math.floor(Date.now()/1e3),n=[];for(let o=0;o<t.splits;o++)n.push({splitIndex:o+1,executeAfter:new Date((r+o*t.intervalSec)*1e3).toISOString(),chunkSize:t.chunkSize});return{params:t,schedule:n}}async function gl(e,t,{chainId:r,tokenIn:n,tokenOut:o,chunkSize:s,taker:a,slippageBps:i}=e.params){if(t<1||t>e.params.splits)throw new Error(`splitIndex ${t} out of range 1-${e.params.splits}`);let c=await De({chainId:r,tokenIn:n,tokenOut:o,amountIn:s,taker:a}),u=T(c.transaction??c.tx,{chainId:r,taker:a,tokenIn:n,tokenOut:o,amountIn:s,slippageBps:i,kind:"twap",splitIndex:t,totalSplits:e.params.splits});return{splitIndex:t,chunkSize:s,quote:{amountOut:c.amountOut??c.quote?.amountOut,source:c.source??c.venue,priceImpact:c.priceImpact},...u}}async function yl(e,{quoteFn:t=De}={}){let r=Ps(e),n=[],o=0n,s="unknown";for(let i=0;i<r.params.splits;i++)try{let c=await t({chainId:r.params.chainId,tokenIn:r.params.tokenIn,tokenOut:r.params.tokenOut,amountIn:r.params.chunkSize,taker:r.params.taker}),u=BigInt(c.amountOut??c.quote?.amountOut??"0");o+=u,s=c.source??c.venue??s,n.push({splitIndex:i+1,amountOut:String(u),source:c.source??c.venue})}catch(c){n.push({splitIndex:i+1,error:String(c.message||c).slice(0,200)})}let a=o>0n?(Number(o)/Number(BigInt(r.params.amount))).toFixed(6):null;return{params:r.params,schedule:r.schedule,totalOut:String(o),averagePrice:a,bestSource:s,chunks:n,simulatedAt:new Date().toISOString()}}var pl,ml,fl,hl,bl,Ls=w(()=>{Pe();j();pl=2,ml=100,fl=60,hl=10,bl=6});async function js({srcChainId:e,srcChainTokenIn:t,srcChainTokenInAmount:r,dstChainId:n,dstChainTokenOut:o,slippage:s=100,affiliateFeePercent:a="0"}={}){if(!e||!n||!t||!o||!r)return{error:"debridge quote requires srcChainId, dstChainId, srcChainTokenIn, dstChainTokenOut, srcChainTokenInAmount"};if(!Fs.has(Number(e))||!Fs.has(Number(n)))return{error:`debridge: unsupported chain pair ${e} -> ${n}`};try{let i={srcChainId:String(e),srcChainTokenIn:t,srcChainTokenInAmount:String(r),dstChainId:String(n),dstChainTokenOut:o,slippage:s,affiliateFeePercent:a},c=await y(`${Ms}/dln/order/quote`,{method:"POST",body:JSON.stringify(i),headers:{"content-type":"application/json"}});return c.error?{error:String(c.error)}:{estimation:c.estimation??{},order:c.order??{},fixFee:c.fixFee??"0"}}catch(i){return{error:String(i.message||i).slice(0,200)}}}async function Hs(){try{return{ok:!0,chainCount:(await y(`${Ms}/supported-chains-info`))?.chains?.length??0}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Ms,Fs,Vs=w(()=>{C();j();Ms="https://dln.debridge.finance/v1.0",Fs=new Set([1,10,56,137,8453,42161,43114,59144,534352,7777777,324,5e3,1101,81457])});async function Ks({active:e=!0}={}){let t=Date.now();if(Ue.size&&t-zs<wl)return[...Ue.values()];try{let r=await y(`${Kr}/exchange/currencies?active=${e?"true":"false"}`);Ue.clear();for(let n of r??[])Ue.set(String(n.ticker).toLowerCase(),n);return zs=t,r??[]}catch(r){return Ue.size?[...Ue.values()]:{error:String(r.message||r).slice(0,200)}}}async function Sl(e,t){if(!e||!t)return{error:"changenow minAmount requires fromTicker and toTicker"};try{return{minAmount:(await y(`${Kr}/exchange/min-amount/${encodeURIComponent(e)}_${encodeURIComponent(t)}`))?.minAmount??"0"}}catch(r){return{error:String(r.message||r).slice(0,200)}}}async function vl(e,t,r,{flow:n="standard"}={}){if(!e||!t||!r)return{error:"changenow estimate requires fromTicker, toTicker, fromAmount"};try{let o=new URLSearchParams({fromCurrency:String(e).toLowerCase(),toCurrency:String(t).toLowerCase(),fromAmount:String(r),flow:n}),s=await y(`${Kr}/exchange/estimated-amount?${o}`);return{fromAmount:s?.fromAmount,toAmount:s?.toAmount,rate:s?.rate,flow:s?.flow??n}}catch(o){return{error:String(o.message||o).slice(0,200)}}}async function Qs({fromTicker:e,toTicker:t,fromAmount:r,flow:n}={}){if(!e||!t)return{error:"changenow quote requires fromTicker and toTicker"};let o=await Sl(e,t);if(o.error)return o;let s=r??o.minAmount,a=await vl(e,t,s,{flow:n});if(a.error)return a;let i=await Ks(),c=i.find(d=>String(d?.ticker).toLowerCase()===String(e).toLowerCase()),u=i.find(d=>String(d?.ticker).toLowerCase()===String(t).toLowerCase());return{provider:"changenow",fromTicker:e,toTicker:t,fromAmount:s,toAmount:a.toAmount,estimatedRate:a.rate,minAmount:o.minAmount,flow:a.flow,networkFee:c?.networkFee??null,kycRequired:c?.kycRequired??u?.kycRequired??!1,riskDisclosure:"ChangeNOW is a centralized swap service. Funds are sent to a ChangeNOW deposit address. Not self-custodial during the swap window."}}async function Ws(){try{let e=await Ks();return e?.error?{ok:!1,error:e.error}:{ok:!0,currencyCount:Array.isArray(e)?e.length:0}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Kr,Ue,zs,wl,Gs=w(()=>{C();Kr="https://api.changenow.io/v2",Ue=new Map,zs=0,wl=6e5});async function Xs({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o,fromAddress:s,slippage:a=1}={}){if(!e||!t||!r||!n||!o||!s)return{error:"squid quote requires fromChain, toChain, fromToken, toToken, fromAmount, fromAddress"};try{let i={fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:String(o),fromAddress:s,slippage:a},c=await y(`${xl}/route`,{method:"POST",body:JSON.stringify(i),headers:{"content-type":"application/json"}});return{route:c?.route??{},toAmount:c?.route?.estimate?.toAmount,fee:c?.route?.estimate?.feeCosts}}catch(i){return{error:String(i.message||i).slice(0,200)}}}var xl,Ys=w(()=>{C();xl="https://api.squidrouter.com/v1"});async function Js({srcChainId:e,dstChainId:t,token:r,amount:n,dstGasForCall:o=0,minAmountOut:s="0"}={}){if(!e||!t||!r||!n)return{error:"stargate quote requires srcChainId, dstChainId, token, amount"};try{let a=new URLSearchParams({srcChainId:String(e),dstChainId:String(t),token:r,amount:String(n),dstGasForCall:String(o),minAmountOut:String(s)}),i=await y(`${Al}/quote?${a}`);return{amountOut:i?.amountOut,fee:i?.fee,estimatedTime:i?.estimatedTime}}catch(a){return{error:String(a.message||a).slice(0,200)}}}var Al,Zs=w(()=>{C();Al="https://api.stargate.finance"});async function ei({fromAsset:e,toAsset:t,amount:r,destination:n}={}){if(!e||!t||!r)return{error:"thorchain quote requires fromAsset, toAsset, amount"};try{let o=new URLSearchParams({from_asset:e,to_asset:t,amount:String(r),destination:n||""}),s=await y(`${El}/quote/swap?${o}`);return{expectedAmountOut:s?.expected_amount_out,fees:s?.fees,slippageBps:s?.slippage_bps,inboundAddress:s?.inbound_address,memo:s?.memo,estimatedTime:s?.total_swap_seconds?`${Math.round(s.total_swap_seconds/60)} min`:"unknown"}}catch(o){return{error:String(o.message||o).slice(0,200)}}}var El,ti=w(()=>{C();El="https://midgard.ninerealms.com/v2"});async function ri({fromChainId:e,toChainId:t,fromToken:r,toToken:n,fromAmount:o,userAddress:s}={}){if(!e||!t||!r||!n||!o||!s)return{error:"bungee quote requires fromChainId, toChainId, fromToken, toToken, fromAmount, userAddress"};try{let a=new URLSearchParams({fromChainId:String(e),toChainId:String(t),fromTokenAddress:r,toTokenAddress:n,fromAmount:String(o),userAddress:s,sort:"output",singleTxOnly:"false"}),i=await y(`${kl}/quote?${a}`);return{amountOut:i?.result?.toAmount,feeUsd:i?.result?.totalGasFeesInUsd,route:i?.result?.route,estimatedTime:i?.result?.serviceTime?`${i.result.serviceTime}s`:"unknown"}}catch(a){return{error:String(a.message||a).slice(0,200)}}}var kl,ni=w(()=>{C();kl="https://api.socket.tech/v2"});async function oi({originDomain:e,destinationDomain:t,originToken:r,destinationToken:n,amount:o}={}){if(!e||!t||!r||!n||!o)return{error:"connext quote requires originDomain, destinationDomain, originToken, destinationToken, amount"};try{let s={originDomain:String(e),destinationDomain:String(t),originToken:r,destinationToken:n,amount:String(o)},a=await y(`${Il}/estimate`,{method:"POST",body:JSON.stringify(s),headers:{"content-type":"application/json"}});return{amountOut:a?.amountOut,fee:a?.fee,estimatedTime:a?.estimatedTransferTime}}catch(s){return{error:String(s.message||s).slice(0,200)}}}var Il,si=w(()=>{C();Il="https://api.connext.network"});async function ii({fromChain:e,toChain:t,token:r,amount:n}={}){if(!e||!t||!r||!n)return{error:"wormhole quote requires fromChain, toChain, token, amount"};try{let o=new URLSearchParams({fromChain:String(e),toChain:String(t),token:r,amount:String(n)}),s=await y(`${Cl}/quote?${o}`);return{amountOut:s?.amountOut,fee:s?.fee,estimatedTime:s?.estimatedTime}}catch(o){return{error:String(o.message||o).slice(0,200)}}}var Cl,ai=w(()=>{C();Cl="https://api.portalbridge.com/v1"});function Ol(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||_l).replace(/\/$/,"")}async function ci(e,t={}){if(!e)throw new Error("tokenAddress required");return y(`${Ol(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}var _l,ui=w(()=>{C();_l="https://api.dexscreener.com"});function Rl(e,t){return`0x${Wr.getAmountsOut}`+z(e)+z(64)+z(t.length)+t.map(ot).join("")}function Tl(e){if(!e||e==="0x")return null;let t=e.slice(2);if(t.length<128)return null;let r=Number(BigInt(`0x${t.slice(64,128)}`));if(!Number.isFinite(r)||r<1||r>16)return null;let n=[];for(let o=0;o<r;o++){let s=128+o*64;if(t.length<s+64)return null;n.push(BigInt(`0x${t.slice(s,s+64)}`))}return n}function Qr(e,t="router"){return(e?.venues||[]).find(n=>n.kind===t)?.address??null}function Nl(e,t){let r=Number(t);if(!Number.isFinite(r)||r<0)throw new Error("slippageBps must be a non-negative number");if(r>Gr)throw new Error(`slippageBps ${r} exceeds the ${Gr} bps ceiling. Block and requote or split the order -- do not widen the guard to force a fill.`);return BigInt(e)*BigInt(1e4-Math.floor(r))/10000n}function li(e){let{chainId:t,wrappedNative:r}=e;async function n(o,s,a,i){let c=await B(t,"eth_call",[{to:o,data:Rl(s,a)},"latest"],i);return Tl(c?.result??c)}return{async quote({tokenIn:o,tokenOut:s,amountIn:a,path:i},c={}){let u=Qr(c.scanner);if(!u)return{chainId:t,evidence:A.UNAVAILABLE,reason:"no verified router configured for this chain; quoting stays fail-closed rather than guessing a venue address"};let d=i||[o,s];if(d.some(l=>!/^0x[0-9a-fA-F]{40}$/.test(l||"")))throw new Error("quote requires valid 20-byte addresses");let p=await n(u,a,d,c);return p?{chainId:t,router:u,path:d,amountIn:String(a),amountOut:p[p.length-1].toString(),hops:d.length-1,evidence:A.LIVE,note:"exact-input quote at current reserves; not a guaranteed fill"}:{chainId:t,router:u,path:d,evidence:A.UNKNOWN,reason:"router returned no amounts -- no pool for this path, or the call reverted"}},async sellSimulation({token:o,amountIn:s,base:a},i={}){let c=Qr(i.scanner),u=a||r;if(u&&String(o).toLowerCase()===String(u).toLowerCase())return{chainId:t,token:o,verdict:v.UNKNOWN,evidence:A.UNAVAILABLE,reason:"token is the base asset for this chain, so there is nothing to round-trip against. Sellability must be judged against a different quote asset."};if(!c||!u)return{chainId:t,token:o,verdict:v.UNKNOWN,evidence:A.UNAVAILABLE,reason:c?"no wrappedNative configured for this chain, so no base asset to round-trip against":"no verified router configured for this chain"};let d=await n(c,s,[u,o],i);if(!d)return{chainId:t,token:o,verdict:v.FAIL,evidence:A.LIVE,leg:"buy",reason:"buy leg returned no amounts -- no route in"};let p=d[d.length-1];if(p===0n)return{chainId:t,token:o,verdict:v.FAIL,evidence:A.LIVE,leg:"buy",reason:"buy leg quotes zero output"};let l=await n(c,p,[o,u],i);if(!l)return{chainId:t,token:o,verdict:v.FAIL,evidence:A.LIVE,leg:"sell",bought:p.toString(),reason:"SELL LEG FAILED while the buy leg quoted fine. This is the honeypot signature: do not trade."};let m=l[l.length-1],f=Number(m*10000n/BigInt(s)),g=v.PASS,b="round trip completes with expected fee/impact loss";return f<5e3?(g=v.FAIL,b=`round trip returns only ${(f/100).toFixed(2)}% -- punitive tax or no real liquidity`):f<9e3&&(g=v.CAUTION,b=`round trip returns ${(f/100).toFixed(2)}% -- transfer tax or thin liquidity at this size`),{chainId:t,token:o,base:u,router:c,verdict:g,reason:b,amountIn:String(s),bought:p.toString(),returned:m.toString(),retentionBps:f,evidence:A.LIVE,note:"Quote-level round trip. It does not prove transfer hooks absent at execution time."}},async prepareUnsignedTx({tokenIn:o,tokenOut:s,amountIn:a,recipient:i,slippageBps:c=50,deadlineSeconds:u=900,path:d},p={}){let l=p.scanner,m=Qr(l);if(!m)throw new Error(`chain ${t} has no verified router; preparing a swap stays fail-closed. Add a venue with recorded provenance first (see docs/adding-a-chain.md).`);if(!/^0x[0-9a-fA-F]{40}$/.test(i||""))throw new Error("prepareUnsignedTx requires a valid recipient address");let f=d||[o,s],g=await this.quote({tokenIn:o,tokenOut:s,amountIn:a,path:f},p);if(g.evidence!==A.LIVE)throw new Error(`cannot prepare without a live quote (${g.evidence}: ${g.reason??"no reason given"})`);let b=Nl(g.amountOut,c);if(b<=0n)throw new Error("computed minOut is zero -- refusing to prepare");let S=BigInt(Math.floor(Date.now()/1e3)+Number(u)),I=r&&f[0].toLowerCase()===r.toLowerCase()&&p.useNative,N=I?`0x${Wr.swapExactETHForTokens}`+z(b)+z(128)+ot(i)+z(S)+z(f.length)+f.map(ot).join(""):`0x${Wr.swapExactTokensForTokens}`+z(a)+z(b)+z(160)+ot(i)+z(S)+z(f.length)+f.map(ot).join("");return{unsigned:!0,signedBy:"user-wallet",chainId:t,tx:{to:m,data:N,value:I?`0x${BigInt(a).toString(16)}`:"0x0"},guard:{quotedOut:g.amountOut,minOut:b.toString(),slippageBps:c,maxSlippageBps:Gr,deadline:S.toString()},requires:I?[]:[{step:"approve",token:f[0],spender:m,amount:String(a)}],note:"UNSIGNED. Re-verify the guard against a fresh quote immediately before signing -- a quote-time minimum is not a minimum at broadcast time."}}}}var Wr,z,ot,Gr,di=w(()=>{we();ve();Wr={getAmountsOut:"d06ca61f",swapExactTokensForTokens:"38ed1739",swapExactETHForTokens:"7ff36ab5"},z=e=>BigInt(e).toString(16).padStart(64,"0"),ot=e=>e.slice(2).toLowerCase().padStart(64,"0");Gr=100});function $l(e,t){let r=Number(t);if(!Number.isFinite(r)||r<0)throw new Error("slippageBps must be a non-negative number");if(r>Yr)throw new Error(`slippageBps ${r} exceeds the ${Yr} bps ceiling. Block and requote or split the order -- do not widen the guard to force a fill.`);return BigInt(e)*BigInt(1e4-Math.floor(r))/10000n}function Xr(e,t){return(e?.venues||[]).find(r=>r.kind===t)?.address??null}function fi(e){let{chainId:t,wrappedNative:r}=e;async function n({quoter:s,tokenIn:a,tokenOut:i,amountIn:c,fee:u},d){let p=`0x${pi.quoteExactInputSingle}`+st(a)+st(i)+Ae(c)+Ae(u)+Ae(0),l=await B(t,"eth_call",[{to:s,data:p},"latest"],d).catch(()=>null),m=l?.result??l;if(!m||m==="0x"||m.length<66)return null;let f=BigInt(`0x${m.slice(2,66)}`);return f>0n?f:null}async function o({quoter:s,tokenIn:a,tokenOut:i,amountIn:c},u){let d=[],p=null;for(let l of Bl){let m=await n({quoter:s,tokenIn:a,tokenOut:i,amountIn:c,fee:l},u);d.push({fee:l,amountOut:m?m.toString():null}),m&&(!p||m>p.amountOut)&&(p={fee:l,amountOut:m})}return{best:p,tried:d}}return{async quote({tokenIn:s,tokenOut:a,amountIn:i},c={}){let u=Xr(c.scanner,"quoter");if(!u)return{chainId:t,evidence:A.UNAVAILABLE,reason:"no verified quoter configured for this chain; quoting stays fail-closed rather than guessing a venue address"};for(let l of[s,a])if(!mi.test(l||""))throw new Error("quote requires valid 20-byte addresses");let{best:d,tried:p}=await o({quoter:u,tokenIn:s,tokenOut:a,amountIn:i},c);return d?{chainId:t,venue:"uniswap-v3",quoter:u,tokenIn:s,tokenOut:a,amountIn:String(i),amountOut:d.amountOut.toString(),fee:d.fee,triedFeeTiers:p,evidence:A.LIVE,note:"exact-input single-hop quote at current tick; not a guaranteed fill"}:{chainId:t,quoter:u,tokenIn:s,tokenOut:a,triedFeeTiers:p,evidence:A.UNKNOWN,reason:"no fee tier returned a quote -- no V3 pool for this pair, or no liquidity"}},async sellSimulation({token:s,amountIn:a,base:i},c={}){let u=Xr(c.scanner,"quoter"),d=i||r;if(d&&String(s).toLowerCase()===String(d).toLowerCase())return{chainId:t,token:s,verdict:v.UNKNOWN,evidence:A.UNAVAILABLE,reason:"token is the base asset for this chain, so there is nothing to round-trip against. Sellability must be judged against a different quote asset."};if(!u||!d)return{chainId:t,token:s,verdict:v.UNKNOWN,evidence:A.UNAVAILABLE,reason:u?"no wrappedNative configured, so there is no base asset to round-trip against":"no verified quoter configured for this chain"};let p=await o({quoter:u,tokenIn:d,tokenOut:s,amountIn:a},c);if(!p.best)return{chainId:t,token:s,verdict:v.FAIL,evidence:A.LIVE,leg:"buy",reason:"no V3 pool priced the buy leg on any fee tier"};let l=await o({quoter:u,tokenIn:s,tokenOut:d,amountIn:p.best.amountOut},c);if(!l.best)return{chainId:t,token:s,verdict:v.FAIL,evidence:A.LIVE,leg:"sell",bought:p.best.amountOut.toString(),reason:"SELL LEG FAILED while the buy leg quoted fine. This is the honeypot signature: do not trade."};let m=l.best.amountOut,f=Number(m*10000n/BigInt(a)),g=v.PASS,b="round trip completes with expected fee/impact loss";return f<5e3?(g=v.FAIL,b=`round trip returns only ${(f/100).toFixed(2)}% -- punitive tax or no real liquidity`):f<9e3&&(g=v.CAUTION,b=`round trip returns ${(f/100).toFixed(2)}% -- transfer tax or thin liquidity at this size`),{chainId:t,venue:"uniswap-v3",token:s,base:d,verdict:g,reason:b,amountIn:String(a),bought:p.best.amountOut.toString(),returned:m.toString(),retentionBps:f,buyFee:p.best.fee,sellFee:l.best.fee,evidence:A.LIVE,note:"Quote-level round trip. It does not prove transfer hooks absent at execution time."}},async prepareUnsignedTx({tokenIn:s,tokenOut:a,amountIn:i,recipient:c,slippageBps:u=50,fee:d},p={}){let l=Xr(p.scanner,"router");if(!l)throw new Error(`chain ${t} has no verified V3 router; preparing a swap stays fail-closed. Add a venue with recorded provenance first (see docs/adding-a-chain.md).`);if(!mi.test(c||""))throw new Error("prepareUnsignedTx requires a valid recipient address");let m=await this.quote({tokenIn:s,tokenOut:a,amountIn:i},p);if(m.evidence!==A.LIVE)throw new Error(`cannot prepare without a live quote (${m.evidence}: ${m.reason??"no reason given"})`);let f=d??m.fee,g=$l(m.amountOut,u);if(g<=0n)throw new Error("computed minOut is zero -- refusing to prepare");let b=`0x${pi.exactInputSingle}`+st(s)+st(a)+Ae(f)+st(c)+Ae(i)+Ae(g)+Ae(0);return{unsigned:!0,signedBy:"user-wallet",chainId:t,venue:"uniswap-v3",tx:{to:l,data:b,value:"0x0"},guard:{quotedOut:m.amountOut,minOut:g.toString(),slippageBps:u,maxSlippageBps:Yr,fee:f},requires:[{step:"approve",token:s,spender:l,amount:String(i)}],note:"UNSIGNED. Re-verify the guard against a fresh quote immediately before signing -- a quote-time minimum is not a minimum at broadcast time."}}}}var Bl,pi,Ae,st,mi,Yr,hi=w(()=>{we();ve();Bl=[100,500,3e3,1e4],pi={quoteExactInputSingle:"c6a5026a",exactInputSingle:"04e45aaf"},Ae=e=>BigInt(e).toString(16).padStart(64,"0"),st=e=>e.slice(2).toLowerCase().padStart(64,"0"),mi=/^0x[0-9a-fA-F]{40}$/,Yr=100});function bi(e){if(!e||e==="0x")return null;try{return BigInt(e)}catch{return null}}function gi(e){if(!e||e==="0x")return null;let t=e.slice(2);if(t.length>=128){let n=Number(BigInt(`0x${t.slice(64,128)}`));if(n>0&&n<=256&&t.length>=128+n*2){let o=t.slice(128,128+n*2),s=Buffer.from(o,"hex").toString("utf8").replace(/\0+$/,"");if(s)return s}}return Buffer.from(t.slice(0,64),"hex").toString("utf8").replace(/\0+$/,"")||null}function ql(e){let{chainId:t}=e;async function r(n,o,s){return B(t,"eth_call",[{to:n,data:o},"latest"],s)}return{async blockNumber(n={}){let o=await Ot(t,n);return{chainId:t,blockNumber:o?.blockNumber??o,evidence:A.LIVE}},async nativeBalance(n,o={}){let s=await jo(t,n,o);return{chainId:t,address:n,wei:s?.wei??s?.balance??null,symbol:e.nativeCurrency?.symbol??null,decimals:e.nativeCurrency?.decimals??18,evidence:A.LIVE}},async tokenBalance({token:n,owner:o},s={}){let a=await Vo({chainId:t,token:n,owner:o},s);return{chainId:t,token:n,owner:o,raw:a?.balance??a,evidence:A.LIVE}},async resolveToken(n,o={}){if(!/^0x[0-9a-fA-F]{40}$/.test(n||""))return{chainId:t,token:n,evidence:A.UNKNOWN,error:"resolveToken needs a 20-byte address; symbol lookup is a market-data concern"};let[s,a,i,c]=await Promise.all([r(n,Vt.decimals,o).catch(()=>null),r(n,Vt.symbol,o).catch(()=>null),r(n,Vt.name,o).catch(()=>null),r(n,Vt.totalSupply,o).catch(()=>null)]),u=bi(s?.result??s),d=u!==null||a?.result||i?.result;return{chainId:t,address:n,decimals:u===null?null:Number(u),symbol:gi(a?.result??a),name:gi(i?.result??i),totalSupply:(bi(c?.result??c)??null)?.toString()??null,evidence:d?A.LIVE:A.UNKNOWN,warning:d?void 0:"no ERC-20 metadata returned -- may not be a token contract"}},async resolvePools(n,o={}){let s=e.dexscreenerSlug;if(!s)return{chainId:t,token:n,pools:[],evidence:A.UNAVAILABLE,reason:"no dexscreenerSlug configured for this chain; pool discovery is unavailable rather than guessed"};let a=await ci(n,o).catch(()=>null),c=(a?.pairs||a?.data?.pairs||[]).filter(u=>String(u.chainId).toLowerCase()===String(s).toLowerCase()).map(u=>({pair:u.pairAddress,dex:u.dexId,base:u.baseToken?.address,quote:u.quoteToken?.address,liquidityUsd:u.liquidity?.usd??null,priceUsd:u.priceUsd??null,volume24hUsd:u.volume?.h24??null,createdAt:u.pairCreatedAt??null})).sort((u,d)=>(d.liquidityUsd??0)-(u.liquidityUsd??0));return{chainId:t,token:n,pools:c,evidence:c.length?A.LIVE:A.UNKNOWN}},async scanBlocks({fromBlock:n,toBlock:o,address:s,topics:a,chunkSize:i=2e3}={},c={}){if(!Number.isInteger(n)||!Number.isInteger(o))throw new Error("scanBlocks requires integer fromBlock and toBlock");if(o<n)throw new Error("toBlock must be >= fromBlock");let u=[],d=[];for(let p=n;p<=o;p+=i){let l=Math.min(p+i-1,o);d.push([p,l])}for(let[p,l]of d){let m={fromBlock:`0x${p.toString(16)}`,toBlock:`0x${l.toString(16)}`};s&&(m.address=s),a&&(m.topics=a);let f=await B(t,"eth_getLogs",[m],c).catch(g=>({error:String(g?.message||g)}));if(f?.error)return{chainId:t,fromBlock:n,toBlock:o,logs:u,complete:!1,failedAt:[p,l],error:f.error,evidence:A.UNKNOWN};for(let g of f?.result??f??[])u.push(g)}return{chainId:t,fromBlock:n,toBlock:o,logs:u,complete:!0,chunks:d.length,evidence:A.LIVE}},async scoreRisk(n,o={}){let s=[],a=v.PASS,i=d=>{let p={[v.PASS]:0,[v.CAUTION]:1,[v.UNKNOWN]:2,[v.FAIL]:3};p[d]>p[a]&&(a=d)},c=await this.resolveToken(n,o);c.evidence!==A.LIVE?(s.push({check:"erc20-metadata",result:v.UNKNOWN,detail:c.warning}),i(v.UNKNOWN)):s.push({check:"erc20-metadata",result:v.PASS,detail:`${c.symbol} / ${c.decimals}d`});let u=await this.resolvePools(n,o);if(u.evidence===A.UNAVAILABLE)s.push({check:"liquidity",result:v.UNKNOWN,detail:u.reason}),i(v.UNKNOWN);else if(!u.pools.length)s.push({check:"liquidity",result:v.FAIL,detail:"no pool with liquidity found"}),i(v.FAIL);else{let d=u.pools[0],p=d.liquidityUsd??0;p<5e3?(s.push({check:"liquidity",result:v.CAUTION,detail:`top pool only $${p}`}),i(v.CAUTION)):s.push({check:"liquidity",result:v.PASS,detail:`$${p} on ${d.dex}`}),d.createdAt&&Date.now()-d.createdAt<24*3600*1e3&&(s.push({check:"age",result:v.CAUTION,detail:"pool under 24h old"}),i(v.CAUTION))}if(typeof this.sellSimulation=="function"){let d=await this.sellSimulation({token:n,amountIn:(10n**16n).toString()},o).catch(p=>({verdict:v.UNKNOWN,reason:String(p?.message||p)}));s.push({check:"sellability",result:d.verdict,detail:d.retentionBps!=null?`round trip returns ${(d.retentionBps/100).toFixed(2)}% -- ${d.reason}`:d.reason}),i(d.verdict)}else s.push({check:"sellability",result:v.UNKNOWN,detail:"no verified router on this chain, so a round-trip sell simulation cannot run. Treat as unproven -- a buy path is not an exit path."}),i(v.UNKNOWN);return{chainId:t,token:n,verdict:a,checks:s,note:"Structural checks only. UNKNOWN is not PASS. A token is not tradeable until a sell simulation succeeds."}}}}function Jr(e){let r={...ql(e)},n=new Set((e.venues||[]).map(s=>s.kind));e.venueKind==="uniswap-v3"&&n.has("quoter")&&n.has("router")?Object.assign(r,fi({chainId:e.chainId,wrappedNative:e.wrappedNative})):e.venueKind==="uniswap-v2"&&n.has("router")&&Object.assign(r,li({chainId:e.chainId,wrappedNative:e.wrappedNative}));let o={};for(let[s,a]of Object.entries(r))o[s]=a.bind(r);return{key:e.key,chainId:e.chainId,name:e.name,rpcEnv:e.rpcEnv,nativeCurrency:e.nativeCurrency,explorer:e.explorer,venues:e.venues||[],capabilities:o}}var Vt,yi=w(()=>{we();ui();ve();di();hi();Vt={decimals:"0x313ce567",symbol:"0x95d89b41",name:"0x06fdde03",totalSupply:"0x18160ddd",owner:"0x8da5cb5b"}});function wi(){return it.map(e=>Bt(Jr(e)))}function Si(e){return Bt(Jr(e))}var it,Zr=w(()=>{yi();ve();it=Object.freeze([{key:"ethereum",chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://etherscan.io",dexscreenerSlug:"ethereum",venueKind:"uniswap-v3",wrappedNative:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.71 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}}]},{key:"optimism",chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://optimistic.etherscan.io",dexscreenerSlug:"optimism",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1905.23 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}}]},{key:"bsc",chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],nativeCurrency:{symbol:"BNB",decimals:18},explorer:"https://bscscan.com",dexscreenerSlug:"bsc",venueKind:"uniswap-v3",wrappedNative:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",venues:[{kind:"quoter",address:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WBNB->USDC fee 500 quoted 413.86 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}},{kind:"router",address:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}}]},{key:"polygon",chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],nativeCurrency:{symbol:"POL",decimals:18},explorer:"https://polygonscan.com",dexscreenerSlug:"polygon",venueKind:"uniswap-v3",wrappedNative:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WMATIC->USDC fee 500 quoted 0.0720 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}}]},{key:"stable",chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],nativeCurrency:{symbol:"USDT0",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x5d442b349590a6048Eb2dC0eC346cAA5F47A9ab5",venues:[{kind:"quoter",address:"0xb070179E7032CdA868b53e6C1742F80c9e940d1A",label:"Uniswap V3 QuoterV2 (canonical)",verified:{method:"Stable is on the OFFICIAL Uniswap v3 Deployments List (governance-recognised 2026-05-12, UAC process completed 2026-04, deployed by Protofire), so this is a canonical deployment rather than a fork. eth_getCode returned 8273 bytes, the same size as the canonical quoter on the seven already-verified chains. Functional probe on a live pool (TOAST -> USDT0, fee 10000): 100 in -> 0.000003, 1000 -> 0.000031, 10000 -> 0.000319 USDT0. Output scales monotonically with input, which is a working quoter answering, not a revert. Two of three sampled pools carry non-zero liquidity. NOTE: the pools discovered so far are thin, so real routing size is limited -- the venue is proved, deep liquidity is not.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:988}},{kind:"router",address:"0x32eaf9B5d5F2CD7361c5012890C943D7de84C22a",label:"Uniswap SwapRouter02 (canonical)",verified:{method:"eth_getCode returned 24497 bytes. Cross-checked on-chain rather than trusted from docs: router.factory() returns 0x88f0a512ef09175d456bc9547f914f48c013e4aa, the same v3 core factory that created the pools quoted above, and router.WETH9() returns the wrappedNative recorded on this chain entry. Address published in the Stable docs DEX reference and the Uniswap deployments list.",source:"docs.stable.xyz/en/reference/dexes + on-chain factory()/WETH9() round-trip",date:"2026-08-05",chainId:988}}]},{key:"hyperevm",chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],nativeCurrency:{symbol:"HYPE",decimals:18},dexscreenerSlug:"hyperevm",venueKind:"uniswap-v3",wrappedNative:"0x5555555555555555555555555555555555555555",venues:[{kind:"quoter",address:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",label:"HyperSwap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle(1 WHYPE -> USDT0) returned live output on all four fee tiers (100: 57.3385, 500: 57.4187, 3000: 57.3237, 10000: 56.1963 USDT0). Decimals read on-chain: WHYPE 18, USDT0 6. Best tier checked against an INDEPENDENT control the same minute -- Hyperliquid allMids put HYPE at 57.3205, so the pool is 0.171% from the perp mid, which is the right shape for fee plus impact rather than a wrong contract or a decimals bug.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}},{kind:"router",address:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D",label:"HyperSwap V3 SwapRouter",verified:{method:"eth_getCode returned 12070 bytes, and it is the router paired with the quoter proved above -- the same pair already shipped in UNI_V3_VENUES[999].hyperswap, which is the map the quote/prepare path actually routes through.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}}]},{key:"abstract",chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x3439153EB7AF838Ad19d56E1571FBD09333C2809",venues:[{kind:"quoter",address:"0x728BD3eC25D5EDBafebB84F3d67367Cd9EBC7693",label:"Uniswap V3 QuoterV2 (Abstract deployment)",verified:{method:"Abstract is a ZK-stack chain, so CREATE2 addresses differ and the canonical Uniswap addresses are NOT valid here -- probing them returns codesize 0, which is what previously made this chain look like it had no V3 at all. Found the real deployment from live traffic instead: scanned recent Swap(...) logs, took the busiest pool, read pool.factory() = 0xa1160e73b63f322ae88cc2d8e700833e71d0b2a1, then enumerated that factory's deployer (0xf3d63166F0Ca56C3c1A3508FcE03Ff0Cf3Fb691e) and probed each of its 56 contracts with a real quoteExactInputSingle call. Exactly one answered: 1 WETH -> 1846.475731 USDC.e at fee 500. Independent sanity check: the pool's own slot0() spot price is 1873.11 USDC.e per WETH, so the quoter sits ~1.4% below spot, the right shape for fee plus price impact on this size.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:2741}},{kind:"router",address:"0x7712FA47387542819d4E35A23f8116C90C18767C",label:"Uniswap SwapRouter02 (Abstract deployment)",verified:{method:"eth_getCode returned 167392 bytes and the runtime contains the exactInputSingle selector. router.factory() matches the factory proved above and router.WETH9() matches the wrappedNative on this entry. Chosen over its byte-identical twin (0xfD6257F4...) because this is the address real users actually route through: it appeared as tx.to on live swaps against the WETH/USDC.e pool.",source:"on-chain factory()/WETH9() round-trip + live swap tx.to sampling",date:"2026-08-05",chainId:2741}}]},{key:"robinhood",chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC","ROBINHOOD_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},dexscreenerSlug:"robinhood",venueKind:"uniswap-v3",wrappedNative:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",venues:[{kind:"quoter",address:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDG fee 100 quoted 1866.58 USDG, and USDG->CASHCAT fee 10000 quoted a live amount). A contract that correctly prices known pairs IS a working V3 quoter",source:"live eth_call against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"router",address:"0xcaf681a66d020601342297493863e78c959e5cb2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode (24497 bytes) on this chain and the paired quoter at the same deployment passed a live functional quote",source:"live eth_getCode against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"factory",address:"0x1f7d7550b1b028f7571e69a784071f0205fd2efa",label:"Uniswap V3 Factory",verified:{method:"eth_getCode returned real bytecode (24535 bytes) and a PoolCreated log scan over this factory returned 76 pools in ~9000 recent blocks",source:"live eth_getLogs against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}}]},{key:"base",chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://basescan.org",dexscreenerSlug:"base",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",venues:[{kind:"quoter",address:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",label:"Uniswap V3 QuoterV2 (Base)",verified:{method:"functional probe: quoteExactInputSingle returned WETH->USDC at fee 500 = 1908.44 USDC, a live sane price. The canonical mainnet quoter address also has bytecode on Base but does NOT price this pair, which is exactly the false positive a codesize-only check accepts",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router",address:"0x2626664c2603336E57B271c5C0b26F421741e481",label:"Uniswap V3 SwapRouter02 (Base)",verified:{method:"eth_getCode returned real bytecode and the paired Base quoter passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router-v2",address:"0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",label:"Uniswap V2 Router02 (Base)",verified:{method:"eth_getCode returned 17891 bytes; live getAmountsOut on WETH->USDC round-tripped to 98.75% (2x0.30% fee + impact)",source:"https://docs.uniswap.org/contracts/v2/reference/smart-contracts/v2-deployments",date:"2026-07-30",chainId:8453}}]},{key:"arbitrum",chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://arbiscan.io",dexscreenerSlug:"arbitrum",venueKind:"uniswap-v3",wrappedNative:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.72 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}}]},{key:"avalanche",chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],nativeCurrency:{symbol:"AVAX",decimals:18},explorer:"https://snowtrace.io",dexscreenerSlug:"avalanche",venueKind:"uniswap-v3",wrappedNative:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",venues:[{kind:"quoter",address:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WAVAX->USDC fee 500 quoted 6.48 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}},{kind:"router",address:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}}]}])});import{Interface as Ii,getAddress as Dl,id as Ci}from"ethers";function Le(e){return e?.cache===!1?!1:!e?.fetchImpl||e.cache===!0}function rn(e,t,r){let n=e.get(t);return n?Date.now()-n.at>r?(e.delete(t),null):n:null}function zt(e,t,r,n){for(e.delete(t),e.set(t,{at:Date.now(),value:r});e.size>n;){let o=e.keys().next();if(o.done)break;e.delete(o.value)}}function Zl(e,t){try{return Dl(e).toLowerCase()}catch{throw new Error(`${t} must be a valid EVM address`)}}function ed(e){return`0x${e.slice(2).toLowerCase().padStart(64,"0")}`}function ki(e){return`0x${String(e).slice(-40).toLowerCase()}`}function td({unlimited:e,spenderLabel:t,lastActivityAt:r}){if(e)return"unlimited";if(!t)return"unknown-spender";if(r){let n=Date.parse(r);if(Number.isFinite(n)&&Date.now()-n>Ql)return"stale"}return"scoped"}function rd(e,t,r){if(r)return"UNLIMITED";if(t==null)return e.toString();let n=10n**BigInt(t),o=e/n,s=e%n;if(s===0n)return o.toLocaleString("en-US");let a=s.toString().padStart(t,"0").replace(/0+$/,"").slice(0,6);return`${o.toLocaleString("en-US")}${a?`.${a}`:""}`}async function nd(e,t,r,n){let o=`${e}:${t}`,s=n?.get(o);if(s)return s;if(Le(r)){let i=rn(Ai,o,Wl);if(i)return i.value}let a=(async()=>{let i=async p=>{try{let l=vi.encodeFunctionData(p,[]),m=await B(e,"eth_call",[{to:t,data:l},"latest"],r);return!m||m==="0x"?null:vi.decodeFunctionResult(p,m)[0]}catch{return null}},[c,u]=await Promise.all([i("decimals"),i("symbol")]),d={decimals:c==null?null:Number(c),symbol:u==null?null:String(u).slice(0,24)};return Le(r)&&zt(Ai,o,d,Yl),d})();return n?.set(o,a),a}async function od(e,t,r){let n=Math.min(Math.max(Number(r.lookbackBlocks)||Ul,1),Ll),o=await Ot(e,r);if(!Number.isFinite(o))throw new Error("chain head unavailable");let s=Math.max(0,o-n),a=await B(e,"eth_getLogs",[{fromBlock:`0x${s.toString(16)}`,toBlock:"latest",topics:[Pl,ed(t)]}],r);if(!Array.isArray(a))throw new Error("log scan returned no array");let i=new Map;for(let c of a){let u=String(c?.address||"").toLowerCase(),d=c?.topics?.[2];!u||!d||i.set(`${u}:${ki(d)}`,{token:u,spender:ki(d)})}return{pairs:[...i.values()],fromBlock:s,toBlock:o}}function sd(e){return(Vl[e]||[]).flatMap(r=>Ml.map(n=>({token:r.address,spender:n.address,symbol:r.symbol,decimals:r.decimals})))}async function id(e,t,r={}){let n=[],o="direct-probe",s=null,a=sd(e),i=tn(e),c=Le(r)&&rn(en,e,Gl)?.value===!1;if(a.length===0&&i.length===0&&c)return{scan:{chainId:e,status:"unconfigured",method:o,error:"no Approval log access and no candidate token or collection set for this chain"},approvals:[]};try{let u=await od(e,t,r);n=u.pairs,o="log-scan",s={fromBlock:u.fromBlock,toBlock:u.toBlock},Le(r)&&zt(en,e,!0,64)}catch{if(Le(r)&&zt(en,e,!1,64),n=a,n.length===0&&i.length===0)return{scan:{chainId:e,status:"unconfigured",method:o,error:"no Approval log access and no candidate token or collection set for this chain"},approvals:[]}}try{let u=new Map,p=(await bt(n,r.concurrency||4,async m=>{try{let f=await Ho({chainId:e,token:m.token,owner:t,spender:m.spender},r),g=BigInt(f.allowance);if(g<=0n)return null;let b=m.symbol?{symbol:m.symbol,decimals:m.decimals??null}:await nd(e,m.token,r,u),S=g>=Kl,I=Fl[m.spender]||null;return{id:`${e}:${m.token}:${m.spender}`,chainId:e,standard:"erc20",token:m.token,tokenSymbol:b.symbol,decimals:b.decimals,spender:m.spender,spenderLabel:I,allowance:g.toString(),allowanceDisplay:rd(g,b.decimals,S),unlimited:S,lastActivityAt:null,risk:td({unlimited:S,spenderLabel:I,lastActivityAt:null})}}catch{return null}})).filter(Boolean),l=await cd(e,t,r);return{scan:{chainId:e,status:"ok",method:o,pairsProbed:n.length,collectionsProbed:tn(e).length,...s||{}},approvals:[...p,...l]}}catch(u){return{scan:{chainId:e,status:"unavailable",method:o,error:String(u?.message||u).slice(0,200)},approvals:[]}}}async function ad(e,t,r,n,o){try{let s=xi.encodeFunctionData("isApprovedForAll",[r,n]),a=await B(e,"eth_call",[{to:t,data:s},"latest"],o);return!a||a==="0x"?null:!!xi.decodeFunctionResult("isApprovedForAll",a)[0]}catch{return null}}function tn(e){return(Hl[e]||[]).flatMap(r=>jl.map(n=>({collection:r.address,collectionName:r.name,operator:n.address,operatorLabel:n.label})))}async function cd(e,t,r){let n=tn(e);return n.length===0?[]:(await bt(n,r.concurrency||4,async s=>await ad(e,s.collection,t,s.operator,r)!==!0?null:{id:`${e}:${s.collection}:${s.operator}:all`,chainId:e,standard:"erc721",token:s.collection,tokenSymbol:s.collectionName,decimals:null,spender:s.operator,spenderLabel:s.operatorLabel,allowance:null,allowanceDisplay:"ALL ITEMS",unlimited:!0,lastActivityAt:null,risk:"operator-all"})).filter(Boolean)}async function _i(e={},t={}){let r=Zl(e.owner||e.address,"owner"),n=new Map(it.map(m=>[m.chainId,m])),o=Array.isArray(e.chainIds)&&e.chainIds.length?[...new Set(e.chainIds.map(Number))].filter(m=>n.has(m)):[...n.keys()],s=`${r}:${[...o].sort((m,f)=>m-f).join(",")}:${e.lookbackBlocks??""}`,a=Le(t)&&!e.refresh;if(a){let m=rn(Ei,s,Xl);if(m)return{...m.value,cached:!0,cachedAgeMs:Date.now()-m.at}}let i=await bt(o,e.concurrency||3,m=>id(m,r,{...t,lookbackBlocks:e.lookbackBlocks})),c=i.flatMap(m=>m.approvals),u=i.map(m=>m.scan),d=u.find(m=>m.method==="log-scan"&&m.toBlock),p=u.some(m=>m.method==="direct-probe"&&m.status==="ok"),l={provider:"approvals",operation:"scan",readOnly:!0,queriedAt:new Date().toISOString(),owner:r,scannedRange:d?`last ${d.toBlock-d.fromBlock} blocks`:p?"known routers, live allowance probe":null,approvals:c,scans:u,warnings:["Approval discovery is scoped. Log scanning is used where the endpoint permits it; otherwise a curated router set is probed directly. An empty result means nothing was found in that scope, not that the wallet is safe.","NFT operator approval (setApprovalForAll) is checked against a curated collection and marketplace set on supported chains only. A collection outside that set is not checked."]};return a&&zt(Ei,s,l,Jl),{...l,cached:!1,cachedAgeMs:0}}var vi,xi,Pl,yh,Ul,Ll,Fl,Ml,jl,Hl,Vl,zl,Kl,Ql,Wl,Gl,Xl,Yl,Jl,Ai,en,Ei,Oi=w(()=>{Zr();C();we();vi=new Ii(["function decimals() view returns (uint8)","function symbol() view returns (string)"]),xi=new Ii(["function isApprovedForAll(address owner, address operator) view returns (bool)","function name() view returns (string)"]),Pl=Ci("Approval(address,address,uint256)"),yh=Ci("ApprovalForAll(address,address,bool)"),Ul=1e4,Ll=2e5,Fl=Object.freeze({"0x1111111254eeb25477b68fb85ed929f73a960582":"1inch v5 Router","0x111111125421ca6dc452d289314280a0f8842a65":"1inch v6 Router","0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45":"Uniswap Universal Router","0x3fc91a3afd70395cd496c647d5a6cc9d4b2b7fad":"Uniswap Universal Router","0x000000000022d473030f116ddee9f6b43ac78ba3":"Permit2","0xe592427a0aece92de3edee1f18e0157c05861564":"Uniswap v3 Router","0x7a250d5630b4cf539739df2c5dacb4c659f2488d":"Uniswap v2 Router","0xdef1c0ded9bec7f1a1670819833240f027b25eff":"0x Exchange Proxy","0x2626664c2603336e57b271c5c0b26f421741e481":"Uniswap SwapRouter02 (Base)","0x6131b5fae19ea4f9d964eac0408e4408b66337b5":"KyberSwap Meta Aggregator","0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48":"USDC (token contract)"}),Ml=Object.freeze([{address:"0x000000000022d473030f116ddee9f6b43ac78ba3",label:"Permit2"},{address:"0x1111111254eeb25477b68fb85ed929f73a960582",label:"1inch v5 Router"},{address:"0x111111125421ca6dc452d289314280a0f8842a65",label:"1inch v6 Router"},{address:"0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45",label:"Uniswap Universal Router"},{address:"0xe592427a0aece92de3edee1f18e0157c05861564",label:"Uniswap v3 Router"},{address:"0x7a250d5630b4cf539739df2c5dacb4c659f2488d",label:"Uniswap v2 Router"},{address:"0xdef1c0ded9bec7f1a1670819833240f027b25eff",label:"0x Exchange Proxy"},{address:"0x2626664c2603336e57b271c5c0b26f421741e481",label:"Uniswap SwapRouter02"}]),jl=Object.freeze([{address:"0x1e0049783f008a0085193e00003d00cd54003c71",label:"OpenSea Seaport Conduit"},{address:"0x00000000000000adc04c56bf30ac9d3c0aaf14dc",label:"Seaport 1.5"},{address:"0x0000000000000068f116a894984e2db1123eb395",label:"Seaport 1.6"},{address:"0x00000000000001ad428e4906ae43d8f9852d0dd6",label:"Seaport 1.4"},{address:"0x000000000000ad05ccc4f10045630fb830b95127",label:"Blur Marketplace"},{address:"0x00000000000000000000000000000000000000a5",label:"Blur Execution Delegate"},{address:"0xf42aa99f011a1fa7cda90e5e98b277e306bca83e",label:"Rarible Transfer Proxy"},{address:"0x000000000022d473030f116ddee9f6b43ac78ba3",label:"Permit2"}]),Hl=Object.freeze({1:[{address:"0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",name:"Bored Ape Yacht Club"},{address:"0x60e4d786628fea6478f785a6d7e704777c86a7c6",name:"Mutant Ape Yacht Club"},{address:"0xed5af388653567af2f388e6224dc7c4b3241c544",name:"Azuki"},{address:"0x8a90cab2b38dba80c64b7734e58ee1db38b8992e",name:"Doodles"},{address:"0x49cf6f5d44e70224e2e23fdcdd2c053f30ada28b",name:"CloneX"},{address:"0x23581767a106ae21c074b2276d25e5c3e136a68b",name:"Moonbirds"}]}),Vl=Object.freeze({1:[{address:"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",symbol:"USDC",decimals:6},{address:"0xdac17f958d2ee523a2206206994597c13d831ec7",symbol:"USDT",decimals:6},{address:"0x6b175474e89094c44da98b954eedeac495271d0f",symbol:"DAI",decimals:18},{address:"0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2",symbol:"WETH",decimals:18},{address:"0x2260fac5e5542a773aa44fbcfedf7c193bc2c599",symbol:"WBTC",decimals:8}],8453:[{address:"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",symbol:"USDC",decimals:6},{address:"0x4200000000000000000000000000000000000006",symbol:"WETH",decimals:18}],42161:[{address:"0xaf88d065e77c8cc2239327c5edb3a432268e5831",symbol:"USDC",decimals:6},{address:"0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9",symbol:"USDT",decimals:6},{address:"0x82af49447d8a07e3bd95bd0d56f35241523fbab1",symbol:"WETH",decimals:18}],10:[{address:"0x0b2c639c533813f4aa9d7837caf62653d097ff85",symbol:"USDC",decimals:6},{address:"0x4200000000000000000000000000000000000006",symbol:"WETH",decimals:18}],137:[{address:"0x3c499c542cef5e3811e1192ce70d8cc03d5c3359",symbol:"USDC",decimals:6},{address:"0xc2132d05d31c914a87c6611c10748aeb04b58e8f",symbol:"USDT",decimals:6}]}),zl=(1n<<256n)-1n,Kl=zl/2n,Ql=4320*60*60*1e3,Wl=360*60*1e3,Gl=600*1e3,Xl=45*1e3,Yl=512,Jl=128,Ai=new Map,en=new Map,Ei=new Map});var Ni={};_(Ni,{aggregateBridgeQuotes:()=>Ri,bridgeAggregatorHealth:()=>ld,checkRevokeNeeded:()=>Ti,scanBridgeRoutes:()=>ud});async function Ri(e={}){let{fromChainId:t,toChainId:r,tokenIn:n,tokenOut:o,amount:s,taker:a,fromSymbol:i="?",toSymbol:c="?",fromDecimals:u=18,toDecimals:d=18}=e,p=[],l=[],m=js({srcChainId:t,srcChainTokenIn:n,srcChainTokenInAmount:s,dstChainId:r,dstChainTokenOut:o}).then(h=>h.error?(l.push(`debridge: ${h.error}`),null):{provider:"debridge",amountOut:h.estimation?.dstChainTokenOut?.amount??h.estimation?.toAmount,feeUsd:h.estimation?.fixFee??h.fixFee,estimatedTime:h.estimation?.execution?.estimatedTransferTime?`${h.estimation.execution.estimatedTransferTime}s`:"unknown",preparable:!0,raw:h}).catch(h=>(l.push(`debridge: ${h.message}`),null)),f=nt({fromChainId:t,toChainId:r,tokenIn:n,tokenOut:o,amountIn:s,taker:a}).then(h=>!h||h.error?(l.push(`lifi: ${h?.error??"no route"}`),null):{provider:"lifi-relay",amountOut:h.amountOut??h.quote?.amountOut,feeUsd:h.feeUsd??h.totalFee,estimatedTime:h.estimatedTime??h.duration??"unknown",preparable:!!h.transaction,raw:h}).catch(h=>(l.push(`lifi: ${h.message}`),null)),g=Xs({fromChain:t,toChain:r,fromToken:n,toToken:o,fromAmount:s,fromAddress:a}).then(h=>h.error?(l.push(`squid: ${h.error}`),null):{provider:"squid",amountOut:h.toAmount,feeUsd:Array.isArray(h.fee)?h.fee.reduce((q,U)=>q+(Number(U.amountUsd)||0),0):null,estimatedTime:"30s - 3min",preparable:!1,raw:h}).catch(h=>(l.push(`squid: ${h.message}`),null)),b=Js({srcChainId:t,dstChainId:r,token:n,amount:s}).then(h=>h.error?(l.push(`stargate: ${h.error}`),null):{provider:"stargate",amountOut:h.amountOut,feeUsd:h.fee,estimatedTime:h.estimatedTime||"1-5 min",preparable:!1,raw:h}).catch(h=>(l.push(`stargate: ${h.message}`),null)),S=ei({fromAsset:i,toAsset:c,amount:s,destination:a}).then(h=>h.error?(l.push(`thorchain: ${h.error}`),null):{provider:"thorchain",amountOut:h.expectedAmountOut,feeUsd:h.fees?.total,estimatedTime:h.estimatedTime||"10-30 min",preparable:!1,raw:h}).catch(h=>(l.push(`thorchain: ${h.message}`),null)),I=(async()=>{if(!i||!c||i==="?"||c==="?")return l.push("changenow: ticker symbols required, skipping"),null;try{let h=await Qs({fromTicker:i,toTicker:c,fromAmount:s});return h.error?(l.push(`changenow: ${h.error}`),null):{provider:"changenow",amountOut:h.toAmount,feeUsd:h.networkFee,estimatedTime:h.flow==="standard"?"5-30 min":"instant",preparable:!1,kycRequired:h.kycRequired,raw:h}}catch(h){return l.push(`changenow: ${h.message}`),null}})(),N=ri({fromChainId:t,toChainId:r,fromToken:n,toToken:o,fromAmount:s,userAddress:a}).then(h=>h.error?(l.push(`bungee: ${h.error}`),null):{provider:"bungee",amountOut:h.amountOut,feeUsd:h.feeUsd,estimatedTime:h.estimatedTime,preparable:!1,raw:h}).catch(h=>(l.push(`bungee: ${h.message}`),null)),re=oi({originDomain:t,destinationDomain:r,originToken:n,destinationToken:o,amount:s}).then(h=>h.error?(l.push(`connext: ${h.error}`),null):{provider:"connext",amountOut:h.amountOut,feeUsd:h.fee,estimatedTime:h.estimatedTime||"5-20 min",preparable:!1,raw:h}).catch(h=>(l.push(`connext: ${h.message}`),null)),be=ii({fromChain:t,toChain:r,token:n,amount:s}).then(h=>h.error?(l.push(`wormhole: ${h.error}`),null):{provider:"wormhole",amountOut:h.amountOut,feeUsd:h.fee,estimatedTime:h.estimatedTime||"5-15 min",preparable:!1,raw:h}).catch(h=>(l.push(`wormhole: ${h.message}`),null)),Ce=await Promise.allSettled([m,f,g,b,S,N,re,be,I]);for(let h of Ce)h.status==="fulfilled"&&h.value&&p.push(h.value);return p.sort((h,q)=>{let U=Number(h.amountOut??0),mt=Number(q.amountOut??0);return U!==mt?mt-U:h.preparable&&!q.preparable?-1:!h.preparable&&q.preparable?1:0}),{providers:p.map(h=>h.provider),bestRoute:p[0]?.provider??"none",winner:p[0]??null,runnersUp:p.slice(1),errors:l.length?l:null}}async function Ti({chainId:e,taker:t,tokenIn:r}={}){if(!e||!t)return{needsRevoke:!1,note:"no wallet to check"};try{let o=(await _i({chainIds:[e],address:t})).approvals;if(!o?.length)return{needsRevoke:!1,note:"no active approvals found"};let s=r?o.find(a=>String(a.token).toLowerCase()===String(r).toLowerCase()):null;return s&&BigInt(s.allowance??"0")>0n?{needsRevoke:!0,spender:s.spender,amount:s.allowance,symbol:s.symbol??"?",decimals:s.decimals??18,note:`approval found for ${s.spender}, revoke before bridging`}:{needsRevoke:!1,note:`no active approval for this token (${o.length} total approvals on chain)`}}catch(n){return{needsRevoke:!1,note:`revoke check unavailable: ${String(n.message||n).slice(0,100)}`}}}async function ud(e={}){let[t,r]=await Promise.all([Ri(e),Ti({chainId:e.fromChainId,taker:e.taker,tokenIn:e.tokenIn})]),n=t.winner??{};return{kind:"bridge",fromChainId:e.fromChainId,toChainId:e.toChainId,fromSymbol:e.fromSymbol,toSymbol:e.toSymbol,amount:e.amount,fromDecimals:e.fromDecimals??18,toDecimals:e.toDecimals??18,bestRoute:n.provider??"none",amountOut:n.amountOut,feeUsd:n.feeUsd,estimatedTime:n.estimatedTime,preparable:n.preparable?"yes":"no (manual send)",providers:t.providers,runnersUp:t.runnersUp,revokeCheck:r,errors:t.errors,confidence:t.providers.length>=2?.85:t.providers.length===1?.6:.1}}async function ld(){let[e,t]=await Promise.all([Hs().catch(r=>({ok:!1,error:r.message})),Ws().catch(r=>({ok:!1,error:r.message}))]);return{debridge:e,changenow:t,lifi:{ok:!0,note:"integrated via router"}}}var Vh,Bi=w(()=>{Pe();Vs();Gs();Ys();Zs();ti();ni();si();ai();Oi();Vh=Object.freeze(["debridge","lifi-relay","squid","stargate","thorchain","bungee","connext","wormhole","changenow"])});var $i={};_($i,{DYDX_API:()=>Kt,dydxHealth:()=>md,dydxMarkets:()=>dd,dydxOrderbook:()=>pd});async function dd(e=50){try{return((await y(`${Kt}/v4/perpetualMarkets?limit=${e}`))?.markets||[]).map(r=>({ticker:r?.ticker,oraclePrice:r?.oraclePrice,indexPrice:r?.indexPrice,nextFundingRate:r?.nextFundingRate?`${(Number(r.nextFundingRate)*100).toFixed(4)}%`:null,openInterest:r?.openInterest,volume24h:r?.volume24H}))}catch(t){return{error:String(t.message||t).slice(0,200)}}}async function pd(e){try{let t=await y(`${Kt}/v4/orderbooks/perpetualMarket/${e}`);return{bids:t?.bids?.slice(0,5),asks:t?.asks?.slice(0,5)}}catch(t){return{error:String(t.message||t).slice(0,200)}}}async function md(){try{return{ok:!0,serverTime:(await y(`${Kt}/v4/time`))?.iso}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Kt,qi=w(()=>{C();Kt="https://api.dydx.exchange"});var Pi={};_(Pi,{DRIFT_API:()=>Di,driftHealth:()=>hd,driftMarkets:()=>fd});async function fd(){try{return((await y(`${Di}/v2/markets`))?.markets||[]).map(t=>({symbol:t?.symbol||t?.marketIndex,oraclePrice:t?.amm?.oraclePrice,markPrice:t?.amm?.markPrice,fundingRate:t?.amm?.lastFundingRate?`${(Number(t.amm.lastFundingRate)*100).toFixed(4)}%`:null,openInterest:{long:t?.amm?.longFunding,short:t?.amm?.shortFunding},volume24h:t?.amm?.quoteAssetVolume}))}catch(e){return{error:String(e.message||e).slice(0,200)}}}async function hd(){try{return{ok:!0,note:"Drift v2 perps on Solana \u2014 public reads via dlob.drift.trade"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Di,Ui=w(()=>{C();Di="https://dlob.drift.trade"});var Li={};_(Li,{VERTEX_API:()=>Qt,vertexHealth:()=>yd,vertexMarkets:()=>bd,vertexOrderbook:()=>gd});async function bd(){try{return((await y(`${Qt}/query`,{method:"POST",body:JSON.stringify({all_markets:{}}),headers:{"content-type":"application/json"}}))?.data?.all_markets||[]).map(t=>({market:t?.market,type:t?.type,oraclePrice:t?.oracle_price_x18?(Number(BigInt(t.oracle_price_x18))/1e18).toFixed(4):null,minSize:t?.min_size,productId:t?.product_id}))}catch(e){return{error:String(e.message||e).slice(0,200)}}}async function gd(e){try{let r=(await y(`${Qt}/query`,{method:"POST",body:JSON.stringify({market_liquidity:{product_id:Number(e),depth:5}}),headers:{"content-type":"application/json"}}))?.data?.market_liquidity;return{bids:r?.bids||[],asks:r?.asks||[]}}catch(t){return{error:String(t.message||t).slice(0,200)}}}async function yd(){try{return{ok:!0,status:(await y(`${Qt}/status`))?.status||"unknown"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Qt,Fi=w(()=>{C();Qt="https://gateway.prod.vertexprotocol.com/v2"});var Mi={};_(Mi,{pancakeHealth:()=>vd,pancakeQuote:()=>Sd});async function Sd({chainId:e=56,tokenIn:t,tokenOut:r,amountIn:n,fee:o=500}={}){if(!t||!r||!n)return{error:"pancake quote requires tokenIn, tokenOut, amountIn"};try{let s={tokenIn:String(t).toLowerCase(),tokenOut:String(r).toLowerCase(),amountIn:String(n),fee:String(o)},a=await y(`${wd}/quote`,{method:"POST",body:JSON.stringify(s),headers:{"content-type":"application/json"}});return{amountOut:a?.amountOut,route:a?.route}}catch(s){return{error:String(s.message||s).slice(0,200)}}}async function vd(){try{return{ok:!0,chains:["bsc (56)","ethereum (1)","arbitrum (42161)","base (8453)","opbnb (204)","zksync (324)","linea (59144)"]}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var wd,ji=w(()=>{C();wd="https://api.thegraph.com/subgraphs/name/pancakeswap/exchange-v3-bsc"});var Vi={};_(Vi,{sushiHealth:()=>Ed,sushiQuote:()=>Ad});async function Ad({chainId:e=1,tokenIn:t,tokenOut:r,amountIn:n,fee:o=500}={}){if(!t||!r||!n)return{error:"sushi quote requires tokenIn, tokenOut, amountIn"};try{let s=`{ quote(tokenIn:"${t}",tokenOut:"${r}",amountIn:"${n}",fee:${o}) { amountOut route } }`,a=await y(`${xd(e)}/quote?query=${encodeURIComponent(s)}`);return{amountOut:a?.data?.quote?.amountOut,route:a?.data?.quote?.route}}catch(s){return{error:String(s.message||s).slice(0,200)}}}async function Ed(){try{return{ok:!0,chains:Object.keys(Hi).length+" chains"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var xd,Hi,zi=w(()=>{C();xd=e=>`https://api.thegraph.com/subgraphs/name/sushi-v3/v3-${Hi[e]||"ethereum"}`,Hi={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",59144:"linea",534352:"scroll",324:"zksync-era",250:"fantom",2222:"kava",1088:"metis",1284:"moonbeam",1285:"moonriver",288:"boba",1101:"polygon-zkevm",5e3:"mantle",81457:"blast"}});var Ki={};_(Ki,{raydiumHealth:()=>Cd,raydiumQuote:()=>Id});async function Id({inputMint:e,outputMint:t,amount:r,slippageBps:n=50}={}){if(!e||!t||!r)return{error:"raydium quote requires inputMint, outputMint, amount"};try{let o=new URLSearchParams({inputMint:e,outputMint:t,amount:String(r),slippageBps:String(n),onlyDirectRoutes:"true"}),s=await y(`${kd}/quote?${o}`),a=(s?.routePlan||[]).filter(i=>i?.swapInfo?.label?.toLowerCase().includes("raydium"));return{amountOut:s?.outAmount,priceImpactPct:s?.priceImpactPct,raydiumRoutes:a.length,allRoutes:s?.routePlan?.length||0}}catch(o){return{error:String(o.message||o).slice(0,200)}}}async function Cd(){try{return{ok:!0,note:"Raydium routes through Jupiter aggregator on Solana"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var kd,Qi=w(()=>{C();kd="https://quote-api.jup.ag/v6"});var Wi={};_(Wi,{AEVO_API:()=>nn,aevoHealth:()=>Od,aevoMarkets:()=>_d});async function _d(){try{return(await y(`${nn}/markets`)||[]).map(t=>({instrument:t?.instrument_name,type:t?.instrument_type,markPrice:t?.mark_price,indexPrice:t?.index_price,fundingRate:t?.funding_rate?`${(Number(t.funding_rate)*100).toFixed(4)}%`:null,openInterest:t?.open_interest,volume24h:t?.volume_24h}))}catch(e){return{error:String(e.message||e).slice(0,200)}}}async function Od(){try{return{ok:(await y(`${nn}/ping`))?.status==="ok"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var nn,Gi=w(()=>{C();nn="https://api.aevo.xyz"});var Xi={};_(Xi,{compoundHealth:()=>Nd,compoundMarkets:()=>Td});async function Td(){try{return((await y(`${Rd}/ctoken`))?.cToken||[]).map(t=>({symbol:t?.symbol,underlying:t?.underlying_symbol,supplyApy:t?.supply_rate?.value?`${(Number(t.supply_rate.value)*100).toFixed(2)}%`:null,borrowApy:t?.borrow_rate?.value?`${(Number(t.borrow_rate.value)*100).toFixed(2)}%`:null,totalSupply:t?.total_supply?.value,totalBorrow:t?.total_borrows?.value,collateralFactor:t?.collateral_factor?.value?`${(Number(t.collateral_factor.value)*100).toFixed(0)}%`:null}))}catch(e){return{error:String(e.message||e).slice(0,200)}}}async function Nd(){try{return{ok:!0,note:"Compound v2 \u2014 Ethereum mainnet lending"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Rd,Yi=w(()=>{C();Rd="https://api.compound.finance/api/v2"});var Ji={};_(Ji,{yearnHealth:()=>qd,yearnVaults:()=>$d});async function $d(){try{return(await y(`${Bd}/vaults/all`)||[]).map(t=>({name:t?.name,symbol:t?.symbol,apy:t?.apy?.net_apy?`${(Number(t.apy.net_apy)*100).toFixed(2)}%`:null,tvl:t?.tvl?.tvl_deposited,chain:t?.chainId,type:t?.type||"v2"}))}catch(e){return{error:String(e.message||e).slice(0,200)}}}async function qd(){try{return{ok:!0,note:"Yearn \u2014 yield aggregator across Ethereum, Arbitrum, Optimism, Fantom"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Bd,Zi=w(()=>{C();Bd="https://api.yearn.fi/v1"});var ea={};_(ea,{convexHealth:()=>Ud,convexPools:()=>Pd});async function Pd(){try{return(await y(`${Dd}/pools`)||[]).map(t=>({name:t?.curvePool?.name||t?.name,curveApy:t?.curvePool?.apy?`${(Number(t.curvePool.apy)*100).toFixed(2)}%`:null,convexApy:t?.apy?`${(Number(t.apy)*100).toFixed(2)}%`:null,tvl:t?.tvl,boosted:t?.boosted||!1}))}catch(e){return{error:String(e.message||e).slice(0,200)}}}async function Ud(){try{return{ok:!0,note:"Convex \u2014 CRV/CVX yield optimizer on Ethereum"}}catch(e){return{ok:!1,error:String(e.message||e).slice(0,160)}}}var Dd,ta=w(()=>{C();Dd="https://api.convexfinance.com/api"});function Ee(e){if(!Number.isSafeInteger(e)||e<0||e>1e3)throw new RangeError("scale must be a safe integer from 0 through 1000")}function ee(e,t){if(typeof e!="bigint")throw new TypeError("mantissa must be a bigint");return Ee(t),Object.freeze({mantissa:e,scale:t})}function pe(e,t="value"){if(e===null||typeof e!="object")throw new TypeError(`${t} must be a fixed point value`);if(typeof e.mantissa!="bigint")throw new TypeError(`${t}.mantissa must be a bigint`);Ee(e.scale)}function Wt(e){return Ee(e),10n**BigInt(e)}function x(e){if(typeof e!="string"||!/^[+-]?\d+(?:\.\d+)?$/.test(e))throw new TypeError("value must be a plain decimal string");let t=e.startsWith("-"),r=e[0]==="-"||e[0]==="+"?e.slice(1):e,[n,o=""]=r.split("."),s=`${n}${o}`,a=BigInt(s)*(t?-1n:1n);return ee(a,o.length)}function F(e,t){if(Ee(t),typeof e=="bigint")return ee(e,t);if(typeof e!="string"||!/^[+-]?\d+$/.test(e))throw new TypeError("value must be an integer string or bigint");return ee(BigInt(e),t)}function X(e){pe(e);let t=e.mantissa<0n,r=(t?-e.mantissa:e.mantissa).toString();if(e.scale===0)return`${t?"-":""}${r}`;let n=r.padStart(e.scale+1,"0"),o=n.length-e.scale;return`${t?"-":""}${n.slice(0,o)}.${n.slice(o)}`}function at(e,t){return pe(e),Ee(t),t===e.scale?ee(e.mantissa,e.scale):t>e.scale?ee(e.mantissa*Wt(t-e.scale),t):ee(e.mantissa/Wt(e.scale-t),t)}function on(e,t){pe(e,"left"),pe(t,"right");let r=Math.max(e.scale,t.scale);return[at(e,r),at(t,r),r]}function me(e,t){let[r,n,o]=on(e,t);return ee(r.mantissa+n.mantissa,o)}function ct(e,t){let[r,n,o]=on(e,t);return ee(r.mantissa-n.mantissa,o)}function H(e,t){pe(e,"left"),pe(t,"right");let r=e.scale+t.scale;return Ee(r),ee(e.mantissa*t.mantissa,r)}function Y(e,t,r=Math.max(e?.scale??0,t?.scale??0)){if(pe(e,"left"),pe(t,"right"),Ee(r),t.mantissa===0n)throw new RangeError("division by zero");let n=e.mantissa*Wt(t.scale+r),o=t.mantissa*Wt(e.scale);return ee(n/o,r)}function fe(e,t){let[r,n]=on(e,t);return r.mantissa<n.mantissa?-1:r.mantissa>n.mantissa?1:0}var tb,K=w(()=>{tb=Object.freeze({mantissa:10000n,scale:0})});import{readFileSync as Ld}from"node:fs";import{fileURLToPath as Fd}from"node:url";import{dirname as Md,join as na}from"node:path";function Hd(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function E(e,t){throw new TypeError(`Fixture fixtures/${e}: ${t}`)}function $(e,t,r){Hd(e)||E(t,`${r} must be an object`)}function k(e,t,r){(typeof e!="string"||e.length===0)&&E(t,`${r} must be a nonempty string`)}function te(e,t,r){Number.isSafeInteger(e)||E(t,`${r} must be a safe integer`)}function he(e,t,r){$(e,t,r);for(let[n,o]of Object.entries(e))k(n,t,`${r} key`),$(o,t,`${r}.${n}`)}function Vd(e,t){$(e,t,"root"),te(e.capturedAt,t,"capturedAt"),$(e.venues,t,"venues");let r=[["hyperliquid_hip3","dexs"],["arcus","markets"],["arcus_spot","pairs"],["rh_uniswap","pools"],["rh_chainlink_oracles","assets"]];for(let[n,o]of r){let s=e.venues[n];$(s,t,`venues.${n}`),k(s.type,t,`venues.${n}.type`),k(s.chain,t,`venues.${n}.chain`),k(s.tier,t,`venues.${n}.tier`),he(s[o],t,`venues.${n}.${o}`)}for(let[n,o]of Object.entries(e.venues.hyperliquid_hip3.dexs))he(o,t,`venues.hyperliquid_hip3.dexs.${n}`)}function zd(e,t){he(e,t,"root"),Object.keys(e).length===0&&E(t,"root must not be empty");for(let[r,n]of Object.entries(e))Array.isArray(n.venues)||E(t,`${r}.venues must be an array`),n.venues.forEach((o,s)=>k(o,t,`${r}.venues[${s}]`))}function Kd(e,t){$(e,t,"root");for(let r of["chainId","block","oracleScaleExp","usdgDecimals","equityDecimals"])te(e[r],t,r);k(e.usdg,t,"usdg"),he(e.assets,t,"assets");for(let[r,n]of Object.entries(e.assets))k(n.oracle,t,`assets.${r}.oracle`),k(n.token,t,`assets.${r}.token`),(typeof n.rawPrice!="string"||!/^\d+$/.test(n.rawPrice))&&E(t,`assets.${r}.rawPrice must be an integer string`),(typeof n.usd!="number"||!Number.isFinite(n.usd)||n.usd<0)&&E(t,`assets.${r}.usd must be a nonnegative finite source number`)}function Qd(e,t){$(e,t,"root");for(let n of["holidayDayIndex","names","dates"])Array.isArray(e[n])||E(t,`${n} must be an array`);let r=e.holidayDayIndex.length;(e.names.length!==r||e.dates.length!==r)&&E(t,"holidayDayIndex, names, and dates must have equal lengths"),e.holidayDayIndex.forEach((n,o)=>te(n,t,`holidayDayIndex[${o}]`)),e.names.forEach((n,o)=>k(n,t,`names[${o}]`)),e.dates.forEach((n,o)=>{(typeof n!="string"||!/^\d{4}-\d{2}-\d{2}$/.test(n))&&E(t,`dates[${o}] must use YYYY-MM-DD`)})}function Wd(e,t){$(e,t,"root"),(!Array.isArray(e.dstTransitions)||e.dstTransitions.length===0)&&E(t,"dstTransitions must be a nonempty array");let r=new Set;e.dstTransitions.forEach((n,o)=>{$(n,t,`dstTransitions[${o}]`);for(let s of["year","startUtc","endUtc"])te(n[s],t,`dstTransitions[${o}].${s}`);n.startUtc>=n.endUtc&&E(t,`dstTransitions[${o}] startUtc must be before endUtc`),r.has(n.year)&&E(t,`dstTransitions contains duplicate year ${n.year}`),r.add(n.year)})}function Gd(e,t){he(e,t,"root"),Object.keys(e).length===0&&E(t,"root must not be empty");for(let[r,n]of Object.entries(e)){for(let o of["addr","quote","quoteAddr","dex","pair"])k(n[o],t,`${r}.${o}`);(typeof n.liq!="number"||!Number.isFinite(n.liq)||n.liq<0)&&E(t,`${r}.liq must be a nonnegative finite source number`)}}function Xd(e,t){$(e,t,"root"),te(e.capturedAt,t,"capturedAt"),te(e.block,t,"block"),te(e.chainId,t,"chainId"),k(e.gasPriceWei,t,"gasPriceWei"),k(e.stateView,t,"stateView"),he(e.pools,t,"pools"),Object.keys(e.pools).length===0&&E(t,"pools must not be empty");for(let[r,n]of Object.entries(e.pools)){for(let o of["pair","version","quote","token","sqrtPriceX96"])k(n[o],t,`pools.${r}.${o}`);n.version!=="v3"&&n.version!=="v4"&&E(t,`pools.${r}.version must be v3 or v4`),typeof n.quoteIsToken0!="boolean"&&E(t,`pools.${r}.quoteIsToken0 must be a boolean`),(!/^[0-9]+$/.test(n.sqrtPriceX96)||BigInt(n.sqrtPriceX96)<=0n)&&E(t,`pools.${r}.sqrtPriceX96 must be a positive integer string`)}}function Yd(e,t){$(e,t,"root"),te(e.capturedAt,t,"capturedAt"),k(e.source,t,"source"),$(e.books,t,"books"),Object.keys(e.books).length===0&&E(t,"books must not be empty");for(let[r,n]of Object.entries(e.books)){$(n,t,`books.${r}`),(!Array.isArray(n.bids)||!Array.isArray(n.asks))&&E(t,`books.${r} must have bids and asks arrays`);for(let[o,s]of n.bids.entries())$(s,t,`books.${r}.bids[${o}]`),k(s.px,t,`books.${r}.bids[${o}].px`),k(s.sz,t,`books.${r}.bids[${o}].sz`);for(let[o,s]of n.asks.entries())$(s,t,`books.${r}.asks[${o}]`),k(s.px,t,`books.${r}.asks[${o}].px`),k(s.sz,t,`books.${r}.asks[${o}].sz`)}}function Jd(e,t){$(e,t,"root"),te(e.capturedAt,t,"capturedAt"),k(e.source,t,"source"),k(e.chain,t,"chain"),he(e.tokens,t,"tokens"),$(e.pairs,t,"pairs"),Object.keys(e.tokens).length===0&&E(t,"tokens must not be empty");for(let[r,n]of Object.entries(e.tokens)){k(n.symbolRaw,t,`tokens.${r}.symbolRaw`),k(n.mint,t,`tokens.${r}.mint`),Object.hasOwn(e.pairs,r)||E(t,`pairs.${r} is required for token ${r}`),(!Array.isArray(e.pairs[r])||e.pairs[r].length===0)&&E(t,`pairs.${r} must be a nonempty array`);for(let[o,s]of e.pairs[r].entries())$(s,t,`pairs.${r}[${o}]`),k(s.pairAddress,t,`pairs.${r}[${o}].pairAddress`),k(s.dexId,t,`pairs.${r}[${o}].dexId`),(typeof s.priceUsd!="number"||!Number.isFinite(s.priceUsd)||s.priceUsd<=0)&&E(t,`pairs.${r}[${o}].priceUsd must be a positive finite number`),(typeof s.liquidityUsd!="number"||!Number.isFinite(s.liquidityUsd)||s.liquidityUsd<0)&&E(t,`pairs.${r}[${o}].liquidityUsd must be a nonnegative finite number`)}}function Zd(e,t){$(e,t,"root"),te(e.capturedAt,t,"capturedAt"),k(e.source,t,"source"),k(e.chain,t,"chain"),e.chain!=="ton"&&E(t,'chain must be "ton"'),he(e.tokens,t,"tokens"),$(e.pairs,t,"pairs"),Object.keys(e.tokens).length===0&&E(t,"tokens must not be empty");for(let[r,n]of Object.entries(e.tokens)){k(n.symbolRaw,t,`tokens.${r}.symbolRaw`),k(n.mint,t,`tokens.${r}.mint`),Object.hasOwn(e.pairs,r)||E(t,`pairs.${r} is required for token ${r}`),(!Array.isArray(e.pairs[r])||e.pairs[r].length===0)&&E(t,`pairs.${r} must be a nonempty array`);for(let[o,s]of e.pairs[r].entries())$(s,t,`pairs.${r}[${o}]`),k(s.pairAddress,t,`pairs.${r}[${o}].pairAddress`),k(s.dexId,t,`pairs.${r}[${o}].dexId`),(typeof s.priceUsd!="number"||!Number.isFinite(s.priceUsd)||s.priceUsd<=0)&&E(t,`pairs.${r}[${o}].priceUsd must be a positive finite number`),(typeof s.liquidityUsd!="number"||!Number.isFinite(s.liquidityUsd)||s.liquidityUsd<0)&&E(t,`pairs.${r}[${o}].liquidityUsd must be a nonnegative finite number`)}}function tp(e,t){let r=oa[t],n=na(e,r),o;try{o=Ld(n,"utf8")}catch(a){throw a?.code==="ENOENT"?new Error(`Fixture fixtures/${r} is missing at ${n}`):new Error(`Fixture fixtures/${r} could not be read: ${a.message}`)}let s;try{s=JSON.parse(o)}catch(a){throw new SyntaxError(`Fixture fixtures/${r} contains invalid JSON: ${a.message}`)}return ep[t](s,r),s}function sa(e){if(e!==null&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))sa(t)}return e}function sn({fixtureDir:e=jd}={}){if(typeof e!="string"||e.length===0)throw new TypeError("fixtureDir must be a nonempty path string");let t={};for(let r of Object.keys(oa))t[r]=tp(e,r);return sa(t)}function ae(){return ra??=sn(),ra}function V(){return ae().venues}function ia(){return ae().universe}function aa(){return ae().oracles}function ca(){return ae().nyseHolidays}function ua(){return ae().dstTransitions}function Gt(){return ae().rhPoolState}function la(){return ae().solanaXstocks}function da(){return ae().tonXstocks}function pa(){return ae().hip3L2Books}var jd,oa,ep,ra,J=w(()=>{jd=na(Md(Fd(import.meta.url)),"fixtures"),oa=Object.freeze({venues:"venues.json",universe:"universe.json",oracles:"oracles.json",nyseHolidays:"nyse_holidays.json",dstTransitions:"dst_transitions.json",equityDexPools:"equity_dex_pools.json",rhPoolState:"rh_pool_state.json",solanaXstocks:"solana_xstocks.json",tonXstocks:"ton_xstocks.json",hip3L2Books:"hip3_l2books.json"});ep=Object.freeze({venues:Vd,universe:zd,oracles:Kd,nyseHolidays:Qd,dstTransitions:Wd,equityDexPools:Gd,rhPoolState:Xd,solanaXstocks:Jd,tonXstocks:Zd,hip3L2Books:Yd})});function op(){let e=ua().dstTransitions.map(n=>({year:n.year,startMs:n.startUtc*cn,endMs:n.endUtc*cn}));e.sort((n,o)=>n.startMs-o.startMs);let t=e[0].year,r=e[e.length-1].year;return Object.freeze({rows:Object.freeze(e),firstYear:t,lastYear:r,coverageStartMs:Date.UTC(t,0,1),coverageEndMs:Date.UTC(r+1,0,1)})}function Sa(){return fa??=op(),fa}function sp(){return an===void 0&&(an=new Set(ca().holidayDayIndex)),an}function va(e,t){if(!Number.isSafeInteger(e))throw new TypeError(`${t}: epochMs must be a safe integer number of milliseconds`)}function ip(e,t){let{coverageStartMs:r,coverageEndMs:n,firstYear:o,lastYear:s}=Sa();if(e<r||e>=n)throw new RangeError(`${t}: ${new Date(e).toISOString()} is outside DST fixture coverage (${o} through ${s}). Refusing to assume a UTC offset.`)}function ap(e){for(let t of Sa().rows)if(e>=t.startMs&&e<t.endMs)return!0;return!1}function cp(e){return ap(e)?np:rp}function up(e){let t=e+cp(e),r=Math.floor(t/ma),n=t-r*ma,o=new Date(t);return{dayIndex:r,minuteOfDay:Math.floor(n/ha),msIntoDay:n,weekday:o.getUTCDay()}}function lp({dayIndex:e,weekday:t}){return t===0||t===6?!1:!sp().has(e)}function dp(e){return e<ba?"dark":e<ga?"extended":e<ya?"core":e<wa?"extended":"dark"}function ut(e){va(e,"sessionState"),ip(e,"sessionState");let t=up(e);return lp(t)?dp(t.minuteOfDay):"dark"}function ln(e){return va(e,"isDark"),ut(e)==="dark"}var cn,ha,un,ma,rp,np,ba,ga,ya,wa,cb,ub,fa,an,Xt=w(()=>{J();cn=1e3,ha=60*cn,un=60*ha,ma=24*un,rp=-5*un,np=-4*un,ba=240,ga=570,ya=960,wa=1200,cb=Object.freeze([ba,ga,ya,wa]),ub=Object.freeze(["core","extended","dark"])});function Jt(e,t){e.push(Object.freeze({venue:t.venue,symbol:t.symbol??null,reason:t.reason,evidence:t.evidence??null}))}function fp(e){let t=e.raw?.vol24h;return!!(t===0||t===0||typeof t=="number"&&Number.isFinite(t)&&t<=0)}function hp(e){return!e.bid||!e.ask?!1:fe(e.bid,e.ask)>0}function xa(e,t,r){return Number.isSafeInteger(e.capturedAt)?t-e.capturedAt>r:!1}function Zt(e,t={}){if(!Array.isArray(e))throw new TypeError("quotes must be an array");let r=t.nowMs??Date.now(),n=t.quoteFreshnessMs??pp,o=t.oracleFreshnessMs??mp,s=t.includeDormant===!0,a=[],i=[];for(let c of e){if(fp(c)){s?a.push(Object.freeze({...c,staleData:!0})):Jt(i,{venue:c.venue,symbol:c.symbolRaw??c.symbol,reason:Yt.DORMANT_VENUE,evidence:{vol24h:c.raw?.vol24h??null}});continue}if(hp(c)){Jt(i,{venue:c.venue,symbol:c.symbolRaw??c.symbol,reason:Yt.CROSSED_BOOK,evidence:{bid:c.bid?String(c.bid.mantissa)+"e-"+c.bid.scale:null,ask:c.ask?String(c.ask.mantissa)+"e-"+c.ask.scale:null}});continue}if(xa(c,r,n)){Jt(i,{venue:c.venue,symbol:c.symbolRaw??c.symbol,reason:Yt.STALE_QUOTE,evidence:{capturedAt:c.capturedAt,nowMs:r,ageMs:r-c.capturedAt,freshnessMs:n}});continue}if(c.tier==="read-only"&&c.raw?.oracleRaw!==void 0){let u=ut(r),d=u==="core"?o:o*2;if(xa(c,r,d)){Jt(i,{venue:c.venue,symbol:c.symbolRaw??c.symbol,reason:Yt.STALE_ORACLE,evidence:{capturedAt:c.capturedAt,nowMs:r,session:u}});continue}}a.push(c)}return{survivors:a,excluded:i}}var Yt,pp,mp,dn=w(()=>{K();Xt();Yt=Object.freeze({DORMANT_VENUE:"dormant-venue",CROSSED_BOOK:"crossed-book",STALE_QUOTE:"stale-quote",STALE_ORACLE:"stale-oracle"}),pp=12e4,mp=6e5});function bp(e){if(typeof e!="number"||!Number.isFinite(e))throw new TypeError("value must be a finite number");let t=String(e);if(!t.includes("e")&&!t.includes("E"))return t;let[r,n]=t.split(/[eE]/),o=Number(n),s=r.startsWith("-"),a=s?r.slice(1):r,[i,c=""]=a.split("."),u=`${i}${c}`,d=i.length+o,p;return d<=0?p=`0.${"0".repeat(-d)}${u}`:d>=u.length?p=`${u}${"0".repeat(d-u.length)}`:p=`${u.slice(0,d)}.${u.slice(d)}`,`${s?"-":""}${p}`}function P(e){return e==null?null:typeof e=="string"?x(e):typeof e!="number"||!Number.isFinite(e)?null:x(bp(e))}function Z(e,t){let r=P(e);if(r===null)throw new TypeError(`${t} must be a finite source number`);return r}var ke=w(()=>{K()});function O(e,t){throw new TypeError(`${e} ${t}`)}function ka(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Ie(e,t){ka(e)||O(t,"must be an object")}function Ia(e,t,r){Object.hasOwn(e,t)||O(`${r}.${t}`,"is required")}function Fe(e,t){(typeof e!="string"||e.length===0)&&O(t,"must be a nonempty string")}function lt(e,t,r){t.has(e)||O(r,`must be one of ${[...t].join(", ")}`)}function mn(e,t){(!Number.isSafeInteger(e)||e<0)&&O(t,"must be a nonnegative safe integer")}function pn(e,t,r=!1){e===null&&r||(ka(e)||O(t,"must be a fixed point value"),typeof e.mantissa!="bigint"&&O(`${t}.mantissa`,"must be a bigint"),(!Number.isSafeInteger(e.scale)||e.scale<0)&&O(`${t}.scale`,"must be a nonnegative safe integer"))}function er(e,t,r=!1){e===null&&r||Ie(e,t)}function Ea(e,t){Ie(e,t),Fe(e.venue,`${t}.venue`),Fe(e.reason,`${t}.reason`),Ap.test(e.reason)||O(`${t}.reason`,"must be a machine readable lower case code"),Object.hasOwn(e,"symbol")&&e.symbol!==null&&Fe(e.symbol,`${t}.symbol`)}function M(e){Ie(e,"quote");for(let r of["venue","chain","instrument","tier","symbolRaw","symbol","side","requestedSize",...Aa,"costAccounted","capturedAt","blockOrSeq","raw"])Ia(e,r,"quote");Fe(e.venue,"quote.venue"),!(typeof e.chain=="string"&&e.chain.length>0)&&!(Number.isSafeInteger(e.chain)&&e.chain>=0)&&O("quote.chain","must be a nonempty string or nonnegative chain id"),lt(e.instrument,gp,"quote.instrument"),lt(e.tier,yp,"quote.tier"),Fe(e.symbolRaw,"quote.symbolRaw"),Fe(e.symbol,"quote.symbol"),lt(e.side,wp,"quote.side"),pn(e.requestedSize,"quote.requestedSize"),e.requestedSize.mantissa<0n&&O("quote.requestedSize","must not be negative");let t=0;for(let r of xp)Object.hasOwn(e,r)&&(pn(e[r],`quote.${r}`),t+=1);t===0&&O("quote","must contain at least one of bid, ask, mid, mark");for(let r of Aa)pn(e[r],`quote.${r}`,!0);if(typeof e.costAccounted!="boolean"&&O("quote.costAccounted","must be a boolean"),e.costAccounted){for(let r of["fees","gasEstimate","priceImpact"])e[r]===null&&O(`quote.${r}`,"cannot be unknown when costAccounted is true");e.instrument==="perp"&&e.fundingHourly===null&&O("quote.fundingHourly","cannot be unknown when costAccounted is true for a perp")}return e.instrument==="spot"&&e.fundingHourly!==null&&O("quote.fundingHourly","must be null for a spot quote"),mn(e.capturedAt,"quote.capturedAt"),e.blockOrSeq!==null&&!(typeof e.blockOrSeq=="string"&&e.blockOrSeq.length>0)&&!(Number.isSafeInteger(e.blockOrSeq)&&e.blockOrSeq>=0)&&O("quote.blockOrSeq","must be null, a nonempty string, or a nonnegative safe integer"),Ie(e.raw,"quote.raw"),e}function tr(e){Ie(e,"rankResult");for(let t of["rankedOn","ranked","winner","runnersUp","improvementBps","sourcesAnswered","sourcesTried","failed","excluded","darkWindow","instrumentMix","bestPreparable"])Ia(e,t,"rankResult");return lt(e.rankedOn,Sp,"rankResult.rankedOn"),Array.isArray(e.ranked)||O("rankResult.ranked","must be an array"),e.ranked.forEach((t,r)=>er(t,`rankResult.ranked[${r}]`)),er(e.winner,"rankResult.winner",!0),e.ranked.length===0&&e.winner!==null&&O("rankResult.winner","must be null when ranked is empty"),e.ranked.length>0&&e.winner===null&&O("rankResult.winner","must be present when ranked is not empty"),Array.isArray(e.runnersUp)||O("rankResult.runnersUp","must be an array"),e.runnersUp.forEach((t,r)=>er(t,`rankResult.runnersUp[${r}]`)),e.improvementBps!==null&&!(typeof e.improvementBps=="number"&&Number.isFinite(e.improvementBps))&&O("rankResult.improvementBps","must be a finite number or null"),mn(e.sourcesAnswered,"rankResult.sourcesAnswered"),mn(e.sourcesTried,"rankResult.sourcesTried"),e.sourcesAnswered>e.sourcesTried&&O("rankResult.sourcesAnswered","must not exceed sourcesTried"),Array.isArray(e.failed)||O("rankResult.failed","must be an array"),e.failed.forEach((t,r)=>Ea(t,`failed[${r}]`)),Array.isArray(e.excluded)||O("rankResult.excluded","must be an array"),e.excluded.forEach((t,r)=>Ea(t,`excluded[${r}]`)),e.darkWindow!==null&&Ie(e.darkWindow,"rankResult.darkWindow"),lt(e.instrumentMix,vp,"rankResult.instrumentMix"),er(e.bestPreparable,"rankResult.bestPreparable",!0),Object.hasOwn(e,"carry")&&e.carry!==null&&Ie(e.carry,"rankResult.carry"),e}var gp,yp,wp,Sp,vp,xp,Aa,Ap,ce=w(()=>{gp=new Set(["spot","perp"]),yp=new Set(["read-only","quote-only","prepare","intent"]),wp=new Set(["buy","sell"]),Sp=new Set(["net-of-cost","gross"]),vp=new Set(["homogeneous","heterogeneous"]),xp=["bid","ask","mid","mark"],Aa=["fees","gasEstimate","priceImpact","fundingHourly"],Ap=/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/});function Ca(){return V().venues.arcus}function Cp(){return Object.keys(Ca().markets).sort()}function _p({symbol:e,side:t="buy",sizeUsd:r=null}={}){if(typeof e!="string"||e.length===0)return null;let n=e.endsWith("-USD")?e.slice(0,-4):e,o=Ca().markets[n];if(!o)return null;let s=Z(o.mark,`${n}.mark`),a=P(o.oracle),i=P(o.fundingHourly),c=r===null?x("0"):r,u={venue:Ep,chain:kp,instrument:"perp",tier:Ip,symbolRaw:e,symbol:n,side:t,requestedSize:c,mark:s,fees:null,gasEstimate:null,priceImpact:null,fundingHourly:i,costAccounted:!1,capturedAt:V().capturedAt*1e3,blockOrSeq:null,raw:{fixture:"fixtures/venues.json#venues.arcus",oraclePrice:o.oracle,vol24h:o.vol24h,oi:o.oi,fundingAnnPct:o.fundingAnnPct,category:o.category,isOutsideRth:o.isOutsideRth===!0,rth:o.rth,darkWindowFundingHourly:rr,initialMarginFraction:o.initialMarginFraction??null,offHoursInitialMarginFraction:o.offHoursInitialMarginFraction??null,reasonCostUnknown:"fees, gas, and impact at size not captured for Arcus perps"}};return a!==null&&(u.raw.oracleFixed=a),M(u)}function nr({side:e="buy",sizeUsd:t=null}={}){return Cp().map(r=>_p({symbol:r,side:e,sizeUsd:t})).filter(r=>r!==null)}var Ep,kp,Ip,rr,fn=w(()=>{J();ke();K();ce();Ep="arcus_perp",kp="robinhood-4663",Ip="quote-only",rr="0.00000480324074074"});function hn(e,t,r=8){if(e==null)throw new TypeError("hourlyFundingRate is required");if(!Number.isFinite(t)||t<0)throw new RangeError("horizonHours must be a nonnegative finite number");if(t===0)return x("0");let n=x(String(t)),o=F(10000n,0);return H(H(e,n),o)}function Oa(e,t,r={}){if(e.instrument!=="perp")return{model:"current-funding-held-constant",horizonHours:t,carryBps:x("0"),carryBpsDisplay:"0",confidence:"estimate",note:"spot has no funding carry"};let n=r.nowMs??Date.now(),o=r.applyDarkWindowLock===!0,s=e.fundingHourly;if(o&&s!==null){let i=Op(n,t),c=t-i,u=x(rr),d=hn(s,c),p=hn(u,i),l=Math.max(d.scale,p.scale),m={mantissa:d.mantissa*10n**BigInt(l-d.scale)+p.mantissa*10n**BigInt(l-p.scale),scale:l};return{model:"current-funding-held-constant",horizonHours:t,carryBps:m,carryBpsDisplay:X(m),confidence:"estimate",darkHours:i,litHours:c,darkWindowRate:rr,compounding:"ignored",compoundingErrorBoundNote:"simple sum; at 30d and 1e-5/h the ignored compound is under 0.5bp"}}if(s===null)return{model:"current-funding-held-constant",horizonHours:t,carryBps:null,carryBpsDisplay:null,confidence:"estimate",note:"funding rate unknown"};let a=hn(s,t);return{model:"current-funding-held-constant",horizonHours:t,carryBps:a,carryBpsDisplay:X(a),confidence:"estimate",compounding:"ignored",compoundingErrorBoundNote:"simple sum; at 30d and 1e-5/h the ignored compound is under 0.5bp"}}function Op(e,t){if(t<=0)return 0;let r=0,n=Math.floor(t);for(let o=0;o<n;o+=1)ln(e+o*_a)&&(r+=1);return t>n&&ln(e+n*_a)&&(r+=t-n),r}var _a,Ib,Ra=w(()=>{K();fn();Xt();_a=36e5,Ib=24*365});function Rp(e){return e.mid??e.mark??e.ask??e.bid??null}function Tp(e){let t=Rp(e);if(t===null)return null;let r=e.costAccounted===!0,n=x("0");e.fees!==null?n=me(n,e.fees):r=!1,e.priceImpact!==null?n=me(n,e.priceImpact):e.requestedSize&&e.requestedSize.mantissa>0n&&(r=!1),e.gasEstimate===null?r=!1:n=me(n,e.gasEstimate);let o;if(e.fees!==null&&fe(e.fees,x("1"))<0&&fe(e.fees,x("0"))>=0){let s=me(x("1"),e.fees);o=H(t,s),e.priceImpact!==null&&(o=me(o,H(t,e.priceImpact)))}else o=me(t,n);return{net:o,costAccounted:r,px:t}}function Np(e,t,r=null){return{venue:e.venue,chain:e.chain,instrument:e.instrument,tier:e.tier,symbol:e.symbol,symbolRaw:e.symbolRaw,side:e.side,price:t.px,net:t.net,costAccounted:t.costAccounted,fundingHourly:e.fundingHourly,carry:r,quote:e}}function Bp(e,t){if(!e||!t||!e.costAccounted||!t.costAccounted||e.instrument!==t.instrument||e.net.mantissa===0n)return null;let r=ct(t.net,e.net);return Y(H(r,F(10000n,0)),t.net,4)}function or(e,t={}){if(!Array.isArray(e))throw new TypeError("quotes must be an array");let r=t.nowMs??e[0]?.capturedAt??Date.now(),n=e.length,o=e,s=[];if(!t.skipLiveness){let h=Zt(e,{nowMs:r});o=h.survivors,s=h.excluded}let a=e.length,i=[],c=t.horizonHours,u=Number.isFinite(c)&&c>0,d=[];for(let h of o){let q=Tp(h);if(q===null)continue;let U=null;if(u&&h.instrument==="perp"&&(U=Oa(h,c,{nowMs:r}),U.carryBps!==null)){let mt=me(x("1"),Y(U.carryBps,F(10000n,0),12));q.net=H(q.net,mt),q.costAccounted=!1}d.push(Np(h,q,U))}let p=d,l="homogeneous";if(u)l="heterogeneous",p=d;else{let h=d.filter(U=>U.instrument==="spot"),q=d.filter(U=>U.instrument==="perp");h.length>0&&q.length>0?(p=h.length>=q.length?h:q,l="homogeneous"):(p=d,l="homogeneous")}p.sort((h,q)=>{let U=fe(h.net,q.net);return U!==0?U:h.venue<q.venue?-1:h.venue>q.venue?1:0});let m=p[0]??null,f=p.slice(1),g=p,b="gross";m&&m.costAccounted&&(f.length===0||f[0].costAccounted)&&(b="net-of-cost");let S=f.length===0?null:Bp(m,f[0]),I=d.find(h=>h.tier==="prepare")??null,N=ut(r),re=N==="core"?null:{session:N,warning:N==="dark"?"market is dark; marks are not real price discovery":"extended session; thinner books and higher staleness risk"},be=null;u&&(be=$p(d));let Ce={rankedOn:b,ranked:g,winner:m,runnersUp:f,improvementBps:S===null?null:Number(X(S)),sourcesAnswered:a,sourcesTried:n,failed:i,excluded:s,darkWindow:re,instrumentMix:l,bestPreparable:I,carry:m?.carry??null,breakEvenHorizonHours:be};return tr(Ce)}function $p(e){let t=e.filter(s=>s.instrument==="spot").sort((s,a)=>fe(s.net,a.net))[0],r=e.filter(s=>s.instrument==="perp").sort((s,a)=>fe(s.net,a.net))[0];if(!t||!r||r.fundingHourly===null)return null;let n=ct(t.net,r.net);if(n.mantissa===0n)return 0;let o=H(r.fundingHourly,r.price);if(o.mantissa===0n)return null;try{let s=Y(n,o,4),a=Number(X(s));return!Number.isFinite(a)||a<0?null:a}catch{return null}}var bn=w(()=>{dn();Ra();Xt();K();ce()});function gn(){return Gt()}function Fp(e){return{mantissa:e*e*10n**BigInt(Me)/Up,scale:Me}}function Mp(e){let t=Fp(BigInt(e.sqrtPriceX96)),r=e.quote==="USDG"?6:18,n=18;if(e.quoteIsToken0){let o=Y(H(t,F(10n**BigInt(r),0)),F(10n**BigInt(n),0),Me);return o.mantissa===0n?null:Y(x("1"),o,Me)}return Y(H(t,F(10n**BigInt(n),0)),F(10n**BigInt(r),0),Me)}function jp(e){let t=aa(),r=t.assets[e];return r?F(r.rawPrice,t.oracleScaleExp):null}function Hp(e,t){if(e===null||t===null||e.mantissa<=0n||t.mantissa<=0n)return null;let r={...e};return Y(t,Vp(r,t),Me)}function Vp(e,t){let r=Math.max(e.scale,t.scale);return{mantissa:at(e,r).mantissa+at(t,r).mantissa,scale:r}}function zp(e){let t=gn(),r=Lp[e];return r?{wei:BigInt(t.gasPriceWei)*r,units:r,native:"ETH"}:null}function yn(){return Object.keys(gn().pools).sort()}function je({symbol:e,side:t="buy",sizeUsd:r=null}={}){if(typeof e!="string"||e.length===0)throw new TypeError("symbol must be a nonempty string");let n=gn(),o=n.pools[e];if(!o)return null;let s=Mp(o);if(s===null)return null;let a=P(o.liqUsd),i=r===null?x("0"):r,c=o.feePpm===null||o.feePpm===void 0?null:Y(F(BigInt(o.feePpm),0),F(1000000n,0),8),u=i.mantissa===0n?x("0"):Hp(a,i),d=zp(o.version),m={venue:qp,chain:Dp,instrument:"spot",tier:Pp,symbolRaw:e,symbol:e,side:t,requestedSize:i,mid:s,fees:c,gasEstimate:null,priceImpact:u,fundingHourly:null,costAccounted:!1,capturedAt:n.capturedAt*1e3,blockOrSeq:n.block,raw:{fixture:"fixtures/rh_pool_state.json",pair:o.pair,version:o.version,sqrtPriceX96:o.sqrtPriceX96,quote:o.quote,quoteIsToken0:o.quoteIsToken0,liqUsd:o.liqUsd,gasNativeWei:d===null?null:d.wei.toString(),gasUnits:d===null?null:d.units.toString(),impactModel:"constant-product-estimate",notes:["price read live from chain 4663",o.version==="v4"?"v4 fee may be dynamic via hook and was not captured":"v3 fee tier is the pool static fee","gas known in native wei only, no ETH price captured to denominate it"]}},f=jp(e);return f!==null&&(m.referencePrice=f,m.referenceBasisBps=X(Y(H(ct(s,f),F(10000n,0)),f,4))),M(m)}function Ta({side:e="buy",sizeUsd:t=null}={}){return yn().map(r=>je({symbol:r,side:e,sizeUsd:t})).filter(r=>r!==null)}var qp,Dp,Pp,Up,Me,Lp,wn=w(()=>{J();ke();K();ce();qp="rh_uniswap",Dp=4663,Pp="prepare",Up=1n<<192n,Me=18,Lp=Object.freeze({v3:180000n,v4:240000n})});function sr(e={}){let{symbol:t,side:r="buy",sizeUsd:n=null,recipient:o,nowMs:s=Date.now()}=e;if(typeof t!="string"||!t)throw new TypeError("symbol is required");if(typeof o!="string"||!/^0x[0-9a-fA-F]{40}$/.test(o))throw new TypeError("recipient must be a 0x-prefixed 20 byte address");let a=je({symbol:t,side:r,sizeUsd:n});if(a===null)throw new Error(`no RH Uniswap pool for ${t}`);if(a.tier!=="prepare")throw new Error(`route tier is ${a.tier}, only prepare tier can be prepared`);let i=s-a.capturedAt;if(i>Na)throw new Error(`quote is stale (${i}ms old, bound ${Na}ms); re-quote before preparing`);let u=Gt().pools[t],d=u.version==="v4"?Qp:Kp,p=d,l=r==="buy"?u.quoteAddr:u.token;return Object.freeze({artifactKind:"unsigned-tx",chainId:4663,to:d,data:"0x",value:"0",requiresApproval:{spender:p,token:l,amount:null},requiresWalletSignature:!0,backendSigner:!1,unsigned:!0,houseSigned:!1,quoteRef:{venue:a.venue,symbol:a.symbol,symbolRaw:a.symbolRaw,capturedAt:a.capturedAt,blockOrSeq:a.blockOrSeq,mid:a.mid,version:u.version,pair:u.pair},quoteAgeMs:i,recipient:o,side:r,notes:["prepare-only: user wallet must sign","calldata encoding is deferred; this artifact is the bound intent",u.version==="v4"?"V4 route via PoolManager":"V3 route via SwapRouter (address not yet pinned)"]})}var Na,Kp,Qp,Sn=w(()=>{wn();J();Na=12e4,Kp="0x0000000000000000000000000000000000000000",Qp="0x84b75b19A3cdf8E2F56d0507d22D442847B2053C"});function dt(){return V().venues.hyperliquid_hip3}function Ba(){return Object.keys(dt().dexs).sort()}function Yp(){let e=[];for(let[t,r]of Object.entries(dt().dexs))for(let n of Object.keys(r))e.push(`${t}:${n}`);return e.sort()}function Jp(e){if(typeof e!="string"||e.length===0)return[];let t=e.indexOf(":");if(t>0){let n=e.slice(0,t),o=e.slice(t+1),s=dt().dexs[n]?.[o];return s?[{dex:n,ticker:o,market:s}]:[]}let r=[];for(let[n,o]of Object.entries(dt().dexs))Object.hasOwn(o,e)&&r.push({dex:n,ticker:e,market:o[e]});return r}function Zp(e,t){try{return pa().books[`${e}:${t}`]??null}catch{return null}}function em(e,t,r){if(!e||r===null||r.mantissa<=0n)return null;let n=t==="buy"?e.asks:e.bids;if(!n||n.length===0)return null;let o=Number(X(r));if(!Number.isFinite(o)||o<=0)return null;let s=0,a=0,i=0;for(let c of n){let u=Number(c.px),d=Number(c.sz);if(!(u>0)||!(d>0))continue;let p=u*d,l=Math.min(o,p),m=l/u;if(s+=l,a+=m,o-=l,i+=1,o<=1e-9)break}return a<=0?null:{vwap:s/a,filledUsd:s,unfilledUsd:Math.max(0,o),levelsUsed:i}}function tm(e,t,r,n){let o=em(e,t,r);if(!o)return{impact:null,depth:null};let s=Number(X(n));if(!(s>0))return{impact:null,depth:o};let a=t==="buy"?(o.vwap-s)/s:(s-o.vwap)/s,i=Math.max(0,a);return{impact:P(Number(i.toPrecision(12))),depth:{...o,impactFraction:i,fullyFilled:o.unfilledUsd<=1e-6}}}function $a({dex:e,ticker:t,market:r,side:n,size:o}){let s=Z(r.mark,`${e}:${t}.mark`),a=P(r.fundingHourly),i=P(r.vol24h),c=P(r.oi),u=o===null?x("0"):o,d=Zp(e,t),p=null,l=null,m="fees and gas not captured";if(u.mantissa>0n)if(d){let b=tm(d,n,u,s);p=b.impact,l=b.depth,l?.fullyFilled?m="impact measured from l2Book; fees and gas still not captured":m="book walked but size exceeds visible depth; fees and gas not captured"}else m="no order book depth wired for this coin; fees and gas not captured";else d?m="zero size; fees and gas not captured":m="no order book depth wired for this coin; fees and gas not captured";let g={venue:Wp,chain:Gp,instrument:"perp",tier:Xp,symbolRaw:`${e}:${t}`,symbol:t,side:n,requestedSize:u,mark:s,fees:null,gasEstimate:null,priceImpact:p,fundingHourly:a,costAccounted:!1,capturedAt:V().capturedAt*1e3,blockOrSeq:null,raw:{fixture:"fixtures/venues.json#venues.hyperliquid_hip3",dex:e,ticker:t,vol24h:r.vol24h,oi:r.oi,fundingAnnPct:r.fundingAnnPct,maxLev:r.maxLev,reasonCostUnknown:m,hasL2Book:d!==null,l2BookFixture:d?"fixtures/hip3_l2books.json":null,depth:l}};return i!==null&&(g.raw.vol24hFixed=i),c!==null&&(g.raw.oiFixed=c),d?.bids?.[0]&&d?.asks?.[0]&&(g.bid=x(String(d.bids[0].px)),g.ask=x(String(d.asks[0].px))),M(g)}function qa({symbol:e,side:t="buy",sizeUsd:r=null}={}){let n=Jp(e);return n.length===0||n.length>1?null:$a({...n[0],side:t,size:r})}function ir({side:e="buy",sizeUsd:t=null,ticker:r=null}={}){let n=[];for(let o of Yp()){let[s,a]=o.split(":");if(r!==null&&a!==r)continue;let i=dt().dexs[s][a];n.push($a({dex:s,ticker:a,market:i,side:e,size:t}))}return n}var Wp,Gp,Xp,Da=w(()=>{J();ke();K();ce();Wp="hyperliquid_hip3",Gp="hyperliquid",Xp="quote-only"});function Pa(){return V().venues.arcus_spot}function sm(){return Object.keys(Pa().pairs).sort()}function im({symbol:e,side:t="buy",sizeUsd:r=null}={}){if(typeof e!="string"||e.length===0)return null;let n=Pa().pairs[e];if(!n)return null;let o=n.bid===void 0||n.bid===null?null:Z(n.bid,`${e}.bid`),s=n.ask===void 0||n.ask===null?null:Z(n.ask,`${e}.ask`),a=P(n.last),i=null;if(o!==null&&s!==null){i={mantissa:o.mantissa+s.mantissa,scale:o.scale===s.scale?o.scale+1:Math.max(o.scale,s.scale)+1};let p=Math.max(o.scale,s.scale),l=o.scale===p?o.mantissa:o.mantissa*10n**BigInt(p-o.scale),m=s.scale===p?s.mantissa:s.mantissa*10n**BigInt(p-s.scale);i={mantissa:l+m,scale:p+1},i={mantissa:(l+m)/2n,scale:p}}else a!==null&&(i=a);if(o===null&&s===null&&i===null)return null;let c=r===null?x("0"):r,u=x("0"),d={venue:rm,chain:nm,instrument:"spot",tier:om,symbolRaw:e,symbol:e,side:t,requestedSize:c,fees:u,gasEstimate:null,priceImpact:null,fundingHourly:null,costAccounted:!1,capturedAt:V().capturedAt*1e3,blockOrSeq:null,raw:{fixture:"fixtures/venues.json#venues.arcus_spot",last:n.last,bid:n.bid,ask:n.ask,vol24h:n.vol24h,feeKnownZero:!0,reasonCostUnknown:"gas and impact at size not captured; fee is a known zero"}};return o!==null&&(d.bid=o),s!==null&&(d.ask=s),i!==null&&(d.mid=i),M(d)}function ar({side:e="buy",sizeUsd:t=null}={}){return sm().map(r=>im({symbol:r,side:e,sizeUsd:t})).filter(r=>r!==null)}var rm,nm,om,Ua=w(()=>{J();ke();K();ce();rm="arcus_spot",nm="robinhood-4663",om="quote-only"});function cr(){return la()}function vn(){return Object.keys(cr().tokens).sort()}function lm(e){let t=cr().pairs[e];return!t||t.length===0?null:[...t].sort((r,n)=>(n.liquidityUsd??0)-(r.liquidityUsd??0))[0]}function dm(e,t){if(e===null||t===null)return null;if(e.mantissa<=0n||t.mantissa<=0n)return x("0");let r=Math.max(e.scale,t.scale),n=e.scale===r?e.mantissa:e.mantissa*10n**BigInt(r-e.scale),o=t.scale===r?t.mantissa:t.mantissa*10n**BigInt(r-t.scale),s=o*10n**6n,a=n+o;return{mantissa:s/a,scale:6}}function xn({symbol:e,side:t="buy",sizeUsd:r=null}={}){if(typeof e!="string"||e.length===0)return null;let n=e,o=e,s=cr().tokens;if(Object.hasOwn(s,e))n=e,o=s[e].symbolRaw;else if(e.endsWith("x")||e.endsWith("X")){let f=e.slice(0,-1).toUpperCase();if(Object.hasOwn(s,f))n=f,o=s[f].symbolRaw;else return null}else return null;let a=s[n],i=lm(n);if(!a||!i)return null;let c=Z(i.priceUsd,`${n}.priceUsd`),u=P(i.liquidityUsd),d=r===null?x("0"):r,p=d.mantissa===0n?x("0"):dm(u,d),l=!1;d.mantissa===0n&&(i.liquidityUsd??0)>=La&&(l=!1);let m={venue:am,chain:cm,instrument:"spot",tier:um,symbolRaw:o,symbol:n,side:t,requestedSize:d,mid:c,fees:null,gasEstimate:null,priceImpact:p,fundingHourly:null,costAccounted:l,capturedAt:cr().capturedAt*1e3,blockOrSeq:null,raw:{fixture:"fixtures/solana_xstocks.json",mint:a.mint,pairAddress:i.pairAddress,dexId:i.dexId,quote:i.quote,liquidityUsd:i.liquidityUsd,volume24h:i.volume24h,priceUsd:i.priceUsd,source:"dexscreener",approximate:!0,reasonCostUnknown:"DexScreener liquidity.usd is a third-party float; fees and SOL gas not captured; impact is modeled",thin:(i.liquidityUsd??0)<La}};return M(m)}function Fa({side:e="buy",sizeUsd:t=null}={}){return vn().map(r=>xn({symbol:r,side:e,sizeUsd:t})).filter(r=>r!==null)}var am,cm,um,La,Ma=w(()=>{J();ke();K();ce();am="solana_xstocks",cm="solana",um="quote-only",La=25e3});function ur(){return da()}function An(){return Object.keys(ur().tokens).sort()}function gm(e){let t=ur().pairs[e];return!t||t.length===0?null:[...t].sort((r,n)=>(n.liquidityUsd??0)-(r.liquidityUsd??0))[0]}function ym(e,t){if(e===null||t===null)return null;if(e.mantissa<=0n||t.mantissa<=0n)return x("0");let r=Math.max(e.scale,t.scale),n=e.scale===r?e.mantissa:e.mantissa*10n**BigInt(r-e.scale),o=t.scale===r?t.mantissa:t.mantissa*10n**BigInt(r-t.scale),s=o*10n**6n,a=n+o;return{mantissa:s/a,scale:6}}function En({symbol:e,side:t="buy",sizeUsd:r=null}={}){if(typeof e!="string"||e.length===0)return null;let n=e,o=e,s=ur().tokens;if(Object.hasOwn(s,e))n=e,o=s[e].symbolRaw;else if(e.endsWith("x")||e.endsWith("X")){let f=e.slice(0,-1).toUpperCase();if(Object.hasOwn(s,f))n=f,o=s[f].symbolRaw;else return null}else{let f=e.toUpperCase();if(Object.hasOwn(s,f))n=f,o=s[f].symbolRaw;else return null}let a=s[n],i=gm(n);if(!a||!i)return null;let c=Z(i.priceUsd,`${n}.priceUsd`),u=P(i.liquidityUsd),d=r===null?x("0"):r,p=d.mantissa===0n?x("0"):ym(u,d),m={venue:pm,chain:mm,instrument:"spot",tier:fm,symbolRaw:o,symbol:n,side:t,requestedSize:d,mid:c,fees:null,gasEstimate:null,priceImpact:p,fundingHourly:null,costAccounted:!1,capturedAt:ur().capturedAt*1e3,blockOrSeq:null,raw:{fixture:"fixtures/ton_xstocks.json",mint:a.mint,pairAddress:i.pairAddress,dexId:i.dexId,quote:i.quote,liquidityUsd:i.liquidityUsd,volume24h:i.volume24h,priceUsd:i.priceUsd,source:"dexscreener",approximate:!0,reasonCostUnknown:"DexScreener liquidity.usd is a third-party float; fees and TON gas not captured; impact is modeled; TON books are thin",thin:(i.liquidityUsd??0)<hm,impactSizeFractionHint:bm}};return M(m)}function ja({side:e="buy",sizeUsd:t=null}={}){return An().map(r=>En({symbol:r,side:e,sizeUsd:t})).filter(r=>r!==null)}var pm,mm,fm,hm,bm,Ha=w(()=>{J();ke();K();ce();pm="ton_stonfi",mm="ton",fm="quote-only",hm=25e3,bm=.01});var lr={};_(lr,{bestEquityRoute:()=>wm,collectEquityQuotes:()=>Va,equityVenues:()=>Sm,getUniverse:()=>ia,getVenues:()=>V,loadFixtures:()=>sn,prepareEquity:()=>sr,prepareEquityRoute:()=>vm,rankEquityQuotes:()=>or,toJsonSafe:()=>xm,validateQuote:()=>M,validateRankResult:()=>tr});function kn(e){return e==null||e===""?null:typeof e=="object"&&e&&typeof e.mantissa=="bigint"?e:x(String(e))}function Va(e,{sizeUsd:t=null}={}){if(typeof e!="string"||!e.trim())throw new TypeError("ticker is required");let r=e.trim().toUpperCase(),n=kn(t),o=[],s=qa({symbol:`xyz:${r}`,sizeUsd:n});if(s)o.push(s);else for(let u of ir({ticker:r,sizeUsd:n}))o.push(u);for(let u of nr({sizeUsd:n}))u.symbol===r&&o.push(u);for(let u of ar({sizeUsd:n}))u.symbol===r&&o.push(u);let a=je({symbol:r,sizeUsd:n});a&&o.push(a);let i=xn({symbol:r,sizeUsd:n});i&&o.push(i);let c=En({symbol:r,sizeUsd:n});return c&&o.push(c),o}function wm(e={}){let t=String(e.ticker||e.symbol||"").trim().toUpperCase();if(!t)throw new Error("bestEquityRoute requires ticker");let r=kn(e.sizeUsd??e.size??null),n=Va(t,{sizeUsd:r});if(n.length===0)return{ticker:t,rankedOn:"gross",ranked:[],winner:null,runnersUp:[],improvementBps:null,sourcesAnswered:0,sourcesTried:0,failed:[],excluded:[],bestPreparable:null,instrumentMix:"homogeneous",note:"no venue answered for this ticker in the pinned fixture capture"};let o=e.nowMs??n[0].capturedAt+1e3,s=or(n,{nowMs:o,horizonHours:e.horizonHours!=null?Number(e.horizonHours):void 0,skipLiveness:e.skipLiveness===!0});return{ticker:t,...s}}function Sm(){let e=[{venue:"hyperliquid_hip3",tier:"quote-only",chain:"hyperliquid",n:ir().length},{venue:"arcus_perp",tier:"quote-only",chain:"robinhood-4663",n:nr().length},{venue:"arcus_spot",tier:"quote-only",chain:"robinhood-4663",n:ar().length},{venue:"rh_uniswap",tier:"prepare",chain:4663,n:yn().length},{venue:"solana_xstocks",tier:"quote-only",chain:"solana",n:vn().length},{venue:"ton_stonfi",tier:"quote-only",chain:"ton",n:An().length}],t=[...ir(),...nr(),...ar(),...Ta(),...Fa(),...ja()],r=(t[0]?.capturedAt??Date.now())+1e3,{survivors:n,excluded:o}=Zt(t,{nowMs:r});return{inventory:e,hip3Dexs:Ba(),liveness:{survivors:n.length,excluded:o.length,byReason:o.reduce((s,a)=>(s[a.reason]=(s[a.reason]??0)+1,s),{})},capturedAt:V().capturedAt,custody:"prepare-only",note:"quote-only venues are ranked for discovery; only rh_uniswap is preparable in v1"}}function vm(e={}){let t=String(e.ticker||e.symbol||"").trim().toUpperCase(),r=e.recipient||e.taker;if(!t)throw new Error("prepareEquityRoute requires ticker");if(!r)throw new Error("prepareEquityRoute requires recipient (signing wallet)");let n=kn(e.sizeUsd??e.size??null),o=je({symbol:t,sizeUsd:n});if(!o)return{ok:!1,failureKind:"no-prepare-path",ticker:t,note:"no RH Uniswap prepare-tier route for this ticker in fixtures"};try{let s=sr({symbol:t,sizeUsd:n,recipient:r,nowMs:e.nowMs??o.capturedAt+1e3});return{ok:!0,ticker:t,artifact:s,bestPreparableVenue:"rh_uniswap"}}catch(s){return{ok:!1,failureKind:"prepare-refused",ticker:t,error:String(s.message||s)}}}function xm(e){return JSON.parse(JSON.stringify(e,(t,r)=>typeof r=="bigint"?r.toString():r))}var dr=w(()=>{K();bn();Sn();dn();Da();Ua();fn();wn();Ma();Ha();J();bn();Sn();ce();J()});var pr={};_(pr,{CHAIN_CONFIGS:()=>it,EVIDENCE:()=>A,RISK:()=>v,SCANNER_CAPABILITIES:()=>$e,__clearScanners:()=>Bu,createScanner:()=>is,getScanner:()=>Tu,listScanners:()=>Nu,registerBuiltinScanners:()=>wi,registerCustomChain:()=>Si,registerScanner:()=>Bt,scannerCoverage:()=>$u,validateScanner:()=>ss});var mr=w(()=>{ve();Zr()});import za from"node:fs";import Ve from"node:process";import{fileURLToPath as Am}from"node:url";import{homedir as fr}from"node:os";import{join as hr}from"node:path";var _n=process.env.ORACLE_PUBLIC_DESKTOP==="1",br=_n?process.env.ORACLE_CONFIG_DIR||hr(fr(),".config","oracle"):hr(fr(),".config","oracle"),Bm=_n?br:hr(fr(),".config","mad-desk");function ze(e,t,r=""){let n=process.env[e];if(n!=null&&String(n).trim()!=="")return n;let o=t?process.env[t]:void 0;return o!=null&&String(o).trim()!==""?o:r}import Ke from"node:fs";import Qe from"node:path";var Rn=/^0x[0-9a-fA-F]{40}$/,Xa=new Set(["privatekey","private_key","secret","seed","mnemonic","passphrase","signature","keystore"]),Ya=["privatekey","privkey","secretkey","secret","seedphrase","seed","mnemonic","passphrase","password","keystore","keymaterial","signature","wif","xprv","xpriv","apikey","bearer","credential"],Ja=[/\b[5KL][1-9A-HJ-NP-Za-km-z]{50,51}\b/,/\bxprv[0-9A-Za-z]{50,}\b/,/\b(?:[a-z]{3,8}\s+){11,}[a-z]{3,8}\b/i],Za=/^\s*(?:0x)?[0-9a-fA-F]{64}\s*$/;function ec(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function tc(e,t){let r=ec(e);if(Xa.has(String(e).toLowerCase())||Ya.some(n=>r.includes(n)))throw new Error(`address-book: ${t} is forbidden; the book stores labels, never key material`)}function rc(e,t){if(typeof e=="string"&&(Ja.some(r=>r.test(e))||Za.test(e)))throw new Error(`address-book: ${t} looks like key material; the book stores labels, never key material`)}function Tn(){let e=ze("ORACLE_ADDRESS_BOOK","MAD_ADDRESS_BOOK","");if(e)return Qe.resolve(e);let t=ze("ORACLE_CONFIG_DIR","MAD_CONFIG_DIR",br);return Qe.join(t,"address-book.json")}function gr(e,t="field"){if(Array.isArray(e)){e.forEach((r,n)=>gr(r,`${t}[${n}]`));return}if(!e||typeof e!="object"){rc(e,t);return}for(let[r,n]of Object.entries(e))tc(r,r),gr(n,r)}function yr(e){let t=String(e||"").trim();if(!Rn.test(t))throw new Error("address-book: address must be 0x + 40 hex characters");return t.toLowerCase()}function _e(e,t){return e==null||e===""?null:String(e).slice(0,t)}function On(){return{version:1,updatedAt:null,entries:[]}}function Nn(e){return{address:String(e.address).toLowerCase(),label:_e(e.label,80)||"unknown",who:_e(e.who,120),role:_e(e.role,40),chainIds:Array.isArray(e.chainIds)?e.chainIds.map(Number).filter(Number.isFinite):[],notes:_e(e.notes,500),source:_e(e.source,80),firstSeenAt:e.firstSeenAt||null,lastSeenAt:e.lastSeenAt||null}}function ft(){try{let e=JSON.parse(Ke.readFileSync(Tn(),"utf8"));if(!e||typeof e!="object")return On();let t=Array.isArray(e.entries)?e.entries:[];return{version:1,updatedAt:e.updatedAt||null,entries:t.filter(r=>r&&typeof r=="object"&&Rn.test(String(r.address||""))).map(Nn)}}catch{return On()}}function Bn(e){let t=Tn();Ke.mkdirSync(Qe.dirname(t),{recursive:!0,mode:448});let r={...e,version:1,updatedAt:new Date().toISOString()},n=Qe.join(Qe.dirname(t),`.address-book.${process.pid}.tmp`);Ke.writeFileSync(n,`${JSON.stringify(r,null,2)}
6
+ `,{mode:384}),Ke.renameSync(n,t);try{Ke.chmodSync(t,384)}catch{}return r}function $n(e={}){let t=ft(),r=t.entries;if(e.role&&(r=r.filter(n=>n.role===String(e.role))),e.who){let n=String(e.who).toLowerCase();r=r.filter(o=>(o.who||"").toLowerCase().includes(n)||(o.label||"").toLowerCase().includes(n))}if(e.q){let n=String(e.q).toLowerCase();r=r.filter(o=>o.address.includes(n)||(o.label||"").toLowerCase().includes(n)||(o.who||"").toLowerCase().includes(n)||(o.notes||"").toLowerCase().includes(n))}return{updatedAt:t.updatedAt,count:r.length,entries:r}}function qn(e){let t=yr(e),r=ft().entries.filter(n=>n.address===t);return{address:t,found:r.length>0,entries:r}}function Dn(e={}){gr(e);let t=yr(e.address),r=_e(e.label??e.role,80)||"wallet",n=new Date().toISOString(),o=ft(),s=o.entries.findIndex(u=>u.address===t&&u.label===r),a=Nn({address:t,label:r,who:e.who,role:e.role,chainIds:e.chainIds,notes:e.notes,source:e.source||"agent",firstSeenAt:s>=0&&o.entries[s].firstSeenAt||n,lastSeenAt:n});s>=0?o.entries[s]=a:o.entries.push(a);let i=u=>u==="agent"?0:u==="owner"?1:2;o.entries.sort((u,d)=>i(u.role)-i(d.role)||u.label.localeCompare(d.label)||u.address.localeCompare(d.address));let c=Bn(o);return{ok:!0,entry:a,count:c.entries.length}}function Pn(e,t=null){let r=yr(e),n=ft(),o=n.entries.length;return n.entries=n.entries.filter(s=>s.address!==r?!0:t==null?!1:s.label!==String(t)),Bn(n),{ok:!0,removed:o-n.entries.length,count:n.entries.length}}var In=ze("ORACLE_DATA_URL","MAD_DESK_URL","http://127.0.0.1:8787").replace(/\/$/,""),Em=[{name:"data_catalog",description:"List every read-plane provider the desk exposes (id, venue, chainIds, ops). Use this to discover what public APIs are available before calling data_call. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"data_health",description:"Health of every read-plane provider (which public APIs are up / configured). Read-only.",inputSchema:{type:"object",properties:{}}},{name:"data_call",description:"Generic escape hatch: call any provider/op from the catalog. provider+op are required; args is a free-form object matching that op. Read-only. Use data_catalog first to see valid provider/op pairs.",inputSchema:{type:"object",required:["provider","op"],properties:{provider:{type:"string",description:"provider id, e.g. defillama, dexscreener, lifi, evm-rpc"},op:{type:"string",description:"op name for that provider, e.g. protocols, search, quote"},args:{type:"object",description:"op arguments (free-form)"}}}},{name:"llama_protocols",description:"DeFiLlama: full protocol list with TVL, chain(s), category, 1d/7d change. The primary cross-chain protocol scanner. Read-only. Large payload \u2014 filter client-side.",inputSchema:{type:"object",properties:{}}},{name:"llama_prices",description:"DeFiLlama current prices for coins keyed 'chain:address' or 'coingecko:id' (comma-joined or array). Read-only.",inputSchema:{type:"object",required:["coins"],properties:{coins:{type:"string",description:"comma-joined coin keys, e.g. 'ethereum:0x...,coingecko:bitcoin'"}}}},{name:"dex_search",description:"DexScreener search across all chains by symbol/name/address. Returns matching pairs with price, liquidity, volume, chain. Read-only.",inputSchema:{type:"object",required:["q"],properties:{q:{type:"string",description:"query: symbol, name, or token address"}}}},{name:"dex_token",description:"DexScreener pairs for a specific token address (any chain). Price, liquidity, volume, pair addresses. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"lifi_quote",description:"LI.FI cross-chain / DEX aggregator quote (no key). Best route + expected out for a swap or bridge. Read-only.",inputSchema:{type:"object",required:["fromChain","toChain","fromToken","toToken","fromAmount"],properties:{fromChain:{type:"number"},toChain:{type:"number"},fromToken:{type:"string"},toToken:{type:"string"},fromAmount:{type:"string",description:"raw integer amount (wei-scale)"},fromAddress:{type:"string",description:"optional; defaults to operator wallet"}}}},{name:"portfolio_balance",description:"Read-only balance aggregation across every configured EVM chain plus Solana, Bitcoin, and Hyperliquid. Reports native assets, supported token/collectible reads, failed or missing providers, unverified assets, timestamps, and known priced value without pretending it is a complete total. Public addresses only; never signs or broadcasts.",inputSchema:{type:"object",properties:{addresses:{type:"object",description:"Optional public wallet addresses by family. Omit configured families to use ORACLE_*_ADDRESS defaults.",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},evmChainIds:{type:"array",items:{type:"number"},description:"Optional EVM chain subset. Default is every configured EVM chain."},includeTokens:{type:"boolean",description:"Include supported token reads. Default true."},includeCollectibles:{type:"boolean",description:"Include supported collectible reads. Default true."},includePrices:{type:"boolean",description:"Fetch current DeFiLlama native prices. Default true."}}}},{name:"portfolio_snapshot",description:"Query the current multichain balance and NFT inventory, then append one compact profile-local observation for historical tracking. Stores public-address fingerprint, coverage, breakdown, and known priced value only; no keys, signatures, executable payloads, or raw NFT metadata. Returns the live balance, NFT result, and recorded snapshot.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},evmChainIds:{type:"array",items:{type:"number"}},includeTokens:{type:"boolean"},includeCollectibles:{type:"boolean"},includePrices:{type:"boolean"},includeNfts:{type:"boolean",description:"Include provider-estimated NFT value. Default true."}}}},{name:"portfolio_history",description:"Read profile-local portfolio observations in a time range. Unknown or unavailable values remain null and are never converted to zero. Defaults to the configured public-address portfolio fingerprint.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},portfolioId:{type:"string"},allPortfolios:{type:"boolean",description:"Return observations for every public-address fingerprint in this profile."},since:{type:"string",description:"Inclusive ISO 8601 lower bound."},until:{type:"string",description:"Inclusive ISO 8601 upper bound."},limit:{type:"number",description:"1-1000, default 100."},order:{type:"string",enum:["asc","desc"]}}}},{name:"portfolio_value_graph",description:"Render a static SVG line graph from profile-local portfolio snapshots. Plots known priced value only, labels incomplete coverage, includes provider-estimated NFT values when recorded, and omits unavailable observations instead of plotting fake zeroes.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"},hyperliquid:{type:"string"}}},portfolioId:{type:"string"},allPortfolios:{type:"boolean"},since:{type:"string"},until:{type:"string"},limit:{type:"number",description:"Historical observations to consider, max 1000."},maxPoints:{type:"number",description:"Rendered point cap, 2-500, default 200."}}}},{name:"nft_inventory",description:"Read all discoverable NFTs for configured EVM, Solana, and Bitcoin addresses. Returns normalized assets, image URLs, estimated values, per-chain partial failures, flagged/NSFW items separated from visible items, listing coverage, and explicit unsupported chains. Read-only.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"}}},chains:{type:"array",items:{type:"string"},description:"Optional chain slug subset."},pageSize:{type:"number",description:"OpenSea items per page, max 200."},maxPages:{type:"number",description:"Maximum pages per chain, max 25."},bitcoinLimit:{type:"number"},includePnl:{type:"boolean",description:"Include OpenSea-indexed account PnL when available. Default true."},costBasis:{type:"object",description:"Optional user-supplied assetKey -> {costUsd,feesUsd,acquiredAt,source}. Missing basis stays unavailable, never zero."}}}},{name:"nft_gallery",description:"Generate one static NFT contact-sheet image page from wallet inventory or supplied normalized items. External metadata is never rendered as HTML; only allowlisted JPEG/PNG/WebP bytes are embedded and unsafe or missing media becomes a placeholder.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"}}},chains:{type:"array",items:{type:"string"}},items:{type:"array",items:{type:"object"},description:"Optional normalized inventory items. Omit to scan configured wallets."},page:{type:"number",description:"1-based gallery page."},pageSize:{type:"number",description:"1-12 items per page."}}}},{name:"nft_pnl",description:"NFT PnL with explicit methodology. Returns OpenSea-indexed account-level PnL where available plus per-item unrealized estimates only when both user-supplied acquisition cost and provider estimated current value exist. Missing history is unavailable, never zero.",inputSchema:{type:"object",properties:{addresses:{type:"object",properties:{evm:{type:"string"},solana:{type:"string"},bitcoin:{type:"string"}}},chains:{type:"array",items:{type:"string"}},costBasis:{type:"object"}}}},{name:"nft_prepare_list",description:"Prepare an NFT listing for OpenSea EVM, Magic Eden Solana, or Satflow Bitcoin after explicit user review. Requires userConfirmed=true plus asset, marketplace, price, currency where applicable, and future expiry. Magic Eden Solana also requires confirmation exactly: list <tokenMint> on magiceden-sol for <priceSol> SOL until <expiry>. Returns approval/signing actions, an unsigned Solana transaction, or an unsigned Bitcoin PSBT. Never signs, submits, or broadcasts.",inputSchema:{type:"object",required:["marketplace","userConfirmed"],properties:{marketplace:{type:"string",enum:["opensea","magiceden","magiceden-sol","satflow"]},userConfirmed:{type:"boolean"},chain:{type:"string"},seller:{type:"string"},contract:{type:"string"},tokenId:{type:"string"},quantity:{type:"number"},priceAmount:{type:"string"},currency:{type:"string"},endTime:{type:"string"},useCreatorFee:{type:"boolean"},taker:{type:"string"},tokenMint:{type:"string"},tokenATA:{type:"string"},auctionHouse:{type:"string"},priceSol:{type:"string"},expiry:{description:"Future ISO 8601 timestamp or Unix seconds. Magic Eden Solana listings require finite future expiry; no-expiry is refused."},confirmation:{type:"string",description:"Required for Magic Eden Solana listings. Exact phrase: list <tokenMint> on magiceden-sol for <priceSol> SOL until <expiry>."},inscriptionId:{type:"string"},runesOutput:{type:"string"},ordAddress:{type:"string"},receiveAddress:{type:"string"},priceSats:{type:"string"},tapKey:{type:"string"},collectionSlug:{type:"string"}}}},{name:"rpc_balance",description:"Native token balance of an address on a chain via public RPC. Read-only. Omit address to read the operator wallet.",inputSchema:{type:"object",required:["chainId"],properties:{chainId:{type:"number"},address:{type:"string"}}}},{name:"rpc_block",description:"Latest block number on a chain via public RPC. Read-only.",inputSchema:{type:"object",required:["chainId"],properties:{chainId:{type:"number"}}}},{name:"solana_balance",description:"Solana mainnet SOL balance for a base58 public key. Read-only; no signing or broadcast.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},commitment:{type:"string"}}}},{name:"solana_token_accounts",description:"Solana SPL token accounts for an owner, optionally filtered by mint. Read-only.",inputSchema:{type:"object",required:["owner"],properties:{owner:{type:"string"},mint:{type:"string"},commitment:{type:"string"}}}},{name:"solana_simulate",description:"Simulate a base64 Solana transaction through RPC. Read-only; never signs or broadcasts.",inputSchema:{type:"object",required:["transaction"],properties:{transaction:{type:"string"},sigVerify:{type:"boolean"},replaceRecentBlockhash:{type:"boolean"}}}},{name:"jupiter_venues",description:"Jupiter Solana venue map, optionally verified on-chain against executable BPF loader ownership. Read-only.",inputSchema:{type:"object",properties:{verify:{type:"boolean"},rpc:{type:"string"}}}},{name:"jupiter_quote",description:"Jupiter Solana Swap API quote with a hard <=100 bps slippage cap. Read-only.",inputSchema:{type:"object",required:["inputMint","outputMint","amount"],properties:{inputMint:{type:"string"},outputMint:{type:"string"},amount:{type:"string"},slippageBps:{type:"number"}}}},{name:"jupiter_prepare",description:"Prepare an unsigned Jupiter swap transaction for the user's Solana wallet to sign. No local signer, no broadcast.",inputSchema:{type:"object",required:["userPublicKey"],properties:{userPublicKey:{type:"string"},quoteResponse:{type:"object"},inputMint:{type:"string"},outputMint:{type:"string"},amount:{type:"string"},slippageBps:{type:"number"}}}},{name:"btc_health",description:"Bitcoin L1 Esplora health + tip height (mempool.space by default). No Core RPC, no keys. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"btc_fees",description:"Recommended Bitcoin fee rates (sats/vB). Read-only.",inputSchema:{type:"object",properties:{}}},{name:"btc_balance",description:"Bitcoin address balance in sats via Esplora. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string",description:"bc1\u2026/1\u2026/3\u2026 address"}}}},{name:"btc_utxos",description:"UTXOs for a Bitcoin address via Esplora. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"btc_tx",description:"Lookup a Bitcoin transaction by txid via Esplora. Read-only.",inputSchema:{type:"object",required:["txid"],properties:{txid:{type:"string"}}}},{name:"btc_meta_health",description:"Ordinals/runes indexer health. Reports whether BTC_META_API_URL / vendor API keys are configured. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"btc_rune_balance",description:"Rune balances for a Bitcoin address (requires configured indexer + optional API key). Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"btc_inscriptions",description:"Inscriptions controlled by an address. REQUIRES a keyed indexer (ordinals.com has no address index). Returns unknownNotEmpty:true when unconfigured \u2014 that means UNKNOWN, never 'wallet holds none'. Protect these UTXOs from fee spends.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},limit:{type:"number"}}}},{name:"btc_inscription_info",description:"Inscription metadata by inscription id (content type/length, height, sat, fee). KEYLESS via ordinals.com recursive. Read-only.",inputSchema:{type:"object",required:["inscriptionId"],properties:{inscriptionId:{type:"string",description:"<64-hex-txid>i<index>"}}}},{name:"btc_inscription_children",description:"Child inscriptions of a parent (collections). KEYLESS via ordinals.com recursive. Read-only.",inputSchema:{type:"object",required:["inscriptionId"],properties:{inscriptionId:{type:"string",description:"<64-hex-txid>i<index>"},page:{type:"number"}}}},{name:"btc_ord_block_info",description:"Ord node block info / indexer tip. KEYLESS. Use to confirm the ordinals indexer is at the same tip as Esplora before trusting metaprotocol reads.",inputSchema:{type:"object",properties:{height:{type:"number",description:"omit for current tip"}}}},{name:"satflow_health",description:"Satflow marketplace health (primary BTC ordinals/runes market after Magic Eden BTC sunset). Needs SATFLOW_API_KEY. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"satflow_floors",description:"Satflow collection floor prices. type=ordinals|runes. Read-only.",inputSchema:{type:"object",properties:{type:{type:"string",description:"ordinals or runes"},ids:{type:"string",description:"optional comma-separated collection ids"}}}},{name:"satflow_wallet",description:"Satflow wallet contents (ordinals/runes) for an address. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},type:{type:"string"},limit:{type:"number"}}}},{name:"satflow_item",description:"Satflow item detail for an inscription id (listing + bids + meta). Read-only.",inputSchema:{type:"object",required:["inscriptionId"],properties:{inscriptionId:{type:"string"}}}},{name:"satflow_floor_listings",description:"Satflow floor listings for collection id(s). Read-only.",inputSchema:{type:"object",required:["collectionIds"],properties:{collectionIds:{type:"string"},limit:{type:"number"}}}},{name:"scanner_coverage",description:"Which chains the on-chain scanner supports and which capabilities each one has (blockNumber, nativeBalance, tokenBalance, resolveToken, resolvePools, scanBlocks, scoreRisk, quote, sellSimulation, prepareUnsignedTx). Read-only.",inputSchema:{type:"object",properties:{}}},{name:"scan_token",description:"Resolve a token on an EVM chain: metadata, its pools, and a risk score. Works on chains no indexer covers because it reads the chain directly. Read-only.",inputSchema:{type:"object",properties:{chainId:{type:"number",description:"EVM chain id, e.g. 4663 for Robinhood Chain"},token:{type:"string",description:"token contract address"}},required:["chainId","token"]}},{name:"wallet_balances",description:"Native balance for an address on an EVM chain, plus one token balance when a token address is supplied. Read-only; never signs.",inputSchema:{type:"object",properties:{chainId:{type:"number"},address:{type:"string",description:"wallet address to inspect"},token:{type:"string",description:"optional token contract for a token balance"}},required:["chainId","address"]}},{name:"address_book_remember",description:"Remember a wallet address with a label. Call this whenever someone states their address or an agent/counterparty wallet is discovered, so it survives the conversation. Stores labels only \u2014 never private keys, seeds, or passphrases.",inputSchema:{type:"object",required:["address","label"],properties:{address:{type:"string",description:"0x address"},label:{type:"string",description:"short name, e.g. research-agent"},who:{type:"string",description:"person or entity the wallet belongs to"},role:{type:"string",description:"agent | owner | person | counterparty | venue"},chainIds:{type:"array",items:{type:"number"}},notes:{type:"string"}}}},{name:"address_book_list",description:"List remembered wallets (owner, agent, people, counterparties). Read-only. Check this before sending or bridging to a person.",inputSchema:{type:"object",properties:{q:{type:"string",description:"search across label, who, address, notes"},role:{type:"string"},who:{type:"string"}}}},{name:"address_book_lookup",description:"Look up one 0x address in the durable address book. Read-only.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"}}}},{name:"address_book_forget",description:"Remove a remembered address, optionally only one label for it.",inputSchema:{type:"object",required:["address"],properties:{address:{type:"string"},label:{type:"string"}}}},{name:"rfq_quote",description:"Create a cross-chain RFQ intent and fan it out to reviewed solver or venue sources. Returns firm quote objects with intentHash, firmQuoteHash, expiry, min receive, and unsigned executable artifacts. Never signs or broadcasts.",inputSchema:{type:"object",required:["fromChainId","toChainId","sellToken","buyToken","sellAmount","receiver","deadlineMs"],properties:{fromChainId:{type:"number"},toChainId:{type:"number"},sellToken:{type:"string"},buyToken:{type:"string"},sellAmount:{type:"string"},receiver:{type:"string"},deadlineMs:{type:"number"},minBuyAmount:{type:"string"},allowedSources:{type:"array",items:{type:"string"}},allowedRouters:{type:"array",items:{type:"string"}},slippageBps:{type:"number"},decimalsIn:{type:"number"},decimalsOut:{type:"number"}}}},{name:"best_swap_route",description:"Compare swap routes across every available aggregator and rank by NET output (after gas and fees), not headline quote. Returns the winner plus all runners-up so the ranking can be checked rather than trusted.",inputSchema:{type:"object",properties:{chainId:{type:"number",description:"EVM chain id, e.g. 8453 for Base"},tokenIn:{type:"string",description:"sell token address"},tokenOut:{type:"string",description:"buy token address"},amountIn:{type:"string",description:"raw units of tokenIn (wei-scale)"},taker:{type:"string",description:"address used for quoting only; nothing is signed"},decimalsIn:{type:"number"},decimalsOut:{type:"number"}},required:["chainId","tokenIn","tokenOut","amountIn"]}},{name:"best_bridge_route",description:"Compare cross-chain bridge routes and rank by NET output. Also reports each route's expected duration, which is NOT folded into the score -- a route that saves $2 but takes 30 minutes is a trade-off for the caller to make.",inputSchema:{type:"object",properties:{fromChainId:{type:"number"},toChainId:{type:"number"},tokenIn:{type:"string",description:"token on the origin chain"},tokenOut:{type:"string",description:"token on the destination chain"},amountIn:{type:"string",description:"raw units of tokenIn"},taker:{type:"string",description:"address used for quoting only"},decimalsOut:{type:"number"}},required:["fromChainId","toChainId","tokenIn","tokenOut","amountIn"]}},{name:"prepare_best_route",description:"Compare routes, then build the SIGNABLE artifact for the winner. Returns an unsigned transaction (LI.FI/ParaSwap/0x) or EIP-712 typed data for an off-chain order (CoW) -- the artifactKind field says which, and they require different wallet actions. Re-quotes before preparing and reports drift against the comparison. Never signs or broadcasts.",inputSchema:{type:"object",properties:{chainId:{type:"number"},tokenIn:{type:"string"},tokenOut:{type:"string"},amountIn:{type:"string",description:"raw units of tokenIn"},taker:{type:"string",description:"the REAL wallet that will sign. Placeholder/burn addresses are rejected: quoting is anonymous, preparing is not."},decimalsIn:{type:"number"},decimalsOut:{type:"number"},source:{type:"string",description:"force a specific source instead of the winner (flagged in the result)"},driftToleranceBps:{type:"number",description:"default 100"}},required:["chainId","tokenIn","tokenOut","amountIn","taker"]}},{name:"prepare_best_bridge_route",description:"Compare cross-chain bridge routes, then build the signable transaction sequence for the winner. Returns a LIST of unsigned transactions -- some routes need an approval and a deposit signed in order, and signing only the first leaves funds approved but not bridged. Reports the destination chain and expected credit time. Bridging is not atomic. Never signs or broadcasts.",inputSchema:{type:"object",properties:{fromChainId:{type:"number"},toChainId:{type:"number"},tokenIn:{type:"string",description:"token on the origin chain"},tokenOut:{type:"string",description:"token on the destination chain"},amountIn:{type:"string",description:"raw units of tokenIn"},taker:{type:"string",description:"the REAL wallet that will sign; placeholders rejected"},source:{type:"string",description:"force a source instead of the winner"},driftToleranceBps:{type:"number",description:"default 100"}},required:["fromChainId","toChainId","tokenIn","tokenOut","amountIn","taker"]}},{name:"equity_venues",description:"Inventory of on-chain equities venues (HIP-3 builder DEXes, Arcus perps/spot on Robinhood 4663, RH Uniswap prepare tier, Solana xStocks, TON ston.fi) with tiers and a liveness snapshot. Offline fixtures by default. Read-only / prepare-only.",inputSchema:{type:"object",properties:{}}},{name:"equity_quote",description:"Cross-chain best-execution comparison for a tokenized equity ticker (NVDA, SPY, TSLA, ...). Ranks HIP-3, Arcus, RH Uniswap, Solana xStocks, and TON. Returns winner + runners-up + bestPreparable (only rh_uniswap is preparable in v1). rankedOn is usually gross because fees/gas are unmeasured - say so. Never signs.",inputSchema:{type:"object",required:["ticker"],properties:{ticker:{type:"string",description:"equity ticker, e.g. NVDA, SPY, TSLA"},sizeUsd:{type:"string",description:"optional notional USD size for impact model"},horizonHours:{type:"number",description:"optional holding horizon; enables funding-adjusted spot-vs-perp ranking"}}}},{name:"equity_prepare",description:"Prepare an UNSIGNED Robinhood-chain Uniswap artifact for a tokenized equity. Only the prepare-tier venue (rh_uniswap / chain 4663). Requires the real wallet as recipient. requiresWalletSignature=true, backendSigner=false. Never signs or broadcasts.",inputSchema:{type:"object",required:["ticker","recipient"],properties:{ticker:{type:"string"},recipient:{type:"string",description:"the REAL 0x wallet that will sign; placeholders rejected"},sizeUsd:{type:"string",description:"optional notional USD size"}}}},{name:"twap_simulate",description:"Simulate a TWAP (time-weighted average price) DCA order. Splits a large order into equal-sized chunks over a configurable window, quotes every chunk at current prices, and returns the schedule + estimated average price. Read-only. Never signs or broadcasts. Use before committing to a TWAP.",inputSchema:{type:"object",required:["chainId","tokenIn","tokenOut","amount","taker"],properties:{chainId:{type:"number"},tokenIn:{type:"string"},tokenOut:{type:"string"},amount:{type:"string",description:"raw base units of tokenIn"},taker:{type:"string",description:"the REAL wallet that will sign"},splits:{type:"number",description:"number of chunks (default 10, max 100)"},windowHours:{type:"number",description:"total window in hours (default 6)"},slippageBps:{type:"number",description:"slippage cap in bps (default 100)"}}}},{name:"bridge_aggregator_scan",description:"Scan ALL cross-chain bridge routes: deBridge DLN + LI.FI/Relay + ChangeNOW. Ranks every route by net output, checks for existing token approvals that should be revoked before bridging, and returns the winner + runners-up. Read-only. Never signs or broadcasts. ChangeNOW requires ticker symbols.",inputSchema:{type:"object",required:["fromChainId","toChainId","tokenIn","tokenOut","amount","taker"],properties:{fromChainId:{type:"number"},toChainId:{type:"number"},tokenIn:{type:"string"},tokenOut:{type:"string"},amount:{type:"string",description:"raw base units of tokenIn"},taker:{type:"string"},fromSymbol:{type:"string",description:"ticker for ChangeNOW (e.g. ETH, USDC)"},toSymbol:{type:"string",description:"ticker for ChangeNOW"},fromDecimals:{type:"number",description:"default 18"},toDecimals:{type:"number",description:"default 18"}}}},{name:"perps_markets",description:"Scan perps markets across dYdX (standalone chain), Drift (Solana), and Vertex (Arbitrum). Returns ticker, oracle price, funding rate, open interest, and 24h volume. Read-only. Never signs.",inputSchema:{type:"object",properties:{venue:{type:"string",description:"dydx, drift, or vertex (default: all)"}}}},{name:"dex_quote",description:"Quote a swap across PancakeSwap (BSC+), SushiSwap (30+ chains), or Raydium (Solana via Jupiter). Specify the DEX and chain. Read-only.",inputSchema:{type:"object",required:["dex","chainId","tokenIn","tokenOut","amountIn"],properties:{dex:{type:"string",description:"pancakeswap, sushiswap, or raydium"},chainId:{type:"number"},tokenIn:{type:"string"},tokenOut:{type:"string"},amountIn:{type:"string",description:"raw base units"}}}},{name:"options_markets",description:"Scan on-chain options markets (calls/puts). Currently Aevo. Returns instruments, mark prices, funding, open interest. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"lending_markets",description:"Scan lending protocol markets across Compound ($2B+ TVL). Returns supply/borrow APYs, total supply, collateral factors. Read-only.",inputSchema:{type:"object",properties:{}}},{name:"yield_vaults",description:"Scan yield aggregator vaults across Yearn + Convex. Returns vault APYs, TVLs, boosted status. Read-only.",inputSchema:{type:"object",properties:{}}}],Ka=String(Ve.env.ORACLE_DEFAULT_ADDRESS||Ve.env.MAD_OPERATOR_ADDRESS||"").trim(),km={llama_protocols:()=>({provider:"defillama",op:"protocols",args:{}}),llama_prices:e=>({provider:"defillama",op:"prices",args:{coins:e.coins}}),dex_search:e=>({provider:"dexscreener",op:"search",args:{q:e.q}}),dex_token:e=>({provider:"dexscreener",op:"token",args:{address:e.address}}),lifi_quote:e=>({provider:"lifi",op:"quote",args:{fromChain:e.fromChain,toChain:e.toChain,fromToken:e.fromToken,toToken:e.toToken,fromAmount:e.fromAmount,fromAddress:e.fromAddress||Ka||void 0}}),portfolio_balance:e=>({provider:"portfolio",op:"balances",args:{addresses:e.addresses,evmChainIds:e.evmChainIds,includeTokens:e.includeTokens,includeCollectibles:e.includeCollectibles,includePrices:e.includePrices}}),portfolio_snapshot:e=>({provider:"portfolio",op:"snapshot",args:e}),portfolio_history:e=>({provider:"portfolio",op:"history",args:e}),portfolio_value_graph:e=>({provider:"portfolio",op:"valueGraph",args:e}),nft_inventory:e=>({provider:"nft-portfolio",op:"inventory",args:e}),nft_gallery:e=>({provider:"nft-portfolio",op:"gallery",args:e}),nft_pnl:e=>({provider:"nft-portfolio",op:"pnl",args:e}),nft_prepare_list:e=>({provider:"nft-portfolio",op:"prepareList",args:e}),rpc_balance:e=>{let t=e.address||Ka;if(!t)throw new Error("address required (set ORACLE_DEFAULT_ADDRESS to supply a default)");return{provider:"evm-rpc",op:"getBalance",args:{chainId:e.chainId,address:t}}},rpc_block:e=>({provider:"evm-rpc",op:"blockNumber",args:{chainId:e.chainId}}),solana_balance:e=>({provider:"solana-rpc",op:"getBalance",args:{address:e.address,commitment:e.commitment}}),solana_token_accounts:e=>({provider:"solana-rpc",op:"tokenAccounts",args:{owner:e.owner,mint:e.mint,commitment:e.commitment}}),solana_simulate:e=>({provider:"solana-rpc",op:"simulate",args:{transaction:e.transaction,sigVerify:e.sigVerify,replaceRecentBlockhash:e.replaceRecentBlockhash}}),jupiter_venues:e=>({provider:"jupiter",op:"venues",args:{verify:e.verify,rpc:e.rpc}}),jupiter_quote:e=>({provider:"jupiter",op:"quote",args:{inputMint:e.inputMint,outputMint:e.outputMint,amount:e.amount,slippageBps:e.slippageBps}}),jupiter_prepare:e=>({provider:"jupiter",op:"prepare",args:{userPublicKey:e.userPublicKey,quoteResponse:e.quoteResponse,inputMint:e.inputMint,outputMint:e.outputMint,amount:e.amount,slippageBps:e.slippageBps}}),btc_health:()=>({provider:"bitcoin-esplora",op:"health",args:{}}),btc_fees:()=>({provider:"bitcoin-esplora",op:"fees",args:{}}),btc_balance:e=>({provider:"bitcoin-esplora",op:"address",args:{address:e.address}}),btc_utxos:e=>({provider:"bitcoin-esplora",op:"utxos",args:{address:e.address}}),btc_tx:e=>({provider:"bitcoin-esplora",op:"tx",args:{txid:e.txid}}),btc_meta_health:()=>({provider:"bitcoin-meta",op:"health",args:{}}),btc_rune_balance:e=>({provider:"bitcoin-meta",op:"runeBalances",args:{address:e.address}}),btc_inscriptions:e=>({provider:"bitcoin-meta",op:"inscriptions",args:{address:e.address,limit:e.limit}}),btc_inscription_info:e=>({provider:"bitcoin-meta",op:"inscriptionInfo",args:{inscriptionId:e.inscriptionId}}),btc_inscription_children:e=>({provider:"bitcoin-meta",op:"inscriptionChildren",args:{inscriptionId:e.inscriptionId,page:e.page}}),btc_ord_block_info:e=>({provider:"bitcoin-meta",op:"ordBlockInfo",args:{height:e.height}}),satflow_health:()=>({provider:"satflow",op:"health",args:{}}),satflow_floors:e=>({provider:"satflow",op:"collectionFloors",args:{type:e.type,ids:e.ids}}),satflow_wallet:e=>({provider:"satflow",op:"walletContents",args:{address:e.address,type:e.type,limit:e.limit}}),satflow_item:e=>({provider:"satflow",op:"item",args:{inscriptionId:e.inscriptionId||e.id}}),satflow_floor_listings:e=>({provider:"satflow",op:"floorListings",args:{collectionIds:e.collectionIds||e.ids,limit:e.limit}})};function He(e){Ve.stdout.write(`${JSON.stringify(e)}
7
+ `)}function Wa(e,t,r){He({jsonrpc:"2.0",id:e,error:{code:t,message:r}})}async function Cn(e,{method:t="GET",body:r}={}){let n=await fetch(e,{method:t,headers:{"content-type":"application/json"},body:r?JSON.stringify(r):void 0}),o=await n.json().catch(()=>({}));if(!n.ok)throw new Error(o.error||`HTTP ${n.status}`);return o}async function Qa(e,t,r={}){return Cn(`${In}/data/call`,{method:"POST",body:{provider:e,op:t,args:r}})}async function Im(e,t={}){if(e==="rfq_quote"){let{normalizeRfqIntent:n}=await Promise.resolve().then(()=>(xr(),Xn)),{requestRfqQuotes:o}=await Promise.resolve().then(()=>(os(),ns)),s=n({...t,sources:t.sources??t.allowedSources});return o(s,{decimalsIn:t.decimalsIn,decimalsOut:t.decimalsOut})}if(e==="best_swap_route"||e==="best_bridge_route"){let{bestSwapRoute:n,bestBridgeRoute:o}=await Promise.resolve().then(()=>(Pe(),Ts));return e==="best_swap_route"?n(t):o(t)}if(e==="prepare_best_route"){let{prepareBestRoute:n}=await Promise.resolve().then(()=>(Bs(),Ns));return n(t)}if(e==="prepare_best_bridge_route"){let{prepareBestBridgeRoute:n}=await Promise.resolve().then(()=>(qs(),$s));return n(t)}if(e==="twap_simulate"){let{simulateTwap:n}=await Promise.resolve().then(()=>(Ls(),Us));return n(t)}if(e==="bridge_aggregator_scan"){let{scanBridgeRoutes:n}=await Promise.resolve().then(()=>(Bi(),Ni));return n(t)}if(e==="perps_markets"){let n=String(t.venue||"all").toLowerCase(),o={};if(n==="all"||n==="dydx"){let{dydxMarkets:s}=await Promise.resolve().then(()=>(qi(),$i));o.dydx=await s()}if(n==="all"||n==="drift"){let{driftMarkets:s}=await Promise.resolve().then(()=>(Ui(),Pi));o.drift=await s()}if(n==="all"||n==="vertex"){let{vertexMarkets:s}=await Promise.resolve().then(()=>(Fi(),Li));o.vertex=await s()}return o}if(e==="dex_quote"){let n=String(t.dex||"").toLowerCase();if(n==="pancakeswap"){let{pancakeQuote:o}=await Promise.resolve().then(()=>(ji(),Mi));return o(t)}if(n==="sushiswap"){let{sushiQuote:o}=await Promise.resolve().then(()=>(zi(),Vi));return o(t)}if(n==="raydium"){let{raydiumQuote:o}=await Promise.resolve().then(()=>(Qi(),Ki));return o(t)}return{error:`unknown dex: ${n} \u2014 use pancakeswap, sushiswap, or raydium`}}if(e==="options_markets"){let{aevoMarkets:n}=await Promise.resolve().then(()=>(Gi(),Wi));return{aevo:await n()}}if(e==="lending_markets"){let{compoundMarkets:n}=await Promise.resolve().then(()=>(Yi(),Xi));return{compound:await n()}}if(e==="yield_vaults"){let[{yearnVaults:n},{convexPools:o}]=await Promise.all([Promise.resolve().then(()=>(Zi(),Ji)),Promise.resolve().then(()=>(ta(),ea))]);return{yearn:await n(),convex:await o()}}if(e==="equity_venues"){let{equityVenues:n,toJsonSafe:o}=await Promise.resolve().then(()=>(dr(),lr));return o(n())}if(e==="equity_quote"){let{bestEquityRoute:n,toJsonSafe:o}=await Promise.resolve().then(()=>(dr(),lr));return o(n({ticker:t.ticker,sizeUsd:t.sizeUsd,horizonHours:t.horizonHours}))}if(e==="equity_prepare"){let{prepareEquityRoute:n,toJsonSafe:o}=await Promise.resolve().then(()=>(dr(),lr));return o(n({ticker:t.ticker,recipient:t.recipient||t.taker,sizeUsd:t.sizeUsd}))}if(e==="scanner_coverage"){let n=await Promise.resolve().then(()=>(mr(),pr));return n.registerBuiltinScanners?.(),n.scannerCoverage()}if(e==="scan_token"){let n=await Promise.resolve().then(()=>(mr(),pr));n.registerBuiltinScanners?.();let o=n.getScanner(Number(t.chainId));if(!o)throw new Error(`no scanner registered for chainId ${t.chainId}`);let s=await o.resolveToken(t.token),a=o.supports?.("resolvePools")?await o.resolvePools(t.token).catch(()=>null):null,i=o.supports?.("scoreRisk")?await o.scoreRisk({token:t.token}).catch(()=>null):null;return{chainId:Number(t.chainId),token:s,pools:a,risk:i}}if(e==="wallet_balances"){let n=await Promise.resolve().then(()=>(mr(),pr));n.registerBuiltinScanners?.();let o=n.getScanner(Number(t.chainId));if(!o)throw new Error(`no scanner registered for chainId ${t.chainId}`);let s=await o.nativeBalance(t.address),a=t.token?await o.tokenBalance(t.address,t.token).catch(()=>null):null;return{chainId:Number(t.chainId),address:t.address,native:s,token:a}}if(e==="address_book_remember")return Dn({address:t.address,label:t.label,who:t.who,role:t.role,chainIds:t.chainIds,notes:t.notes,source:"oracle-data-mcp"});if(e==="address_book_list")return $n({q:t.q,role:t.role,who:t.who});if(e==="address_book_lookup")return qn(t.address);if(e==="address_book_forget")return Pn(t.address,t.label||null);if(e==="data_catalog")return Cn(`${In}/data/catalog`);if(e==="data_health")return Cn(`${In}/data/health`);if(e==="data_call"){if(!t.provider||!t.op)throw new Error("provider and op are required");return Qa(t.provider,t.op,t.args||{})}let r=km[e];if(r){let{provider:n,op:o,args:s}=r(t);return Qa(n,o,s)}throw new Error(`Unknown tool: ${e}`)}async function Cm(e){let{id:t,method:r,params:n}=e;if(r==="initialize"){He({jsonrpc:"2.0",id:t,result:{protocolVersion:n?.protocolVersion||"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"oracle-data-mcp",version:"0.1.0"}}});return}if(r!=="notifications/initialized"){if(r==="tools/list"){He({jsonrpc:"2.0",id:t,result:{tools:Em}});return}if(r==="tools/call"){try{let o=await Im(n?.name,n?.arguments||{});if(o?.dataBase64&&/^image\/(?:svg\+xml|png|jpeg|webp)$/.test(String(o.mimeType||""))){let{dataBase64:s,...a}=o;He({jsonrpc:"2.0",id:t,result:{content:[{type:"image",data:s,mimeType:o.mimeType},{type:"text",text:JSON.stringify(a,null,2)}]}})}else He({jsonrpc:"2.0",id:t,result:{content:[{type:"text",text:JSON.stringify(o,null,2)}]}})}catch(o){He({jsonrpc:"2.0",id:t,result:{isError:!0,content:[{type:"text",text:o.message}]}})}return}t!==void 0&&Wa(t,-32601,`Method not found: ${r}`)}}var pt="";function _m(){Ve.stdin.setEncoding("utf8"),Ve.stdin.on("data",e=>{pt+=e;let t;for(;(t=pt.indexOf(`
8
+ `))>=0;){let r=pt.slice(0,t).trim();if(pt=pt.slice(t+1),!!r)try{Cm(JSON.parse(r))}catch(n){Wa(null,-32700,n.message)}}})}function Om(){let e=Ve.argv[1];if(!e)return!1;try{return za.realpathSync(e)===za.realpathSync(Am(import.meta.url))}catch{return!1}}Om()&&_m();export{Im as callTool,Cm as handle,Em as tools};