@oracle-agent/oracle 0.35.49 → 0.35.51

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 (86) hide show
  1. package/README.md +3 -2
  2. package/artifacts/specialist-packs/oracle-full-crypto.json +11 -0
  3. package/dist/agent-sessions.mjs +19 -19
  4. package/dist/artifacts/token-dashboard.mjs +1 -1
  5. package/dist/assets/profiles/near-agent/SOUL.md +46 -0
  6. package/dist/assets/profiles/near-agent/profile.json +30 -0
  7. package/dist/assets/profiles/oracle/SOUL.md +1 -0
  8. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  9. package/dist/assets/skills/oracle-near/SKILL.md +66 -0
  10. package/dist/automation-plan.mjs +1 -1
  11. package/dist/bin/desk-server.mjs +33 -33
  12. package/dist/bin/oracle-data-mcp.mjs +16 -16
  13. package/dist/bin/oracle-gateway.mjs +3 -3
  14. package/dist/bin/oracle-launch-radar-shadow.mjs +3 -3
  15. package/dist/bin/oracle-mev-arb-shadow.mjs +4 -4
  16. package/dist/bin/oracle-mev-shadow.mjs +4 -4
  17. package/dist/bin/oracle-public-server.mjs +5 -5
  18. package/dist/bin/oracle-route.mjs +27 -27
  19. package/dist/bin/oracle-scan.mjs +3 -3
  20. package/dist/bin/oracle-telegram-mcp.mjs +1 -1
  21. package/dist/chains.mjs +1 -1
  22. package/dist/cli/commands/account.mjs +22 -22
  23. package/dist/cli/commands/agent-session.mjs +23 -23
  24. package/dist/cli/commands/auth.mjs +16 -15
  25. package/dist/cli/commands/chain.mjs +5 -5
  26. package/dist/cli/commands/chat.mjs +310 -228
  27. package/dist/cli/commands/data.mjs +37 -37
  28. package/dist/cli/commands/doctor.mjs +5 -5
  29. package/dist/cli/commands/eval.mjs +249 -167
  30. package/dist/cli/commands/farm.mjs +1 -1
  31. package/dist/cli/commands/follow.mjs +4 -4
  32. package/dist/cli/commands/harness.mjs +5 -5
  33. package/dist/cli/commands/mint.mjs +11 -11
  34. package/dist/cli/commands/model.mjs +313 -231
  35. package/dist/cli/commands/project.mjs +8 -7
  36. package/dist/cli/commands/quickstart.mjs +2 -2
  37. package/dist/cli/commands/receipt.mjs +2 -2
  38. package/dist/cli/commands/resolve.mjs +4 -4
  39. package/dist/cli/commands/session-vault.mjs +4 -4
  40. package/dist/cli/commands/setup.mjs +53 -52
  41. package/dist/cli/commands/snipe.mjs +13 -13
  42. package/dist/cli/commands/strategy.mjs +5 -5
  43. package/dist/cli/commands/swap.mjs +11 -11
  44. package/dist/cli/commands/telegram.mjs +7 -7
  45. package/dist/cli/commands/venues.mjs +1 -1
  46. package/dist/cli/project-access.mjs +4 -3
  47. package/dist/data/desk-data.mjs +31 -31
  48. package/dist/data/holder-table.mjs +2 -2
  49. package/dist/data/market-tape.mjs +1 -1
  50. package/dist/data/names.mjs +3 -3
  51. package/dist/data/providers/farming.mjs +2 -2
  52. package/dist/data/providers/lp-destination-discovery.mjs +4 -4
  53. package/dist/index.mjs +49 -49
  54. package/dist/launch-radar/index.mjs +5 -5
  55. package/dist/lp/index.mjs +4 -4
  56. package/dist/nft/universal-mint-router.mjs +4 -4
  57. package/dist/notifications/index.mjs +1 -1
  58. package/dist/router/index.mjs +3 -3
  59. package/dist/router/prepare-bridge.mjs +2 -2
  60. package/dist/router/prepare-route.mjs +3 -3
  61. package/dist/scanner/index.mjs +3 -3
  62. package/dist/strategy/index.mjs +4 -4
  63. package/dist/task.mjs +1 -1
  64. package/dist/teams/index.mjs +6 -6
  65. package/dist/telegram/chart-card.mjs +5 -5
  66. package/dist/telegram/market-commands.mjs +1 -1
  67. package/dist/tui/standalone-client.mjs +179 -97
  68. package/package.json +2 -2
  69. package/public/oracle-splash/assets/desktop-app.jpg +0 -0
  70. package/public/oracle-splash/docs/browser-and-web/index.html +2 -2
  71. package/public/oracle-splash/docs/connectors/index.html +2 -2
  72. package/public/oracle-splash/docs/getting-started/index.html +2 -2
  73. package/public/oracle-splash/docs/index.html +3 -3
  74. package/public/oracle-splash/docs/reference/index.html +2 -2
  75. package/public/oracle-splash/docs/security/index.html +2 -2
  76. package/public/oracle-splash/docs/using-oracle/index.html +2 -2
  77. package/public/oracle-splash/download/index.html +219 -5
  78. package/public/oracle-splash/downloads/index.html +1 -1
  79. package/public/oracle-splash/eval/index.html +19 -19
  80. package/public/oracle-splash/eval/releases/oracle-0.35.49.json +852 -0
  81. package/public/oracle-splash/index.html +262 -37
  82. package/public/oracle-splash/pricing/index.html +215 -1
  83. package/public/oracle-splash/security/index.html +215 -1
  84. package/public/oracle-splash/what-it-does/index.html +215 -1
  85. package/public/oracle-splash/where-it-works/index.html +215 -1
  86. package/server.json +2 -2
@@ -1,8 +1,8 @@
1
- import{createHash as Sr}from"node:crypto";import{types as G}from"node:util";import{AsyncLocalStorage as fr}from"node:async_hooks";var pr=new fr,hr=["http","retry","shared"],mr=512;function Se(e){let t=pr.getStore();if(!t||t.closed||!hr.includes(e))return null;if(t.spans.length>=mr)return t.droppedSpans++,null;let r={stage:e,startMs:t.now()-t.start,durationMs:null,outcome:"pending",status:null};return t.spans.push(r),(n,o=null)=>{t.closed||r.durationMs!==null||(r.durationMs=Math.max(0,t.now()-t.start-r.startMs),r.outcome=n==="succeeded"?"succeeded":"failed",r.status=Number.isInteger(o)&&o>=100&&o<=599?o:null)}}import X from"node:net";import br from"node:dns";var yr=new Set(["localhost","metadata.google.internal","metadata.goog"]);function Ee(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=c=>{if(!c)return[];let h=c.split(":"),d=h.at(-1);if(d?.includes(".")){let f=d.split(".").map(Number);if(f.length!==4||f.some(p=>!Number.isInteger(p)||p<0||p>255))return null;h.splice(h.length-1,1,(f[0]<<8|f[1]).toString(16),(f[2]<<8|f[3]).toString(16))}return h.some(f=>!/^[0-9a-f]{1,4}$/.test(f))?null:h.map(f=>Number.parseInt(f,16))},[n,o]=t.split("::"),s=r(n),i=r(o);if(!s||!i)return null;let l=t.includes("::"),a=8-s.length-i.length;if(!l&&a!==0||l&&a<1)return null;let u=[...s,...Array(Math.max(0,a)).fill(0),...i];return u.length!==8?null:Uint8Array.from(u.flatMap(c=>[c>>8,c&255]))}function Fe(e,t,r){let n=Math.floor(r/8),o=r%8;for(let i=0;i<n;i+=1)if(e[i]!==t[i])return!1;if(!o)return!0;let s=255<<8-o;return(e[n]&s)===(t[n]&s)}function Pe(e){if(X.isIPv4(e)){let t=e.split(".").map(Number);return!(t[0]===0||t[0]===10||t[0]===127||t[0]>=224||t[0]===100&&t[1]>=64&&t[1]<=127||t[0]===169&&t[1]===254||t[0]===172&&t[1]>=16&&t[1]<=31||t[0]===192&&(t[1]===0||t[1]===2||t[1]===168)||t[0]===192&&t[1]===88&&t[2]===99||t[0]===198&&(t[1]===18||t[1]===19||t[1]===51)||t[0]===203&&t[1]===0&&t[2]===113)}if(X.isIPv6(e)){let t=Ee(e);if(!t)return!1;let r=Ee("::ffff:0:0");return Fe(t,r,96)?Pe([...t.slice(12)].join(".")):Fe(t,Ee("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,s])=>Fe(t,Ee(o),s)):!1}return!1}function gr(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let r=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(yr.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=X.isIP(r);return n!==0&&!Pe(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function Be(e,{lookupFn:t=br.promises.lookup}={}){let r=gr(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:X.isIPv6(r.host)?6:4}]};let n;if(process.env.ORACLE_HOSTED_EGRESS_PROXY)return{ok:!0,url:r.url,addresses:[]};try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(o=>!Pe(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}function wr(e=process.env){let t=e.ORACLE_HOSTED_EGRESS_PROXY||"";if(!t)return null;let r;try{r=new URL(t)}catch{throw new Error("egress-guard: ORACLE_HOSTED_EGRESS_PROXY is not a URL")}if(r.protocol!=="http:"||!["127.0.0.1","::1","localhost","[::1]"].includes(r.hostname)||!r.port||r.username||r.password)throw new Error("egress-guard: egress proxy must be an exact loopback http origin");let n=e.ORACLE_HOSTED_EGRESS_TOKEN||"";if(!/^[A-Za-z0-9_-]{43}$/.test(n))throw new Error("egress-guard: egress proxy token is missing");return{uri:r.origin,token:n}}async function De({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n,o;try{o=await t(),r=o.Agent,n=o.fetch}catch(f){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${f?.message||f}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let s=f=>String(f).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,l=f=>(Array.isArray(f)?f:[f]).map(p=>typeof p=="string"?{address:p}:p).filter(p=>p&&p.address).map(p=>({address:p.address,family:p.family||(X.isIPv6(p.address)?6:4)})),a=(f,p,m)=>{i.set(s(f),l(typeof p=="string"?[{address:p,family:m}]:p))},u=f=>{let p=s(f);if(X.isIP(p))return[{address:p,family:X.isIPv6(p)?6:4}];let m=i.get(p);if(!m||!m.length)throw new Error(`refused: unpinned host ${f} during pinned fetch`);return m},c=wr(),h=c&&typeof o.ProxyAgent=="function"?new o.ProxyAgent({uri:c.uri,token:`Bearer ${c.token}`,connectTimeout:1e4}):new r({connect:{lookup(f,p,m){let x;try{x=u(f)}catch(b){return m(b)}return p?.all?m(null,x):m(null,x[0].address,x[0].family)}}}),d=xr((f,p={})=>n(f,{...p,dispatcher:h}),a);return{dispatcher:h,fetch:d,pin:a,resolve:u,async close(){try{await h.destroy()}catch{}}}}var je=Symbol.for("oracle.egressGuard.pinCapableFetch");function xr(e,t){if(typeof e!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof t!="function")throw new Error("markPinCapableFetch: pin must be a function");return e[je]=Object.freeze({pin:t}),e}function qe(e){return typeof e=="function"&&typeof e[je]?.pin=="function"}function mt(e,t,r){if(!qe(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[je].pin(t,r)}var Er=new Set([408,425,429,500,502,503,504]),bt=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Ar=2,yt=4e3,vr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Nr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Tr=AbortSignal.prototype.throwIfAborted,Cr=EventTarget.prototype.addEventListener,gt=EventTarget.prototype.removeEventListener,wt=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,de=e=>e?vr.call(e):!1,kr=e=>e?Nr.call(e):void 0,Ir=new Set([301,302,303,307,308]),ve=3,is=64*1024,W=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});function _(e){return Y(`HTTP JSON body refused: ${e}`)}function Or(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof G[t]=="function"&&G[t](e))}function _r(e){let t=[],r=0,n=0,o=0,s=0,i=new WeakSet,l=c=>{if(r+=Buffer.byteLength(c,"utf8"),r>W.bytes)throw _("serialized byte limit exceeded");t.push(c)},a=c=>{if(Buffer.byteLength(c,"utf8")>W.bytes)throw _("serialized byte limit exceeded");return JSON.stringify(c)},u=(c,h)=>{if(n+=1,n>W.nodes)throw _("node limit exceeded");if(h>W.depth)throw _("depth limit exceeded");if(c===null){l("null");return}if(typeof c=="string"){l(a(c));return}if(typeof c=="boolean"){l(c?"true":"false");return}if(typeof c=="number"){if(!Number.isFinite(c))throw _("non-finite number");l(Object.is(c,-0)?"0":String(c));return}if(typeof c!="object")throw _("unsupported non-JSON value");if(G.isProxy(c))throw _("proxy value");if(Or(c))throw _("unsupported exotic object");if(i.has(c))throw _("cyclic value");i.add(c);try{if(Object.getOwnPropertySymbols(c).length>0)throw _("symbol-keyed fields are unsupported");if(Array.isArray(c)){let p=Object.getPrototypeOf(c),m=0;for(;p!==null;){if(G.isProxy(p))throw _("proxy array prototype");if(m+=1,m>W.depth)throw _("array prototype depth limit exceeded");p=Object.getPrototypeOf(p)}if(c.length>W.arrayLength)throw _("array length limit exceeded");for(let b=0;b<c.length;b+=1){let y=Object.getOwnPropertyDescriptor(c,String(b));if(!y||!Object.hasOwn(y,"value")||y.enumerable!==!0)throw _("array entries must be dense enumerable own data")}let x=0;for(let b in c){if(s+=1,s>W.fields)throw _("enumeration limit exceeded");if(Object.hasOwn(c,b)&&(x+=1,x>c.length))throw _("named array fields are unsupported")}if(x!==c.length)throw _("array entries must be dense enumerable own data");l("[");for(let b=0;b<c.length;b+=1)b&&l(","),u(Object.getOwnPropertyDescriptor(c,String(b)).value,h+1);l("]");return}let d=Object.getPrototypeOf(c);if(d!==Object.prototype&&d!==null)throw _("non-plain object");let f=[];for(let p in c){if(s+=1,s>W.fields)throw _("enumeration limit exceeded");if(!Object.hasOwn(c,p))continue;if(o+=1,o>W.fields)throw _("field limit exceeded");let m=Object.getOwnPropertyDescriptor(c,p);if(!m||!Object.hasOwn(m,"value")||m.enumerable!==!0)throw _("object fields must be enumerable own data");f.push([p,m.value])}l("{");for(let p=0;p<f.length;p+=1)p&&l(","),l(a(f[p][0])),l(":"),u(f[p][1],h+1);l("}")}finally{i.delete(c)}};return u(e,0),t.join("")}function $r(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(G.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let r=new Set;for(let n of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(n))throw new TypeError("HTTP header names must be valid tokens");let o=n.toLowerCase();if(r.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");r.add(o);let s=Object.getOwnPropertyDescriptor(e,n);if(!s||!Object.hasOwn(s,"value"))throw new TypeError("HTTP headers must contain own data properties");let i=s.value;if(i==null||["object","function","symbol"].includes(typeof i))throw new TypeError("HTTP header values must be scalar");t[n]=String(i)}return t}function Rr(){return Object.assign(Object.create(null),{Accept:"application/json"})}function Lr(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 Ur(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}var He=new Map,xt=new WeakMap,St=1;function Ae(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=xt.get(e);return t||(t=St,St+=1,xt.set(e,t)),`reference:${t}`}var Fr=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),Pr=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);function Et(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?Fr.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function At(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}if(Array.isArray(r))return r.length>0&&r.every(Et);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return Et(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&Pr.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function Br(e,t,r,n={},o=null){let s=Sr("sha256"),i=(a,u)=>{let c=String(u);s.update(String(Buffer.byteLength(a,"utf8"))).update(":").update(a),s.update("=").update(String(Buffer.byteLength(c,"utf8"))).update(":").update(c).update(`
2
- `)};i("method",e),i("url",t),Object.keys(r||{}).map((a,u)=>({name:a.toLowerCase(),order:u,value:String(r[a])})).sort((a,u)=>a.name.localeCompare(u.name)||a.order-u.order).forEach((a,u)=>{i(`header-name-${u}`,a.name),i(`header-value-${u}`,a.value)}),i("body",o??"-");for(let a of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])i(`context-${a}`,n[a]??"-");return s.digest("hex")}function Dr(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,yt):Math.min(250*2**e,yt)+Math.floor(Math.random()*100)}var jr=e=>new Promise(t=>setTimeout(t,e));function Y(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function Me(e,t,r){return Y(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function Z(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function qr(e){return e?e.byteLength??e.length??0:0}async function Hr(e,t,{url:r,truncate:n=!1,onOversize:o}={}){if(t==null)return await e.text();let s=Number(e.headers?.get?.("content-length"));if(Number.isFinite(s)&&s>t&&(Z(e),!n))throw Me(r,`content-length ${s}`,t);let i=e.body?.getReader?.();if(!i){let h=await e.text(),d=Buffer.byteLength(h,"utf8");if(d>t){if(!n)throw Me(r,`body ${d} bytes`,t);return Buffer.from(h,"utf8").subarray(0,t).toString("utf8")}return h}let l=[],a=0,u=!1;try{for(;;){let{value:h,done:d}=await i.read();if(d)break;if(h&&(l.push(Buffer.from(h)),a+=qr(h),a>t)){u=!0;break}}}finally{if(u)try{await i.cancel()}catch{}try{i.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!n))throw Me(r,`streamed ${a} bytes`,t);let c=Buffer.concat(l);return(u?c.subarray(0,t):c).toString("utf8")}function Mr(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function zr(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s,lookupFn:i,realFetch:l,untrustedUrl:a=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:c=!1,importUndici:h,validateResponse:d,signal:f,redirectPolicy:p="follow",maxRedirects:m=ve}){let x=null,b=t,y=i?{lookupFn:i}:{};if(a&&!l&&!qe(b))throw Y(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let v=new AbortController,O=setTimeout(()=>v.abort(),s),k=f?wt?wt([f,v.signal]):f:v.signal,R=async(E,{status:T=null}={})=>{let N=await Be(E,y);if(!N.ok)throw Y(T==null?`HTTP refused ${E}: ${N.error}`:`HTTP redirect to ${E} ${N.error}`,T==null?{}:{status:T});let L=new URL(E).hostname;if(l){if(x&&(await x.close(),x=null),!x)try{x=await De({requireUndici:!0,...h?{importUndici:h}:{}})}catch(w){throw Y(T==null?`HTTP refused ${E}: ${w?.message||w}`:`HTTP redirect to ${E} refused: ${w?.message||w}`,T==null?{}:{status:T})}x.pin(L,N.addresses),b=x.fetch}else mt(b,L,N.addresses);return N};try{let E=String(e),T=Object.assign(Object.create(null),n||{});a&&await R(E);for(let N=0;N<=m;N+=1){let L=Object.assign(Object.create(null),{method:r,headers:T,body:o,signal:k,redirect:"manual",dispatcher:void 0}),w=await b(E,L);if((p==="error"||m===0)&&w.status>=300&&w.status<400)throw Z(w),Y(`HTTP ${w.status} ${r} redirect refused`,{status:w.status,redirectRefused:!0});if(Ir.has(w.status)){let $=c===!0&&r==="POST"&&[307,308].includes(w.status)&&At(r,o);if(r!=="GET"&&r!=="HEAD"&&!$){Z(w);let g=new Error(`HTTP ${w.status} ${r} ${E} redirected non-idempotent request`);throw g.status=w.status,g}if(N===m)throw Z(w),Y(`HTTP ${w.status} ${r} redirect budget exhausted`,{status:w.status,redirectRefused:!0});let P=w.headers?.get?.("location"),C;try{C=Lr(P,E)}catch(g){throw Z(w),g}let U=!Ur(C,E);if(Z(w),U&&r==="POST"){let g=new Error(`HTTP ${w.status} ${r} cross-origin redirect refused`);throw g.status=w.status,g}if(U&&c){let g=new Error(`HTTP ${w.status} ${r} cross-origin redirect refused`);throw g.status=w.status,g.retryable=!1,g}if(U&&(T=Rr(T)),a)await R(C,{status:w.status});else if(U){let g=await Be(C,y);if(!g.ok){let A=new Error(`HTTP redirect from ${E} ${g.error}`);throw A.status=w.status,A.retryable=!1,A}l&&g.addresses?.length&&(x||(x=await De(h?{importUndici:h}:{})),x&&(x.pin(new URL(C).hostname,g.addresses),b=x.fetch))}E=C;continue}if(typeof d=="function")try{await d(w,{url:E})}catch($){throw Z(w),Y($?.message||String($))}let I=await Hr(w,u,{url:E,onOversize:()=>v.abort()}),q=Mr(I);if(!w.ok){let $=new Error(`HTTP ${w.status} ${r} ${E}`);throw $.status=w.status,$.retryAfter=w.headers?.get?.("retry-after")??null,$.body=q??I.slice(0,300),$}return q??I}throw new Error(`HTTP redirect loop for ${e}`)}catch(E){if(v.signal.aborted&&!de(f)){let T=E&&(typeof E=="object"||typeof E=="function")&&!G.isProxy(E)?E:null,N=T?Object.getOwnPropertyDescriptor(T,"oversize"):null;if(!(N&&Object.hasOwn(N,"value")&&N.value===!0))try{if(!T)throw new TypeError("unsafe rejection");Object.defineProperties(T,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let w=new Error("HTTP request timed out");throw Object.defineProperties(w,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),w}}throw E}finally{clearTimeout(O),x&&await x.close()}}async function fe(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&G.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let r=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let A of Object.getOwnPropertyNames(t)){let S=Object.getOwnPropertyDescriptor(t,A);if(!(A==="toJSON"&&S&&Object.hasOwn(S,"value")&&S.value===void 0)){if(!r.has(A))throw new TypeError("HTTP options contain unknown fields");if(!S||!S.enumerable||!Object.hasOwn(S,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=A=>{if(t==null||!Object.hasOwn(t,A))return;let S=Object.getOwnPropertyDescriptor(t,A);if(!S||!Object.hasOwn(S,"value"))throw new TypeError("HTTP options must contain own data properties");return S.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=n("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let s=n("timeoutMs");if(s!==void 0&&(!Number.isInteger(s)||s<1||s>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let i=n("retries");if(i!==void 0&&(!Number.isInteger(i)||i<0||i>10))throw new TypeError("HTTP retries must be a bounded integer");let l=n("redirectPolicy");if(l!==void 0&&l!=="follow"&&l!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let a=n("maxRedirects");if(a!==void 0&&(!Number.isInteger(a)||a<0||a>ve))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${ve}`);if(l==="error"&&a!==void 0&&a!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=l??"follow",c=u==="error"?0:a??ve;for(let A of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let S=n(A);if(S!==void 0&&typeof S!="boolean")throw new TypeError(`HTTP ${A} must be boolean`)}let h=n("maxResponseBytes");if(h!==void 0&&(!Number.isInteger(h)||h<1||h>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let d=n("signal");if(d!==void 0){if(G.isProxy(d)||!(d instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{de(d)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let A of["importUndici","lookupFn","validateResponse"]){let S=n(A);if(S!==void 0&&typeof S!="function")throw new TypeError(`HTTP ${A} must be a function`)}let f=n("fetchImpl"),p=f||globalThis.fetch;if(typeof p!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let m=s??12e3,x=(o||"GET").toUpperCase(),b=n("headers"),y=$r(b),v=Object.assign(Object.create(null),y);Object.keys(v).some(A=>A.toLowerCase()==="accept")||(v.Accept="application/json");let O=n("body");O!=null&&typeof O!="string"&&(Object.keys(v).find(S=>S.toLowerCase()==="content-type")||(v["Content-Type"]="application/json"),O=_r(O));let k=i??Ar,R=n("lookupFn"),E=!f,T=n("untrustedUrl")===!0,N=n("sameOriginRedirectsOnly")===!0,L=n("importUndici"),w=n("validateResponse"),I=d,q=h??null,$=async()=>{let A;for(let S=0;S<=k;S++){I&&Tr.call(I);let J=Se("http");try{let D=await zr(e,{fetchImpl:p,method:x,headers:v,body:O,timeoutMs:m,lookupFn:R,realFetch:E,untrustedUrl:T,maxResponseBytes:q,sameOriginRedirectsOnly:N,importUndici:L,validateResponse:w,signal:I,redirectPolicy:u,maxRedirects:c});return J?.("succeeded"),D}catch(D){A=D;let j=Ue=>{if(!D||typeof D!="object"&&typeof D!="function"||G.isProxy(D))return;let le=Object.getOwnPropertyDescriptor(D,Ue);return le&&Object.hasOwn(le,"value")?le.value:void 0},K=j("status");J?.("failed",K);let Q=j("oracleTimeout")===!0||j("name")==="AbortError"||j("name")==="TimeoutError"||de(I),Le=new Set([408,425,429]),ur=j("retryable")===!1?!1:K!=null?Le.has(K)||Er.has(K)&&bt.has(x):!Q&&bt.has(x);if(S===k||!ur)throw D;let ft=Dr(S,j("retryAfter")),dr=Se("retry"),pt=!1;try{I?await new Promise((Ue,le)=>{let ht,ue=()=>{clearTimeout(ht),gt.call(I,"abort",ue),le(kr(I)||new DOMException("Aborted","AbortError"))};if(de(I)){ue();return}ht=setTimeout(()=>{gt.call(I,"abort",ue),Ue()},ft),Cr.call(I,"abort",ue,{once:!0}),de(I)&&ue()}):await jr(ft),pt=!0}finally{dr?.(pt?"succeeded":"failed")}}}throw A};if(!(n("dedupe")!==!1&&!I&&At(x,O)))return $();let C=Br(x,e,v,{untrustedUrl:T,maxResponseBytes:q,sameOriginRedirectsOnly:N,redirectPolicy:u,maxRedirects:c,timeoutMs:m,retries:k,fetchImpl:Ae(p),realFetch:E,lookupFn:Ae(R),importUndici:Ae(L),validateResponse:Ae(w)},O),U=He.get(C);if(U){let A=Se("shared");try{let S=await U;return A?.("succeeded"),S}catch(S){throw A?.("failed"),S}}let g=$().finally(()=>He.delete(C));return He.set(C,g),g}var ze={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}};var Vr=new Map(Object.values(ze).map(e=>[e.chainId,e]));function vt(e){return Vr.get(Number(e))||null}function Nt(e,t=process.env){let r=vt(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as Wr,getAddress as ms}from"ethers";var bs=new Wr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Ve={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};function Gr(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=Nt(e,r);return n||Ve[Number(e)]||null}var Kr=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Yr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!Kr.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}var pe=new Map,Tt=new Map;function Jr(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function Qr(e){if(e?.error)throw Jr(e.error);return e?.result}function Xr(e,t,r){return`${e}
1
+ import{createHash as Sr}from"node:crypto";import{types as G}from"node:util";import{AsyncLocalStorage as fr}from"node:async_hooks";var pr=new fr,hr=["http","retry","shared"],mr=512;function Se(e){let t=pr.getStore();if(!t||t.closed||!hr.includes(e))return null;if(t.spans.length>=mr)return t.droppedSpans++,null;let r={stage:e,startMs:t.now()-t.start,durationMs:null,outcome:"pending",status:null};return t.spans.push(r),(n,o=null)=>{t.closed||r.durationMs!==null||(r.durationMs=Math.max(0,t.now()-t.start-r.startMs),r.outcome=n==="succeeded"?"succeeded":"failed",r.status=Number.isInteger(o)&&o>=100&&o<=599?o:null)}}import X from"node:net";import br from"node:dns";var yr=new Set(["localhost","metadata.google.internal","metadata.goog"]);function Ee(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=c=>{if(!c)return[];let h=c.split(":"),d=h.at(-1);if(d?.includes(".")){let f=d.split(".").map(Number);if(f.length!==4||f.some(p=>!Number.isInteger(p)||p<0||p>255))return null;h.splice(h.length-1,1,(f[0]<<8|f[1]).toString(16),(f[2]<<8|f[3]).toString(16))}return h.some(f=>!/^[0-9a-f]{1,4}$/.test(f))?null:h.map(f=>Number.parseInt(f,16))},[n,o]=t.split("::"),s=r(n),i=r(o);if(!s||!i)return null;let l=t.includes("::"),a=8-s.length-i.length;if(!l&&a!==0||l&&a<1)return null;let u=[...s,...Array(Math.max(0,a)).fill(0),...i];return u.length!==8?null:Uint8Array.from(u.flatMap(c=>[c>>8,c&255]))}function Pe(e,t,r){let n=Math.floor(r/8),o=r%8;for(let i=0;i<n;i+=1)if(e[i]!==t[i])return!1;if(!o)return!0;let s=255<<8-o;return(e[n]&s)===(t[n]&s)}function Fe(e){if(X.isIPv4(e)){let t=e.split(".").map(Number);return!(t[0]===0||t[0]===10||t[0]===127||t[0]>=224||t[0]===100&&t[1]>=64&&t[1]<=127||t[0]===169&&t[1]===254||t[0]===172&&t[1]>=16&&t[1]<=31||t[0]===192&&(t[1]===0||t[1]===2||t[1]===168)||t[0]===192&&t[1]===88&&t[2]===99||t[0]===198&&(t[1]===18||t[1]===19||t[1]===51)||t[0]===203&&t[1]===0&&t[2]===113)}if(X.isIPv6(e)){let t=Ee(e);if(!t)return!1;let r=Ee("::ffff:0:0");return Pe(t,r,96)?Fe([...t.slice(12)].join(".")):Pe(t,Ee("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,s])=>Pe(t,Ee(o),s)):!1}return!1}function gr(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let r=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(yr.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=X.isIP(r);return n!==0&&!Fe(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function Be(e,{lookupFn:t=br.promises.lookup}={}){let r=gr(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:X.isIPv6(r.host)?6:4}]};let n;if(process.env.ORACLE_HOSTED_EGRESS_PROXY)return{ok:!0,url:r.url,addresses:[]};try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(o=>!Fe(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}function wr(e=process.env){let t=e.ORACLE_HOSTED_EGRESS_PROXY||"";if(!t)return null;let r;try{r=new URL(t)}catch{throw new Error("egress-guard: ORACLE_HOSTED_EGRESS_PROXY is not a URL")}if(r.protocol!=="http:"||!["127.0.0.1","::1","localhost","[::1]"].includes(r.hostname)||!r.port||r.username||r.password)throw new Error("egress-guard: egress proxy must be an exact loopback http origin");let n=e.ORACLE_HOSTED_EGRESS_TOKEN||"";if(!/^[A-Za-z0-9_-]{43}$/.test(n))throw new Error("egress-guard: egress proxy token is missing");return{uri:r.origin,token:n}}async function De({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n,o;try{o=await t(),r=o.Agent,n=o.fetch}catch(f){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${f?.message||f}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let s=f=>String(f).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,l=f=>(Array.isArray(f)?f:[f]).map(p=>typeof p=="string"?{address:p}:p).filter(p=>p&&p.address).map(p=>({address:p.address,family:p.family||(X.isIPv6(p.address)?6:4)})),a=(f,p,m)=>{i.set(s(f),l(typeof p=="string"?[{address:p,family:m}]:p))},u=f=>{let p=s(f);if(X.isIP(p))return[{address:p,family:X.isIPv6(p)?6:4}];let m=i.get(p);if(!m||!m.length)throw new Error(`refused: unpinned host ${f} during pinned fetch`);return m},c=wr(),h=c&&typeof o.ProxyAgent=="function"?new o.ProxyAgent({uri:c.uri,token:`Bearer ${c.token}`,connectTimeout:1e4}):new r({connect:{lookup(f,p,m){let x;try{x=u(f)}catch(b){return m(b)}return p?.all?m(null,x):m(null,x[0].address,x[0].family)}}}),d=xr((f,p={})=>n(f,{...p,dispatcher:h}),a);return{dispatcher:h,fetch:d,pin:a,resolve:u,async close(){try{await h.destroy()}catch{}}}}var je=Symbol.for("oracle.egressGuard.pinCapableFetch");function xr(e,t){if(typeof e!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof t!="function")throw new Error("markPinCapableFetch: pin must be a function");return e[je]=Object.freeze({pin:t}),e}function qe(e){return typeof e=="function"&&typeof e[je]?.pin=="function"}function mt(e,t,r){if(!qe(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[je].pin(t,r)}var Er=new Set([408,425,429,500,502,503,504]),bt=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Ar=2,yt=4e3,vr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Nr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Tr=AbortSignal.prototype.throwIfAborted,Cr=EventTarget.prototype.addEventListener,gt=EventTarget.prototype.removeEventListener,wt=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,de=e=>e?vr.call(e):!1,kr=e=>e?Nr.call(e):void 0,Or=new Set([301,302,303,307,308]),ve=3,is=64*1024,W=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});function _(e){return Y(`HTTP JSON body refused: ${e}`)}function Ir(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof G[t]=="function"&&G[t](e))}function _r(e){let t=[],r=0,n=0,o=0,s=0,i=new WeakSet,l=c=>{if(r+=Buffer.byteLength(c,"utf8"),r>W.bytes)throw _("serialized byte limit exceeded");t.push(c)},a=c=>{if(Buffer.byteLength(c,"utf8")>W.bytes)throw _("serialized byte limit exceeded");return JSON.stringify(c)},u=(c,h)=>{if(n+=1,n>W.nodes)throw _("node limit exceeded");if(h>W.depth)throw _("depth limit exceeded");if(c===null){l("null");return}if(typeof c=="string"){l(a(c));return}if(typeof c=="boolean"){l(c?"true":"false");return}if(typeof c=="number"){if(!Number.isFinite(c))throw _("non-finite number");l(Object.is(c,-0)?"0":String(c));return}if(typeof c!="object")throw _("unsupported non-JSON value");if(G.isProxy(c))throw _("proxy value");if(Ir(c))throw _("unsupported exotic object");if(i.has(c))throw _("cyclic value");i.add(c);try{if(Object.getOwnPropertySymbols(c).length>0)throw _("symbol-keyed fields are unsupported");if(Array.isArray(c)){let p=Object.getPrototypeOf(c),m=0;for(;p!==null;){if(G.isProxy(p))throw _("proxy array prototype");if(m+=1,m>W.depth)throw _("array prototype depth limit exceeded");p=Object.getPrototypeOf(p)}if(c.length>W.arrayLength)throw _("array length limit exceeded");for(let b=0;b<c.length;b+=1){let y=Object.getOwnPropertyDescriptor(c,String(b));if(!y||!Object.hasOwn(y,"value")||y.enumerable!==!0)throw _("array entries must be dense enumerable own data")}let x=0;for(let b in c){if(s+=1,s>W.fields)throw _("enumeration limit exceeded");if(Object.hasOwn(c,b)&&(x+=1,x>c.length))throw _("named array fields are unsupported")}if(x!==c.length)throw _("array entries must be dense enumerable own data");l("[");for(let b=0;b<c.length;b+=1)b&&l(","),u(Object.getOwnPropertyDescriptor(c,String(b)).value,h+1);l("]");return}let d=Object.getPrototypeOf(c);if(d!==Object.prototype&&d!==null)throw _("non-plain object");let f=[];for(let p in c){if(s+=1,s>W.fields)throw _("enumeration limit exceeded");if(!Object.hasOwn(c,p))continue;if(o+=1,o>W.fields)throw _("field limit exceeded");let m=Object.getOwnPropertyDescriptor(c,p);if(!m||!Object.hasOwn(m,"value")||m.enumerable!==!0)throw _("object fields must be enumerable own data");f.push([p,m.value])}l("{");for(let p=0;p<f.length;p+=1)p&&l(","),l(a(f[p][0])),l(":"),u(f[p][1],h+1);l("}")}finally{i.delete(c)}};return u(e,0),t.join("")}function $r(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(G.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let r=new Set;for(let n of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(n))throw new TypeError("HTTP header names must be valid tokens");let o=n.toLowerCase();if(r.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");r.add(o);let s=Object.getOwnPropertyDescriptor(e,n);if(!s||!Object.hasOwn(s,"value"))throw new TypeError("HTTP headers must contain own data properties");let i=s.value;if(i==null||["object","function","symbol"].includes(typeof i))throw new TypeError("HTTP header values must be scalar");t[n]=String(i)}return t}function Rr(){return Object.assign(Object.create(null),{Accept:"application/json"})}function Lr(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 Ur(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}var He=new Map,xt=new WeakMap,St=1;function Ae(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=xt.get(e);return t||(t=St,St+=1,xt.set(e,t)),`reference:${t}`}var Pr=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),Fr=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);function Et(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?Pr.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function At(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}if(Array.isArray(r))return r.length>0&&r.every(Et);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return Et(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&Fr.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function Br(e,t,r,n={},o=null){let s=Sr("sha256"),i=(a,u)=>{let c=String(u);s.update(String(Buffer.byteLength(a,"utf8"))).update(":").update(a),s.update("=").update(String(Buffer.byteLength(c,"utf8"))).update(":").update(c).update(`
2
+ `)};i("method",e),i("url",t),Object.keys(r||{}).map((a,u)=>({name:a.toLowerCase(),order:u,value:String(r[a])})).sort((a,u)=>a.name.localeCompare(u.name)||a.order-u.order).forEach((a,u)=>{i(`header-name-${u}`,a.name),i(`header-value-${u}`,a.value)}),i("body",o??"-");for(let a of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])i(`context-${a}`,n[a]??"-");return s.digest("hex")}function Dr(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,yt):Math.min(250*2**e,yt)+Math.floor(Math.random()*100)}var jr=e=>new Promise(t=>setTimeout(t,e));function Y(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function Me(e,t,r){return Y(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function Z(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function qr(e){return e?e.byteLength??e.length??0:0}async function Hr(e,t,{url:r,truncate:n=!1,onOversize:o}={}){if(t==null)return await e.text();let s=Number(e.headers?.get?.("content-length"));if(Number.isFinite(s)&&s>t&&(Z(e),!n))throw Me(r,`content-length ${s}`,t);let i=e.body?.getReader?.();if(!i){let h=await e.text(),d=Buffer.byteLength(h,"utf8");if(d>t){if(!n)throw Me(r,`body ${d} bytes`,t);return Buffer.from(h,"utf8").subarray(0,t).toString("utf8")}return h}let l=[],a=0,u=!1;try{for(;;){let{value:h,done:d}=await i.read();if(d)break;if(h&&(l.push(Buffer.from(h)),a+=qr(h),a>t)){u=!0;break}}}finally{if(u)try{await i.cancel()}catch{}try{i.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!n))throw Me(r,`streamed ${a} bytes`,t);let c=Buffer.concat(l);return(u?c.subarray(0,t):c).toString("utf8")}function Mr(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function zr(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s,lookupFn:i,realFetch:l,untrustedUrl:a=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:c=!1,importUndici:h,validateResponse:d,signal:f,redirectPolicy:p="follow",maxRedirects:m=ve}){let x=null,b=t,y=i?{lookupFn:i}:{};if(a&&!l&&!qe(b))throw Y(`HTTP refused ${e}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let v=new AbortController,I=setTimeout(()=>v.abort(),s),k=f?wt?wt([f,v.signal]):f:v.signal,R=async(E,{status:T=null}={})=>{let N=await Be(E,y);if(!N.ok)throw Y(T==null?`HTTP refused ${E}: ${N.error}`:`HTTP redirect to ${E} ${N.error}`,T==null?{}:{status:T});let L=new URL(E).hostname;if(l){if(x&&(await x.close(),x=null),!x)try{x=await De({requireUndici:!0,...h?{importUndici:h}:{}})}catch(w){throw Y(T==null?`HTTP refused ${E}: ${w?.message||w}`:`HTTP redirect to ${E} refused: ${w?.message||w}`,T==null?{}:{status:T})}x.pin(L,N.addresses),b=x.fetch}else mt(b,L,N.addresses);return N};try{let E=String(e),T=Object.assign(Object.create(null),n||{});a&&await R(E);for(let N=0;N<=m;N+=1){let L=Object.assign(Object.create(null),{method:r,headers:T,body:o,signal:k,redirect:"manual",dispatcher:void 0}),w=await b(E,L);if((p==="error"||m===0)&&w.status>=300&&w.status<400)throw Z(w),Y(`HTTP ${w.status} ${r} redirect refused`,{status:w.status,redirectRefused:!0});if(Or.has(w.status)){let $=c===!0&&r==="POST"&&[307,308].includes(w.status)&&At(r,o);if(r!=="GET"&&r!=="HEAD"&&!$){Z(w);let g=new Error(`HTTP ${w.status} ${r} ${E} redirected non-idempotent request`);throw g.status=w.status,g}if(N===m)throw Z(w),Y(`HTTP ${w.status} ${r} redirect budget exhausted`,{status:w.status,redirectRefused:!0});let F=w.headers?.get?.("location"),C;try{C=Lr(F,E)}catch(g){throw Z(w),g}let U=!Ur(C,E);if(Z(w),U&&r==="POST"){let g=new Error(`HTTP ${w.status} ${r} cross-origin redirect refused`);throw g.status=w.status,g}if(U&&c){let g=new Error(`HTTP ${w.status} ${r} cross-origin redirect refused`);throw g.status=w.status,g.retryable=!1,g}if(U&&(T=Rr(T)),a)await R(C,{status:w.status});else if(U){let g=await Be(C,y);if(!g.ok){let A=new Error(`HTTP redirect from ${E} ${g.error}`);throw A.status=w.status,A.retryable=!1,A}l&&g.addresses?.length&&(x||(x=await De(h?{importUndici:h}:{})),x&&(x.pin(new URL(C).hostname,g.addresses),b=x.fetch))}E=C;continue}if(typeof d=="function")try{await d(w,{url:E})}catch($){throw Z(w),Y($?.message||String($))}let O=await Hr(w,u,{url:E,onOversize:()=>v.abort()}),q=Mr(O);if(!w.ok){let $=new Error(`HTTP ${w.status} ${r} ${E}`);throw $.status=w.status,$.retryAfter=w.headers?.get?.("retry-after")??null,$.body=q??O.slice(0,300),$}return q??O}throw new Error(`HTTP redirect loop for ${e}`)}catch(E){if(v.signal.aborted&&!de(f)){let T=E&&(typeof E=="object"||typeof E=="function")&&!G.isProxy(E)?E:null,N=T?Object.getOwnPropertyDescriptor(T,"oversize"):null;if(!(N&&Object.hasOwn(N,"value")&&N.value===!0))try{if(!T)throw new TypeError("unsafe rejection");Object.defineProperties(T,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let w=new Error("HTTP request timed out");throw Object.defineProperties(w,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),w}}throw E}finally{clearTimeout(I),x&&await x.close()}}async function fe(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&G.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let r=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let A of Object.getOwnPropertyNames(t)){let S=Object.getOwnPropertyDescriptor(t,A);if(!(A==="toJSON"&&S&&Object.hasOwn(S,"value")&&S.value===void 0)){if(!r.has(A))throw new TypeError("HTTP options contain unknown fields");if(!S||!S.enumerable||!Object.hasOwn(S,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=A=>{if(t==null||!Object.hasOwn(t,A))return;let S=Object.getOwnPropertyDescriptor(t,A);if(!S||!Object.hasOwn(S,"value"))throw new TypeError("HTTP options must contain own data properties");return S.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=n("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let s=n("timeoutMs");if(s!==void 0&&(!Number.isInteger(s)||s<1||s>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let i=n("retries");if(i!==void 0&&(!Number.isInteger(i)||i<0||i>10))throw new TypeError("HTTP retries must be a bounded integer");let l=n("redirectPolicy");if(l!==void 0&&l!=="follow"&&l!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let a=n("maxRedirects");if(a!==void 0&&(!Number.isInteger(a)||a<0||a>ve))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${ve}`);if(l==="error"&&a!==void 0&&a!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=l??"follow",c=u==="error"?0:a??ve;for(let A of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let S=n(A);if(S!==void 0&&typeof S!="boolean")throw new TypeError(`HTTP ${A} must be boolean`)}let h=n("maxResponseBytes");if(h!==void 0&&(!Number.isInteger(h)||h<1||h>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let d=n("signal");if(d!==void 0){if(G.isProxy(d)||!(d instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{de(d)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let A of["importUndici","lookupFn","validateResponse"]){let S=n(A);if(S!==void 0&&typeof S!="function")throw new TypeError(`HTTP ${A} must be a function`)}let f=n("fetchImpl"),p=f||globalThis.fetch;if(typeof p!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let m=s??12e3,x=(o||"GET").toUpperCase(),b=n("headers"),y=$r(b),v=Object.assign(Object.create(null),y);Object.keys(v).some(A=>A.toLowerCase()==="accept")||(v.Accept="application/json");let I=n("body");I!=null&&typeof I!="string"&&(Object.keys(v).find(S=>S.toLowerCase()==="content-type")||(v["Content-Type"]="application/json"),I=_r(I));let k=i??Ar,R=n("lookupFn"),E=!f,T=n("untrustedUrl")===!0,N=n("sameOriginRedirectsOnly")===!0,L=n("importUndici"),w=n("validateResponse"),O=d,q=h??null,$=async()=>{let A;for(let S=0;S<=k;S++){O&&Tr.call(O);let J=Se("http");try{let D=await zr(e,{fetchImpl:p,method:x,headers:v,body:I,timeoutMs:m,lookupFn:R,realFetch:E,untrustedUrl:T,maxResponseBytes:q,sameOriginRedirectsOnly:N,importUndici:L,validateResponse:w,signal:O,redirectPolicy:u,maxRedirects:c});return J?.("succeeded"),D}catch(D){A=D;let j=Ue=>{if(!D||typeof D!="object"&&typeof D!="function"||G.isProxy(D))return;let le=Object.getOwnPropertyDescriptor(D,Ue);return le&&Object.hasOwn(le,"value")?le.value:void 0},K=j("status");J?.("failed",K);let Q=j("oracleTimeout")===!0||j("name")==="AbortError"||j("name")==="TimeoutError"||de(O),Le=new Set([408,425,429]),ur=j("retryable")===!1?!1:K!=null?Le.has(K)||Er.has(K)&&bt.has(x):!Q&&bt.has(x);if(S===k||!ur)throw D;let ft=Dr(S,j("retryAfter")),dr=Se("retry"),pt=!1;try{O?await new Promise((Ue,le)=>{let ht,ue=()=>{clearTimeout(ht),gt.call(O,"abort",ue),le(kr(O)||new DOMException("Aborted","AbortError"))};if(de(O)){ue();return}ht=setTimeout(()=>{gt.call(O,"abort",ue),Ue()},ft),Cr.call(O,"abort",ue,{once:!0}),de(O)&&ue()}):await jr(ft),pt=!0}finally{dr?.(pt?"succeeded":"failed")}}}throw A};if(!(n("dedupe")!==!1&&!O&&At(x,I)))return $();let C=Br(x,e,v,{untrustedUrl:T,maxResponseBytes:q,sameOriginRedirectsOnly:N,redirectPolicy:u,maxRedirects:c,timeoutMs:m,retries:k,fetchImpl:Ae(p),realFetch:E,lookupFn:Ae(R),importUndici:Ae(L),validateResponse:Ae(w)},I),U=He.get(C);if(U){let A=Se("shared");try{let S=await U;return A?.("succeeded"),S}catch(S){throw A?.("failed"),S}}let g=$().finally(()=>He.delete(C));return He.set(C,g),g}var ze={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},elysium:{chainId:1339,name:"Elysium",rpcEnv:["ELYSIUM_RPC_URL"],evm:!0,readOnly:!0}};var Vr=new Map(Object.values(ze).map(e=>[e.chainId,e]));function vt(e){return Vr.get(Number(e))||null}function Nt(e,t=process.env){let r=vt(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as Wr,getAddress as ms}from"ethers";var bs=new Wr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Ve={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",1339:"https://rpc.elysiumchain.tech"};function Gr(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=Nt(e,r);return n||Ve[Number(e)]||null}var Kr=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Yr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!Kr.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}var pe=new Map,Tt=new Map;function Jr(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function Qr(e){if(e?.error)throw Jr(e.error);return e?.result}function Xr(e,t,r){return`${e}
3
3
  ${t}
4
- ${JSON.stringify(r??[])}`}async function Zr(e,t,r){return fe(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function ee(e,t,r=[],n={}){let o=String(t||""),s=Yr(o),i=Gr(e,n);if(!i)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);if(s==="eth_chainid"&&n.cacheChainId!==!1){let c=Tt.get(i);if(c!=null)return c}let a=n.dedupe!==!1&&!n.signal?Xr(i,o,r):null;if(a&&pe.has(a))return pe.get(a);let u=(async()=>{let c=await Zr(i,{jsonrpc:"2.0",id:1,method:t,params:r},n),h=Qr(c);return s==="eth_chainid"&&typeof h=="string"&&Tt.set(i,h),h})();return a&&(pe.set(a,u),u.finally(()=>{pe.get(a)===u&&pe.delete(a)}).catch(()=>{})),u}var Ss=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});var As=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),We=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Ge=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var he=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",stableQuoteAssets:["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","0xdAC17F958D2ee523a2206206994597C13D831ec7"],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",stableQuoteAssets:["0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85","0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"],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",stableQuoteAssets:["0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d","0x55d398326f99059fF775485246999027B3197955"],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",stableQuoteAssets:["0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359","0xc2132D05D31c914a87C6611C10748AEb04B58e8F"],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",stableQuoteAssets:["0x5fc5360d0400a0fd4f2af552add042d716f1d168"],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",stableQuoteAssets:["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],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",stableQuoteAssets:["0xaf88d065e77c8cC2239327C5EDb3A432268e5831","0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"],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",stableQuoteAssets:["0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"],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 H="unknown",Ct=/^0x[0-9a-fA-F]{64}$/,Te=/^0x[0-9a-fA-F]{40}$/;function Ne(e){if(e==null)return null;try{return BigInt(e)}catch{return null}}function kt(e,{timeoutMs:t=2e4,fetchImpl:r=globalThis.fetch}={}){return async function(o,s=[]){let i=new AbortController,l=setTimeout(()=>i.abort(),t);try{let u=await(await r(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:o,params:s}),signal:i.signal})).json();if(u.error)throw new Error(`${o} rpc: ${u.error.message||"rpc error"}`);return u.result}finally{clearTimeout(l)}}}async function tn(e,t){let r={txHash:e,txFrom:null,txTo:null,nativeValueWei:H,gasWei:H,gasUsed:H,effectiveGasPrice:H,status:H,error:null},n=[];try{let o=await t("eth_getTransactionByHash",[e]);if(o){let s=Ne(o.value);s!=null&&(r.nativeValueWei=s.toString()),typeof o.from=="string"&&Te.test(o.from)&&(r.txFrom=o.from.toLowerCase()),typeof o.to=="string"&&Te.test(o.to)&&(r.txTo=o.to.toLowerCase())}else n.push("eth_getTransactionByHash: null (not found / pruned)")}catch(o){n.push(`eth_getTransactionByHash: ${o?.message||o}`)}try{let o=await t("eth_getTransactionReceipt",[e]);if(o){let s=Ne(o.gasUsed),i=Ne(o.effectiveGasPrice??o.gasPrice);if(s!=null&&(r.gasUsed=s.toString()),i!=null&&(r.effectiveGasPrice=i.toString()),s!=null&&i!=null&&(r.gasWei=(s*i).toString()),o.status!=null){let l=Ne(o.status);r.status=l==null?H:l===1n?"success":"reverted"}!r.txFrom&&typeof o.from=="string"&&Te.test(o.from)&&(r.txFrom=o.from.toLowerCase())}else n.push("eth_getTransactionReceipt: null (pending / pruned)")}catch(o){n.push(`eth_getTransactionReceipt: ${o?.message||o}`)}return n.length&&(r.error=n.join("; ")),r}async function Ke(e,t={}){let{rpc:r,concurrency:n=4,cap:o=200,cache:s=new Map,wallet:i}=t;if(typeof r!="function")throw new TypeError("enrichNativeLeg: opts.rpc(method, params) is required");if(!Array.isArray(e))throw new TypeError("enrichNativeLeg: events must be an array");let l=typeof i=="string"&&Te.test(i)?i.toLowerCase():null,a=[],u=[],c=new Set;for(let b of e){let y=String(b?.txHash||"").toLowerCase();!Ct.test(y)||c.has(y)||(c.add(y),u.push(y))}let h=u.filter(b=>!s.has(b)),d=Math.max(0,h.length-o),f=h.slice(0,o);for(let b of h.slice(o))a.push({txHash:b,stage:"cap",error:`per-call cap ${o} exceeded`});let p=0,m=Array.from({length:Math.max(1,Math.min(n,f.length))},async()=>{for(;p<f.length;){let b=f[p++];try{let y=await tn(b,r);s.set(b,y),y.error&&a.push({txHash:b,stage:"nativeLeg",error:y.error})}catch(y){let v={txHash:b,nativeValueWei:H,gasWei:H,error:String(y?.message||y)};s.set(b,v),a.push({txHash:b,stage:"nativeLeg",error:v.error})}}});return await Promise.all(m),{events:e.map(b=>{let y=String(b?.txHash||"").toLowerCase(),v=s.get(y);if(!v){let k=Ct.test(y)?`per-call cap ${o} exceeded`:"invalid txHash";return{...b,nativeValueWei:H,gasWei:H,nativeLeg:{error:k}}}let O={...b,txFrom:b.txFrom??v.txFrom??null,nativeValueWei:v.nativeValueWei,gasWei:v.gasWei,nativeLeg:v.error?{...v,error:v.error}:{...v,error:null}};return l&&String(b.from||"").toLowerCase()===l&&(O.nativeReceived=H),O}),errors:a,looked:f.length,capped:d}}var It="0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",Rt=Object.freeze({1:Object.freeze(["https://mainnet.gateway.tenderly.co","https://eth.drpc.org","https://rpc.flashbots.net"]),8453:Object.freeze(["https://base.gateway.tenderly.co","https://mainnet.base.org","https://base.drpc.org"]),42161:Object.freeze(["https://arbitrum.gateway.tenderly.co","https://arb1.arbitrum.io/rpc","https://arbitrum.drpc.org"]),4663:Object.freeze(["https://rpc.mainnet.chain.robinhood.com"])}),rn=/publicnode/i;function Ot(e){return rn.test(String(e||""))}var nn=e=>typeof e=="string"&&/^https:\/\//.test(e),Je=new Map(he.filter(e=>Number.isInteger(Number(e?.chainId))&&Number(e.chainId)>0).map(e=>[Number(e.chainId),e]));function on(){return[...new Set([...Je.keys(),...Object.keys(Rt).map(Number)])].sort((t,r)=>t-r)}function Lt(e,{env:t=null,curated:r=Rt,fallbacks:n=Ve}={}){let o=Number(e),s=[],i=[],l=(d,f)=>{!nn(d)||s.includes(d)||(s.push(d),i.push(f))};if(t&&typeof t=="object"){let d=Je.get(o);for(let f of Array.isArray(d?.rpcEnv)?d.rpcEnv:[]){let p=String(t[f]||"").trim();p&&l(p,`env:${f}`)}}let a=r?.[o],u=Array.isArray(a)&&a.length>0;if(u)for(let d of a)l(d,"curated");let c=n?.[o];c&&!(u&&Ot(c))&&l(c,"public-fallback");let h=s.length>0&&s.every(Ot);return{chainId:o,urls:s,curated:u,shallow:h,source:i}}var me=Object.freeze(Object.fromEntries(on().map(e=>[e,Object.freeze(Lt(e).urls)]).filter(([,e])=>e.length>0)));function sn(e=me){return Object.keys(e).map(Number).filter(t=>Number.isInteger(t)&&t>0&&e[t]?.length).sort((t,r)=>t-r)}var an=1e4,cn=e=>new Promise(t=>setTimeout(t,e)),_t=e=>"0x"+BigInt(e).toString(16),ln=e=>"0x"+"0".repeat(24)+e.slice(2).toLowerCase(),$t=e=>"0x"+e.slice(26).toLowerCase(),un=/timeout|timed out|too many requests|rate.?limit|429|502|503|504|internal error|temporarily|aborted|fetch failed|ECONNRESET|socket hang up/i,dn=/too many|exceeds|limited to|not supported on free plan|response too large|range must not exceed|narrow your filter/i,te=class extends Error{constructor(t,{transient:r=!1,tooBig:n=!1,http:o=0}={}){super(t),this.transient=r,this.tooBig=n,this.http=o}};async function fn(e,t,r,n){let o=new AbortController,s=setTimeout(()=>o.abort(),n),i,l;try{i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:t,params:r}),signal:o.signal}),l=await i.text()}catch(u){throw new te(`${t} network: ${u.message}`,{transient:!0})}finally{clearTimeout(s)}let a;try{a=JSON.parse(l)}catch{throw new te(`${t} non-JSON http=${i.status}: ${l.slice(0,80)}`,{transient:i.status>=500||i.status===429,http:i.status})}if(a.error){let u=a.error.message||"rpc error";throw new te(`${t} rpc: ${u}`,{transient:un.test(u),tooBig:dn.test(u),http:i.status})}if(i.status!==200)throw new te(`${t} http=${i.status}: ${l.slice(0,80)}`,{transient:i.status>=500||i.status===429,http:i.status});return a.result}async function Ut(e,t,r,{retries:n,timeoutMs:o,onWarn:s}){let i;for(let l of e){for(let a=0;a<=n;a++)try{return{result:await fn(l,t,r,o),url:l}}catch(u){if(i=u,u.tooBig)throw u;if(!u.transient||a===n)break;let c=Math.min(2e3*2**a,8e3)+Math.random()*250;s?.(`retry ${l} (${u.message.slice(0,70)}) in ${Math.round(c)}ms`),await cn(c)}s?.(`endpoint exhausted: ${l} -> ${i?.message.slice(0,70)}`)}throw i??new te("no endpoints available")}async function Ye(e,t,r,n,o,s){let i=[{...t,fromBlock:_t(r),toBlock:_t(n)}];try{let{result:a}=await Ut(e,"eth_getLogs",i,o);Array.isArray(a)&&s.push(...a);return}catch(a){if(!a.tooBig||n<=r)throw a;o.onWarn?.(`splitting ${r}-${n} (${a.message.slice(0,60)})`)}let l=r+Math.floor((n-r)/2);await Promise.all([Ye(e,t,r,l,o,s),Ye(e,t,l+1,n,o,s)])}async function Qe(e,t={}){if(!/^0x[0-9a-fA-F]{40}$/.test(e||""))throw new Error(`invalid address: ${e}`);let{chains:r=sn(t.endpoints??me),lookback:n=1e5,fromBlock:o,toBlock:s,chunkSize:i=an,tokens:l,direction:a="both",retries:u=3,timeoutMs:c=2e4,concurrency:h=4,endpoints:d=null,env:f=process.env,onWarn:p}=t,m={retries:u,timeoutMs:c,onWarn:p},x=ln(e),b=[],y=[],v={},O=new Set;return await Promise.all(r.map(async k=>{let R,E=!1;if(d&&typeof d=="object")R=d[k];else{let T=Lt(k,{env:f});R=T.urls,E=T.shallow}if(!R?.length){y.push({chainId:k,stage:"config",error:"no endpoints configured"});return}E&&p?.(`chain ${k}: only shallow (~128 block) public endpoints; deep lookback will fail \u2014 set ${(Je.get(Number(k))?.rpcEnv||[]).join("/")||"an archive RPC"} for archive depth`);try{let T=s;if(T==null){let{result:g}=await Ut(R,"eth_blockNumber",[],m);T=parseInt(g,16)}let N=Math.max(0,o??T-n+1),L=Math.max(N,T);v[k]={fromBlock:N,toBlock:L,blocks:L-N+1,shallow:E};let w=[];for(let g=N;g<=L;g+=i)w.push([g,Math.min(g+i-1,L)]);let I=[],q=l?.length?{address:l}:{};(a==="in"||a==="both")&&I.push({...q,topics:[It,null,x]}),(a==="out"||a==="both")&&I.push({...q,topics:[It,x,null]});let $=[];for(let g of I)for(let A of w)$.push([g,A]);let P=[],C=0,U=Array.from({length:Math.min(h,$.length)},async()=>{for(;C<$.length;){let[g,[A,S]]=$[C++];try{await Ye(R,g,A,S,m,P)}catch(J){y.push({chainId:k,stage:"getLogs",range:[A,S],error:J.message})}}});await Promise.all(U);for(let g of P){if(!g?.topics||g.topics.length<3)continue;let A=parseInt(g.logIndex,16),S=`${k}|${g.transactionHash}|${A}`;O.has(S)||(O.add(S),b.push({chainId:k,token:g.address.toLowerCase(),from:$t(g.topics[1]),to:$t(g.topics[2]),value:BigInt(g.data==="0x"?"0x0":g.data).toString(),blockNumber:parseInt(g.blockNumber,16),txHash:g.transactionHash,logIndex:A}))}}catch(T){y.push({chainId:k,stage:"range",error:T.message})}})),b.sort((k,R)=>R.blockNumber-k.blockNumber||R.logIndex-k.logIndex),{events:b,errors:y,ranges:v}}import{keccak_256 as Xe}from"@noble/hashes/sha3.js";var et=999,Ze=1,pn=8453,Ft="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",hn="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",Pt="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",mn="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",bn=".80002105.reverse",tt=/^0x[a-fA-F0-9]{40}$/,Bt=new TextEncoder,Dt=e=>"0x"+Buffer.from(e).toString("hex"),re=e=>Dt(Xe(Bt.encode(e))).slice(0,10),jt=e=>e.toLowerCase().replace(/^0x/,"").padStart(64,"0");function Ce(e){let t=new Uint8Array(32);if(e)for(let r of String(e).split(".").reverse()){let n=Xe(Bt.encode(r)),o=new Uint8Array(64);o.set(t,0),o.set(n,32),t=Xe(o)}return Dt(t)}function rt(e){if(!e||e==="0x"||/^0x0*$/.test(e))return"";try{let t=e.slice(2),r=parseInt(t.slice(0,64),16)*2,n=parseInt(t.slice(r,r+64),16);if(!Number.isFinite(n)||n<=0)return"";let o=t.slice(r+64,r+64+n*2);return Buffer.from(o,"hex").toString("utf8")}catch{return""}}async function ne(e,t,r){try{return await ee(e,"eth_call",[{to:t,data:r},"latest"])}catch{return null}}async function yn(e){let t=await ne(et,Ft,re("primaryName(address)")+jt(e)),r=rt(t);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function gn(e){let t=await ne(et,hn,re("getName(address)")+jt(e)),r=rt(t);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function qt(e,t,r){let n=await ne(e,r,re("name(bytes32)")+t.slice(2));return rt(n)||null}async function wn(e){let t=Ce(`${e.slice(2).toLowerCase()}.addr.reverse`),r=await ne(Ze,Pt,re("resolver(bytes32)")+t.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:qt(Ze,t,n)}async function xn(e){let t=Ce(e.slice(2).toLowerCase()+bn);return qt(pn,t,mn)}var Sn=[{source:"hl",fn:yn},{source:"hype",fn:gn},{source:"ens",fn:wn},{source:"basename",fn:xn}];async function En(e){let t=Ce(e),r=await ne(et,Ft,re("ownerOf(uint256)")+t.slice(2));if(!r||r.length<66)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:n}async function An(e,t,r){let n=Ce(t),o=await ne(e,r,re("resolver(bytes32)")+n.slice(2));if(!o)return null;let s="0x"+o.slice(-40);if(/^0x0+$/.test(s))return null;let i=await ne(e,s,re("addr(bytes32)")+n.slice(2));if(!i)return null;let l="0x"+i.slice(-40);return/^0x0+$/.test(l)?null:l}async function Ht(e){let t=String(e||"").trim().toLowerCase();if(!t||!t.includes("."))return null;if(t.endsWith(".hl")){let r=await En(t);return r?{address:r,source:"hl",name:t}:null}if(t.endsWith(".eth")){let r=await An(Ze,t,Pt);return r?{address:r,source:t.endsWith(".base.eth")?"basename":"ens",name:t}:null}return null}var li=Sn.map(e=>e.source);var vn="protective-monitors",Nn="read-only",fi=Object.freeze(["depeg","oracleDeviation","exploitFeed","goplus","liquidationLadder"]),Tn="https://hermes.pyth.network",Cn="https://coins.llama.fi",kn="https://api.llama.fi/hacks",In="https://api.gopluslabs.io/api/v1/token_security",On="https://api.v3.aave.com/user",_n=Object.freeze({USDT:"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",USDC:"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"}),$n=Object.freeze({USDT:"coingecko:tether",USDC:"coingecko:usd-coin",DAI:"coingecko:dai"}),Rn=Object.freeze(["is_honeypot","is_proxy","is_mintable","owner_change_balance","hidden_owner","selfdestruct","cannot_buy","cannot_sell_all","is_blacklisted"]),Mt=Object.freeze({liquidatable:0,danger:1,critical:2,warning:3,healthy:4}),Ln=/^0x[0-9a-fA-F]{40}$/,Un=/^[0-9a-fA-F]{64}$/;function be(e,t={}){return{ok:!0,provider:vn,op:e,alertOnly:!0,execution:Nn,exec:!1,...t}}function F(e,t){throw new Error(`protective-monitors: ${e}${t?` ${t}`:""}`)}async function ye(e,t={}){return typeof t.http=="function"?t.http(e,t):typeof t.httpJson=="function"?t.httpJson(e,t):fe(e,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3,retries:t.retries??0})}function ke(e){return String(e||"USDT").trim().toUpperCase().replace(/\/USD$/,"")}function Fn(e={}){if(e.feedId){let n=String(e.feedId).replace(/^0x/i,"");return Un.test(n)||F("feedId must be a 32-byte hex id"),n.toLowerCase()}let t=ke(e.symbol),r=_n[t];return r||F("unknown symbol",t),r}function Pn(e={}){if(e.llamaCoin)return String(e.llamaCoin);let t=ke(e.symbol);return $n[t]||`coingecko:${t.toLowerCase()}`}function zt(e,t){let r=Number(e.thresholdBps??t);return(!Number.isFinite(r)||r<0)&&F("thresholdBps must be a non-negative number"),r}function Bn(e){let t=Array.isArray(e?.parsed)?e.parsed[0]:e?.price?e:null,r=Number(t?.price?.price),n=Number(t?.price?.expo);return(!Number.isFinite(r)||!Number.isFinite(n))&&F("no pyth price returned"),n<0?r/10**-n:r*10**n}function Dn(e,t){let r=e?.coins?.[t]||e?.coins?.[String(t).toLowerCase()],n=Number(r?.price);return Number.isFinite(n)?n:null}function jn(e,t={}){let r=String(t.pythBaseUrl||Tn).replace(/\/$/,""),n=new URL(`${r}/v2/updates/price/latest`);return n.searchParams.append("ids[]",e),n.searchParams.set("parsed","true"),n.toString()}function qn(e,t={}){return`${String(t.llamaCoinsBaseUrl||Cn).replace(/\/$/,"")}/prices/current/${encodeURIComponent(e)}`}async function Vt(e,t){let r=Fn(e),n=await ye(jn(r,t),t),o=Bn(n);return o>0||F("pyth price must be positive"),{id:r,price:o}}async function Wt(e,t){let r=Pn(e),n=await ye(qn(r,t),t);return{coin:r,price:Dn(n,r)}}async function Hn(e={},t={}){let r=Number(e.peg??1);(!Number.isFinite(r)||r<=0)&&F("peg must be a positive number");let n=zt(e,50),o=await Vt(e,t),s=Math.round(Math.abs(o.price-r)*1e4),i={required:!1,llamaPrice:null};try{let l=await Wt(e,t);i={required:!1,llamaPrice:l.price,llamaCoin:l.coin}}catch{i={required:!1,llamaPrice:null}}return be("depeg",{symbol:ke(e.symbol),feedId:o.id,price:o.price,peg:r,thresholdBps:n,deviationBps:s,alert:s>n,crossCheck:i})}async function Mn(e={},t={}){let r=zt(e,100),n=await Vt(e,t),o=await Wt(e,t);o.price>0||F("llama price required for oracleDeviation");let s=(n.price+o.price)/2,i=Math.round(Math.abs(n.price-o.price)/s*1e4);return be("oracleDeviation",{symbol:ke(e.symbol),pythPrice:n.price,llamaPrice:o.price,mid:s,thresholdBps:r,deviationBps:i,alert:i>r})}function zn(e,t){return String(e.id||e.defillamaId||e.slug||`hack-${t}`)}function Vn(e,t){return{id:zn(e,t),name:String(e.name||e.protocol||"unknown"),classification:e.classification?String(e.classification):null,technique:e.technique?String(e.technique):null,amount:Number.isFinite(Number(e.amount))?Number(e.amount):null,chain:Array.isArray(e.chain)?e.chain.map(String):e.chain?[String(e.chain)]:[],source:e.source?String(e.source):null}}function Wn(e){return(String(e).match(/<item\b[\s\S]*?<\/item>/gi)||[]).map((r,n)=>{let o=s=>{let i=r.match(new RegExp(`<${s}[^>]*>([\\s\\S]*?)</${s}>`,"i"));return i?i[1].replace(/<!\[CDATA\[|\]\]>/g,"").trim():""};return{id:o("guid")||o("link")||o("title")||`rss-${n}`,name:o("title")||"unknown",classification:"rss",technique:null,amount:null,chain:[],source:o("link")||null}})}function Gt(e){if(typeof e=="string"){let t=e.trim();if(t.startsWith("<"))return Wn(t);try{return Gt(JSON.parse(t))}catch{F("exploitFeed payload is not JSON or RSS")}}return Array.isArray(e)?e:Array.isArray(e?.hacks)?e.hacks:Array.isArray(e?.items)?e.items:[]}function Gn(e){return e.map((t,r)=>({item:t,index:r})).sort((t,r)=>{let n=String(t.item.id).localeCompare(String(r.item.id));return n!==0?n:t.index-r.index}).map(t=>t.item)}async function Kn(e={},t={}){let r=kn,n=e.payload??await ye(r,t),o=Gn(Gt(n).map(Vn));return be("exploitFeed",{count:o.length,fingerprint:o.map(s=>s.id).join("|"),items:o,alert:o.length>0})}function Yn(e){return e===!0||e===1||e==="1"}function Jn(e,t){let r=e?.result&&typeof e.result=="object"?e.result:e,n=String(t).toLowerCase();if(r&&typeof r=="object"){for(let[o,s]of Object.entries(r))if(String(o).toLowerCase()===n&&s&&typeof s=="object")return{address:o,token:s}}return null}async function nt(e={},t={}){e.asSoleGate===!0&&F("goplus is a second opinion and must never be a sole gate");let r=String(e.address||e.token||"").trim();Ln.test(r)||F("goplus requires an EVM token address");let n=Number(e.chainId??1);(!Number.isInteger(n)||n<=0)&&F("chainId must be a positive integer");let s=`${String(t.goplusBaseUrl||In).replace(/\/$/,"")}/${n}?contract_addresses=${r}`,i=e.payload??await ye(s,t),l=Jn(i,r);l||F("goplus returned no result for",r);let a=Rn.filter(u=>Yn(l.token[u]));return be("goplus",{chainId:n,address:r.toLowerCase(),role:"second-opinion",secondOpinion:!0,soleGate:!1,neverSoleGate:!0,token:{address:l.address,name:l.token.token_name||null,symbol:l.token.token_symbol||null},findings:a,alert:a.length>0,note:"second opinion only \u2014 never the sole gate"})}function Qn(e){let t=Number(e);return(!Number.isFinite(t)||t<0)&&F("healthFactor must be a non-negative number"),t<1?"liquidatable":t<1.05?"danger":t<1.2?"critical":t<1.5?"warning":"healthy"}function Xn(e,t){let r=Number(e.healthFactor??e.hf);Number.isFinite(r)||F("position healthFactor required");let n=Qn(r);return{id:String(e.id||e.protocol||`pos-${t}`),protocol:String(e.protocol||"unknown"),healthFactor:r,collateralUsd:e.collateralUsd!=null?Number(e.collateralUsd):null,debtUsd:e.debtUsd!=null?Number(e.debtUsd):null,rung:n}}async function Zn(e={},t={}){let r=null;if(Array.isArray(e.positions))r=e;else if(Array.isArray(e))r={positions:e};else{let i=String(e.user||"").trim();i||F("liquidationLadder requires user or positions");let l=String(t.aaveUrl||`${On}/${i}`);r=await ye(l,t)}let o=(Array.isArray(r?.positions)?r.positions:[]).map(Xn),s=o.reduce((i,l)=>i?Mt[l.rung]<Mt[i]?l.rung:i:l.rung,null);return be("liquidationLadder",{user:r?.user||e.user||null,chainId:r?.chainId??e.chainId??null,ladder:o,worstRung:s,alert:o.some(i=>i.rung!=="healthy")})}var pi=Object.freeze({depeg:Hn,oracleDeviation:Mn,exploitFeed:Kn,goplus:nt,liquidationLadder:Zn});import se from"node:fs";import bo from"node:os";import Oe from"node:path";import{randomUUID as yo}from"node:crypto";var mi=Object.freeze(["wallet","pool","nft_floor","hl_flow","prediction_market"]),bi=Object.freeze({wallets:"wallet",smart_wallet:"wallet",pools:"pool",new_pool:"pool",nft:"nft_floor",nft_floors:"nft_floor",hyperliquid:"hl_flow",prediction:"prediction_market",prediction_markets:"prediction_market"}),V=(e,t=0,r=1)=>Math.min(r,Math.max(t,e)),M=e=>Number.isFinite(Number(e))?Number(e):null,eo=e=>Math.round(e*1e4)/1e4;function z(e,t,r,n=!0){!n||r===null||!Number.isFinite(r)||e.push({feature:t,value:eo(r)})}function to(e,t){let r=M(e.repeatBuys??e.repeat_buys??e.buyCount),n=M(e.walletWinRate??e.winRate);z(t,"repeat_buys",r===null?null:V((r-1)/4)*.38),z(t,"wallet_win_rate",n===null?null:(V(n)-.5)*.5)}function ro(e,t){let r=M(e.ageHours??e.poolAgeHours),n=M(e.liquidityUsd??e.liquidity),o=e.liquidityLocked??e.locked;z(t,"pool_age",r===null?null:r<24?-.42:V(r/720)*.12),z(t,"liquidity",n===null?null:(V(Math.log10(Math.max(1,n))/7)-.5)*.28),z(t,"liquidity_lock",o==null?null:o?.12:-.28)}function no(e,t){let r=M(e.floorChange??e.floorChangePct),n=M(e.sales??e.saleCount);z(t,"floor_change",r===null?null:V(r,-1,1)*.35),z(t,"sales_depth",n===null?null:V(n/50)*.18)}function oo(e,t){let r=M(e.flowImbalance??e.imbalance),n=M(e.fundingRate??e.funding);z(t,"flow_imbalance",r===null?null:V(r,-1,1)*.42),z(t,"funding",n===null?null:-V(n*100,-1,1)*.12)}function so(e,t){let r=M(e.marketProbability??e.marketPrice??e.probability),n=M(e.fairProbability??e.referenceProbability??e.fairValue);z(t,"probability_mispricing",r===null||n===null?null:V(n-r,-1,1)*.65);let o=M(e.liquidityUsd??e.liquidity);z(t,"market_liquidity",o===null?null:V(Math.log10(Math.max(1,o))/6)*.12)}var yi=Object.freeze({wallet:to,pool:ro,nft_floor:no,hl_flow:oo,prediction_market:so});import{createHash as uo}from"node:crypto";var wi=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),xi=Object.freeze(["read","simulate"]);var Si=1440*60;var ge=class extends Error{constructor(t,r){super(`secret material must never appear in a public API object (at ${t}, rule: ${r})`),this.name="SecretLeakError",this.path=t,this.rule=r}},io=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,ao=Object.freeze(["privkey","wif","xprv","seed"]);function Kt(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return io.test(t)||ao.includes(r)}var co=Object.freeze([{rule:"raw-32-byte-hex-key",re:/^0x[0-9a-fA-F]{64}$/},{rule:"raw-32-byte-hex-bare",re:/^[0-9a-fA-F]{64}$/},{rule:"extended-private-key",re:/\b(?:xprv|tprv|yprv|zprv)[1-9A-HJ-NP-Za-km-z]{107}\b/},{rule:"bitcoin-wif",re:/\b[59KLc][1-9A-HJ-NP-Za-km-z]{50,51}\b/},{rule:"bip39-mnemonic",re:/\b(?:[a-z]{3,8}\s+){11,23}[a-z]{3,8}\b/},{rule:"bearer-token",re:/bearer\s+[A-Za-z0-9._~+/=-]+/i},{rule:"pem-private-key",re:/-----BEGIN[A-Z ]*PRIVATE KEY-----/},{rule:"keystore-path",re:/keystore/i},{rule:"signer-url",re:/https?:\/\/\S*sign/i},{rule:"authorization-header",re:/authorization\s*:/i}]),lo=Object.freeze(["grantid","id","hash","sha256","sha256hex","checksum","txhash","transactionhash","blockhash","digest","userophash","commithash","prevhash","intenthash","canonicalhash","payloadhash","requestid"]);function oe(e,t="$",r=new Set,n=""){if(e==null)return e;if(typeof e=="string"){let o=lo.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:s,re:i}of co)if(!(o&&s.startsWith("raw-32-byte-hex"))&&i.test(e))throw new ge(t,s);return e}if(typeof e!="object"||r.has(e)||(r.add(e),ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e;if(e instanceof Map){for(let[o,s]of e.entries()){if(typeof o=="string"&&Kt(o))throw new ge(`${t}[${JSON.stringify(o)}]`,"forbidden-key-name");oe(o,`${t}[key]`,r),oe(s,`${t}[${String(o)}]`,r)}return e}if(e instanceof Set){let o=0;for(let s of e.values())oe(s,`${t}[${o++}]`,r);return e}if(Array.isArray(e))return e.forEach((o,s)=>oe(o,`${t}[${s}]`,r)),e;for(let[o,s]of Object.entries(e)){if(Kt(o))throw new ge(`${t}.${o}`,"forbidden-key-name");oe(s,`${t}.${o}`,r,o)}return e}var ot=Object.freeze(["intent","quote_comparison","simulation","prepared","approval","signed","broadcast","settlement","balance_delta","position"]),Ri=Object.freeze(Object.fromEntries(ot.map((e,t)=>[e,Object.freeze(t+1<ot.length?[ot[t+1]]:[])])));function st(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(st).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${st(e[t])}`).join(",")}}`}function fo(e){return e===void 0?null:JSON.parse(JSON.stringify(e))}function it(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))it(t)}return e}function po(e,t="fact"){try{oe(e,t)}catch{throw new Error(`${t} contains custody material and is forbidden`)}}function ho(e){return uo("sha256").update(st(e)).digest("hex")}function mo({tradeId:e,state:t,fact:r,asOf:n,previousHash:o,external:s}){let i={tradeId:e,state:t,asOf:n,previousHash:o??null,external:s===!0,fact:fo(r)};return it({...i,hash:ho(i)})}function Yt({tradeId:e,intent:t,asOf:r=0}={}){if(!e||typeof e!="string")throw new Error("tradeId is required");if(!t||typeof t!="object"||Array.isArray(t))throw new Error("intent fact is required");po(t,"intent");let n=mo({tradeId:e,state:"intent",fact:t,asOf:r,previousHash:null,external:!1});return it({tradeId:e,state:"intent",events:[n],headHash:n.hash,custody:"none",execution:"prepare-only"})}function Jt(e,t={}){if(!e||typeof e!="object")throw new TypeError("signal required");if(e.noTrade===!0)throw new Error("NO_TRADE signal cannot open a trade lifecycle");if(e.executionAllowed===!0)throw new Error("executionAllowed must be false on public plane");let r=String(t.tradeId||`sig-${e.id||"unknown"}`).slice(0,128),n={source:"signal_score",signalId:e.id,signalType:e.type,score:e.score,confidence:e.confidence,flags:e.flags||[],promote:"research_only",execution:"prepare-only",custody:"none",note:"Cold signal \u2192 prepare intent only. Owner wallet must sign any later tx.",...t.intentExtra&&typeof t.intentExtra=="object"?t.intentExtra:{}},o=Yt({tradeId:r,intent:n,asOf:t.asOf??Date.now()});return{tradeId:r,intent:n,lifecycle:o,recommendation:"PREPARE_RESEARCH_ONLY"}}var Zt=1,at=5e3,go=Object.freeze({1:new Set(["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0xdac17f958d2ee523a2206206994597c13d831ec7","0x6b175474e89094c44da98b954eedeac495271d0f","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]),8453:new Set(["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","0x4200000000000000000000000000000000000006"]),42161:new Set(["0xaf88d065e77c8cc2239327c5edb3a432268e5831","0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9","0x82af49447d8a07e3bd95bd0d56f35241523fbab1"]),4663:new Set(["0x5fc5360d0400a0fd4f2af552add042d716f1d168"])}),wo=/^0x[0-9a-fA-F]{40}$/,xo=/^0x[0-9a-fA-F]{64}$/,So=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/,Eo=/^(?:0|[1-9]\d*)(?:\.\d+)?$/;function B(e,t){let r=String(e||"").trim();if(!wo.test(r))throw new TypeError(`${t} must be a 0x-prefixed EVM address`);return r.toLowerCase()}var Ao=(()=>{let e=new Map;for(let t of he){let r=Number(t?.chainId);if(!Number.isInteger(r)||r<=0)continue;let n=new Set;for(let o of Array.isArray(t.stableQuoteAssets)?t.stableQuoteAssets:[])try{n.add(B(o,"stableQuoteAsset"))}catch{}if(t.wrappedNative)try{n.add(B(t.wrappedNative,"wrappedNative"))}catch{}e.set(r,n)}return e})();function er(e,t){let r=Number(e);if(!Number.isInteger(r)||r<=0)return!1;let n;try{n=B(t,"token")}catch{return!1}let o=go[r];if(o&&o.has(n))return!0;let s=Ao.get(r);return!!(s&&s.has(n))}function we(e,t="usd"){let r=typeof e=="number"?String(e):e;if(typeof r!="string"||!So.test(r))throw new TypeError(`${t} must be a non-negative decimal string with at most 2 decimal places`);let[n,o=""]=r.split("."),s=(o+"00").slice(0,2);return BigInt(n)*100n+BigInt(s)}function ie(e){let t=BigInt(e);if(t<0n)throw new RangeError("centsToUsd: cents must be non-negative");let r=t/100n,n=t%100n;return`${r.toString()}.${n.toString().padStart(2,"0")}`}function vo({dailyCapUsd:e,spentTodayUsd:t,proportionalUsd:r=null}){let n=we(e,"dailyCapUsd"),o=we(t,"spentTodayUsd"),s=n-o;if(s<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"daily-cap-exhausted"};if(r==null)return{sizeCents:s,sizeUsd:ie(s),basis:"cap-only"};let i=we(r,"proportionalUsd");if(i<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"sized-to-zero"};let l=i<s?i:s;return{sizeCents:l,sizeUsd:ie(l),basis:l===s?"cap-limited":"proportional"}}function No({amount:e,decimals:t,poolPriceUsd:r}){let n=BigInt(e);if(n<0n)throw new RangeError("amount must be non-negative");let o=Number(t);if(!Number.isInteger(o)||o<0||o>77)throw new TypeError("decimals must be an integer 0..77");let s=typeof r=="number"?String(r):String(r??"").trim();if(!Eo.test(s))throw new TypeError("poolPriceUsd must be a non-negative decimal string");let[i,l=""]=s.split("."),a=BigInt(i+l),u=n*a*100n/10n**BigInt(o+l.length);return{usd:ie(u),estimated:!0,priced:"pool-estimate"}}function To(e,{estimated:t=!1,priced:r=null}={}){return`${t===!0||r==="pool-estimate"?"~":""}$${e}`}function Co(e=null){let t=new Map;async function r(n,o){let s;try{s=B(o,"address")}catch{return"unknown"}let i=`${Number(n)}:${s}`;if(t.has(i))return t.get(i);let l="unknown";if(typeof e=="function")try{let a=await e(Number(n),s);a===!0?l="contract":a===!1&&(l="eoa")}catch{l="unknown"}return l!=="unknown"&&t.set(i,l),l}return Object.freeze({resolve:r,cache:t})}function ko(e={}){let t=String(e.txHash||"").trim().toLowerCase();if(!xo.test(t))throw new TypeError("event.txHash must be a 32-byte tx hash");let r=B(e.token,"event.token"),n=B(e.from,"event.from"),o=B(e.to,"event.to"),s=e.txFrom==null?null:B(e.txFrom,"event.txFrom");return{txHash:t,token:r,from:n,to:o,txFrom:s,chainId:Number(e.chainId),blockNumber:Number.isFinite(Number(e.blockNumber))?Number(e.blockNumber):null,logIndex:Number.isFinite(Number(e.logIndex))?Number(e.logIndex):null,value:e.value==null?null:String(e.value),valueUsd:e.valueUsd==null?null:String(e.valueUsd),priced:e.priced==="pool-estimate"?"pool-estimate":"event",counterpartyKind:e.counterpartyKind==="contract"||e.counterpartyKind==="eoa"?e.counterpartyKind:"unknown"}}function Io(e,t){return e.to===t?e.from:e.from===t?e.to:null}function Oo(e,{followedWallet:t,counterpartyKind:r}={}){let n=B(t,"followedWallet");if(!e.txFrom)return{included:!1,reason:"tx-from-unknown"};if(e.txFrom!==n)return{included:!1,reason:"not-initiated-by-followed-wallet"};if(er(e.chainId,e.token))return{included:!1,reason:"quote-asset-transfer"};let o=e.to===n?"buy":e.from===n?"sell":null;if(!o)return{included:!1,reason:"wallet-not-a-party"};let s=r==="contract"||r==="eoa"?r:e.counterpartyKind==="contract"||e.counterpartyKind==="eoa"?e.counterpartyKind:"unknown";if(s==="contract")return{included:!0,side:o,origin:"curve",priced:"pool-estimate",counterpartyKind:s};if(s==="eoa")return{included:!1,reason:"eoa-transfer",origin:"transfer",counterpartyKind:s};let i=e.valueUsd!=null&&e.priced==="event"?"swap":"transfer";return{included:!0,side:o,origin:i,priced:e.priced==="pool-estimate"?"pool-estimate":"event",counterpartyKind:"unknown"}}function _o({chainId:e,txHash:t,noTrade:r}){return{id:`follow-mirror:${e}:${t}`,type:"wallet_mirror",score:r?0:1,confidence:r?0:1,noTrade:r,executionAllowed:!1,flags:r?["FOLLOW_MIRROR","NO_TRADE"]:["FOLLOW_MIRROR"]}}function Ie({chainId:e,txHash:t,token:r,side:n,sizeUsd:o,sizeBasis:s,followedWallet:i,origin:l="transfer",priced:a="event",refuseReason:u=null}={}){let c=_o({chainId:e,txHash:t,noTrade:u!=null}),h=a==="pool-estimate",d=To(o,{estimated:h});try{let f=Jt(c,{tradeId:`follow-mirror-${e}-${t}`,intentExtra:{source:"follow_mirror",chain:e,followedWallet:i,token:r,side:n,origin:l,priced:a,estimated:h,sizeUsd:o,sizeUsdDisplay:d,sizeBasis:s,txHash:t,executionAllowed:!1,backendSigner:!1,note:h?"Wallet-follow mirror of a launchpad-curve trade. USD size is a pool-price ESTIMATE (~). Cold, prepare-only. Owner wallet must sign any later tx.":"Wallet-follow mirror. Cold, prepare-only. Owner wallet must sign any later tx."}});return{ok:!0,requiresWalletSignature:!0,backendSigner:!1,executionAllowed:!1,tradeId:f.tradeId,chain:e,token:r,side:n,origin:l,priced:a,estimated:h,sizeUsd:o,sizeUsdDisplay:d,sizeBasis:s,txHash:t,followedWallet:i,recommendation:f.recommendation,lifecycle:f.lifecycle,intent:f.intent}}catch(f){return{ok:!1,reason:u||String(f?.message||f)}}}function $o(e,t,r){if(!r)return"unknown";let n=e[`${t}:${r}`]??e[r];return n==="contract"||n==="eoa"?n:"unknown"}function Ro(e=[],{followedWallet:t,dailyCapUsd:r,spentTodayUsd:n="0",seenTxHashes:o=new Set,honeypotResults:s={},counterpartyKinds:i={}}={}){if(!Array.isArray(e))throw new TypeError("rawEvents must be an array");let l=B(t,"followedWallet"),a=new Set(o),u=we(n,"spentTodayUsd"),c=we(r,"dailyCapUsd"),h=[],d=[],f=[];for(let p of e){let m;try{m=ko(p)}catch(N){f.push({txHash:p?.txHash??null,reason:`malformed-event: ${N.message}`});continue}if(a.has(m.txHash)){f.push({txHash:m.txHash,reason:"duplicate-tx"});continue}let x=Io(m,l),b=m.counterpartyKind!=="unknown"?m.counterpartyKind:$o(i,m.chainId,x),y=Oo(m,{followedWallet:l,counterpartyKind:b});if(!y.included){f.push({txHash:m.txHash,reason:y.reason});continue}let v={chainId:m.chainId,txHash:m.txHash,token:m.token,side:y.side,origin:y.origin,priced:y.priced,followedWallet:l},O=N=>({txHash:m.txHash,token:m.token,side:y.side,origin:y.origin,priced:y.priced,reason:N}),k=s[m.token];if(k?.flagged){a.add(m.txHash);let N=Ie({...v,sizeUsd:"0.00",sizeBasis:"refused",refuseReason:`token flagged: ${k.reason||"security check flagged this token"}`});d.push(O(N.reason));continue}if(c-u<=0n){a.add(m.txHash);let N=Ie({...v,sizeUsd:"0.00",sizeBasis:"refused",refuseReason:"daily-cap-exhausted"});d.push(O(N.reason));continue}let E=vo({dailyCapUsd:ie(c),spentTodayUsd:ie(u),proportionalUsd:m.valueUsd});if(E.sizeCents<=0n){a.add(m.txHash);let N=Ie({...v,sizeUsd:"0.00",sizeBasis:E.basis,refuseReason:E.basis});d.push(O(N.reason));continue}let T=Ie({...v,sizeUsd:E.sizeUsd,sizeBasis:E.basis});a.add(m.txHash),T.ok?(h.push(T),u+=E.sizeCents):d.push(O(T.reason))}return{intents:h,refusals:d,skipped:f,seenTxHashes:a,spentTodayUsd:ie(u)}}function ct(e=process.env){let t=e.ORACLE_CONFIG_DIR||Oe.join(bo.homedir(),".config","oracle");return Oe.join(t,"follow-mirror.json")}function Qt(){return{version:Zt,targets:{}}}function Xt(e,t){return`${String(e).toLowerCase()}:${B(t,"address")}`}function _e(e){try{let t=se.readFileSync(e,"utf8"),r=JSON.parse(t);return!r||typeof r!="object"||r.version!==Zt||!r.targets||typeof r.targets!="object"?Qt():r}catch{return Qt()}}function Lo(e,t){let r=Oe.dirname(e);se.mkdirSync(r,{recursive:!0,mode:448});let n=Oe.join(r,`.follow-mirror.${process.pid}.${Date.now()}.${yo()}.tmp`);try{se.writeFileSync(n,`${JSON.stringify(t)}
5
- `,{mode:384,flag:"wx"}),se.renameSync(n,e);try{se.chmodSync(e,384)}catch{}}catch(o){try{se.unlinkSync(n)}catch{}throw o}}function Uo(e){return new Date(e).toISOString().slice(0,10)}function Fo(e,t,r){let n=e.targets[t],o=new Set(Array.isArray(n?.seenTxHashes)?n.seenTxHashes:[]),s=typeof n?.days?.[r]=="string"?n.days[r]:"0";return{seenTxHashes:o,spentTodayUsd:s}}function Po(e,t,{seenTxHashes:r,spentTodayUsd:n,day:o,newIntents:s,newRefusals:i}){let l=e.targets[t]||{seenTxHashes:[],days:{},intents:[],refusals:[]},a=[...r].slice(-at),u=[...l.intents||[],...s].slice(-at),c=[...l.refusals||[],...i].slice(-at);e.targets[t]={seenTxHashes:a,days:{...l.days||{},[o]:n},intents:u,refusals:c}}function lt({now:e=()=>Date.now(),fetchWallet:t,fetchTxFrom:r,checkHoneypot:n,estimateUsdValue:o=async()=>null,isContract:s=null,poolPriceUsd:i=async()=>null,tokenDecimals:l=async()=>18,storePath:a=ct()}={}){if(typeof t!="function")throw new TypeError("createFollowMirror requires fetchWallet");if(typeof r!="function")throw new TypeError("createFollowMirror requires fetchTxFrom");if(typeof n!="function")throw new TypeError("createFollowMirror requires checkHoneypot");let u=Co(s);async function c({address:d,chain:f,chainId:p,dailyCapUsd:m,lookback:x}={}){let b=B(d,"address"),y=Number(p);if(!Number.isInteger(y)||y<=0)throw new TypeError("observe requires a numeric chainId");let v=e(),O=Uo(v),k=Xt(f||y,b),R=_e(a),{seenTxHashes:E,spentTodayUsd:T}=Fo(R,k,O),N=await t(b,{chains:[y],lookback:x}),L=Array.isArray(N?.events)?N.events:[],w=[],I={},q=new Set,$={};for(let C of L){let U=null;try{U=await r(y,C.txHash)}catch{U=null}let g=null,A="event";try{g=await o({...C,chainId:y,txFrom:U})}catch{g=null}let S=String(C.token||"").toLowerCase(),J=String(C.from||"").toLowerCase(),D=String(C.to||"").toLowerCase(),j="unknown";if(U===b&&!er(y,S)&&S){let K=D===b?J:J===b?D:null;if(K&&(j=await u.resolve(y,K),$[`${y}:${K}`]=j),j==="contract"&&g==null&&C.value!=null)try{let Q=await i(y,S);if(Q!=null){let Le=await l(y,S);g=No({amount:C.value,decimals:Le??18,poolPriceUsd:Q}).usd,A="pool-estimate"}}catch{g=null}else j==="contract"&&(A="pool-estimate");if(!q.has(S)){q.add(S);try{I[S]=await n(y,S)}catch(Q){I[S]={flagged:!0,reason:`security check unavailable: ${String(Q?.message||Q).slice(0,160)}`}}}}w.push({...C,chainId:y,txFrom:U,valueUsd:g,priced:A,counterpartyKind:j})}let P=Ro(w,{followedWallet:b,dailyCapUsd:String(m),spentTodayUsd:T,seenTxHashes:E,honeypotResults:I,counterpartyKinds:$});return Po(R,k,{seenTxHashes:P.seenTxHashes,spentTodayUsd:P.spentTodayUsd,day:O,newIntents:P.intents.map(C=>({tradeId:C.tradeId,txHash:C.txHash,token:C.token,side:C.side,origin:C.origin,priced:C.priced,sizeUsd:C.sizeUsd,sizeUsdDisplay:C.sizeUsdDisplay,createdAt:v})),newRefusals:P.refusals.map(C=>({...C,createdAt:v}))}),Lo(a,R),{ok:!0,cold:!0,executionAllowed:!1,chain:f||y,chainId:y,address:b,observed:L.length,intents:P.intents,refusals:P.refusals,skipped:P.skipped,spentTodayUsd:P.spentTodayUsd,dailyCapUsd:String(m),errors:N?.errors||[]}}function h({address:d,chain:f}={}){let p=B(d,"address"),m=_e(a),x=Xt(f,p),b=m.targets[x]||{intents:[],refusals:[],days:{}};return{ok:!0,address:p,chain:f,intents:b.intents||[],refusals:b.refusals||[],days:b.days||{}}}return Object.freeze({observe:c,status:h,storePath:a})}import xe from"node:fs";import Bo from"node:os";import Re from"node:path";import{randomUUID as Do}from"node:crypto";var sr=1,tr=500,rr=Object.freeze(["tap","cli","signal"]),jo=/^0x[0-9a-fA-F]{40}$/,qo=64;function ir(e=process.env){let t=e.ORACLE_CONFIG_DIR||Re.join(Bo.homedir(),".config","oracle");return Re.join(t,"follow-list.json")}function $e(e){let t=String(e||"").trim();if(!jo.test(t))throw new TypeError("address must be a 0x-prefixed 40-hex EVM address");return t.toLowerCase()}function nr(e){return e==null?null:String(e).replace(/[\u0000-\u001f\u007f]/g,"").trim().slice(0,qo)||null}function or(){return{version:sr,entries:{}}}function Ho(e){try{let t=JSON.parse(xe.readFileSync(e,"utf8"));return!t||t.version!==sr||!t.entries||typeof t.entries!="object"?or():t}catch{return or()}}function ut(e,t){let r=Re.dirname(e);xe.mkdirSync(r,{recursive:!0,mode:448});let n=Re.join(r,`.follow-list.${process.pid}.${Date.now()}.${Do()}.tmp`);try{xe.writeFileSync(n,`${JSON.stringify(t)}
4
+ ${JSON.stringify(r??[])}`}async function Zr(e,t,r){return fe(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function ee(e,t,r=[],n={}){let o=String(t||""),s=Yr(o),i=Gr(e,n);if(!i)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);if(s==="eth_chainid"&&n.cacheChainId!==!1){let c=Tt.get(i);if(c!=null)return c}let a=n.dedupe!==!1&&!n.signal?Xr(i,o,r):null;if(a&&pe.has(a))return pe.get(a);let u=(async()=>{let c=await Zr(i,{jsonrpc:"2.0",id:1,method:t,params:r},n),h=Qr(c);return s==="eth_chainid"&&typeof h=="string"&&Tt.set(i,h),h})();return a&&(pe.set(a,u),u.finally(()=>{pe.get(a)===u&&pe.delete(a)}).catch(()=>{})),u}var Ss=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});var As=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),We=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Ge=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var he=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",stableQuoteAssets:["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","0xdAC17F958D2ee523a2206206994597C13D831ec7"],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",stableQuoteAssets:["0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85","0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"],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",stableQuoteAssets:["0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d","0x55d398326f99059fF775485246999027B3197955"],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",stableQuoteAssets:["0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359","0xc2132D05D31c914a87C6611C10748AEb04B58e8F"],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",stableQuoteAssets:["0x5fc5360d0400a0fd4f2af552add042d716f1d168"],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",stableQuoteAssets:["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],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",stableQuoteAssets:["0xaf88d065e77c8cC2239327C5EDb3A432268e5831","0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"],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",stableQuoteAssets:["0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"],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 H="unknown",Ct=/^0x[0-9a-fA-F]{64}$/,Te=/^0x[0-9a-fA-F]{40}$/;function Ne(e){if(e==null)return null;try{return BigInt(e)}catch{return null}}function kt(e,{timeoutMs:t=2e4,fetchImpl:r=globalThis.fetch}={}){return async function(o,s=[]){let i=new AbortController,l=setTimeout(()=>i.abort(),t);try{let u=await(await r(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:o,params:s}),signal:i.signal})).json();if(u.error)throw new Error(`${o} rpc: ${u.error.message||"rpc error"}`);return u.result}finally{clearTimeout(l)}}}async function tn(e,t){let r={txHash:e,txFrom:null,txTo:null,nativeValueWei:H,gasWei:H,gasUsed:H,effectiveGasPrice:H,status:H,error:null},n=[];try{let o=await t("eth_getTransactionByHash",[e]);if(o){let s=Ne(o.value);s!=null&&(r.nativeValueWei=s.toString()),typeof o.from=="string"&&Te.test(o.from)&&(r.txFrom=o.from.toLowerCase()),typeof o.to=="string"&&Te.test(o.to)&&(r.txTo=o.to.toLowerCase())}else n.push("eth_getTransactionByHash: null (not found / pruned)")}catch(o){n.push(`eth_getTransactionByHash: ${o?.message||o}`)}try{let o=await t("eth_getTransactionReceipt",[e]);if(o){let s=Ne(o.gasUsed),i=Ne(o.effectiveGasPrice??o.gasPrice);if(s!=null&&(r.gasUsed=s.toString()),i!=null&&(r.effectiveGasPrice=i.toString()),s!=null&&i!=null&&(r.gasWei=(s*i).toString()),o.status!=null){let l=Ne(o.status);r.status=l==null?H:l===1n?"success":"reverted"}!r.txFrom&&typeof o.from=="string"&&Te.test(o.from)&&(r.txFrom=o.from.toLowerCase())}else n.push("eth_getTransactionReceipt: null (pending / pruned)")}catch(o){n.push(`eth_getTransactionReceipt: ${o?.message||o}`)}return n.length&&(r.error=n.join("; ")),r}async function Ke(e,t={}){let{rpc:r,concurrency:n=4,cap:o=200,cache:s=new Map,wallet:i}=t;if(typeof r!="function")throw new TypeError("enrichNativeLeg: opts.rpc(method, params) is required");if(!Array.isArray(e))throw new TypeError("enrichNativeLeg: events must be an array");let l=typeof i=="string"&&Te.test(i)?i.toLowerCase():null,a=[],u=[],c=new Set;for(let b of e){let y=String(b?.txHash||"").toLowerCase();!Ct.test(y)||c.has(y)||(c.add(y),u.push(y))}let h=u.filter(b=>!s.has(b)),d=Math.max(0,h.length-o),f=h.slice(0,o);for(let b of h.slice(o))a.push({txHash:b,stage:"cap",error:`per-call cap ${o} exceeded`});let p=0,m=Array.from({length:Math.max(1,Math.min(n,f.length))},async()=>{for(;p<f.length;){let b=f[p++];try{let y=await tn(b,r);s.set(b,y),y.error&&a.push({txHash:b,stage:"nativeLeg",error:y.error})}catch(y){let v={txHash:b,nativeValueWei:H,gasWei:H,error:String(y?.message||y)};s.set(b,v),a.push({txHash:b,stage:"nativeLeg",error:v.error})}}});return await Promise.all(m),{events:e.map(b=>{let y=String(b?.txHash||"").toLowerCase(),v=s.get(y);if(!v){let k=Ct.test(y)?`per-call cap ${o} exceeded`:"invalid txHash";return{...b,nativeValueWei:H,gasWei:H,nativeLeg:{error:k}}}let I={...b,txFrom:b.txFrom??v.txFrom??null,nativeValueWei:v.nativeValueWei,gasWei:v.gasWei,nativeLeg:v.error?{...v,error:v.error}:{...v,error:null}};return l&&String(b.from||"").toLowerCase()===l&&(I.nativeReceived=H),I}),errors:a,looked:f.length,capped:d}}var Ot="0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",Rt=Object.freeze({1:Object.freeze(["https://mainnet.gateway.tenderly.co","https://eth.drpc.org","https://rpc.flashbots.net"]),8453:Object.freeze(["https://base.gateway.tenderly.co","https://mainnet.base.org","https://base.drpc.org"]),42161:Object.freeze(["https://arbitrum.gateway.tenderly.co","https://arb1.arbitrum.io/rpc","https://arbitrum.drpc.org"]),4663:Object.freeze(["https://rpc.mainnet.chain.robinhood.com"])}),rn=/publicnode/i;function It(e){return rn.test(String(e||""))}var nn=e=>typeof e=="string"&&/^https:\/\//.test(e),Je=new Map(he.filter(e=>Number.isInteger(Number(e?.chainId))&&Number(e.chainId)>0).map(e=>[Number(e.chainId),e]));function on(){return[...new Set([...Je.keys(),...Object.keys(Rt).map(Number)])].sort((t,r)=>t-r)}function Lt(e,{env:t=null,curated:r=Rt,fallbacks:n=Ve}={}){let o=Number(e),s=[],i=[],l=(d,f)=>{!nn(d)||s.includes(d)||(s.push(d),i.push(f))};if(t&&typeof t=="object"){let d=Je.get(o);for(let f of Array.isArray(d?.rpcEnv)?d.rpcEnv:[]){let p=String(t[f]||"").trim();p&&l(p,`env:${f}`)}}let a=r?.[o],u=Array.isArray(a)&&a.length>0;if(u)for(let d of a)l(d,"curated");let c=n?.[o];c&&!(u&&It(c))&&l(c,"public-fallback");let h=s.length>0&&s.every(It);return{chainId:o,urls:s,curated:u,shallow:h,source:i}}var me=Object.freeze(Object.fromEntries(on().map(e=>[e,Object.freeze(Lt(e).urls)]).filter(([,e])=>e.length>0)));function sn(e=me){return Object.keys(e).map(Number).filter(t=>Number.isInteger(t)&&t>0&&e[t]?.length).sort((t,r)=>t-r)}var an=1e4,cn=e=>new Promise(t=>setTimeout(t,e)),_t=e=>"0x"+BigInt(e).toString(16),ln=e=>"0x"+"0".repeat(24)+e.slice(2).toLowerCase(),$t=e=>"0x"+e.slice(26).toLowerCase(),un=/timeout|timed out|too many requests|rate.?limit|429|502|503|504|internal error|temporarily|aborted|fetch failed|ECONNRESET|socket hang up/i,dn=/too many|exceeds|limited to|not supported on free plan|response too large|range must not exceed|narrow your filter/i,te=class extends Error{constructor(t,{transient:r=!1,tooBig:n=!1,http:o=0}={}){super(t),this.transient=r,this.tooBig=n,this.http=o}};async function fn(e,t,r,n){let o=new AbortController,s=setTimeout(()=>o.abort(),n),i,l;try{i=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:t,params:r}),signal:o.signal}),l=await i.text()}catch(u){throw new te(`${t} network: ${u.message}`,{transient:!0})}finally{clearTimeout(s)}let a;try{a=JSON.parse(l)}catch{throw new te(`${t} non-JSON http=${i.status}: ${l.slice(0,80)}`,{transient:i.status>=500||i.status===429,http:i.status})}if(a.error){let u=a.error.message||"rpc error";throw new te(`${t} rpc: ${u}`,{transient:un.test(u),tooBig:dn.test(u),http:i.status})}if(i.status!==200)throw new te(`${t} http=${i.status}: ${l.slice(0,80)}`,{transient:i.status>=500||i.status===429,http:i.status});return a.result}async function Ut(e,t,r,{retries:n,timeoutMs:o,onWarn:s}){let i;for(let l of e){for(let a=0;a<=n;a++)try{return{result:await fn(l,t,r,o),url:l}}catch(u){if(i=u,u.tooBig)throw u;if(!u.transient||a===n)break;let c=Math.min(2e3*2**a,8e3)+Math.random()*250;s?.(`retry ${l} (${u.message.slice(0,70)}) in ${Math.round(c)}ms`),await cn(c)}s?.(`endpoint exhausted: ${l} -> ${i?.message.slice(0,70)}`)}throw i??new te("no endpoints available")}async function Ye(e,t,r,n,o,s){let i=[{...t,fromBlock:_t(r),toBlock:_t(n)}];try{let{result:a}=await Ut(e,"eth_getLogs",i,o);Array.isArray(a)&&s.push(...a);return}catch(a){if(!a.tooBig||n<=r)throw a;o.onWarn?.(`splitting ${r}-${n} (${a.message.slice(0,60)})`)}let l=r+Math.floor((n-r)/2);await Promise.all([Ye(e,t,r,l,o,s),Ye(e,t,l+1,n,o,s)])}async function Qe(e,t={}){if(!/^0x[0-9a-fA-F]{40}$/.test(e||""))throw new Error(`invalid address: ${e}`);let{chains:r=sn(t.endpoints??me),lookback:n=1e5,fromBlock:o,toBlock:s,chunkSize:i=an,tokens:l,direction:a="both",retries:u=3,timeoutMs:c=2e4,concurrency:h=4,endpoints:d=null,env:f=process.env,onWarn:p}=t,m={retries:u,timeoutMs:c,onWarn:p},x=ln(e),b=[],y=[],v={},I=new Set;return await Promise.all(r.map(async k=>{let R,E=!1;if(d&&typeof d=="object")R=d[k];else{let T=Lt(k,{env:f});R=T.urls,E=T.shallow}if(!R?.length){y.push({chainId:k,stage:"config",error:"no endpoints configured"});return}E&&p?.(`chain ${k}: only shallow (~128 block) public endpoints; deep lookback will fail \u2014 set ${(Je.get(Number(k))?.rpcEnv||[]).join("/")||"an archive RPC"} for archive depth`);try{let T=s;if(T==null){let{result:g}=await Ut(R,"eth_blockNumber",[],m);T=parseInt(g,16)}let N=Math.max(0,o??T-n+1),L=Math.max(N,T);v[k]={fromBlock:N,toBlock:L,blocks:L-N+1,shallow:E};let w=[];for(let g=N;g<=L;g+=i)w.push([g,Math.min(g+i-1,L)]);let O=[],q=l?.length?{address:l}:{};(a==="in"||a==="both")&&O.push({...q,topics:[Ot,null,x]}),(a==="out"||a==="both")&&O.push({...q,topics:[Ot,x,null]});let $=[];for(let g of O)for(let A of w)$.push([g,A]);let F=[],C=0,U=Array.from({length:Math.min(h,$.length)},async()=>{for(;C<$.length;){let[g,[A,S]]=$[C++];try{await Ye(R,g,A,S,m,F)}catch(J){y.push({chainId:k,stage:"getLogs",range:[A,S],error:J.message})}}});await Promise.all(U);for(let g of F){if(!g?.topics||g.topics.length<3)continue;let A=parseInt(g.logIndex,16),S=`${k}|${g.transactionHash}|${A}`;I.has(S)||(I.add(S),b.push({chainId:k,token:g.address.toLowerCase(),from:$t(g.topics[1]),to:$t(g.topics[2]),value:BigInt(g.data==="0x"?"0x0":g.data).toString(),blockNumber:parseInt(g.blockNumber,16),txHash:g.transactionHash,logIndex:A}))}}catch(T){y.push({chainId:k,stage:"range",error:T.message})}})),b.sort((k,R)=>R.blockNumber-k.blockNumber||R.logIndex-k.logIndex),{events:b,errors:y,ranges:v}}import{keccak_256 as Xe}from"@noble/hashes/sha3.js";var et=999,Ze=1,pn=8453,Pt="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",hn="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",Ft="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",mn="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",bn=".80002105.reverse",tt=/^0x[a-fA-F0-9]{40}$/,Bt=new TextEncoder,Dt=e=>"0x"+Buffer.from(e).toString("hex"),re=e=>Dt(Xe(Bt.encode(e))).slice(0,10),jt=e=>e.toLowerCase().replace(/^0x/,"").padStart(64,"0");function Ce(e){let t=new Uint8Array(32);if(e)for(let r of String(e).split(".").reverse()){let n=Xe(Bt.encode(r)),o=new Uint8Array(64);o.set(t,0),o.set(n,32),t=Xe(o)}return Dt(t)}function rt(e){if(!e||e==="0x"||/^0x0*$/.test(e))return"";try{let t=e.slice(2),r=parseInt(t.slice(0,64),16)*2,n=parseInt(t.slice(r,r+64),16);if(!Number.isFinite(n)||n<=0)return"";let o=t.slice(r+64,r+64+n*2);return Buffer.from(o,"hex").toString("utf8")}catch{return""}}async function ne(e,t,r){try{return await ee(e,"eth_call",[{to:t,data:r},"latest"])}catch{return null}}async function yn(e){let t=await ne(et,Pt,re("primaryName(address)")+jt(e)),r=rt(t);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function gn(e){let t=await ne(et,hn,re("getName(address)")+jt(e)),r=rt(t);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function qt(e,t,r){let n=await ne(e,r,re("name(bytes32)")+t.slice(2));return rt(n)||null}async function wn(e){let t=Ce(`${e.slice(2).toLowerCase()}.addr.reverse`),r=await ne(Ze,Ft,re("resolver(bytes32)")+t.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:qt(Ze,t,n)}async function xn(e){let t=Ce(e.slice(2).toLowerCase()+bn);return qt(pn,t,mn)}var Sn=[{source:"hl",fn:yn},{source:"hype",fn:gn},{source:"ens",fn:wn},{source:"basename",fn:xn}];async function En(e){let t=Ce(e),r=await ne(et,Pt,re("ownerOf(uint256)")+t.slice(2));if(!r||r.length<66)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:n}async function An(e,t,r){let n=Ce(t),o=await ne(e,r,re("resolver(bytes32)")+n.slice(2));if(!o)return null;let s="0x"+o.slice(-40);if(/^0x0+$/.test(s))return null;let i=await ne(e,s,re("addr(bytes32)")+n.slice(2));if(!i)return null;let l="0x"+i.slice(-40);return/^0x0+$/.test(l)?null:l}async function Ht(e){let t=String(e||"").trim().toLowerCase();if(!t||!t.includes("."))return null;if(t.endsWith(".hl")){let r=await En(t);return r?{address:r,source:"hl",name:t}:null}if(t.endsWith(".eth")){let r=await An(Ze,t,Ft);return r?{address:r,source:t.endsWith(".base.eth")?"basename":"ens",name:t}:null}return null}var li=Sn.map(e=>e.source);var vn="protective-monitors",Nn="read-only",fi=Object.freeze(["depeg","oracleDeviation","exploitFeed","goplus","liquidationLadder"]),Tn="https://hermes.pyth.network",Cn="https://coins.llama.fi",kn="https://api.llama.fi/hacks",On="https://api.gopluslabs.io/api/v1/token_security",In="https://api.v3.aave.com/user",_n=Object.freeze({USDT:"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",USDC:"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"}),$n=Object.freeze({USDT:"coingecko:tether",USDC:"coingecko:usd-coin",DAI:"coingecko:dai"}),Rn=Object.freeze(["is_honeypot","is_proxy","is_mintable","owner_change_balance","hidden_owner","selfdestruct","cannot_buy","cannot_sell_all","is_blacklisted"]),Mt=Object.freeze({liquidatable:0,danger:1,critical:2,warning:3,healthy:4}),Ln=/^0x[0-9a-fA-F]{40}$/,Un=/^[0-9a-fA-F]{64}$/;function be(e,t={}){return{ok:!0,provider:vn,op:e,alertOnly:!0,execution:Nn,exec:!1,...t}}function P(e,t){throw new Error(`protective-monitors: ${e}${t?` ${t}`:""}`)}async function ye(e,t={}){return typeof t.http=="function"?t.http(e,t):typeof t.httpJson=="function"?t.httpJson(e,t):fe(e,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3,retries:t.retries??0})}function ke(e){return String(e||"USDT").trim().toUpperCase().replace(/\/USD$/,"")}function Pn(e={}){if(e.feedId){let n=String(e.feedId).replace(/^0x/i,"");return Un.test(n)||P("feedId must be a 32-byte hex id"),n.toLowerCase()}let t=ke(e.symbol),r=_n[t];return r||P("unknown symbol",t),r}function Fn(e={}){if(e.llamaCoin)return String(e.llamaCoin);let t=ke(e.symbol);return $n[t]||`coingecko:${t.toLowerCase()}`}function zt(e,t){let r=Number(e.thresholdBps??t);return(!Number.isFinite(r)||r<0)&&P("thresholdBps must be a non-negative number"),r}function Bn(e){let t=Array.isArray(e?.parsed)?e.parsed[0]:e?.price?e:null,r=Number(t?.price?.price),n=Number(t?.price?.expo);return(!Number.isFinite(r)||!Number.isFinite(n))&&P("no pyth price returned"),n<0?r/10**-n:r*10**n}function Dn(e,t){let r=e?.coins?.[t]||e?.coins?.[String(t).toLowerCase()],n=Number(r?.price);return Number.isFinite(n)?n:null}function jn(e,t={}){let r=String(t.pythBaseUrl||Tn).replace(/\/$/,""),n=new URL(`${r}/v2/updates/price/latest`);return n.searchParams.append("ids[]",e),n.searchParams.set("parsed","true"),n.toString()}function qn(e,t={}){return`${String(t.llamaCoinsBaseUrl||Cn).replace(/\/$/,"")}/prices/current/${encodeURIComponent(e)}`}async function Vt(e,t){let r=Pn(e),n=await ye(jn(r,t),t),o=Bn(n);return o>0||P("pyth price must be positive"),{id:r,price:o}}async function Wt(e,t){let r=Fn(e),n=await ye(qn(r,t),t);return{coin:r,price:Dn(n,r)}}async function Hn(e={},t={}){let r=Number(e.peg??1);(!Number.isFinite(r)||r<=0)&&P("peg must be a positive number");let n=zt(e,50),o=await Vt(e,t),s=Math.round(Math.abs(o.price-r)*1e4),i={required:!1,llamaPrice:null};try{let l=await Wt(e,t);i={required:!1,llamaPrice:l.price,llamaCoin:l.coin}}catch{i={required:!1,llamaPrice:null}}return be("depeg",{symbol:ke(e.symbol),feedId:o.id,price:o.price,peg:r,thresholdBps:n,deviationBps:s,alert:s>n,crossCheck:i})}async function Mn(e={},t={}){let r=zt(e,100),n=await Vt(e,t),o=await Wt(e,t);o.price>0||P("llama price required for oracleDeviation");let s=(n.price+o.price)/2,i=Math.round(Math.abs(n.price-o.price)/s*1e4);return be("oracleDeviation",{symbol:ke(e.symbol),pythPrice:n.price,llamaPrice:o.price,mid:s,thresholdBps:r,deviationBps:i,alert:i>r})}function zn(e,t){return String(e.id||e.defillamaId||e.slug||`hack-${t}`)}function Vn(e,t){return{id:zn(e,t),name:String(e.name||e.protocol||"unknown"),classification:e.classification?String(e.classification):null,technique:e.technique?String(e.technique):null,amount:Number.isFinite(Number(e.amount))?Number(e.amount):null,chain:Array.isArray(e.chain)?e.chain.map(String):e.chain?[String(e.chain)]:[],source:e.source?String(e.source):null}}function Wn(e){return(String(e).match(/<item\b[\s\S]*?<\/item>/gi)||[]).map((r,n)=>{let o=s=>{let i=r.match(new RegExp(`<${s}[^>]*>([\\s\\S]*?)</${s}>`,"i"));return i?i[1].replace(/<!\[CDATA\[|\]\]>/g,"").trim():""};return{id:o("guid")||o("link")||o("title")||`rss-${n}`,name:o("title")||"unknown",classification:"rss",technique:null,amount:null,chain:[],source:o("link")||null}})}function Gt(e){if(typeof e=="string"){let t=e.trim();if(t.startsWith("<"))return Wn(t);try{return Gt(JSON.parse(t))}catch{P("exploitFeed payload is not JSON or RSS")}}return Array.isArray(e)?e:Array.isArray(e?.hacks)?e.hacks:Array.isArray(e?.items)?e.items:[]}function Gn(e){return e.map((t,r)=>({item:t,index:r})).sort((t,r)=>{let n=String(t.item.id).localeCompare(String(r.item.id));return n!==0?n:t.index-r.index}).map(t=>t.item)}async function Kn(e={},t={}){let r=kn,n=e.payload??await ye(r,t),o=Gn(Gt(n).map(Vn));return be("exploitFeed",{count:o.length,fingerprint:o.map(s=>s.id).join("|"),items:o,alert:o.length>0})}function Yn(e){return e===!0||e===1||e==="1"}function Jn(e,t){let r=e?.result&&typeof e.result=="object"?e.result:e,n=String(t).toLowerCase();if(r&&typeof r=="object"){for(let[o,s]of Object.entries(r))if(String(o).toLowerCase()===n&&s&&typeof s=="object")return{address:o,token:s}}return null}async function nt(e={},t={}){e.asSoleGate===!0&&P("goplus is a second opinion and must never be a sole gate");let r=String(e.address||e.token||"").trim();Ln.test(r)||P("goplus requires an EVM token address");let n=Number(e.chainId??1);(!Number.isInteger(n)||n<=0)&&P("chainId must be a positive integer");let s=`${String(t.goplusBaseUrl||On).replace(/\/$/,"")}/${n}?contract_addresses=${r}`,i=e.payload??await ye(s,t),l=Jn(i,r);l||P("goplus returned no result for",r);let a=Rn.filter(u=>Yn(l.token[u]));return be("goplus",{chainId:n,address:r.toLowerCase(),role:"second-opinion",secondOpinion:!0,soleGate:!1,neverSoleGate:!0,token:{address:l.address,name:l.token.token_name||null,symbol:l.token.token_symbol||null},findings:a,alert:a.length>0,note:"second opinion only \u2014 never the sole gate"})}function Qn(e){let t=Number(e);return(!Number.isFinite(t)||t<0)&&P("healthFactor must be a non-negative number"),t<1?"liquidatable":t<1.05?"danger":t<1.2?"critical":t<1.5?"warning":"healthy"}function Xn(e,t){let r=Number(e.healthFactor??e.hf);Number.isFinite(r)||P("position healthFactor required");let n=Qn(r);return{id:String(e.id||e.protocol||`pos-${t}`),protocol:String(e.protocol||"unknown"),healthFactor:r,collateralUsd:e.collateralUsd!=null?Number(e.collateralUsd):null,debtUsd:e.debtUsd!=null?Number(e.debtUsd):null,rung:n}}async function Zn(e={},t={}){let r=null;if(Array.isArray(e.positions))r=e;else if(Array.isArray(e))r={positions:e};else{let i=String(e.user||"").trim();i||P("liquidationLadder requires user or positions");let l=String(t.aaveUrl||`${In}/${i}`);r=await ye(l,t)}let o=(Array.isArray(r?.positions)?r.positions:[]).map(Xn),s=o.reduce((i,l)=>i?Mt[l.rung]<Mt[i]?l.rung:i:l.rung,null);return be("liquidationLadder",{user:r?.user||e.user||null,chainId:r?.chainId??e.chainId??null,ladder:o,worstRung:s,alert:o.some(i=>i.rung!=="healthy")})}var pi=Object.freeze({depeg:Hn,oracleDeviation:Mn,exploitFeed:Kn,goplus:nt,liquidationLadder:Zn});import se from"node:fs";import bo from"node:os";import Ie from"node:path";import{randomUUID as yo}from"node:crypto";var mi=Object.freeze(["wallet","pool","nft_floor","hl_flow","prediction_market"]),bi=Object.freeze({wallets:"wallet",smart_wallet:"wallet",pools:"pool",new_pool:"pool",nft:"nft_floor",nft_floors:"nft_floor",hyperliquid:"hl_flow",prediction:"prediction_market",prediction_markets:"prediction_market"}),V=(e,t=0,r=1)=>Math.min(r,Math.max(t,e)),M=e=>Number.isFinite(Number(e))?Number(e):null,eo=e=>Math.round(e*1e4)/1e4;function z(e,t,r,n=!0){!n||r===null||!Number.isFinite(r)||e.push({feature:t,value:eo(r)})}function to(e,t){let r=M(e.repeatBuys??e.repeat_buys??e.buyCount),n=M(e.walletWinRate??e.winRate);z(t,"repeat_buys",r===null?null:V((r-1)/4)*.38),z(t,"wallet_win_rate",n===null?null:(V(n)-.5)*.5)}function ro(e,t){let r=M(e.ageHours??e.poolAgeHours),n=M(e.liquidityUsd??e.liquidity),o=e.liquidityLocked??e.locked;z(t,"pool_age",r===null?null:r<24?-.42:V(r/720)*.12),z(t,"liquidity",n===null?null:(V(Math.log10(Math.max(1,n))/7)-.5)*.28),z(t,"liquidity_lock",o==null?null:o?.12:-.28)}function no(e,t){let r=M(e.floorChange??e.floorChangePct),n=M(e.sales??e.saleCount);z(t,"floor_change",r===null?null:V(r,-1,1)*.35),z(t,"sales_depth",n===null?null:V(n/50)*.18)}function oo(e,t){let r=M(e.flowImbalance??e.imbalance),n=M(e.fundingRate??e.funding);z(t,"flow_imbalance",r===null?null:V(r,-1,1)*.42),z(t,"funding",n===null?null:-V(n*100,-1,1)*.12)}function so(e,t){let r=M(e.marketProbability??e.marketPrice??e.probability),n=M(e.fairProbability??e.referenceProbability??e.fairValue);z(t,"probability_mispricing",r===null||n===null?null:V(n-r,-1,1)*.65);let o=M(e.liquidityUsd??e.liquidity);z(t,"market_liquidity",o===null?null:V(Math.log10(Math.max(1,o))/6)*.12)}var yi=Object.freeze({wallet:to,pool:ro,nft_floor:no,hl_flow:oo,prediction_market:so});import{createHash as uo}from"node:crypto";var wi=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),xi=Object.freeze(["read","simulate"]);var Si=1440*60;var ge=class extends Error{constructor(t,r){super(`secret material must never appear in a public API object (at ${t}, rule: ${r})`),this.name="SecretLeakError",this.path=t,this.rule=r}},io=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,ao=Object.freeze(["privkey","wif","xprv","seed"]);function Kt(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return io.test(t)||ao.includes(r)}var co=Object.freeze([{rule:"raw-32-byte-hex-key",re:/^0x[0-9a-fA-F]{64}$/},{rule:"raw-32-byte-hex-bare",re:/^[0-9a-fA-F]{64}$/},{rule:"extended-private-key",re:/\b(?:xprv|tprv|yprv|zprv)[1-9A-HJ-NP-Za-km-z]{107}\b/},{rule:"bitcoin-wif",re:/\b[59KLc][1-9A-HJ-NP-Za-km-z]{50,51}\b/},{rule:"bip39-mnemonic",re:/\b(?:[a-z]{3,8}\s+){11,23}[a-z]{3,8}\b/},{rule:"bearer-token",re:/bearer\s+[A-Za-z0-9._~+/=-]+/i},{rule:"pem-private-key",re:/-----BEGIN[A-Z ]*PRIVATE KEY-----/},{rule:"keystore-path",re:/keystore/i},{rule:"signer-url",re:/https?:\/\/\S*sign/i},{rule:"authorization-header",re:/authorization\s*:/i}]),lo=Object.freeze(["grantid","id","hash","sha256","sha256hex","checksum","txhash","transactionhash","blockhash","digest","userophash","commithash","prevhash","intenthash","canonicalhash","payloadhash","requestid"]);function oe(e,t="$",r=new Set,n=""){if(e==null)return e;if(typeof e=="string"){let o=lo.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:s,re:i}of co)if(!(o&&s.startsWith("raw-32-byte-hex"))&&i.test(e))throw new ge(t,s);return e}if(typeof e!="object"||r.has(e)||(r.add(e),ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e;if(e instanceof Map){for(let[o,s]of e.entries()){if(typeof o=="string"&&Kt(o))throw new ge(`${t}[${JSON.stringify(o)}]`,"forbidden-key-name");oe(o,`${t}[key]`,r),oe(s,`${t}[${String(o)}]`,r)}return e}if(e instanceof Set){let o=0;for(let s of e.values())oe(s,`${t}[${o++}]`,r);return e}if(Array.isArray(e))return e.forEach((o,s)=>oe(o,`${t}[${s}]`,r)),e;for(let[o,s]of Object.entries(e)){if(Kt(o))throw new ge(`${t}.${o}`,"forbidden-key-name");oe(s,`${t}.${o}`,r,o)}return e}var ot=Object.freeze(["intent","quote_comparison","simulation","prepared","approval","signed","broadcast","settlement","balance_delta","position"]),Ri=Object.freeze(Object.fromEntries(ot.map((e,t)=>[e,Object.freeze(t+1<ot.length?[ot[t+1]]:[])])));function st(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(st).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${st(e[t])}`).join(",")}}`}function fo(e){return e===void 0?null:JSON.parse(JSON.stringify(e))}function it(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))it(t)}return e}function po(e,t="fact"){try{oe(e,t)}catch{throw new Error(`${t} contains custody material and is forbidden`)}}function ho(e){return uo("sha256").update(st(e)).digest("hex")}function mo({tradeId:e,state:t,fact:r,asOf:n,previousHash:o,external:s}){let i={tradeId:e,state:t,asOf:n,previousHash:o??null,external:s===!0,fact:fo(r)};return it({...i,hash:ho(i)})}function Yt({tradeId:e,intent:t,asOf:r=0}={}){if(!e||typeof e!="string")throw new Error("tradeId is required");if(!t||typeof t!="object"||Array.isArray(t))throw new Error("intent fact is required");po(t,"intent");let n=mo({tradeId:e,state:"intent",fact:t,asOf:r,previousHash:null,external:!1});return it({tradeId:e,state:"intent",events:[n],headHash:n.hash,custody:"none",execution:"prepare-only"})}function Jt(e,t={}){if(!e||typeof e!="object")throw new TypeError("signal required");if(e.noTrade===!0)throw new Error("NO_TRADE signal cannot open a trade lifecycle");if(e.executionAllowed===!0)throw new Error("executionAllowed must be false on public plane");let r=String(t.tradeId||`sig-${e.id||"unknown"}`).slice(0,128),n={source:"signal_score",signalId:e.id,signalType:e.type,score:e.score,confidence:e.confidence,flags:e.flags||[],promote:"research_only",execution:"prepare-only",custody:"none",note:"Cold signal \u2192 prepare intent only. Owner wallet must sign any later tx.",...t.intentExtra&&typeof t.intentExtra=="object"?t.intentExtra:{}},o=Yt({tradeId:r,intent:n,asOf:t.asOf??Date.now()});return{tradeId:r,intent:n,lifecycle:o,recommendation:"PREPARE_RESEARCH_ONLY"}}var Zt=1,at=5e3,go=Object.freeze({1:new Set(["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0xdac17f958d2ee523a2206206994597c13d831ec7","0x6b175474e89094c44da98b954eedeac495271d0f","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]),8453:new Set(["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","0x4200000000000000000000000000000000000006"]),42161:new Set(["0xaf88d065e77c8cc2239327c5edb3a432268e5831","0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9","0x82af49447d8a07e3bd95bd0d56f35241523fbab1"]),4663:new Set(["0x5fc5360d0400a0fd4f2af552add042d716f1d168"])}),wo=/^0x[0-9a-fA-F]{40}$/,xo=/^0x[0-9a-fA-F]{64}$/,So=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/,Eo=/^(?:0|[1-9]\d*)(?:\.\d+)?$/;function B(e,t){let r=String(e||"").trim();if(!wo.test(r))throw new TypeError(`${t} must be a 0x-prefixed EVM address`);return r.toLowerCase()}var Ao=(()=>{let e=new Map;for(let t of he){let r=Number(t?.chainId);if(!Number.isInteger(r)||r<=0)continue;let n=new Set;for(let o of Array.isArray(t.stableQuoteAssets)?t.stableQuoteAssets:[])try{n.add(B(o,"stableQuoteAsset"))}catch{}if(t.wrappedNative)try{n.add(B(t.wrappedNative,"wrappedNative"))}catch{}e.set(r,n)}return e})();function er(e,t){let r=Number(e);if(!Number.isInteger(r)||r<=0)return!1;let n;try{n=B(t,"token")}catch{return!1}let o=go[r];if(o&&o.has(n))return!0;let s=Ao.get(r);return!!(s&&s.has(n))}function we(e,t="usd"){let r=typeof e=="number"?String(e):e;if(typeof r!="string"||!So.test(r))throw new TypeError(`${t} must be a non-negative decimal string with at most 2 decimal places`);let[n,o=""]=r.split("."),s=(o+"00").slice(0,2);return BigInt(n)*100n+BigInt(s)}function ie(e){let t=BigInt(e);if(t<0n)throw new RangeError("centsToUsd: cents must be non-negative");let r=t/100n,n=t%100n;return`${r.toString()}.${n.toString().padStart(2,"0")}`}function vo({dailyCapUsd:e,spentTodayUsd:t,proportionalUsd:r=null}){let n=we(e,"dailyCapUsd"),o=we(t,"spentTodayUsd"),s=n-o;if(s<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"daily-cap-exhausted"};if(r==null)return{sizeCents:s,sizeUsd:ie(s),basis:"cap-only"};let i=we(r,"proportionalUsd");if(i<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"sized-to-zero"};let l=i<s?i:s;return{sizeCents:l,sizeUsd:ie(l),basis:l===s?"cap-limited":"proportional"}}function No({amount:e,decimals:t,poolPriceUsd:r}){let n=BigInt(e);if(n<0n)throw new RangeError("amount must be non-negative");let o=Number(t);if(!Number.isInteger(o)||o<0||o>77)throw new TypeError("decimals must be an integer 0..77");let s=typeof r=="number"?String(r):String(r??"").trim();if(!Eo.test(s))throw new TypeError("poolPriceUsd must be a non-negative decimal string");let[i,l=""]=s.split("."),a=BigInt(i+l),u=n*a*100n/10n**BigInt(o+l.length);return{usd:ie(u),estimated:!0,priced:"pool-estimate"}}function To(e,{estimated:t=!1,priced:r=null}={}){return`${t===!0||r==="pool-estimate"?"~":""}$${e}`}function Co(e=null){let t=new Map;async function r(n,o){let s;try{s=B(o,"address")}catch{return"unknown"}let i=`${Number(n)}:${s}`;if(t.has(i))return t.get(i);let l="unknown";if(typeof e=="function")try{let a=await e(Number(n),s);a===!0?l="contract":a===!1&&(l="eoa")}catch{l="unknown"}return l!=="unknown"&&t.set(i,l),l}return Object.freeze({resolve:r,cache:t})}function ko(e={}){let t=String(e.txHash||"").trim().toLowerCase();if(!xo.test(t))throw new TypeError("event.txHash must be a 32-byte tx hash");let r=B(e.token,"event.token"),n=B(e.from,"event.from"),o=B(e.to,"event.to"),s=e.txFrom==null?null:B(e.txFrom,"event.txFrom");return{txHash:t,token:r,from:n,to:o,txFrom:s,chainId:Number(e.chainId),blockNumber:Number.isFinite(Number(e.blockNumber))?Number(e.blockNumber):null,logIndex:Number.isFinite(Number(e.logIndex))?Number(e.logIndex):null,value:e.value==null?null:String(e.value),valueUsd:e.valueUsd==null?null:String(e.valueUsd),priced:e.priced==="pool-estimate"?"pool-estimate":"event",counterpartyKind:e.counterpartyKind==="contract"||e.counterpartyKind==="eoa"?e.counterpartyKind:"unknown"}}function Oo(e,t){return e.to===t?e.from:e.from===t?e.to:null}function Io(e,{followedWallet:t,counterpartyKind:r}={}){let n=B(t,"followedWallet");if(!e.txFrom)return{included:!1,reason:"tx-from-unknown"};if(e.txFrom!==n)return{included:!1,reason:"not-initiated-by-followed-wallet"};if(er(e.chainId,e.token))return{included:!1,reason:"quote-asset-transfer"};let o=e.to===n?"buy":e.from===n?"sell":null;if(!o)return{included:!1,reason:"wallet-not-a-party"};let s=r==="contract"||r==="eoa"?r:e.counterpartyKind==="contract"||e.counterpartyKind==="eoa"?e.counterpartyKind:"unknown";if(s==="contract")return{included:!0,side:o,origin:"curve",priced:"pool-estimate",counterpartyKind:s};if(s==="eoa")return{included:!1,reason:"eoa-transfer",origin:"transfer",counterpartyKind:s};let i=e.valueUsd!=null&&e.priced==="event"?"swap":"transfer";return{included:!0,side:o,origin:i,priced:e.priced==="pool-estimate"?"pool-estimate":"event",counterpartyKind:"unknown"}}function _o({chainId:e,txHash:t,noTrade:r}){return{id:`follow-mirror:${e}:${t}`,type:"wallet_mirror",score:r?0:1,confidence:r?0:1,noTrade:r,executionAllowed:!1,flags:r?["FOLLOW_MIRROR","NO_TRADE"]:["FOLLOW_MIRROR"]}}function Oe({chainId:e,txHash:t,token:r,side:n,sizeUsd:o,sizeBasis:s,followedWallet:i,origin:l="transfer",priced:a="event",refuseReason:u=null}={}){let c=_o({chainId:e,txHash:t,noTrade:u!=null}),h=a==="pool-estimate",d=To(o,{estimated:h});try{let f=Jt(c,{tradeId:`follow-mirror-${e}-${t}`,intentExtra:{source:"follow_mirror",chain:e,followedWallet:i,token:r,side:n,origin:l,priced:a,estimated:h,sizeUsd:o,sizeUsdDisplay:d,sizeBasis:s,txHash:t,executionAllowed:!1,backendSigner:!1,note:h?"Wallet-follow mirror of a launchpad-curve trade. USD size is a pool-price ESTIMATE (~). Cold, prepare-only. Owner wallet must sign any later tx.":"Wallet-follow mirror. Cold, prepare-only. Owner wallet must sign any later tx."}});return{ok:!0,requiresWalletSignature:!0,backendSigner:!1,executionAllowed:!1,tradeId:f.tradeId,chain:e,token:r,side:n,origin:l,priced:a,estimated:h,sizeUsd:o,sizeUsdDisplay:d,sizeBasis:s,txHash:t,followedWallet:i,recommendation:f.recommendation,lifecycle:f.lifecycle,intent:f.intent}}catch(f){return{ok:!1,reason:u||String(f?.message||f)}}}function $o(e,t,r){if(!r)return"unknown";let n=e[`${t}:${r}`]??e[r];return n==="contract"||n==="eoa"?n:"unknown"}function Ro(e=[],{followedWallet:t,dailyCapUsd:r,spentTodayUsd:n="0",seenTxHashes:o=new Set,honeypotResults:s={},counterpartyKinds:i={}}={}){if(!Array.isArray(e))throw new TypeError("rawEvents must be an array");let l=B(t,"followedWallet"),a=new Set(o),u=we(n,"spentTodayUsd"),c=we(r,"dailyCapUsd"),h=[],d=[],f=[];for(let p of e){let m;try{m=ko(p)}catch(N){f.push({txHash:p?.txHash??null,reason:`malformed-event: ${N.message}`});continue}if(a.has(m.txHash)){f.push({txHash:m.txHash,reason:"duplicate-tx"});continue}let x=Oo(m,l),b=m.counterpartyKind!=="unknown"?m.counterpartyKind:$o(i,m.chainId,x),y=Io(m,{followedWallet:l,counterpartyKind:b});if(!y.included){f.push({txHash:m.txHash,reason:y.reason});continue}let v={chainId:m.chainId,txHash:m.txHash,token:m.token,side:y.side,origin:y.origin,priced:y.priced,followedWallet:l},I=N=>({txHash:m.txHash,token:m.token,side:y.side,origin:y.origin,priced:y.priced,reason:N}),k=s[m.token];if(k?.flagged){a.add(m.txHash);let N=Oe({...v,sizeUsd:"0.00",sizeBasis:"refused",refuseReason:`token flagged: ${k.reason||"security check flagged this token"}`});d.push(I(N.reason));continue}if(c-u<=0n){a.add(m.txHash);let N=Oe({...v,sizeUsd:"0.00",sizeBasis:"refused",refuseReason:"daily-cap-exhausted"});d.push(I(N.reason));continue}let E=vo({dailyCapUsd:ie(c),spentTodayUsd:ie(u),proportionalUsd:m.valueUsd});if(E.sizeCents<=0n){a.add(m.txHash);let N=Oe({...v,sizeUsd:"0.00",sizeBasis:E.basis,refuseReason:E.basis});d.push(I(N.reason));continue}let T=Oe({...v,sizeUsd:E.sizeUsd,sizeBasis:E.basis});a.add(m.txHash),T.ok?(h.push(T),u+=E.sizeCents):d.push(I(T.reason))}return{intents:h,refusals:d,skipped:f,seenTxHashes:a,spentTodayUsd:ie(u)}}function ct(e=process.env){let t=e.ORACLE_CONFIG_DIR||Ie.join(bo.homedir(),".config","oracle");return Ie.join(t,"follow-mirror.json")}function Qt(){return{version:Zt,targets:{}}}function Xt(e,t){return`${String(e).toLowerCase()}:${B(t,"address")}`}function _e(e){try{let t=se.readFileSync(e,"utf8"),r=JSON.parse(t);return!r||typeof r!="object"||r.version!==Zt||!r.targets||typeof r.targets!="object"?Qt():r}catch{return Qt()}}function Lo(e,t){let r=Ie.dirname(e);se.mkdirSync(r,{recursive:!0,mode:448});let n=Ie.join(r,`.follow-mirror.${process.pid}.${Date.now()}.${yo()}.tmp`);try{se.writeFileSync(n,`${JSON.stringify(t)}
5
+ `,{mode:384,flag:"wx"}),se.renameSync(n,e);try{se.chmodSync(e,384)}catch{}}catch(o){try{se.unlinkSync(n)}catch{}throw o}}function Uo(e){return new Date(e).toISOString().slice(0,10)}function Po(e,t,r){let n=e.targets[t],o=new Set(Array.isArray(n?.seenTxHashes)?n.seenTxHashes:[]),s=typeof n?.days?.[r]=="string"?n.days[r]:"0";return{seenTxHashes:o,spentTodayUsd:s}}function Fo(e,t,{seenTxHashes:r,spentTodayUsd:n,day:o,newIntents:s,newRefusals:i}){let l=e.targets[t]||{seenTxHashes:[],days:{},intents:[],refusals:[]},a=[...r].slice(-at),u=[...l.intents||[],...s].slice(-at),c=[...l.refusals||[],...i].slice(-at);e.targets[t]={seenTxHashes:a,days:{...l.days||{},[o]:n},intents:u,refusals:c}}function lt({now:e=()=>Date.now(),fetchWallet:t,fetchTxFrom:r,checkHoneypot:n,estimateUsdValue:o=async()=>null,isContract:s=null,poolPriceUsd:i=async()=>null,tokenDecimals:l=async()=>18,storePath:a=ct()}={}){if(typeof t!="function")throw new TypeError("createFollowMirror requires fetchWallet");if(typeof r!="function")throw new TypeError("createFollowMirror requires fetchTxFrom");if(typeof n!="function")throw new TypeError("createFollowMirror requires checkHoneypot");let u=Co(s);async function c({address:d,chain:f,chainId:p,dailyCapUsd:m,lookback:x}={}){let b=B(d,"address"),y=Number(p);if(!Number.isInteger(y)||y<=0)throw new TypeError("observe requires a numeric chainId");let v=e(),I=Uo(v),k=Xt(f||y,b),R=_e(a),{seenTxHashes:E,spentTodayUsd:T}=Po(R,k,I),N=await t(b,{chains:[y],lookback:x}),L=Array.isArray(N?.events)?N.events:[],w=[],O={},q=new Set,$={};for(let C of L){let U=null;try{U=await r(y,C.txHash)}catch{U=null}let g=null,A="event";try{g=await o({...C,chainId:y,txFrom:U})}catch{g=null}let S=String(C.token||"").toLowerCase(),J=String(C.from||"").toLowerCase(),D=String(C.to||"").toLowerCase(),j="unknown";if(U===b&&!er(y,S)&&S){let K=D===b?J:J===b?D:null;if(K&&(j=await u.resolve(y,K),$[`${y}:${K}`]=j),j==="contract"&&g==null&&C.value!=null)try{let Q=await i(y,S);if(Q!=null){let Le=await l(y,S);g=No({amount:C.value,decimals:Le??18,poolPriceUsd:Q}).usd,A="pool-estimate"}}catch{g=null}else j==="contract"&&(A="pool-estimate");if(!q.has(S)){q.add(S);try{O[S]=await n(y,S)}catch(Q){O[S]={flagged:!0,reason:`security check unavailable: ${String(Q?.message||Q).slice(0,160)}`}}}}w.push({...C,chainId:y,txFrom:U,valueUsd:g,priced:A,counterpartyKind:j})}let F=Ro(w,{followedWallet:b,dailyCapUsd:String(m),spentTodayUsd:T,seenTxHashes:E,honeypotResults:O,counterpartyKinds:$});return Fo(R,k,{seenTxHashes:F.seenTxHashes,spentTodayUsd:F.spentTodayUsd,day:I,newIntents:F.intents.map(C=>({tradeId:C.tradeId,txHash:C.txHash,token:C.token,side:C.side,origin:C.origin,priced:C.priced,sizeUsd:C.sizeUsd,sizeUsdDisplay:C.sizeUsdDisplay,createdAt:v})),newRefusals:F.refusals.map(C=>({...C,createdAt:v}))}),Lo(a,R),{ok:!0,cold:!0,executionAllowed:!1,chain:f||y,chainId:y,address:b,observed:L.length,intents:F.intents,refusals:F.refusals,skipped:F.skipped,spentTodayUsd:F.spentTodayUsd,dailyCapUsd:String(m),errors:N?.errors||[]}}function h({address:d,chain:f}={}){let p=B(d,"address"),m=_e(a),x=Xt(f,p),b=m.targets[x]||{intents:[],refusals:[],days:{}};return{ok:!0,address:p,chain:f,intents:b.intents||[],refusals:b.refusals||[],days:b.days||{}}}return Object.freeze({observe:c,status:h,storePath:a})}import xe from"node:fs";import Bo from"node:os";import Re from"node:path";import{randomUUID as Do}from"node:crypto";var sr=1,tr=500,rr=Object.freeze(["tap","cli","signal"]),jo=/^0x[0-9a-fA-F]{40}$/,qo=64;function ir(e=process.env){let t=e.ORACLE_CONFIG_DIR||Re.join(Bo.homedir(),".config","oracle");return Re.join(t,"follow-list.json")}function $e(e){let t=String(e||"").trim();if(!jo.test(t))throw new TypeError("address must be a 0x-prefixed 40-hex EVM address");return t.toLowerCase()}function nr(e){return e==null?null:String(e).replace(/[\u0000-\u001f\u007f]/g,"").trim().slice(0,qo)||null}function or(){return{version:sr,entries:{}}}function Ho(e){try{let t=JSON.parse(xe.readFileSync(e,"utf8"));return!t||t.version!==sr||!t.entries||typeof t.entries!="object"?or():t}catch{return or()}}function ut(e,t){let r=Re.dirname(e);xe.mkdirSync(r,{recursive:!0,mode:448});let n=Re.join(r,`.follow-list.${process.pid}.${Date.now()}.${Do()}.tmp`);try{xe.writeFileSync(n,`${JSON.stringify(t)}
6
6
  `,{mode:384,flag:"wx"}),xe.renameSync(n,e)}finally{try{xe.unlinkSync(n)}catch{}}}function ar({path:e,denylist:t=new Set,now:r=Date.now}={}){if(!e)throw new TypeError("createFollowStore requires { path }");let n=new Set([...t].map(c=>String(c).toLowerCase()));function o(){return Ho(e)}function s(){let c=o();return Object.values(c.entries).sort((h,d)=>d.addedAt-h.addedAt)}function i(c){let h;try{h=$e(c)}catch{return!1}return!!o().entries[h]}function l({address:c,chainId:h=null,label:d=null,source:f="tap"}={}){let p=$e(c);if(!rr.includes(f))throw new TypeError(`source must be one of ${rr.join(", ")}`);if(n.has(p))return{added:!1,reason:"denylisted",address:p};let m=o();if(m.entries[p])return{added:!1,reason:"already-following",address:p,entry:m.entries[p]};if(Object.keys(m.entries).length>=tr)return{added:!1,reason:"store-full",address:p,max:tr};let x=h==null?null:Number(h);if(x!=null&&(!Number.isInteger(x)||x<=0))throw new TypeError("chainId must be a positive integer");let b={address:p,chainId:x,label:nr(d),source:f,addedAt:r()};return m.entries[p]=b,ut(e,m),{added:!0,address:p,entry:b}}function a(c){let h=$e(c),d=o();return d.entries[h]?(delete d.entries[h],ut(e,d),{removed:!0,address:h}):{removed:!1,reason:"not-following",address:h}}function u(c,h){let d=$e(c),f=o();return f.entries[d]?(f.entries[d].label=nr(h),ut(e,f),{ok:!0,address:d,entry:f.entries[d]}):{ok:!1,reason:"not-following",address:d}}return Object.freeze({path:e,list:s,has:i,add:l,remove:a,setLabel:u})}var ae={1:"ethereum",8453:"base",42161:"arbitrum"},cr=Object.fromEntries(Object.entries(ae).map(([e,t])=>[t,Number(e)])),Mo=new Set(["is_honeypot","cannot_sell_all","cannot_buy","is_blacklisted","selfdestruct","owner_change_balance"]),lr=`oracle follow <name-or-address> [--chain <name>] [--blocks <n>] [--gas] [--json]
7
7
  oracle follow <name-or-address> --chain <name> --mirror --max-usd <n> [--json]
8
8
  oracle follow status [<name-or-address>] [--chain <name>] [--json]
@@ -1,7 +1,7 @@
1
- import k from"node:fs";import b from"node:path";var l=Object.freeze([{id:"oracle",label:"Oracle Native",kind:"oracle",bins:["oracle"],website:!0,detect:!0},{id:"hermes",label:"Hermes Agent",kind:"mcp",bins:["hermes"],mcpTarget:"generic",configKey:"hermes",website:!0,detect:!0},{id:"claude",label:"Claude Code",kind:"mcp",bins:["claude"],mcpTarget:"claude-code",configKey:"claudeCode",website:!0,detect:!0},{id:"claude-desktop",label:"Claude Desktop",kind:"mcp",bins:[],mcpTarget:"claude-desktop",configKey:"claudeDesktop",website:!0,detect:!1},{id:"chatgpt",label:"ChatGPT",kind:"mcp",bins:[],mcpTarget:"chatgpt",configKey:"chatgpt",website:!0,detect:!1},{id:"codex",label:"OpenAI Codex",kind:"mcp",bins:["codex"],mcpTarget:"codex",configKey:"codex",website:!0,detect:!0},{id:"cursor",label:"Cursor",kind:"mcp",bins:["cursor","cursor-agent"],mcpTarget:"cursor",configKey:"cursor",website:!0,detect:!0},{id:"windsurf",label:"Windsurf",kind:"mcp",bins:["windsurf"],mcpTarget:"vscode",configKey:"windsurf",website:!0,detect:!0},{id:"vscode",label:"VS Code / Copilot",kind:"mcp",bins:["code","code-insiders"],mcpTarget:"vscode",configKey:"vscode",website:!0,detect:!0},{id:"openclaw",label:"OpenClaw",kind:"mcp",bins:["openclaw","claw"],mcpTarget:"generic",configKey:"openclaw",website:!0,detect:!0},{id:"perplexity",label:"Perplexity",kind:"mcp",bins:["perplexity","pplx"],mcpTarget:"generic",configKey:"perplexity",website:!0,detect:!0},{id:"manus",label:"Manus",kind:"mcp",bins:["manus"],mcpTarget:"generic",configKey:"manus",website:!0,detect:!0},{id:"prime",label:"Prime Intellect Agent",kind:"mcp",bins:["prime-agent","prime"],mcpTarget:"generic",configKey:"prime",website:!1,detect:!0},{id:"opencode",label:"OpenCode",kind:"mcp",bins:["opencode"],mcpTarget:"generic",configKey:"opencode",website:!1,detect:!0},{id:"aider",label:"Aider",kind:"mcp",bins:["aider"],mcpTarget:"generic",configKey:"aider",website:!1,detect:!0},{id:"continue",label:"Continue",kind:"mcp",bins:["continue"],mcpTarget:"vscode",configKey:"continue",website:!1,detect:!0},{id:"goose",label:"Goose",kind:"mcp",bins:["goose"],mcpTarget:"generic",configKey:"goose",website:!1,detect:!0},{id:"amp",label:"Amp",kind:"mcp",bins:["amp"],mcpTarget:"generic",configKey:"amp",website:!1,detect:!0},{id:"generic",label:"Generic MCP",kind:"mcp",bins:[],mcpTarget:"generic",configKey:"genericMcp",website:!0,detect:!1}]);function s(){return l.filter(e=>e.website)}function d(){return l.filter(e=>e.detect!==!1&&(e.bins?.length||e.kind==="oracle"))}function c(e){return l.find(o=>o.id===e)?.mcpTarget||"generic"}function u(e){return e==="oracle"?"oracle chat":`oracle mcp install ${c(e)}`}var I=Object.freeze([Object.freeze({id:"claude-opus-5",label:"Claude Opus 5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth",badge:"NEW"}),Object.freeze({id:"claude-sonnet-5",label:"Claude Sonnet 5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-fable-5",label:"Claude Fable 5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-haiku-4-5",label:"Claude Haiku 4.5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-opus-4-8",label:"Claude Opus 4.8",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"gpt-5.6-sol",label:"Codex 5.6 Sol",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth"}),Object.freeze({id:"gpt-5.6-sol-900k",label:"Codex 5.6 Sol 900k",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:9e5,upstreamModel:"gpt-5.6-sol"}),Object.freeze({id:"gpt-5.5",label:"GPT-5.5",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth"}),Object.freeze({id:"gpt-5.4",label:"GPT-5.4",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth"}),Object.freeze({id:"grok-4.20-reasoning",label:"Grok 4.20 Reasoning",provider:"xai-oauth",providerLabel:"Grok / xAI OAuth",badge:"NEW"}),Object.freeze({id:"grok-4.6",label:"Grok 4.6",provider:"xai-oauth",providerLabel:"Grok / xAI OAuth"}),Object.freeze({id:"grok-code-fast-1",label:"Grok Code Fast 1",provider:"xai-oauth",providerLabel:"Grok / xAI OAuth"}),Object.freeze({id:"openrouter/auto",label:"OpenRouter Auto",provider:"openrouter",providerLabel:"OpenRouter API key"}),Object.freeze({id:"gpt-5.6-sol",label:"GPT-5.6",provider:"openai",providerLabel:"OpenAI API key"}),Object.freeze({id:"gpt-5.5",label:"GPT-5.5",provider:"openai",providerLabel:"OpenAI API key"}),Object.freeze({id:"gpt-4.1-mini",label:"GPT-4.1 Mini",provider:"openai",providerLabel:"OpenAI API key"}),Object.freeze({id:"claude-opus-5",label:"Claude Opus 5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-sonnet-5",label:"Claude Sonnet 5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-fable-5",label:"Claude Fable 5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-haiku-4-5",label:"Claude Haiku 4.5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-opus-4-8",label:"Claude Opus 4.8",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"grok-4.20-reasoning",label:"Grok 4.20 Reasoning",provider:"xai",providerLabel:"xAI API key"}),Object.freeze({id:"grok-4.6",label:"Grok 4.6",provider:"xai",providerLabel:"xAI API key"}),Object.freeze({id:"grok-code-fast-1",label:"Grok Code Fast 1",provider:"xai",providerLabel:"xAI API key"}),Object.freeze({id:"deepseek-v4-pro",label:"DeepSeek V4 Pro",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"deepseek-v4-flash",label:"DeepSeek V4 Flash",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"deepseek-chat",label:"DeepSeek Chat",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"deepseek-reasoner",label:"DeepSeek Reasoner",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"gemini-2.5-pro",label:"Gemini 2.5 Pro",provider:"gemini",providerLabel:"Google API key"}),Object.freeze({id:"gemini-2.5-flash",label:"Gemini 2.5 Flash",provider:"gemini",providerLabel:"Google API key"}),Object.freeze({id:"kimi-k3",label:"Kimi K3",provider:"kimi",providerLabel:"Kimi API key"}),Object.freeze({id:"mistral-large-latest",label:"Mistral Large",provider:"mistral",providerLabel:"Mistral API key"}),Object.freeze({id:"moonshotai/kimi-k3",label:"Kimi K3",provider:"nous",providerLabel:"Nous Portal API key"}),Object.freeze({id:"openai/gpt-5.6-sol",label:"GPT-5.6",provider:"nous",providerLabel:"Nous Portal API key"}),Object.freeze({id:"qwen-plus",label:"Qwen Plus",provider:"qwen",providerLabel:"Qwen API key"}),Object.freeze({id:"qwen-max",label:"Qwen Max",provider:"qwen",providerLabel:"Qwen API key"}),Object.freeze({id:"glm-4.5",label:"GLM 4.5",provider:"glm",providerLabel:"GLM API key"}),Object.freeze({id:"glm-4.6",label:"GLM 4.6",provider:"glm",providerLabel:"GLM API key"}),Object.freeze({id:"Qwen3-8B-Q4_K_M",label:"Qwen3 8B Local",provider:"local",providerLabel:"Local llama.cpp"}),Object.freeze({id:"llama3.2",label:"Llama 3.2",provider:"ollama",providerLabel:"Ollama loopback"}),Object.freeze({id:"qwen3",label:"Qwen3",provider:"ollama",providerLabel:"Ollama loopback"}),Object.freeze({id:"gpt-6-astra",label:"GPT-6 Astra",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-6-astra-900k",label:"GPT-6 Astra 900k",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:9e5,upstreamModel:"gpt-6-astra",badge:"NEW"}),Object.freeze({id:"gpt-6-astra",label:"GPT-6 Astra",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-5.6-terra",label:"GPT-5.6 Terra",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4}),Object.freeze({id:"gpt-5.6-luna",label:"GPT-5.6 Luna",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4}),Object.freeze({id:"openai/gpt-6-astra",label:"GPT-6 Astra",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"openai/gpt-6-astra-pro",label:"GPT-6 Astra Pro",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"openai/gpt-5.6-terra",label:"GPT-5.6 Terra",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4}),Object.freeze({id:"openai/gpt-5.6-luna",label:"GPT-5.6 Luna",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4}),Object.freeze({id:"google/gemini-3.8-flash",label:"Gemini 3.8 Flash",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576}),Object.freeze({id:"z-ai/glm-5.2",label:"GLM 5.2",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576}),Object.freeze({id:"qwen/qwen3.6-plus",label:"Qwen3.6 Plus",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1e6}),Object.freeze({id:"qwen/qwen3.6-flash",label:"Qwen3.6 Flash",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1e6}),Object.freeze({id:"deepseek/deepseek-v4-pro-0813",label:"DeepSeek V4 Pro 0813",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576}),Object.freeze({id:"moonshotai/kimi-k3",label:"Kimi K3",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576})]);var M=Object.freeze({openrouter:{key:"OPENROUTER_API_KEY",baseUrl:"https://openrouter.ai/api/v1",model:"openrouter/auto"},openai:{key:"OPENAI_API_KEY",baseUrl:"https://api.openai.com/v1",model:"gpt-4.1-mini"},anthropic:{key:"ANTHROPIC_API_KEY",baseUrl:"https://api.anthropic.com/v1",model:"claude-sonnet-4-6",protocol:"anthropic-messages"},xai:{key:"XAI_API_KEY",baseUrl:"https://api.x.ai/v1",model:"grok-4.6"},deepseek:{key:"DEEPSEEK_API_KEY",baseUrl:"https://api.deepseek.com/v1",model:"deepseek-chat"},gemini:{key:"GEMINI_API_KEY",alternateKey:"GOOGLE_API_KEY",baseUrl:"https://generativelanguage.googleapis.com/v1beta/openai",model:"gemini-2.5-flash"},kimi:{key:"MOONSHOT_API_KEY",alternateKey:"KIMI_API_KEY",baseUrl:"https://api.moonshot.ai/v1",model:"kimi-k3",protocol:"openai-chat"},mistral:{key:"MISTRAL_API_KEY",baseUrl:"https://api.mistral.ai/v1",model:"mistral-large-latest",protocol:"openai-chat"},nous:{key:"NOUS_API_KEY",baseUrl:"https://inference-api.nousresearch.com/v1",model:"moonshotai/kimi-k3",protocol:"openai-chat"},qwen:{key:"DASHSCOPE_API_KEY",alternateKey:"QWEN_API_KEY",baseUrl:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",model:"qwen-plus",protocol:"openai-chat"},glm:{key:"ZHIPU_API_KEY",alternateKey:"GLM_API_KEY",baseUrl:"https://open.bigmodel.cn/api/paas/v4",model:"glm-4.5",protocol:"openai-chat"},local:{baseUrl:"http://127.0.0.1:8080/v1",model:"Qwen3-8B-Q4_K_M",protocol:"openai-chat",keyless:!0},ollama:{baseUrl:"http://127.0.0.1:11434/v1",model:"llama3.2",protocol:"openai-chat",keyless:!0}}),U=Object.freeze({"anthropic-oauth":{key:"ANTHROPIC_API_KEY",baseUrl:"https://api.anthropic.com/v1",model:"claude-sonnet-4-20250514",protocol:"anthropic-messages"},"openai-codex":{key:"OPENAI_API_KEY",baseUrl:"https://chatgpt.com/backend-api/codex",model:"gpt-5.6-sol",protocol:"responses"},"xai-oauth":{key:"XAI_API_KEY",baseUrl:"https://api.x.ai/v1",model:"grok-4.6",protocol:"responses"}});var H=Object.freeze(["xai-oauth","anthropic-oauth","openai-codex"]);function A(){return d().map(e=>({name:e.id,bin:e.bins?.[0]||e.id,label:e.label,kind:e.kind,altBins:(e.bins||[]).slice(1)}))}function m(e){for(let n of(process.env.PATH||"").split(b.delimiter)){let o=b.join(n,e);try{if(k.existsSync(o))return o}catch{}}return null}function v(e){let n=[e.bin,...e.altBins||[]].filter(Boolean);for(let o of n){let t=m(o);if(t)return t}return null}function h(e=process.env){let n=[];for(let t of A()){if(t.kind==="oracle"||t.name==="oracle"){n.push({...t,path:process.argv[1]||"oracle"});continue}let a=v(t);a&&n.push({name:t.name,bin:t.bin,label:t.label,kind:t.kind,path:a})}let o=String(e.ORACLE_HARNESS_EXTRA||e.ORACLE_CLIENT_EXTRA||"").split(",").map(t=>t.trim()).filter(Boolean);for(let t of o){if(n.some(r=>r.bin===t||r.name===t))continue;let a=m(t);a&&n.push({name:t,bin:t,label:t,kind:"mcp",path:a})}return n}function L(e){if(e.kind==="oracle"||e.name==="oracle")return{...e,direction:"native",integrate:"oracle chat",outbound:"oracle chat",inbound:null,plugins:null,backendEnv:null,note:"Oracle native harness. Default. No external harness required."};let n=c(e.name)||"generic",o=e.name==="hermes"?"hermes":e.name;return{...e,direction:"client",integrate:`oracle mcp install ${n}`,outbound:`oracle chat --backend ${o}`,inbound:`oracle mcp install ${n}`,plugins:"oracle plugins install <path|git-url>",backendEnv:`ORACLE_CHAT_BACKEND=${o}`,note:"Use through Oracle (`oracle chat --backend \u2026`) or wire Oracle into this harness (`oracle mcp install`). Detection never auto-selects."}}function E(e){let n=e.map(L),o=n.find(i=>i.direction==="native"),t=n.filter(i=>i.direction!=="native"),a=s().filter(i=>i.kind==="mcp"),r=[];if(r.push(""),r.push("Three ways to run Oracle:"),r.push(` 1) Oracle native harness ${o?o.path:"oracle"}`),r.push(" oracle setup model && oracle chat"),r.push(" 2) Through Oracle attach Hermes / Claude / Codex as the engine"),r.push(" oracle chat --backend hermes"),r.push(" 3) Into your harness wire Oracle MCP into the agent you already use"),r.push(" oracle mcp install <target> | oracle plugins install <path>"),r.push(""),r.push("Oracle native is the default harness. Detection never auto-selects another harness."),r.push(""),r.push("Detected on this machine:"),t.length===0)r.push(" (none, Oracle native is enough)");else for(let i of t)r.push(` ${i.label.padEnd(22)} ${i.path}`),r.push(` ${" ".repeat(22)} \u2192 through Oracle: ${i.outbound}`),r.push(` ${" ".repeat(22)} into harness: ${i.inbound}`);r.push(""),r.push("Supported harness roster (MCP install targets):");for(let i of a){let f=u(i.id),g=t.find(O=>O.name===i.id);r.push(` ${i.label.padEnd(22)} ${f}${g?" [detected]":""}`)}return r.push(""),r.push("Also:"),r.push(" oracle mcp print --target generic"),r.push(" oracle plugins list"),r.push(" ORACLE_HARNESS_EXTRA=foo,bar # detect extra bins"),r.push(""),r.push("Models on the site (Grok, Gemini, DeepSeek, Qwen, Kimi) are providers for"),r.push("Oracle native, configure with oracle setup model / oracle auth, not as harnesses."),r.join(`
2
- `)}function p(){return["oracle harness, detect installed agent harnesses",""," oracle harness detect scan PATH + show supported harness roster"," oracle harness list alias of detect","","Modes:"," Oracle native harness oracle chat"," Through Oracle oracle chat --backend hermes|claude|codex|\u2026"," Into your harness oracle mcp install <target>","",`Harness roster: ${s().map(n=>n.id).join(", ")}`,"Extra bins: ORACLE_HARNESS_EXTRA=foo,bar","","Detection never selects a backend."].join(`
3
- `)}var B={name:"harness",aliases:["clients"],summary:"detect agent harnesses; use Oracle native or wire MCP into them",usage:p,async run(e,n){let o=e[0];if(o==="help"||o==="--help"||o==="-h")return process.stdout.write(p()+`
1
+ import A from"node:fs";import b from"node:path";var l=Object.freeze([{id:"oracle",label:"Oracle Native",kind:"oracle",bins:["oracle"],website:!0,detect:!0},{id:"hermes",label:"Hermes Agent",kind:"mcp",bins:["hermes"],mcpTarget:"generic",configKey:"hermes",website:!0,detect:!0},{id:"claude",label:"Claude Code",kind:"mcp",bins:["claude"],mcpTarget:"claude-code",configKey:"claudeCode",website:!0,detect:!0},{id:"claude-desktop",label:"Claude Desktop",kind:"mcp",bins:[],mcpTarget:"claude-desktop",configKey:"claudeDesktop",website:!0,detect:!1},{id:"chatgpt",label:"ChatGPT",kind:"mcp",bins:[],mcpTarget:"chatgpt",configKey:"chatgpt",website:!0,detect:!1},{id:"codex",label:"OpenAI Codex",kind:"mcp",bins:["codex"],mcpTarget:"codex",configKey:"codex",website:!0,detect:!0},{id:"cursor",label:"Cursor",kind:"mcp",bins:["cursor","cursor-agent"],mcpTarget:"cursor",configKey:"cursor",website:!0,detect:!0},{id:"windsurf",label:"Windsurf",kind:"mcp",bins:["windsurf"],mcpTarget:"vscode",configKey:"windsurf",website:!0,detect:!0},{id:"vscode",label:"VS Code / Copilot",kind:"mcp",bins:["code","code-insiders"],mcpTarget:"vscode",configKey:"vscode",website:!0,detect:!0},{id:"openclaw",label:"OpenClaw",kind:"mcp",bins:["openclaw","claw"],mcpTarget:"generic",configKey:"openclaw",website:!0,detect:!0},{id:"perplexity",label:"Perplexity",kind:"mcp",bins:["perplexity","pplx"],mcpTarget:"generic",configKey:"perplexity",website:!0,detect:!0},{id:"manus",label:"Manus",kind:"mcp",bins:["manus"],mcpTarget:"generic",configKey:"manus",website:!0,detect:!0},{id:"prime",label:"Prime Intellect Agent",kind:"mcp",bins:["prime-agent","prime"],mcpTarget:"generic",configKey:"prime",website:!1,detect:!0},{id:"opencode",label:"OpenCode",kind:"mcp",bins:["opencode"],mcpTarget:"generic",configKey:"opencode",website:!1,detect:!0},{id:"aider",label:"Aider",kind:"mcp",bins:["aider"],mcpTarget:"generic",configKey:"aider",website:!1,detect:!0},{id:"continue",label:"Continue",kind:"mcp",bins:["continue"],mcpTarget:"vscode",configKey:"continue",website:!1,detect:!0},{id:"goose",label:"Goose",kind:"mcp",bins:["goose"],mcpTarget:"generic",configKey:"goose",website:!1,detect:!0},{id:"amp",label:"Amp",kind:"mcp",bins:["amp"],mcpTarget:"generic",configKey:"amp",website:!1,detect:!0},{id:"generic",label:"Generic MCP",kind:"mcp",bins:[],mcpTarget:"generic",configKey:"genericMcp",website:!0,detect:!1}]);function c(){return l.filter(e=>e.website)}function s(){return l.filter(e=>e.detect!==!1&&(e.bins?.length||e.kind==="oracle"))}function d(e){return l.find(o=>o.id===e)?.mcpTarget||"generic"}function u(e){return e==="oracle"?"oracle chat":`oracle mcp install ${d(e)}`}var I=Object.freeze([Object.freeze({id:"claude-opus-5-5",label:"Claude Opus 5.5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"claude-sonnet-5-5",label:"Claude Sonnet 5.5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"claude-fable-5-1",label:"Claude Fable 5.1",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"claude-opus-5",label:"Claude Opus 5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-sonnet-5",label:"Claude Sonnet 5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-fable-5",label:"Claude Fable 5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-haiku-4-5",label:"Claude Haiku 4.5",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-opus-4-8",label:"Claude Opus 4.8",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6",provider:"anthropic-oauth",providerLabel:"Anthropic OAuth"}),Object.freeze({id:"gpt-5.6-sol",label:"Codex 5.6 Sol",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth"}),Object.freeze({id:"gpt-5.6-sol-900k",label:"Codex 5.6 Sol 900k",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:9e5,upstreamModel:"gpt-5.6-sol"}),Object.freeze({id:"gpt-5.5",label:"GPT-5.5",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth"}),Object.freeze({id:"gpt-5.4",label:"GPT-5.4",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth"}),Object.freeze({id:"grok-4.7",label:"Grok 4.7",provider:"xai-oauth",providerLabel:"Grok / xAI OAuth",contextLength:5e5,badge:"NEW"}),Object.freeze({id:"grok-4.20-reasoning",label:"Grok 4.20 Reasoning",provider:"xai-oauth",providerLabel:"Grok / xAI OAuth"}),Object.freeze({id:"grok-4.6",label:"Grok 4.6",provider:"xai-oauth",providerLabel:"Grok / xAI OAuth"}),Object.freeze({id:"grok-code-fast-1",label:"Grok Code Fast 1",provider:"xai-oauth",providerLabel:"Grok / xAI OAuth"}),Object.freeze({id:"openrouter/auto",label:"OpenRouter Auto",provider:"openrouter",providerLabel:"OpenRouter API key"}),Object.freeze({id:"gpt-5.6-sol",label:"GPT-5.6",provider:"openai",providerLabel:"OpenAI API key"}),Object.freeze({id:"gpt-5.5",label:"GPT-5.5",provider:"openai",providerLabel:"OpenAI API key"}),Object.freeze({id:"gpt-4.1-mini",label:"GPT-4.1 Mini",provider:"openai",providerLabel:"OpenAI API key"}),Object.freeze({id:"claude-opus-5-5",label:"Claude Opus 5.5",provider:"anthropic",providerLabel:"Anthropic API key",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"claude-sonnet-5-5",label:"Claude Sonnet 5.5",provider:"anthropic",providerLabel:"Anthropic API key",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"claude-fable-5-1",label:"Claude Fable 5.1",provider:"anthropic",providerLabel:"Anthropic API key",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"claude-opus-5",label:"Claude Opus 5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-sonnet-5",label:"Claude Sonnet 5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-fable-5",label:"Claude Fable 5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-haiku-4-5",label:"Claude Haiku 4.5",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-opus-4-8",label:"Claude Opus 4.8",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"claude-sonnet-4-6",label:"Claude Sonnet 4.6",provider:"anthropic",providerLabel:"Anthropic API key"}),Object.freeze({id:"grok-4.7",label:"Grok 4.7",provider:"xai",providerLabel:"xAI API key",contextLength:5e5,badge:"NEW"}),Object.freeze({id:"grok-4.20-reasoning",label:"Grok 4.20 Reasoning",provider:"xai",providerLabel:"xAI API key"}),Object.freeze({id:"grok-4.6",label:"Grok 4.6",provider:"xai",providerLabel:"xAI API key"}),Object.freeze({id:"grok-code-fast-1",label:"Grok Code Fast 1",provider:"xai",providerLabel:"xAI API key"}),Object.freeze({id:"deepseek-v4-pro",label:"DeepSeek V4 Pro",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"deepseek-v4-flash",label:"DeepSeek V4 Flash",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"deepseek-chat",label:"DeepSeek Chat",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"deepseek-reasoner",label:"DeepSeek Reasoner",provider:"deepseek",providerLabel:"DeepSeek API key"}),Object.freeze({id:"gemini-2.5-pro",label:"Gemini 2.5 Pro",provider:"gemini",providerLabel:"Google API key"}),Object.freeze({id:"gemini-2.5-flash",label:"Gemini 2.5 Flash",provider:"gemini",providerLabel:"Google API key"}),Object.freeze({id:"kimi-k3",label:"Kimi K3",provider:"kimi",providerLabel:"Kimi API key"}),Object.freeze({id:"mistral-large-latest",label:"Mistral Large",provider:"mistral",providerLabel:"Mistral API key"}),Object.freeze({id:"moonshotai/kimi-k3",label:"Kimi K3",provider:"nous",providerLabel:"Nous Portal API key"}),Object.freeze({id:"openai/gpt-5.6-sol",label:"GPT-5.6",provider:"nous",providerLabel:"Nous Portal API key"}),Object.freeze({id:"qwen-plus",label:"Qwen Plus",provider:"qwen",providerLabel:"Qwen API key"}),Object.freeze({id:"qwen-max",label:"Qwen Max",provider:"qwen",providerLabel:"Qwen API key"}),Object.freeze({id:"glm-4.5",label:"GLM 4.5",provider:"glm",providerLabel:"GLM API key"}),Object.freeze({id:"glm-4.6",label:"GLM 4.6",provider:"glm",providerLabel:"GLM API key"}),Object.freeze({id:"Qwen3-8B-Q4_K_M",label:"Qwen3 8B Local",provider:"local",providerLabel:"Local llama.cpp"}),Object.freeze({id:"llama3.2",label:"Llama 3.2",provider:"ollama",providerLabel:"Ollama loopback"}),Object.freeze({id:"qwen3",label:"Qwen3",provider:"ollama",providerLabel:"Ollama loopback"}),Object.freeze({id:"gpt-6-astra",label:"GPT-6 Astra",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-6-astra-900k",label:"GPT-6 Astra 900k",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:9e5,upstreamModel:"gpt-6-astra",badge:"NEW"}),Object.freeze({id:"gpt-6-sol",label:"GPT-6 Sol",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-6-luna",label:"GPT-6 Luna",provider:"openai-codex",providerLabel:"OpenAI Codex OAuth",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-6-astra",label:"GPT-6 Astra",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-6-sol",label:"GPT-6 Sol",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-6-luna",label:"GPT-6 Luna",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"gpt-5.6-terra",label:"GPT-5.6 Terra",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4}),Object.freeze({id:"gpt-5.6-luna",label:"GPT-5.6 Luna",provider:"openai",providerLabel:"OpenAI API key",contextLength:105e4}),Object.freeze({id:"openai/gpt-6-astra",label:"GPT-6 Astra",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"openai/gpt-6-astra-pro",label:"GPT-6 Astra Pro",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"openai/gpt-6-sol",label:"GPT-6 Sol",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"openai/gpt-6-luna",label:"GPT-6 Luna",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4,badge:"NEW"}),Object.freeze({id:"anthropic/claude-opus-5.5",label:"Claude Opus 5.5",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"anthropic/claude-sonnet-5.5",label:"Claude Sonnet 5.5",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1e6,badge:"NEW"}),Object.freeze({id:"x-ai/grok-4.7",label:"Grok 4.7",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:5e5,badge:"NEW"}),Object.freeze({id:"openai/gpt-5.6-terra",label:"GPT-5.6 Terra",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4}),Object.freeze({id:"openai/gpt-5.6-luna",label:"GPT-5.6 Luna",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:105e4}),Object.freeze({id:"google/gemini-3.8-flash",label:"Gemini 3.8 Flash",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576}),Object.freeze({id:"z-ai/glm-5.2",label:"GLM 5.2",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576}),Object.freeze({id:"qwen/qwen3.6-plus",label:"Qwen3.6 Plus",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1e6}),Object.freeze({id:"qwen/qwen3.6-flash",label:"Qwen3.6 Flash",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1e6}),Object.freeze({id:"deepseek/deepseek-v4-pro-0813",label:"DeepSeek V4 Pro 0813",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576}),Object.freeze({id:"moonshotai/kimi-k3",label:"Kimi K3",provider:"openrouter",providerLabel:"OpenRouter API key",contextLength:1048576})]);var y=Object.freeze(["low","medium","high","xhigh","max","ultra"]),C=Object.freeze({"gpt-6-luna":"max","gpt-5.6-luna":"max","gpt-5.5":"xhigh"});var M=Object.freeze({openrouter:{key:"OPENROUTER_API_KEY",baseUrl:"https://openrouter.ai/api/v1",model:"openrouter/auto"},openai:{key:"OPENAI_API_KEY",baseUrl:"https://api.openai.com/v1",model:"gpt-4.1-mini"},anthropic:{key:"ANTHROPIC_API_KEY",baseUrl:"https://api.anthropic.com/v1",model:"claude-sonnet-4-6",protocol:"anthropic-messages"},xai:{key:"XAI_API_KEY",baseUrl:"https://api.x.ai/v1",model:"grok-4.6"},deepseek:{key:"DEEPSEEK_API_KEY",baseUrl:"https://api.deepseek.com/v1",model:"deepseek-chat"},gemini:{key:"GEMINI_API_KEY",alternateKey:"GOOGLE_API_KEY",baseUrl:"https://generativelanguage.googleapis.com/v1beta/openai",model:"gemini-2.5-flash"},kimi:{key:"MOONSHOT_API_KEY",alternateKey:"KIMI_API_KEY",baseUrl:"https://api.moonshot.ai/v1",model:"kimi-k3",protocol:"openai-chat"},mistral:{key:"MISTRAL_API_KEY",baseUrl:"https://api.mistral.ai/v1",model:"mistral-large-latest",protocol:"openai-chat"},nous:{key:"NOUS_API_KEY",baseUrl:"https://inference-api.nousresearch.com/v1",model:"moonshotai/kimi-k3",protocol:"openai-chat"},qwen:{key:"DASHSCOPE_API_KEY",alternateKey:"QWEN_API_KEY",baseUrl:"https://dashscope-intl.aliyuncs.com/compatible-mode/v1",model:"qwen-plus",protocol:"openai-chat"},glm:{key:"ZHIPU_API_KEY",alternateKey:"GLM_API_KEY",baseUrl:"https://open.bigmodel.cn/api/paas/v4",model:"glm-4.5",protocol:"openai-chat"},local:{baseUrl:"http://127.0.0.1:8080/v1",model:"Qwen3-8B-Q4_K_M",protocol:"openai-chat",keyless:!0},ollama:{baseUrl:"http://127.0.0.1:11434/v1",model:"llama3.2",protocol:"openai-chat",keyless:!0}}),U=Object.freeze({"anthropic-oauth":{key:"ANTHROPIC_API_KEY",baseUrl:"https://api.anthropic.com/v1",model:"claude-sonnet-4-20250514",protocol:"anthropic-messages"},"openai-codex":{key:"OPENAI_API_KEY",baseUrl:"https://chatgpt.com/backend-api/codex",model:"gpt-5.6-sol",protocol:"responses"},"xai-oauth":{key:"XAI_API_KEY",baseUrl:"https://api.x.ai/v1",model:"grok-4.6",protocol:"responses"}});var H=Object.freeze(["xai-oauth","anthropic-oauth","openai-codex"]);function k(){return s().map(e=>({name:e.id,bin:e.bins?.[0]||e.id,label:e.label,kind:e.kind,altBins:(e.bins||[]).slice(1)}))}function h(e){for(let n of(process.env.PATH||"").split(b.delimiter)){let o=b.join(n,e);try{if(A.existsSync(o))return o}catch{}}return null}function v(e){let n=[e.bin,...e.altBins||[]].filter(Boolean);for(let o of n){let t=h(o);if(t)return t}return null}function m(e=process.env){let n=[];for(let t of k()){if(t.kind==="oracle"||t.name==="oracle"){n.push({...t,path:process.argv[1]||"oracle"});continue}let i=v(t);i&&n.push({name:t.name,bin:t.bin,label:t.label,kind:t.kind,path:i})}let o=String(e.ORACLE_HARNESS_EXTRA||e.ORACLE_CLIENT_EXTRA||"").split(",").map(t=>t.trim()).filter(Boolean);for(let t of o){if(n.some(r=>r.bin===t||r.name===t))continue;let i=h(t);i&&n.push({name:t,bin:t,label:t,kind:"mcp",path:i})}return n}function L(e){if(e.kind==="oracle"||e.name==="oracle")return{...e,direction:"native",integrate:"oracle chat",outbound:"oracle chat",inbound:null,plugins:null,backendEnv:null,note:"Oracle native harness. Default. No external harness required."};let n=d(e.name)||"generic",o=e.name==="hermes"?"hermes":e.name;return{...e,direction:"client",integrate:`oracle mcp install ${n}`,outbound:`oracle chat --backend ${o}`,inbound:`oracle mcp install ${n}`,plugins:"oracle plugins install <path|git-url>",backendEnv:`ORACLE_CHAT_BACKEND=${o}`,note:"Use through Oracle (`oracle chat --backend \u2026`) or wire Oracle into this harness (`oracle mcp install`). Detection never auto-selects."}}function E(e){let n=e.map(L),o=n.find(a=>a.direction==="native"),t=n.filter(a=>a.direction!=="native"),i=c().filter(a=>a.kind==="mcp"),r=[];if(r.push(""),r.push("Three ways to run Oracle:"),r.push(` 1) Oracle native harness ${o?o.path:"oracle"}`),r.push(" oracle setup model && oracle chat"),r.push(" 2) Through Oracle attach Hermes / Claude / Codex as the engine"),r.push(" oracle chat --backend hermes"),r.push(" 3) Into your harness wire Oracle MCP into the agent you already use"),r.push(" oracle mcp install <target> | oracle plugins install <path>"),r.push(""),r.push("Oracle native is the default harness. Detection never auto-selects another harness."),r.push(""),r.push("Detected on this machine:"),t.length===0)r.push(" (none, Oracle native is enough)");else for(let a of t)r.push(` ${a.label.padEnd(22)} ${a.path}`),r.push(` ${" ".repeat(22)} \u2192 through Oracle: ${a.outbound}`),r.push(` ${" ".repeat(22)} into harness: ${a.inbound}`);r.push(""),r.push("Supported harness roster (MCP install targets):");for(let a of i){let f=u(a.id),g=t.find(O=>O.name===a.id);r.push(` ${a.label.padEnd(22)} ${f}${g?" [detected]":""}`)}return r.push(""),r.push("Also:"),r.push(" oracle mcp print --target generic"),r.push(" oracle plugins list"),r.push(" ORACLE_HARNESS_EXTRA=foo,bar # detect extra bins"),r.push(""),r.push("Models on the site (Grok, Gemini, DeepSeek, Qwen, Kimi) are providers for"),r.push("Oracle native, configure with oracle setup model / oracle auth, not as harnesses."),r.join(`
2
+ `)}function p(){return["oracle harness, detect installed agent harnesses",""," oracle harness detect scan PATH + show supported harness roster"," oracle harness list alias of detect","","Modes:"," Oracle native harness oracle chat"," Through Oracle oracle chat --backend hermes|claude|codex|\u2026"," Into your harness oracle mcp install <target>","",`Harness roster: ${c().map(n=>n.id).join(", ")}`,"Extra bins: ORACLE_HARNESS_EXTRA=foo,bar","","Detection never selects a backend."].join(`
3
+ `)}var W={name:"harness",aliases:["clients"],summary:"detect agent harnesses; use Oracle native or wire MCP into them",usage:p,async run(e,n){let o=e[0];if(o==="help"||o==="--help"||o==="-h")return process.stdout.write(p()+`
4
4
  `),0;if(o&&o!=="detect"&&o!=="list")return process.stderr.write(`oracle harness: unknown subcommand '${o}'
5
5
  `),process.stderr.write(p()+`
6
- `),1;let t=h();return process.stdout.write(E(t)+`
7
- `),0}};export{l as HARNESS_ROSTER,L as classifyHarness,B as default,E as renderHarnessReport,s as websiteHarnesses};
6
+ `),1;let t=m();return process.stdout.write(E(t)+`
7
+ `),0}};export{l as HARNESS_ROSTER,L as classifyHarness,W as default,E as renderHarnessReport,c as websiteHarnesses};