@oracle-agent/oracle 0.35.39 → 0.35.41

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 (107) hide show
  1. package/dist/agent-sessions.mjs +11 -11
  2. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  3. package/dist/bin/desk-server.mjs +28 -28
  4. package/dist/bin/oracle-data-mcp.mjs +19 -19
  5. package/dist/bin/oracle-gateway.mjs +43 -43
  6. package/dist/bin/oracle-investigate.mjs +5 -5
  7. package/dist/bin/oracle-launch-radar-shadow.mjs +6 -6
  8. package/dist/bin/oracle-mev-arb-shadow.mjs +6 -6
  9. package/dist/bin/oracle-mev-shadow.mjs +6 -6
  10. package/dist/bin/oracle-public-server.mjs +5 -5
  11. package/dist/bin/oracle-route.mjs +18 -18
  12. package/dist/bin/oracle-scan.mjs +11 -11
  13. package/dist/cli/commands/agent-session.mjs +18 -18
  14. package/dist/cli/commands/airdrop.mjs +8 -8
  15. package/dist/cli/commands/chat.mjs +207 -207
  16. package/dist/cli/commands/doctor.mjs +9 -9
  17. package/dist/cli/commands/eval.mjs +147 -197
  18. package/dist/cli/commands/farm.mjs +17 -17
  19. package/dist/cli/commands/follow.mjs +17 -17
  20. package/dist/cli/commands/mint.mjs +10 -10
  21. package/dist/cli/commands/model.mjs +211 -211
  22. package/dist/cli/commands/quickstart.mjs +6 -6
  23. package/dist/cli/commands/receipt.mjs +12 -12
  24. package/dist/cli/commands/resolve.mjs +7 -7
  25. package/dist/cli/commands/sign.mjs +4 -4
  26. package/dist/cli/commands/signer.mjs +14 -14
  27. package/dist/cli/commands/snipe.mjs +9 -9
  28. package/dist/cli/commands/strategy.mjs +4 -4
  29. package/dist/cli/commands/swap.mjs +14 -14
  30. package/dist/cli/commands/venues.mjs +2 -2
  31. package/dist/data/desk-data.mjs +26 -26
  32. package/dist/data/names.mjs +3 -3
  33. package/dist/data/providers/farming.mjs +2 -2
  34. package/dist/data/providers/lp-destination-discovery.mjs +4 -4
  35. package/dist/index.mjs +44 -44
  36. package/dist/investigator/index.mjs +2 -2
  37. package/dist/launch-radar/index.mjs +5 -5
  38. package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
  39. package/dist/local-signer/index.mjs +2 -2
  40. package/dist/local-signer/runtime.mjs +8 -8
  41. package/dist/nft/universal-mint-router.mjs +4 -4
  42. package/dist/notifications/index.mjs +7 -7
  43. package/dist/router/index.mjs +3 -3
  44. package/dist/router/prepare-bridge.mjs +2 -2
  45. package/dist/router/prepare-route.mjs +3 -3
  46. package/dist/scanner/index.mjs +4 -4
  47. package/dist/strategy/index.mjs +3 -3
  48. package/dist/teams/index.mjs +6 -6
  49. package/dist/tui/standalone-client.mjs +82 -82
  50. package/package.json +4 -4
  51. package/public/eval-report.json +3 -3
  52. package/public/oracle-splash/_variants/ice.html +2 -4
  53. package/public/oracle-splash/_variants/ivory.html +2 -4
  54. package/public/oracle-splash/assets/fonts/LICENSE-Cormorant-Garamond.txt +93 -0
  55. package/public/oracle-splash/assets/fonts/LICENSE-IBM-Plex-Mono.txt +93 -0
  56. package/public/oracle-splash/assets/fonts/LICENSE-Outfit.txt +93 -0
  57. package/public/oracle-splash/assets/fonts/LICENSE-UnifrakturCook.txt +94 -0
  58. package/public/oracle-splash/assets/fonts/font-provenance.json +426 -0
  59. package/public/oracle-splash/assets/fonts/oracle-font-00.woff2 +0 -0
  60. package/public/oracle-splash/assets/fonts/oracle-font-01.woff2 +0 -0
  61. package/public/oracle-splash/assets/fonts/oracle-font-02.woff2 +0 -0
  62. package/public/oracle-splash/assets/fonts/oracle-font-03.woff2 +0 -0
  63. package/public/oracle-splash/assets/fonts/oracle-font-04.woff2 +0 -0
  64. package/public/oracle-splash/assets/fonts/oracle-font-05.woff2 +0 -0
  65. package/public/oracle-splash/assets/fonts/oracle-font-06.woff2 +0 -0
  66. package/public/oracle-splash/assets/fonts/oracle-font-07.woff2 +0 -0
  67. package/public/oracle-splash/assets/fonts/oracle-font-08.woff2 +0 -0
  68. package/public/oracle-splash/assets/fonts/oracle-font-09.woff2 +0 -0
  69. package/public/oracle-splash/assets/fonts/oracle-font-10.woff2 +0 -0
  70. package/public/oracle-splash/assets/fonts/oracle-font-11.woff2 +0 -0
  71. package/public/oracle-splash/assets/fonts/oracle-font-12.woff2 +0 -0
  72. package/public/oracle-splash/assets/fonts/oracle-font-13.woff2 +0 -0
  73. package/public/oracle-splash/assets/fonts/oracle-font-14.woff2 +0 -0
  74. package/public/oracle-splash/assets/fonts/oracle-font-15.woff2 +0 -0
  75. package/public/oracle-splash/assets/fonts/oracle-font-16.woff2 +0 -0
  76. package/public/oracle-splash/assets/fonts/oracle-font-17.woff2 +0 -0
  77. package/public/oracle-splash/assets/fonts/oracle-font-18.woff2 +0 -0
  78. package/public/oracle-splash/assets/fonts/oracle-font-19.woff2 +0 -0
  79. package/public/oracle-splash/assets/fonts/oracle-font-20.woff2 +0 -0
  80. package/public/oracle-splash/assets/fonts/oracle-font-21.woff2 +0 -0
  81. package/public/oracle-splash/assets/fonts/oracle-font-22.woff2 +0 -0
  82. package/public/oracle-splash/assets/fonts/oracle-font-23.woff2 +0 -0
  83. package/public/oracle-splash/assets/fonts/oracle-font-24.woff2 +0 -0
  84. package/public/oracle-splash/assets/fonts/oracle-font-25.woff2 +0 -0
  85. package/public/oracle-splash/assets/fonts/oracle-font-26.woff2 +0 -0
  86. package/public/oracle-splash/assets/fonts/oracle-font-27.woff2 +0 -0
  87. package/public/oracle-splash/assets/fonts/oracle-fonts.css +504 -0
  88. package/public/oracle-splash/assets/transport-probe-sw.js +2 -0
  89. package/public/oracle-splash/docs/browser-and-web/index.html +6 -6
  90. package/public/oracle-splash/docs/connectors/index.html +5 -5
  91. package/public/oracle-splash/docs/docs.css +4 -4
  92. package/public/oracle-splash/docs/docs.js +119 -7
  93. package/public/oracle-splash/docs/getting-started/index.html +5 -5
  94. package/public/oracle-splash/docs/index.html +6 -6
  95. package/public/oracle-splash/docs/reference/index.html +5 -5
  96. package/public/oracle-splash/docs/security/index.html +5 -5
  97. package/public/oracle-splash/docs/using-oracle/index.html +5 -5
  98. package/public/oracle-splash/download/index.html +8 -10
  99. package/public/oracle-splash/downloads/index.html +3 -5
  100. package/public/oracle-splash/eval/index.html +96 -0
  101. package/public/oracle-splash/index.html +16 -18
  102. package/public/oracle-splash/mesh-graph.svg +1 -1
  103. package/public/oracle-splash/pricing/index.html +6 -8
  104. package/public/oracle-splash/security/index.html +3 -5
  105. package/public/oracle-splash/what-it-does/index.html +4 -6
  106. package/public/oracle-splash/where-it-works/index.html +3 -5
  107. package/server.json +2 -2
@@ -1,61 +1,61 @@
1
1
  #!/usr/bin/env node
2
- var No=Object.defineProperty;var $=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var he=(e,t)=>{for(var n in t)No(e,n,{get:t[n],enumerable:!0})};import ie from"node:net";import Po from"node:dns";function Ye(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let n=d=>{if(!d)return[];let s=d.split(":"),p=s.at(-1);if(p?.includes(".")){let m=p.split(".").map(Number);if(m.length!==4||m.some(g=>!Number.isInteger(g)||g<0||g>255))return null;s.splice(s.length-1,1,(m[0]<<8|m[1]).toString(16),(m[2]<<8|m[3]).toString(16))}return s.some(m=>!/^[0-9a-f]{1,4}$/.test(m))?null:s.map(m=>Number.parseInt(m,16))},[r,o]=t.split("::"),i=n(r),a=n(o);if(!i||!a)return null;let c=t.includes("::"),l=8-i.length-a.length;if(!c&&l!==0||c&&l<1)return null;let u=[...i,...Array(Math.max(0,l)).fill(0),...a];return u.length!==8?null:Uint8Array.from(u.flatMap(d=>[d>>8,d&255]))}function wt(e,t,n){let r=Math.floor(n/8),o=n%8;for(let a=0;a<r;a+=1)if(e[a]!==t[a])return!1;if(!o)return!0;let i=255<<8-o;return(e[r]&i)===(t[r]&i)}function bt(e){if(ie.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(ie.isIPv6(e)){let t=Ye(e);if(!t)return!1;let n=Ye("::ffff:0:0");return wt(t,n,96)?bt([...t.slice(12)].join(".")):wt(t,Ye("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>wt(t,Ye(o),i)):!1}return!1}function Lo(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 n=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(Ro.has(n)||n.endsWith(".localhost")||n.endsWith(".internal"))return{ok:!1,error:`refused internal host ${n}`};let r=ie.isIP(n);return r!==0&&!bt(n)?{ok:!1,error:`refused private address ${n}`}:{ok:!0,url:t,host:n,isLiteralIp:r!==0}}async function St(e,{lookupFn:t=Po.promises.lookup}={}){let n=Lo(e);if(!n.ok)return n;if(n.isLiteralIp)return{ok:!0,url:n.url,addresses:[{address:n.host,family:ie.isIPv6(n.host)?6:4}]};let r;try{r=await t(n.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${n.host} did not resolve`}}return!Array.isArray(r)||r.length===0||r.some(o=>!bt(o.address))?{ok:!1,error:`refused: ${n.host} resolves to a non-public address`}:{ok:!0,url:n.url,addresses:r}}async function vt({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let n,r;try{let s=await t();n=s.Agent,r=s.fetch}catch(s){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${s?.message||s}`);return null}if(typeof n!="function"||typeof r!="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 o=s=>String(s).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,a=s=>(Array.isArray(s)?s:[s]).map(p=>typeof p=="string"?{address:p}:p).filter(p=>p&&p.address).map(p=>({address:p.address,family:p.family||(ie.isIPv6(p.address)?6:4)})),c=(s,p,m)=>{i.set(o(s),a(typeof p=="string"?[{address:p,family:m}]:p))},l=s=>{let p=o(s);if(ie.isIP(p))return[{address:p,family:ie.isIPv6(p)?6:4}];let m=i.get(p);if(!m||!m.length)throw new Error(`refused: unpinned host ${s} during pinned fetch`);return m},u=new n({connect:{lookup(s,p,m){let g;try{g=l(s)}catch(w){return m(w)}return p?.all?m(null,g):m(null,g[0].address,g[0].family)}}}),d=Uo((s,p={})=>r(s,{...p,dispatcher:u}),c);return{dispatcher:u,fetch:d,pin:c,resolve:l,async close(){try{await u.destroy()}catch{}}}}function Uo(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[xt]=Object.freeze({pin:t}),e}function Et(e){return typeof e=="function"&&typeof e[xt]?.pin=="function"}function vn(e,t,n){if(!Et(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[xt].pin(t,n)}var Ro,xt,xn=$(()=>{Ro=new Set(["localhost","metadata.google.internal","metadata.goog"]);xt=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as Fo}from"node:crypto";import{types as J}from"node:util";function F(e){return te(`HTTP JSON body refused: ${e}`)}function Wo(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 J[t]=="function"&&J[t](e))}function Go(e){let t=[],n=0,r=0,o=0,i=0,a=new WeakSet,c=d=>{if(n+=Buffer.byteLength(d,"utf8"),n>Y.bytes)throw F("serialized byte limit exceeded");t.push(d)},l=d=>{if(Buffer.byteLength(d,"utf8")>Y.bytes)throw F("serialized byte limit exceeded");return JSON.stringify(d)},u=(d,s)=>{if(r+=1,r>Y.nodes)throw F("node limit exceeded");if(s>Y.depth)throw F("depth limit exceeded");if(d===null){c("null");return}if(typeof d=="string"){c(l(d));return}if(typeof d=="boolean"){c(d?"true":"false");return}if(typeof d=="number"){if(!Number.isFinite(d))throw F("non-finite number");c(Object.is(d,-0)?"0":String(d));return}if(typeof d!="object")throw F("unsupported non-JSON value");if(J.isProxy(d))throw F("proxy value");if(Wo(d))throw F("unsupported exotic object");if(a.has(d))throw F("cyclic value");a.add(d);try{if(Object.getOwnPropertySymbols(d).length>0)throw F("symbol-keyed fields are unsupported");if(Array.isArray(d)){let g=Object.getPrototypeOf(d),w=0;for(;g!==null;){if(J.isProxy(g))throw F("proxy array prototype");if(w+=1,w>Y.depth)throw F("array prototype depth limit exceeded");g=Object.getPrototypeOf(g)}if(d.length>Y.arrayLength)throw F("array length limit exceeded");for(let E=0;E<d.length;E+=1){let N=Object.getOwnPropertyDescriptor(d,String(E));if(!N||!Object.hasOwn(N,"value")||N.enumerable!==!0)throw F("array entries must be dense enumerable own data")}let k=0;for(let E in d){if(i+=1,i>Y.fields)throw F("enumeration limit exceeded");if(Object.hasOwn(d,E)&&(k+=1,k>d.length))throw F("named array fields are unsupported")}if(k!==d.length)throw F("array entries must be dense enumerable own data");c("[");for(let E=0;E<d.length;E+=1)E&&c(","),u(Object.getOwnPropertyDescriptor(d,String(E)).value,s+1);c("]");return}let p=Object.getPrototypeOf(d);if(p!==Object.prototype&&p!==null)throw F("non-plain object");let m=[];for(let g in d){if(i+=1,i>Y.fields)throw F("enumeration limit exceeded");if(!Object.hasOwn(d,g))continue;if(o+=1,o>Y.fields)throw F("field limit exceeded");let w=Object.getOwnPropertyDescriptor(d,g);if(!w||!Object.hasOwn(w,"value")||w.enumerable!==!0)throw F("object fields must be enumerable own data");m.push([g,w.value])}c("{");for(let g=0;g<m.length;g+=1)g&&c(","),c(l(m[g][0])),c(":"),u(m[g][1],s+1);c("}")}finally{a.delete(d)}};return u(e,0),t.join("")}function Ko(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(J.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 n=new Set;for(let r of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(r))throw new TypeError("HTTP header names must be valid tokens");let o=r.toLowerCase();if(n.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");n.add(o);let i=Object.getOwnPropertyDescriptor(e,r);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let a=i.value;if(a==null||["object","function","symbol"].includes(typeof a))throw new TypeError("HTTP header values must be scalar");t[r]=String(a)}return t}function Yo(){return Object.assign(Object.create(null),{Accept:"application/json"})}function Jo(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let n=new URL(String(e),String(t));if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${n.protocol}`);return n.toString()}function Qo(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Je(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=_n.get(e);return t||(t=In,In+=1,_n.set(e,t)),`reference:${t}`}function Cn(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?Xo.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 Tn(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let n=t;if(typeof t=="string")try{n=JSON.parse(t)}catch{return!1}if(Array.isArray(n))return n.length>0&&n.every(Cn);if(!n||typeof n!="object")return!1;if(Object.hasOwn(n,"jsonrpc")||Object.hasOwn(n,"method"))return Cn(n);let r=Object.hasOwn(n,"type")?n.type:null;return typeof r=="string"&&Zo.has(r)&&(!Object.hasOwn(n,"action")||n.action==null)&&(!Object.hasOwn(n,"signature")||n.signature==null)&&(!Object.hasOwn(n,"nonce")||n.nonce==null)}function ei(e,t,n,r={},o=null){let i=Fo("sha256"),a=(l,u)=>{let d=String(u);i.update(String(Buffer.byteLength(l,"utf8"))).update(":").update(l),i.update("=").update(String(Buffer.byteLength(d,"utf8"))).update(":").update(d).update(`
3
- `)};a("method",e),a("url",t),Object.keys(n||{}).map((l,u)=>({name:l.toLowerCase(),order:u,value:String(n[l])})).sort((l,u)=>l.name.localeCompare(u.name)||l.order-u.order).forEach((l,u)=>{a(`header-name-${u}`,l.name),a(`header-value-${u}`,l.value)}),a("body",o??"-");for(let l of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])a(`context-${l}`,r[l]??"-");return i.digest("hex")}function ti(e,t){let n=Number(t);return Number.isFinite(n)&&n>0?Math.min(n*1e3,An):Math.min(250*2**e,An)+Math.floor(Math.random()*100)}function te(e,t={}){let n=new Error(e);return n.retryable=!1,Object.assign(n,t),n}function kt(e,t,n){return te(`HTTP response from ${e} exceeded maxResponseBytes ${n} (${t})`,{oversize:!0})}function ae(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function ri(e){return e?e.byteLength??e.length??0:0}async function oi(e,t,{url:n,truncate:r=!1,onOversize:o}={}){if(t==null)return await e.text();let i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(ae(e),!r))throw kt(n,`content-length ${i}`,t);let a=e.body?.getReader?.();if(!a){let s=await e.text(),p=Buffer.byteLength(s,"utf8");if(p>t){if(!r)throw kt(n,`body ${p} bytes`,t);return Buffer.from(s,"utf8").subarray(0,t).toString("utf8")}return s}let c=[],l=0,u=!1;try{for(;;){let{value:s,done:p}=await a.read();if(p)break;if(s&&(c.push(Buffer.from(s)),l+=ri(s),l>t)){u=!0;break}}}finally{if(u)try{await a.cancel()}catch{}try{a.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!r))throw kt(n,`streamed ${l} bytes`,t);let d=Buffer.concat(c);return(u?d.subarray(0,t):d).toString("utf8")}function ii(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function ai(e,{fetchImpl:t,method:n,headers:r,body:o,timeoutMs:i,lookupFn:a,realFetch:c,untrustedUrl:l=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:d=!1,importUndici:s,validateResponse:p,signal:m,redirectPolicy:g="follow",maxRedirects:w=Qe}){let k=new AbortController,E=setTimeout(()=>k.abort(),i),N=m?kn?kn([m,k.signal]):m:k.signal,b=null,f=t,x=a?{lookupFn:a}:{};if(l&&!c&&!Et(f))throw te(`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 S=async(v,{status:I=null}={})=>{let T=await St(v,x);if(!T.ok)throw te(I==null?`HTTP refused ${v}: ${T.error}`:`HTTP redirect to ${v} ${T.error}`,I==null?{}:{status:I});let P=new URL(v).hostname;if(c){if(b&&(await b.close(),b=null),!b)try{b=await vt({requireUndici:!0,...s?{importUndici:s}:{}})}catch(h){throw te(I==null?`HTTP refused ${v}: ${h?.message||h}`:`HTTP redirect to ${v} refused: ${h?.message||h}`,I==null?{}:{status:I})}b.pin(P,T.addresses),f=b.fetch}else vn(f,P,T.addresses);return T};try{let v=String(e),I=Object.assign(Object.create(null),r||{});l&&await S(v);for(let T=0;T<=w;T+=1){let P=Object.assign(Object.create(null),{method:n,headers:I,body:o,signal:N,redirect:"manual",dispatcher:void 0}),h=await f(v,P);if((g==="error"||w===0)&&h.status>=300&&h.status<400)throw ae(h),te(`HTTP ${h.status} ${n} redirect refused`,{status:h.status,redirectRefused:!0});if(zo.has(h.status)){let R=d===!0&&n==="POST"&&[307,308].includes(h.status)&&Tn(n,o);if(n!=="GET"&&n!=="HEAD"&&!R){ae(h);let L=new Error(`HTTP ${h.status} ${n} ${v} redirected non-idempotent request`);throw L.status=h.status,L}if(T===w)throw ae(h),te(`HTTP ${h.status} ${n} redirect budget exhausted`,{status:h.status,redirectRefused:!0});let q=h.headers?.get?.("location"),j;try{j=Jo(q,v)}catch(L){throw ae(h),L}let H=!Qo(j,v);if(ae(h),H&&n==="POST"){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L}if(H&&d){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L.retryable=!1,L}if(H&&(I=Yo(I)),l)await S(j,{status:h.status});else if(H){let L=await St(j,x);if(!L.ok){let A=new Error(`HTTP redirect from ${v} ${L.error}`);throw A.status=h.status,A.retryable=!1,A}c&&L.addresses?.length&&(b||(b=await vt(s?{importUndici:s}:{})),b&&(b.pin(new URL(j).hostname,L.addresses),f=b.fetch))}v=j;continue}if(typeof p=="function")try{await p(h,{url:v})}catch(R){throw ae(h),te(R?.message||String(R))}let _=await oi(h,u,{url:v,onOversize:()=>k.abort()}),M=ii(_);if(!h.ok){let R=new Error(`HTTP ${h.status} ${n} ${v}`);throw R.status=h.status,R.retryAfter=h.headers?.get?.("retry-after")??null,R.body=M??_.slice(0,300),R}return M??_}throw new Error(`HTTP redirect loop for ${e}`)}catch(v){if(k.signal.aborted&&!_t(m)){let I=v&&(typeof v=="object"||typeof v=="function")&&!J.isProxy(v)?v:null,T=I?Object.getOwnPropertyDescriptor(I,"oversize"):null;if(!(T&&Object.hasOwn(T,"value")&&T.value===!0))try{if(!I)throw new TypeError("unsafe rejection");Object.defineProperties(I,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let h=new Error("HTTP request timed out");throw Object.defineProperties(h,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),h}}throw v}finally{clearTimeout(E),b&&await b.close()}}async function z(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&J.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let n=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 U=Object.getOwnPropertyDescriptor(t,A);if(!(A==="toJSON"&&U&&Object.hasOwn(U,"value")&&U.value===void 0)){if(!n.has(A))throw new TypeError("HTTP options contain unknown fields");if(!U||!U.enumerable||!Object.hasOwn(U,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let r=A=>{if(t==null||!Object.hasOwn(t,A))return;let U=Object.getOwnPropertyDescriptor(t,A);if(!U||!Object.hasOwn(U,"value"))throw new TypeError("HTTP options must contain own data properties");return U.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=r("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 i=r("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let a=r("retries");if(a!==void 0&&(!Number.isInteger(a)||a<0||a>10))throw new TypeError("HTTP retries must be a bounded integer");let c=r("redirectPolicy");if(c!==void 0&&c!=="follow"&&c!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let l=r("maxRedirects");if(l!==void 0&&(!Number.isInteger(l)||l<0||l>Qe))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${Qe}`);if(c==="error"&&l!==void 0&&l!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=c??"follow",d=u==="error"?0:l??Qe;for(let A of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let U=r(A);if(U!==void 0&&typeof U!="boolean")throw new TypeError(`HTTP ${A} must be boolean`)}let s=r("maxResponseBytes");if(s!==void 0&&(!Number.isInteger(s)||s<1||s>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let p=r("signal");if(p!==void 0){if(J.isProxy(p)||!(p instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{_t(p)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let A of["importUndici","lookupFn","validateResponse"]){let U=r(A);if(U!==void 0&&typeof U!="function")throw new TypeError(`HTTP ${A} must be a function`)}let m=r("fetchImpl"),g=m||globalThis.fetch;if(typeof g!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let w=i??12e3,k=(o||"GET").toUpperCase(),E=r("headers"),N=Ko(E),b=Object.assign(Object.create(null),N);Object.keys(b).some(A=>A.toLowerCase()==="accept")||(b.Accept="application/json");let f=r("body");f!=null&&typeof f!="string"&&(Object.keys(b).find(U=>U.toLowerCase()==="content-type")||(b["Content-Type"]="application/json"),f=Go(f));let x=a??Bo,S=r("lookupFn"),v=!m,I=r("untrustedUrl")===!0,T=r("sameOriginRedirectsOnly")===!0,P=r("importUndici"),h=r("validateResponse"),_=p,M=s??null,R=async()=>{let A;for(let U=0;U<=x;U++){_&&jo.call(_);try{return await ai(e,{fetchImpl:g,method:k,headers:b,body:f,timeoutMs:w,lookupFn:S,realFetch:v,untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:T,importUndici:P,validateResponse:h,signal:_,redirectPolicy:u,maxRedirects:d})}catch(K){A=K;let me=ht=>{if(!K||typeof K!="object"&&typeof K!="function"||J.isProxy(K))return;let Ne=Object.getOwnPropertyDescriptor(K,ht);return Ne&&Object.hasOwn(Ne,"value")?Ne.value:void 0},mt=me("status"),Io=me("oracleTimeout")===!0||me("name")==="AbortError"||me("name")==="TimeoutError"||_t(_),Co=new Set([408,425,429]),To=me("retryable")===!1?!1:mt!=null?Co.has(mt)||Mo.has(mt)&&En.has(k):!Io&&En.has(k);if(U===x||!To)throw K;let yn=ti(U,me("retryAfter"));_?await new Promise((ht,Ne)=>{let Oo=setTimeout(ht,yn);Ho.call(_,"abort",()=>{clearTimeout(Oo),Ne(Vo(_)||new DOMException("Aborted","AbortError"))},{once:!0})}):await ni(yn)}}throw A};if(!(r("dedupe")!==!1&&!_&&Tn(k,f)))return R();let j=ei(k,e,b,{untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:T,redirectPolicy:u,maxRedirects:d,timeoutMs:w,retries:x,fetchImpl:Je(g),realFetch:v,lookupFn:Je(S),importUndici:Je(P),validateResponse:Je(h)},f),H=At.get(j);if(H)return H;let L=R().finally(()=>At.delete(j));return At.set(j,L),L}async function Xe(e){let t=Date.now();try{let n=await e();return{ok:!0,ms:Date.now()-t,data:n}}catch(n){return{ok:!1,ms:Date.now()-t,error:String(n.message||n),status:n.status??null}}}async function $e(e,t,n){let r=Array.from(e),o=Math.max(1,Math.min(Number(t)||1,r.length||1)),i=new Array(r.length),a=0;return await Promise.all(Array.from({length:o},async()=>{for(;a<r.length;){let c=a++;i[c]=await n(r[c],c)}})),i}var Mo,En,Bo,An,qo,Do,jo,Ho,kn,_t,Vo,zo,Qe,Mc,Y,At,_n,In,Xo,Zo,ni,V=$(()=>{xn();Mo=new Set([408,425,429,500,502,503,504]),En=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Bo=2,An=4e3,qo=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Do=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,jo=AbortSignal.prototype.throwIfAborted,Ho=EventTarget.prototype.addEventListener,kn=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,_t=e=>e?qo.call(e):!1,Vo=e=>e?Do.call(e):void 0,zo=new Set([301,302,303,307,308]),Qe=3,Mc=64*1024,Y=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});At=new Map,_n=new WeakMap,In=1;Xo=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),Zo=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);ni=e=>new Promise(t=>setTimeout(t,e))});function It(e){return si.get(Number(e))||null}var On,si,Ct=$(()=>{On={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},si=new Map(Object.values(On).map(e=>[e.chainId,e]))});import{Interface as ci,getAddress as Wc}from"ethers";var Gc,Pe=$(()=>{V();Ct();Gc=new ci(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});function ce(e,t=160){return String(e??"").replace(/[\u0000-\u001f\u007f]/g," ").slice(0,t)}function Ft(e){let t=Number(e);return Number.isFinite(t)?t:null}function we(e,t={},n=process.env){let r=String(e||"").trim().toUpperCase().replace(/[^A-Z0-9]/g,"");if(!r)return[];let o=String(n[`ORACLE_OWNER_${r}`]||"").split(/[\s,;]+/).filter(Boolean),i=Array.isArray(t.owners)?t.owners.map(String):[];return[...new Set([...o,...i].map(a=>a.trim()).filter(Boolean))]}function pa(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",n=Ft(e.fromFloor),r=Ft(e.floor),o=Ft(e.changePct),i=ce(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
2
+ var Po=Object.defineProperty;var $=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var he=(e,t)=>{for(var n in t)Po(e,n,{get:t[n],enumerable:!0})};import ie from"node:net";import Lo from"node:dns";function Qe(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let n=d=>{if(!d)return[];let s=d.split(":"),p=s.at(-1);if(p?.includes(".")){let m=p.split(".").map(Number);if(m.length!==4||m.some(g=>!Number.isInteger(g)||g<0||g>255))return null;s.splice(s.length-1,1,(m[0]<<8|m[1]).toString(16),(m[2]<<8|m[3]).toString(16))}return s.some(m=>!/^[0-9a-f]{1,4}$/.test(m))?null:s.map(m=>Number.parseInt(m,16))},[r,o]=t.split("::"),i=n(r),a=n(o);if(!i||!a)return null;let c=t.includes("::"),l=8-i.length-a.length;if(!c&&l!==0||c&&l<1)return null;let u=[...i,...Array(Math.max(0,l)).fill(0),...a];return u.length!==8?null:Uint8Array.from(u.flatMap(d=>[d>>8,d&255]))}function St(e,t,n){let r=Math.floor(n/8),o=n%8;for(let a=0;a<r;a+=1)if(e[a]!==t[a])return!1;if(!o)return!0;let i=255<<8-o;return(e[r]&i)===(t[r]&i)}function vt(e){if(ie.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(ie.isIPv6(e)){let t=Qe(e);if(!t)return!1;let n=Qe("::ffff:0:0");return St(t,n,96)?vt([...t.slice(12)].join(".")):St(t,Qe("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>St(t,Qe(o),i)):!1}return!1}function Fo(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 n=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(Uo.has(n)||n.endsWith(".localhost")||n.endsWith(".internal"))return{ok:!1,error:`refused internal host ${n}`};let r=ie.isIP(n);return r!==0&&!vt(n)?{ok:!1,error:`refused private address ${n}`}:{ok:!0,url:t,host:n,isLiteralIp:r!==0}}async function xt(e,{lookupFn:t=Lo.promises.lookup}={}){let n=Fo(e);if(!n.ok)return n;if(n.isLiteralIp)return{ok:!0,url:n.url,addresses:[{address:n.host,family:ie.isIPv6(n.host)?6:4}]};let r;try{r=await t(n.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${n.host} did not resolve`}}return!Array.isArray(r)||r.length===0||r.some(o=>!vt(o.address))?{ok:!1,error:`refused: ${n.host} resolves to a non-public address`}:{ok:!0,url:n.url,addresses:r}}async function Et({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let n,r;try{let s=await t();n=s.Agent,r=s.fetch}catch(s){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${s?.message||s}`);return null}if(typeof n!="function"||typeof r!="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 o=s=>String(s).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,a=s=>(Array.isArray(s)?s:[s]).map(p=>typeof p=="string"?{address:p}:p).filter(p=>p&&p.address).map(p=>({address:p.address,family:p.family||(ie.isIPv6(p.address)?6:4)})),c=(s,p,m)=>{i.set(o(s),a(typeof p=="string"?[{address:p,family:m}]:p))},l=s=>{let p=o(s);if(ie.isIP(p))return[{address:p,family:ie.isIPv6(p)?6:4}];let m=i.get(p);if(!m||!m.length)throw new Error(`refused: unpinned host ${s} during pinned fetch`);return m},u=new n({connect:{lookup(s,p,m){let g;try{g=l(s)}catch(w){return m(w)}return p?.all?m(null,g):m(null,g[0].address,g[0].family)}}}),d=Mo((s,p={})=>r(s,{...p,dispatcher:u}),c);return{dispatcher:u,fetch:d,pin:c,resolve:l,async close(){try{await u.destroy()}catch{}}}}function Mo(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[At]=Object.freeze({pin:t}),e}function kt(e){return typeof e=="function"&&typeof e[At]?.pin=="function"}function En(e,t,n){if(!kt(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[At].pin(t,n)}var Uo,At,An=$(()=>{Uo=new Set(["localhost","metadata.google.internal","metadata.goog"]);At=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as Bo}from"node:crypto";import{types as J}from"node:util";function F(e){return te(`HTTP JSON body refused: ${e}`)}function Ko(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 J[t]=="function"&&J[t](e))}function Yo(e){let t=[],n=0,r=0,o=0,i=0,a=new WeakSet,c=d=>{if(n+=Buffer.byteLength(d,"utf8"),n>Y.bytes)throw F("serialized byte limit exceeded");t.push(d)},l=d=>{if(Buffer.byteLength(d,"utf8")>Y.bytes)throw F("serialized byte limit exceeded");return JSON.stringify(d)},u=(d,s)=>{if(r+=1,r>Y.nodes)throw F("node limit exceeded");if(s>Y.depth)throw F("depth limit exceeded");if(d===null){c("null");return}if(typeof d=="string"){c(l(d));return}if(typeof d=="boolean"){c(d?"true":"false");return}if(typeof d=="number"){if(!Number.isFinite(d))throw F("non-finite number");c(Object.is(d,-0)?"0":String(d));return}if(typeof d!="object")throw F("unsupported non-JSON value");if(J.isProxy(d))throw F("proxy value");if(Ko(d))throw F("unsupported exotic object");if(a.has(d))throw F("cyclic value");a.add(d);try{if(Object.getOwnPropertySymbols(d).length>0)throw F("symbol-keyed fields are unsupported");if(Array.isArray(d)){let g=Object.getPrototypeOf(d),w=0;for(;g!==null;){if(J.isProxy(g))throw F("proxy array prototype");if(w+=1,w>Y.depth)throw F("array prototype depth limit exceeded");g=Object.getPrototypeOf(g)}if(d.length>Y.arrayLength)throw F("array length limit exceeded");for(let A=0;A<d.length;A+=1){let T=Object.getOwnPropertyDescriptor(d,String(A));if(!T||!Object.hasOwn(T,"value")||T.enumerable!==!0)throw F("array entries must be dense enumerable own data")}let E=0;for(let A in d){if(i+=1,i>Y.fields)throw F("enumeration limit exceeded");if(Object.hasOwn(d,A)&&(E+=1,E>d.length))throw F("named array fields are unsupported")}if(E!==d.length)throw F("array entries must be dense enumerable own data");c("[");for(let A=0;A<d.length;A+=1)A&&c(","),u(Object.getOwnPropertyDescriptor(d,String(A)).value,s+1);c("]");return}let p=Object.getPrototypeOf(d);if(p!==Object.prototype&&p!==null)throw F("non-plain object");let m=[];for(let g in d){if(i+=1,i>Y.fields)throw F("enumeration limit exceeded");if(!Object.hasOwn(d,g))continue;if(o+=1,o>Y.fields)throw F("field limit exceeded");let w=Object.getOwnPropertyDescriptor(d,g);if(!w||!Object.hasOwn(w,"value")||w.enumerable!==!0)throw F("object fields must be enumerable own data");m.push([g,w.value])}c("{");for(let g=0;g<m.length;g+=1)g&&c(","),c(l(m[g][0])),c(":"),u(m[g][1],s+1);c("}")}finally{a.delete(d)}};return u(e,0),t.join("")}function Jo(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(J.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 n=new Set;for(let r of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(r))throw new TypeError("HTTP header names must be valid tokens");let o=r.toLowerCase();if(n.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");n.add(o);let i=Object.getOwnPropertyDescriptor(e,r);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let a=i.value;if(a==null||["object","function","symbol"].includes(typeof a))throw new TypeError("HTTP header values must be scalar");t[r]=String(a)}return t}function Qo(){return Object.assign(Object.create(null),{Accept:"application/json"})}function Xo(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let n=new URL(String(e),String(t));if(n.protocol!=="http:"&&n.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${n.protocol}`);return n.toString()}function Zo(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Xe(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=Tn.get(e);return t||(t=On,On+=1,Tn.set(e,t)),`reference:${t}`}function Nn(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?ei.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 $n(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let n=t;if(typeof t=="string")try{n=JSON.parse(t)}catch{return!1}if(Array.isArray(n))return n.length>0&&n.every(Nn);if(!n||typeof n!="object")return!1;if(Object.hasOwn(n,"jsonrpc")||Object.hasOwn(n,"method"))return Nn(n);let r=Object.hasOwn(n,"type")?n.type:null;return typeof r=="string"&&ti.has(r)&&(!Object.hasOwn(n,"action")||n.action==null)&&(!Object.hasOwn(n,"signature")||n.signature==null)&&(!Object.hasOwn(n,"nonce")||n.nonce==null)}function ni(e,t,n,r={},o=null){let i=Bo("sha256"),a=(l,u)=>{let d=String(u);i.update(String(Buffer.byteLength(l,"utf8"))).update(":").update(l),i.update("=").update(String(Buffer.byteLength(d,"utf8"))).update(":").update(d).update(`
3
+ `)};a("method",e),a("url",t),Object.keys(n||{}).map((l,u)=>({name:l.toLowerCase(),order:u,value:String(n[l])})).sort((l,u)=>l.name.localeCompare(u.name)||l.order-u.order).forEach((l,u)=>{a(`header-name-${u}`,l.name),a(`header-value-${u}`,l.value)}),a("body",o??"-");for(let l of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])a(`context-${l}`,r[l]??"-");return i.digest("hex")}function ri(e,t){let n=Number(t);return Number.isFinite(n)&&n>0?Math.min(n*1e3,_n):Math.min(250*2**e,_n)+Math.floor(Math.random()*100)}function te(e,t={}){let n=new Error(e);return n.retryable=!1,Object.assign(n,t),n}function It(e,t,n){return te(`HTTP response from ${e} exceeded maxResponseBytes ${n} (${t})`,{oversize:!0})}function ae(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function ii(e){return e?e.byteLength??e.length??0:0}async function ai(e,t,{url:n,truncate:r=!1,onOversize:o}={}){if(t==null)return await e.text();let i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(ae(e),!r))throw It(n,`content-length ${i}`,t);let a=e.body?.getReader?.();if(!a){let s=await e.text(),p=Buffer.byteLength(s,"utf8");if(p>t){if(!r)throw It(n,`body ${p} bytes`,t);return Buffer.from(s,"utf8").subarray(0,t).toString("utf8")}return s}let c=[],l=0,u=!1;try{for(;;){let{value:s,done:p}=await a.read();if(p)break;if(s&&(c.push(Buffer.from(s)),l+=ii(s),l>t)){u=!0;break}}}finally{if(u)try{await a.cancel()}catch{}try{a.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!r))throw It(n,`streamed ${l} bytes`,t);let d=Buffer.concat(c);return(u?d.subarray(0,t):d).toString("utf8")}function si(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function ci(e,{fetchImpl:t,method:n,headers:r,body:o,timeoutMs:i,lookupFn:a,realFetch:c,untrustedUrl:l=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:d=!1,importUndici:s,validateResponse:p,signal:m,redirectPolicy:g="follow",maxRedirects:w=Ze}){let E=null,A=t,T=a?{lookupFn:a}:{};if(l&&!c&&!kt(A))throw te(`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,f=setTimeout(()=>v.abort(),i),x=m?Cn?Cn([m,v.signal]):m:v.signal,b=async(S,{status:I=null}={})=>{let O=await xt(S,T);if(!O.ok)throw te(I==null?`HTTP refused ${S}: ${O.error}`:`HTTP redirect to ${S} ${O.error}`,I==null?{}:{status:I});let P=new URL(S).hostname;if(c){if(E&&(await E.close(),E=null),!E)try{E=await Et({requireUndici:!0,...s?{importUndici:s}:{}})}catch(h){throw te(I==null?`HTTP refused ${S}: ${h?.message||h}`:`HTTP redirect to ${S} refused: ${h?.message||h}`,I==null?{}:{status:I})}E.pin(P,O.addresses),A=E.fetch}else En(A,P,O.addresses);return O};try{let S=String(e),I=Object.assign(Object.create(null),r||{});l&&await b(S);for(let O=0;O<=w;O+=1){let P=Object.assign(Object.create(null),{method:n,headers:I,body:o,signal:x,redirect:"manual",dispatcher:void 0}),h=await A(S,P);if((g==="error"||w===0)&&h.status>=300&&h.status<400)throw ae(h),te(`HTTP ${h.status} ${n} redirect refused`,{status:h.status,redirectRefused:!0});if(Go.has(h.status)){let R=d===!0&&n==="POST"&&[307,308].includes(h.status)&&$n(n,o);if(n!=="GET"&&n!=="HEAD"&&!R){ae(h);let L=new Error(`HTTP ${h.status} ${n} ${S} redirected non-idempotent request`);throw L.status=h.status,L}if(O===w)throw ae(h),te(`HTTP ${h.status} ${n} redirect budget exhausted`,{status:h.status,redirectRefused:!0});let q=h.headers?.get?.("location"),j;try{j=Xo(q,S)}catch(L){throw ae(h),L}let H=!Zo(j,S);if(ae(h),H&&n==="POST"){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L}if(H&&d){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L.retryable=!1,L}if(H&&(I=Qo(I)),l)await b(j,{status:h.status});else if(H){let L=await xt(j,T);if(!L.ok){let _=new Error(`HTTP redirect from ${S} ${L.error}`);throw _.status=h.status,_.retryable=!1,_}c&&L.addresses?.length&&(E||(E=await Et(s?{importUndici:s}:{})),E&&(E.pin(new URL(j).hostname,L.addresses),A=E.fetch))}S=j;continue}if(typeof p=="function")try{await p(h,{url:S})}catch(R){throw ae(h),te(R?.message||String(R))}let k=await ai(h,u,{url:S,onOversize:()=>v.abort()}),M=si(k);if(!h.ok){let R=new Error(`HTTP ${h.status} ${n} ${S}`);throw R.status=h.status,R.retryAfter=h.headers?.get?.("retry-after")??null,R.body=M??k.slice(0,300),R}return M??k}throw new Error(`HTTP redirect loop for ${e}`)}catch(S){if(v.signal.aborted&&!Pe(m)){let I=S&&(typeof S=="object"||typeof S=="function")&&!J.isProxy(S)?S:null,O=I?Object.getOwnPropertyDescriptor(I,"oversize"):null;if(!(O&&Object.hasOwn(O,"value")&&O.value===!0))try{if(!I)throw new TypeError("unsafe rejection");Object.defineProperties(I,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let h=new Error("HTTP request timed out");throw Object.defineProperties(h,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),h}}throw S}finally{clearTimeout(f),E&&await E.close()}}async function z(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&J.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let n=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 _ of Object.getOwnPropertyNames(t)){let U=Object.getOwnPropertyDescriptor(t,_);if(!(_==="toJSON"&&U&&Object.hasOwn(U,"value")&&U.value===void 0)){if(!n.has(_))throw new TypeError("HTTP options contain unknown fields");if(!U||!U.enumerable||!Object.hasOwn(U,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let r=_=>{if(t==null||!Object.hasOwn(t,_))return;let U=Object.getOwnPropertyDescriptor(t,_);if(!U||!Object.hasOwn(U,"value"))throw new TypeError("HTTP options must contain own data properties");return U.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=r("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 i=r("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let a=r("retries");if(a!==void 0&&(!Number.isInteger(a)||a<0||a>10))throw new TypeError("HTTP retries must be a bounded integer");let c=r("redirectPolicy");if(c!==void 0&&c!=="follow"&&c!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let l=r("maxRedirects");if(l!==void 0&&(!Number.isInteger(l)||l<0||l>Ze))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${Ze}`);if(c==="error"&&l!==void 0&&l!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=c??"follow",d=u==="error"?0:l??Ze;for(let _ of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let U=r(_);if(U!==void 0&&typeof U!="boolean")throw new TypeError(`HTTP ${_} must be boolean`)}let s=r("maxResponseBytes");if(s!==void 0&&(!Number.isInteger(s)||s<1||s>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let p=r("signal");if(p!==void 0){if(J.isProxy(p)||!(p instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{Pe(p)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let _ of["importUndici","lookupFn","validateResponse"]){let U=r(_);if(U!==void 0&&typeof U!="function")throw new TypeError(`HTTP ${_} must be a function`)}let m=r("fetchImpl"),g=m||globalThis.fetch;if(typeof g!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let w=i??12e3,E=(o||"GET").toUpperCase(),A=r("headers"),T=Jo(A),v=Object.assign(Object.create(null),T);Object.keys(v).some(_=>_.toLowerCase()==="accept")||(v.Accept="application/json");let f=r("body");f!=null&&typeof f!="string"&&(Object.keys(v).find(U=>U.toLowerCase()==="content-type")||(v["Content-Type"]="application/json"),f=Yo(f));let x=a??Do,b=r("lookupFn"),S=!m,I=r("untrustedUrl")===!0,O=r("sameOriginRedirectsOnly")===!0,P=r("importUndici"),h=r("validateResponse"),k=p,M=s??null,R=async()=>{let _;for(let U=0;U<=x;U++){k&&Vo.call(k);try{return await ci(e,{fetchImpl:g,method:E,headers:v,body:f,timeoutMs:w,lookupFn:b,realFetch:S,untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:O,importUndici:P,validateResponse:h,signal:k,redirectPolicy:u,maxRedirects:d})}catch(K){_=K;let me=gt=>{if(!K||typeof K!="object"&&typeof K!="function"||J.isProxy(K))return;let Ne=Object.getOwnPropertyDescriptor(K,gt);return Ne&&Object.hasOwn(Ne,"value")?Ne.value:void 0},yt=me("status"),Oo=me("oracleTimeout")===!0||me("name")==="AbortError"||me("name")==="TimeoutError"||Pe(k),No=new Set([408,425,429]),$o=me("retryable")===!1?!1:yt!=null?No.has(yt)||qo.has(yt)&&kn.has(E):!Oo&&kn.has(E);if(U===x||!$o)throw K;let gn=ri(U,me("retryAfter"));k?await new Promise((gt,Ne)=>{let wn,$e=()=>{clearTimeout(wn),In.call(k,"abort",$e),Ne(Wo(k)||new DOMException("Aborted","AbortError"))};if(Pe(k)){$e();return}wn=setTimeout(()=>{In.call(k,"abort",$e),gt()},gn),zo.call(k,"abort",$e,{once:!0}),Pe(k)&&$e()}):await oi(gn)}}throw _};if(!(r("dedupe")!==!1&&!k&&$n(E,f)))return R();let j=ni(E,e,v,{untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:O,redirectPolicy:u,maxRedirects:d,timeoutMs:w,retries:x,fetchImpl:Xe(g),realFetch:S,lookupFn:Xe(b),importUndici:Xe(P),validateResponse:Xe(h)},f),H=_t.get(j);if(H)return H;let L=R().finally(()=>_t.delete(j));return _t.set(j,L),L}async function et(e){let t=Date.now();try{let n=await e();return{ok:!0,ms:Date.now()-t,data:n}}catch(n){return{ok:!1,ms:Date.now()-t,error:String(n.message||n),status:n.status??null}}}async function Re(e,t,n){let r=Array.from(e),o=Math.max(1,Math.min(Number(t)||1,r.length||1)),i=new Array(r.length),a=0;return await Promise.all(Array.from({length:o},async()=>{for(;a<r.length;){let c=a++;i[c]=await n(r[c],c)}})),i}var qo,kn,Do,_n,jo,Ho,Vo,zo,In,Cn,Pe,Wo,Go,Ze,qc,Y,_t,Tn,On,ei,ti,oi,V=$(()=>{An();qo=new Set([408,425,429,500,502,503,504]),kn=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Do=2,_n=4e3,jo=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Ho=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Vo=AbortSignal.prototype.throwIfAborted,zo=EventTarget.prototype.addEventListener,In=EventTarget.prototype.removeEventListener,Cn=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,Pe=e=>e?jo.call(e):!1,Wo=e=>e?Ho.call(e):void 0,Go=new Set([301,302,303,307,308]),Ze=3,qc=64*1024,Y=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});_t=new Map,Tn=new WeakMap,On=1;ei=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),ti=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);oi=e=>new Promise(t=>setTimeout(t,e))});function Ct(e){return li.get(Number(e))||null}var Pn,li,Tt=$(()=>{Pn={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}},li=new Map(Object.values(Pn).map(e=>[e.chainId,e]))});import{Interface as ui,getAddress as Kc}from"ethers";var Yc,Le=$(()=>{V();Tt();Yc=new ui(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});function ce(e,t=160){return String(e??"").replace(/[\u0000-\u001f\u007f]/g," ").slice(0,t)}function Mt(e){let t=Number(e);return Number.isFinite(t)?t:null}function we(e,t={},n=process.env){let r=String(e||"").trim().toUpperCase().replace(/[^A-Z0-9]/g,"");if(!r)return[];let o=String(n[`ORACLE_OWNER_${r}`]||"").split(/[\s,;]+/).filter(Boolean),i=Array.isArray(t.owners)?t.owners.map(String):[];return[...new Set([...o,...i].map(a=>a.trim()).filter(Boolean))]}function ma(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",n=Mt(e.fromFloor),r=Mt(e.floor),o=Mt(e.changePct),i=ce(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
4
4
 
5
5
  ${[`Collection: ${ce(e.name||e.slug||"Unknown")}`,`Chain: ${ce(e.chain||"unknown")}`,`You hold: ${t}`,`Floor: ${n??"unknown"} \u2192 ${r??"unknown"} ${i}`,`Move: ${o===null?"unknown":`+${o}%`}`,`Contract: ${ce(e.contract||"unknown",64)}`,"Evidence: provider-estimated floor; not an executable bid or guaranteed liquidation value."].join(`
6
- `)}`}function Xn(e=[],t=""){let n=(Array.isArray(e)?e:[]).filter(c=>typeof c?.notifyRecipient=="function");if(!n.length)return null;let r=String(t||"").trim().toLowerCase(),o=r?n.filter(c=>String(c.platform||"").toLowerCase()===r):[],i=n.filter(c=>c.platform==="telegram"),a=o.length?o:i.length?i:n;for(let c of a){let l=[...new Set((Array.isArray(c.ownerIds)?c.ownerIds:[]).map(d=>String(d).trim()).filter(Boolean))];if(l.length!==1)continue;let u=ce(String(c.platform||"").toLowerCase(),32);if(u)return Object.freeze({platform:u,recipientId:l[0],target:c})}return null}function Zn(e){if(!e||typeof e.target?.notifyRecipient!="function")throw new TypeError("one recipient-bound notification subscription is required");let{target:t,recipientId:n}=e,r=ce(e.platform||t.platform||"unknown",32);return async function(i){let a=pa(i);try{let c=Number(await t.notifyRecipient(n,a,i)),l=Number.isSafeInteger(c)&&c>0?1:0;return{delivered:l,recipient:{platform:r,id:n},error:l?null:"delivery-failed"}}catch{return{delivered:0,recipient:{platform:r,id:n},error:"delivery-failed"}}}}function er({watchdog:e,intervalMs:t=3e5,setIntervalFn:n=setInterval,clearIntervalFn:r=clearInterval,onError:o=i=>process.stderr.write(`oracle-gateway: held NFT watchdog failed: ${ce(i?.message||i,200)}
7
- `)}={}){if(typeof e?.tick!="function")throw new TypeError("held NFT watchdog is required");if(!Number.isSafeInteger(t)||t<6e4||t>864e5)throw new TypeError("held NFT watchdog interval is out of range");let i=null,a=!1,c=async()=>{if(a)return{skipped:!0,reason:"tick-in-progress"};a=!0;try{return await e.tick()}catch(l){return o(l),{skipped:!0,reason:"tick-failed"}}finally{a=!1}};return Object.freeze({start(){i===null&&(c(),i=n(c,t),typeof i?.unref=="function"&&i.unref())},stop(){i!==null&&r(i),i=null},run:c})}var Ue=$(()=>{});var tr={};he(tr,{A2ABus:()=>Mt,normalizeName:()=>Fe});function Fe(e){return String(e||"").trim().toLowerCase().replace(/^@/,"")}var Mt,nr=$(()=>{Mt=class{constructor({maxHops:t=4,historyCap:n=200}={}){this.maxHops=t,this.historyCap=n,this.agents=new Map,this.history=[],this.seq=0}register(t,{role:n="",chains:r=[],handler:o}={}){let i=Fe(t);if(!i)throw new Error("a2a: agent name required");if(this.agents.has(i))throw new Error(`a2a: agent '${i}' already registered`);if(typeof o!="function")throw new Error(`a2a: agent '${i}' needs a handler`);return this.agents.set(i,{name:i,role:String(n),chains:r.map(String),handler:o}),this.agents.get(i)}unregister(t){this.agents.delete(Fe(t))}roster(){return[...this.agents.values()].map(({name:t,role:n,chains:r})=>({name:t,role:n,chains:r}))}async send({from:t,to:n,text:r,kind:o="consult",hops:i=0}={}){let a=Fe(t),c=Fe(n);if(!a||!this.agents.has(a))return{ok:!1,error:`a2a: unknown sender '${t}'`};if(!c||!this.agents.has(c))return{ok:!1,error:`a2a: unknown recipient '${n}' (roster: ${[...this.agents.keys()].join(", ")||"empty"})`};if(c===a)return{ok:!1,error:"a2a: self-send refused"};let l=String(r||"").trim().slice(0,8e3);if(!l)return{ok:!1,error:"a2a: empty message"};let u=Number(i)+1;if(u>this.maxHops)return this.record({from:a,to:c,kind:o,dropped:"hop-limit"}),{ok:!1,error:`a2a: hop limit ${this.maxHops} reached \u2014 dropped`};let d={id:`a2a-${Date.now()}-${++this.seq}`,from:a,to:c,kind:String(o),text:l,hops:u,ts:new Date().toISOString()};this.record(d);try{let s=await this.agents.get(c).handler(d);return s&&this.record({id:`${d.id}-reply`,from:c,to:a,kind:"reply",text:String(s).slice(0,8e3),hops:u,ts:new Date().toISOString()}),{ok:!0,reply:s||null,id:d.id}}catch(s){return{ok:!1,error:`a2a: '${c}' handler failed: ${s.message}`}}}record(t){this.history.push(t),this.history.length>this.historyCap&&this.history.splice(0,this.history.length-this.historyCap)}recent(t=20){return this.history.slice(-t)}}});import Me from"node:fs";import fa from"node:os";import Se from"node:path";import{fileURLToPath as ma}from"node:url";function Bt(){return process.env.ORACLE_FAKE_HOME||fa.homedir()}function ya(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function Q(){return ya()?process.env.ORACLE_CONFIG_DIR||Se.join(Bt(),".config","oracle"):Se.join(Bt(),".config","oracle")}function ga(){return Se.join(Q(),"desk.json")}function wa(){return Se.join(Q(),"env")}function be({force:e=!1}={}){if(be._done&&!e)return be._result||null;be._done=!0;let t={},n=(o,i)=>{if(i==null)return;let a=String(i).trim();a&&(process.env[o]!=null&&String(process.env[o]).trim()!==""||(process.env[o]=a,t[o]=a))};try{let o=wa();if(Me.existsSync(o))for(let i of Me.readFileSync(o,"utf8").split(/\r?\n/)){let a=i.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!a||a[2].startsWith("#"))continue;let c=a[2];(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),n(a[1],c)}}catch{}try{let o=ga();if(Me.existsSync(o)){let i=JSON.parse(Me.readFileSync(o,"utf8"));i&&typeof i=="object"&&(n("ORACLE_DESK_URL",i.deskUrl||i.dataUrl||i.url),n("ORACLE_DATA_URL",i.dataUrl||i.deskUrl||i.url),n("ORACLE_API_URL",i.apiUrl||i.dataUrl||i.deskUrl),n("ORACLE_PUBLIC_URL",i.publicUrl||i.deskUrl||i.dataUrl),n("ORACLE_EXEC_URL",i.execUrl),n("MAD_DESK_URL",i.deskUrl||i.dataUrl))}}catch{}let r=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return r&&(n("ORACLE_DESK_URL",r),n("ORACLE_DATA_URL",r),n("ORACLE_API_URL",r),n("ORACLE_PUBLIC_URL",r),n("MAD_DESK_URL",r)),be._result=Object.keys(t).length?t:null,be._result}function ot(e){return Me.mkdirSync(e,{recursive:!0}),e}var ha,Vd,it=$(()=>{ha=Se.dirname(ma(import.meta.url)),Vd=Se.resolve(ha,"../..");try{be()}catch{}});function at(e){return String(e||"").trim()||void 0}function Sa(e,{required:t=!1}={}){let n=at(e)?.toLowerCase();if(!n){if(t)throw new Error("model provider is required");return}if(!ba.has(n))throw new Error(`unsupported provider: ${n}`);return n}function va(e,{required:t=!1}={}){let n=at(e);if(!n){if(t)throw new Error("model is required");return}if(n.includes("..")||n.startsWith("/")||!/^[a-zA-Z0-9._:/-]{1,200}$/.test(n))throw new Error("invalid model id");return n}function xa(e){let t=at(e);if(!t||t.length>2048)throw new Error("invalid custom base URL");let n;try{n=new URL(t)}catch{throw new Error("invalid custom base URL")}let r=n.hostname.toLowerCase().replace(/^\[|\]$/g,""),o=r==="localhost"||r==="127.0.0.1"||r==="::1";if(n.protocol!=="https:"&&!(n.protocol==="http:"&&o)||n.username||n.password||n.search||n.hash)throw new Error("custom base URL must use HTTPS or loopback HTTP without credentials, query, or fragment");return n.toString().replace(/\/+$/,"")}function rr({provider:e,model:t,baseUrl:n}={},{requireModel:r=!1}={}){let o=Sa(e),i=va(t,{required:r});if(o==="custom")return{provider:o,...i?{model:i}:{},baseUrl:xa(n)};if(at(n))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...i?{model:i}:{}}}var ba,or=$(()=>{ba=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import xe from"node:fs";import qt from"node:path";function ir(){return qt.join(Q(),"model.json")}function ve(e){return String(e||"").trim()||void 0}function ar(e={}){let t=ve(e.backend)?.toLowerCase()||"auto",n=rr({provider:e.provider,model:e.model,baseUrl:e.baseUrl},{requireModel:t==="standalone"}),r=ve(e.apiKeyEnv),o=Number.parseInt(String(e.contextLength||""),10),i=ve(e.reasoningEffort),a=ve(e.computeHost||e.remoteHost),c=ve(e.computeUser||e.remoteUser),l=ve(e.computePath||e.remotePath);if(!Ea.has(t))throw new Error(`unsupported backend: ${t}`);if(process.env.ORACLE_PUBLIC_DESKTOP==="1"&&["remote","arch"].includes(t))throw new Error("remote compute backends are disabled in the public desktop");if(r&&!/^[A-Z][A-Z0-9_]*$/.test(r))throw new Error("api key env must be an uppercase environment variable name");if(t==="remote"&&!a)throw new Error("remote backend requires computeHost");return{backend:t,...n,...r?{apiKeyEnv:r}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...i?{reasoningEffort:i}:{},...a?{computeHost:a}:{},...c?{computeUser:c}:{},...l?{computePath:l}:{}}}function Ee(){let e=ir();if(!xe.existsSync(e))return null;try{return ar(JSON.parse(xe.readFileSync(e,"utf8")))}catch{return null}}function Dt(e){let t=ar(e),n=ir();ot(qt.dirname(n)),process.platform!=="win32"&&xe.chmodSync(qt.dirname(n),448);let r=`${n}.${process.pid}.tmp`;return xe.writeFileSync(r,`${JSON.stringify(t,null,2)}
8
- `,{mode:384}),xe.renameSync(r,n),process.platform!=="win32"&&xe.chmodSync(n,384),t}var Ea,sr=$(()=>{it();or();Ea=new Set(["auto","standalone","hermes","remote","arch"])});import{existsSync as Aa,readFileSync as ka}from"node:fs";import{request as _a}from"node:http";import Ia from"node:path";function Ta(e=process.env){let t=String(e.ORACLE_SIGNER_URL||Ca).replace(/\/$/,""),n;try{n=new URL(t)}catch{return null}return n.hostname!=="127.0.0.1"&&n.hostname!=="localhost"&&n.hostname!=="::1"?null:n.origin}function Oa(e=process.env){if(e.ORACLE_SIGNER_TOKEN)return String(e.ORACLE_SIGNER_TOKEN);let t=Ia.join(Q(),"signer","signer-token");return Aa(t)?ka(t,"utf8").trim():null}function le(e,{method:t="GET",body:n=null,env:r=process.env,timeoutMs:o=4e3}={}){let i=Ta(r),a=Oa(r);return!i||!a?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(c=>{let l=new URL(e,i),u=n?Buffer.from(JSON.stringify(n)):null,d=_a({hostname:l.hostname,port:l.port||80,path:l.pathname,method:t,timeout:o,headers:{authorization:`Bearer ${a}`,origin:i,...u?{"content-type":"application/json","content-length":u.length}:{}}},s=>{let p=[];s.on("data",m=>p.push(m)),s.on("end",()=>{let m=Buffer.concat(p).toString("utf8"),g={};try{g=m?JSON.parse(m):{}}catch{g={error:"signer refused"}}c({httpStatus:s.statusCode,...g})})});d.on("timeout",()=>{d.destroy(),c({ok:!1,error:"local signer timed out"})}),d.on("error",()=>c({ok:!1,error:"local signer is not running"})),u&&d.write(u),d.end()})}var Ca,st=$(()=>{it();Ca="http://127.0.0.1:9462"});function $a(e){let t=String(e||"").trim();if(!t||t.includes("ts.net")||!/^https:\/\//i.test(t))return null;try{return new URL(t)}catch{return null}}function cr(e,{coin:t,side:n,sizeUsd:r,leverage:o,venue:i,confirm:a,user:c}={}){let l=$a(e);if(!l)return null;if(t&&Na.test(String(t).toUpperCase())&&l.searchParams.set("coin",String(t).toUpperCase()),(n==="long"||n==="short")&&l.searchParams.set("side",n),Number.isFinite(Number(r))&&Number(r)>=1&&l.searchParams.set("size",String(Math.min(1e5,Math.round(Number(r))))),Number.isInteger(Number(o))&&Number(o)>=1&&l.searchParams.set("lev",String(Math.min(50,Number(o)))),i){let u=String(i).toLowerCase()==="hl"?"hyperliquid":String(i).toLowerCase();l.searchParams.set("venue",u)}else l.searchParams.get("venue")||l.searchParams.set("venue","hyperliquid");return l.searchParams.set("view","perps"),l.searchParams.set("build","1"),a&&/^[0-9a-f]{32}$/i.test(String(a))&&l.searchParams.set("confirm",String(a).toLowerCase()),c&&/^0x[0-9a-fA-F]{40}$/.test(String(c))&&l.searchParams.set("user",String(c).toLowerCase()),l.toString()}var Na,jt=$(()=>{Na=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var ap,sp,lr=$(()=>{jt();ap=Object.freeze([100,50,25]),sp=Object.freeze([100,50,25,10])});function y(e){return B(e)?String(e).replace(Pa,t=>`\\${t}`):C}function B(e){return e==null?!1:typeof e=="number"?Number.isFinite(e):typeof e=="string"?e.trim()!=="":!0}function G(e){if(!B(e))return C;let t=String(e).replace(/`/g,"");return t===""?C:`\`${t}\``}function ue(e,{decimals:t=2}={}){if(!B(e))return C;let n=Number(e);return Number.isFinite(n)?n.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:t}):C}function D(e,{decimals:t=2}={}){let n=ue(e,{decimals:t});return n===C?C:`${n} USD`}function Ht(e,{decimals:t=2}={}){let n=ue(e,{decimals:t});return n===C?C:`${n}%`}function ct(e){let t=ue(e,{decimals:0});return t===C?C:`${t} bps`}function de(e,t){if(!B(e))return C;let n=Number(t);if(!Number.isInteger(n)||n<0||n>77)return C;let r;try{r=BigInt(typeof e=="string"?e.trim():e)}catch{return C}let o=r<0n,i=o?-r:r,a=10n**BigInt(n),c=(i/a).toString(),l=(i%a).toString().padStart(n,"0").replace(/0+$/,"");return`${o?"-":""}${c}${l?`.${l}`:""}`}function Vt(e){if(typeof e=="number"&&Number.isFinite(e))return e<0||e>1?C:e>=.75?"HIGH":e>=.4?"MEDIUM":"LOW";if(typeof e=="string"){let t=e.trim().toUpperCase();if(t==="HIGH"||t==="MEDIUM"||t==="LOW")return t}return C}function ne(e={}){let t=e.chainId;if(!B(t)||!Number.isFinite(Number(t)))return B(e.chain)?y(e.chain):C;let r=It(t)?.name||(B(e.chain)?String(e.chain):C);return`${y(r)} (chainId ${Number(t)})`}function ur(e={}){return y(e.venue??e.dex??e.pool?.venue)}function Ra(e){return e==null?"NONE (text card only)":typeof e=="string"?e.trim()?G(e):"NONE (text card only)":e.error||e.ok===!1||e.available===!1?`UNAVAILABLE${B(e.error)?` \u2014 ${y(e.error)}`:""} (text card stands)`:B(e.url)?G(e.url):"NONE (text card only)"}function pe(e={},{now:t=Date.now()}={}){let n=e.grant??e.session??null;if(!n||typeof n!="object")return{allowed:!1,reason:"no local grant/session",actions:[]};if(n.local===!1)return{allowed:!1,reason:"grant is not local",actions:[]};if(n.revoked===!0)return{allowed:!1,reason:"grant revoked",actions:[]};let r=n.expiresAt??n.expiry;if(B(r)){let i=typeof r=="number"?r:Date.parse(r);if(!Number.isFinite(i))return{allowed:!1,reason:"grant expiry unreadable",actions:[]};if(i<=t)return{allowed:!1,reason:"grant expired",actions:[]}}return{allowed:!0,reason:"valid local grant",actions:Array.isArray(n.actions)&&n.actions.length?n.actions.slice():["BUY","SELL"]}}function La(e){let t=pe(e);return t.allowed?`${t.actions.map(n=>y(n)).join(" / ")} (${y(t.reason)})`:`prepare-only \u2014 ${y(t.reason)}`}function X(e,t,n={}){let r=[`*${e}*`];for(let o of t){if(!o)continue;let[i,a]=o;r.push(`${i}: ${a==null||a===""?C:a}`)}return r.push(`Chart: ${Ra(n.chart)}`),r.push(`Actions: ${La(n)}`),Array.isArray(n.warnings)&&n.warnings.length&&r.push(`Warnings: ${n.warnings.map(o=>y(o)).join("; ")}`),(B(n.source)||B(n.fetchedAt))&&r.push(`Source: ${y(n.source)} at ${y(n.fetchedAt)}`),r.join(`
9
- `)}function Z(e){let t=Vt(e.confidence);return t===C?null:["Confidence",t]}function Ua(e){let t=e.quote;if(!t||typeof t!="object")return[];let n=B(t.decimals)?de(t.amountOutRaw??t.out??t.raw,t.decimals):C;return[["Quote out (raw)",G(t.amountOutRaw??t.out??t.raw)],["Quote out",n===C?C:`${y(n)} ${y(t.symbol??"")}`.trim()]]}function dr(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",C];let n=ct(t.selectedBps),r=ct(t.capBps);return["Auto-slippage",n===C&&r===C?C:`${n} selected, cap ${r}`]}function Fa(e={}){let t=e||{};return X(`ORACLE TOKEN \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",ne(t)],["Venue",ur(t)],["Name",y(t.name)],["Address",G(t.address??t.mint??t.contract)],["Price",D(t.priceUsd,{decimals:8})],["Market cap",D(t.marketCapUsd)],["Liquidity",D(t.liquidityUsd)],["Volume 24h",D(t.volume24hUsd)],["Change 24h",Ht(t.priceChange24h)],["Fee tier",B(t.feeTier)?`${ct(Number(t.feeTier)/100)} (${ue(t.feeTier,{decimals:0})})`:C],["Age",y(t.age)],...Ua(t),dr(t),Z(t)],t)}function Ma(e={}){let t=e||{};return X(`ORACLE LAUNCH \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",ne(t)],["Venue",ur(t)],["Address",G(t.address??t.mint??t.contract)],["Pool",G(t.pool?.address??t.poolAddress??t.pool)],["Liquidity",D(t.liquidityUsd)],["Route ready",y(t.routeReady)],["Sellable",y(t.sellable)],["Sell sim",y(t.sellSimulation??t.sellSim)],["Smart wallets",y(t.smartWalletOverlap)],["Risk",y(t.risk??t.riskStatus)],["Prepared ticket",y(t.preparedTicket??t.ticketStatus)],dr(t),Z(t)],t)}function Ba(e={}){let t=e||{};return X(`ORACLE HIP-3 \u2014 ${y(t.market??t.coin??t.name)}`,[["Venue",`Hyperliquid builder-dex ${y(t.dexName?`${t.dexName} (${t.dex})`:t.dex)}`],["Market",y(t.market??t.coin)],["Mark",D(t.markPx,{decimals:6})],["Oracle",D(t.oraclePx,{decimals:6})],["Funding",Ht(t.funding,{decimals:6})],["Open interest",D(t.openInterestUsd)],["Depth",y(t.depth)],["Liquidation notes",y(t.liquidationNotes??t.riskNotes)],["Account context",y(t.accountContext)],Z(t)],t)}function qa(e={}){let t=e||{};return X(`ORACLE HIP-4 \u2014 ${y(t.event??t.market??t.name)}`,[["Venue",`Hyperliquid HIP-4 ${y(t.dex??"outcome")}`],["Event",y(t.event)],["Outcome",y(t.outcome)],["Market id",G(t.marketId??t.market)],["Bid",D(t.bid,{decimals:6})],["Ask",D(t.ask,{decimals:6})],["Depth",y(t.depth)],["Edge",Ht(t.edge)],["Position",y(t.position)],Z(t)],t)}function Da(e={}){let t=e||{};return X(`ORACLE POLYMARKET \u2014 ${y(t.event??t.market??t.name)}`,[["Venue","Polymarket CLOB"],["Event",y(t.event)],["Market",y(t.market)],["Market id",G(t.marketId??t.conditionId??t.tokenId)],["Yes",D(t.yesPrice,{decimals:4})],["No",D(t.noPrice,{decimals:4})],["Best bid / ask",`${D(t.bestBid,{decimals:4})} / ${D(t.bestAsk,{decimals:4})}`],["Volume",D(t.volumeUsd)],["Resolution risk",y(t.resolutionRisk)],["Order intent",y(t.orderIntent)],Z(t)],t)}function ja(e={}){let t=e||{},n=B(t.completedSplits)&&B(t.totalSplits)?`${ue(t.completedSplits,{decimals:0})} / ${ue(t.totalSplits,{decimals:0})}`:C;return X(`ORACLE TWAP \u2014 ${y(t.pair??t.symbol??t.name)}`,[["Chain",ne(t)],["Side",y(t.side??t.direction)],["Amount",`${y(de(t.amountTotal??t.amount,t.decimals??18))} ${y(t.symbol??"")}`.trim()],["Splits",`${ue(t.totalSplits,{decimals:0})} over ${y(t.window)}`],["Progress",n],["Avg price",D(t.averagePrice,{decimals:6})],["Next split",y(t.nextSplitAt)],["Slippage cap",ct(t.slippageBps)],["Status",y(t.status)],Z(t)],t)}function Ha(e={}){let t=e||{},n=t.approval??t.revokeCheck??{},r=n.needsRevoke&&n.spender?`revoke.cash \u2014 ${y(n.spender)}`:n.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return X(`ORACLE BRIDGE \u2014 ${y(t.pair??t.fromSymbol)} \u2192 ${y(t.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",ne({chainId:t.fromChainId,chain:t.fromChain})],["To chain",ne({chainId:t.toChainId,chain:t.toChain})],["Amount",`${y(de(t.amount,t.fromDecimals??18))} ${y(t.fromSymbol??"")}`.trim()],["Best route",y(t.bestRoute??t.winner)],["Est. received",`${y(de(t.amountOut,t.toDecimals??18))} ${y(t.toSymbol??"")}`.trim()],["Fee",D(t.feeUsd)],["Est. time",y(t.estimatedTime)],["Revoke check",r],["All providers",y(t.providers?.join(", "))],["Preparable",y(t.preparable)],Z(t)],t)}function Va(e){let n=(Array.isArray(e)?e:[]).slice(1,4).map(r=>{let o=y(r.source??r.venue??r.name),i=r.improvementBps==null&&r.deltaBps==null?null:Number(r.improvementBps??r.deltaBps),a=Number.isFinite(i)?`${Math.abs(i).toFixed(0)} bps behind`:"spread UNKNOWN";return`${o} (${a})`});return n.length?n.join("; "):C}function za(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return B(t)?y(t):C}function Wa(e={}){let t=e||{},n=t.swap&&typeof t.swap=="object"?t.swap:t,r=t.bridge&&typeof t.bridge=="object"?t.bridge:null,o=n.best??n.winner??{},i=`${y(t.tokenInSymbol??t.fromSymbol??"IN")} \u2192 ${y(t.tokenOutSymbol??t.toSymbol??"OUT")}`,a=[["Intent",y(t.intent??"swap")],["Chain",ne({chainId:t.chainId??n.chainId,chain:t.chain??n.chain})],["Pair",i],["Amount in",`${y(de(t.amountIn??n.amountIn,t.decimalsIn??18))} ${y(t.tokenInSymbol??"")}`.trim()],["Best swap",y(o.source??o.venue??n.bestRoute??t.bestRoute)],["Net out",`${y(de(o.netOut??o.amountOut??n.amountOut,t.decimalsOut??18))} ${y(t.tokenOutSymbol??"")}`.trim()],["Ranked on",za(n)],["Gas accounted",y(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",B(n.improvementBps)?`${y(n.improvementBps)} bps`:C],["Runners-up",Va(n.routes??t.routes)]];if(r){let c=r.best??r.winner??{};a.push(["Best bridge",y(c.source??r.bestRoute??t.bestBridge)],["Bridge out",`${y(de(c.netOut??c.amountOut??r.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${y(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",ne({chainId:r.toChainId??t.toChainId,chain:r.toChain??t.toChain})],["Est. time",y(r.estimatedTime??c.meta?.durationSeconds)])}else a.push(["Best bridge","same-chain \u2014 use Best swap"]);return a.push(["Preparable",y(t.preparable??o.executionReady)],Z(t)),X(`ORACLE SWAP \u2014 ${i}`,a,t)}function zt(e={}){let t=e||{};return X("ORACLE APPROVE \u2014 local signer",[["Pending id",G(t.id??(typeof t.digest=="string"?t.digest.slice(0,8):null))],["Surface",y(t.surface)],["Action",y(t.action)],["Chain",ne({chainId:t.chain??t.chainId,chain:t.chainName})],["To",G(t.to??t.destination)],["Value",B(t.value)?y(t.value):C],["Signer",y(t.armed===!0?"running + armed":t.armed===!1?"running, disarmed":"not running")],Z({confidence:t.confidence??(t.armed===!0?"high":"low")})],t)}function Wt({platform:e="telegram",id:t,digest:n,hasGrant:r=!1}={}){let o=String(t||(typeof n=="string"?n.slice(0,8):"")||"").trim();return r?o?String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[[{text:"Allow",callback_data:`oracle:approve:${o}`},{text:"Deny",callback_data:`oracle:deny:${o}`}]]},cancelHint:"Allow signs with the local signer. Deny drops the pending artifact."}:{kind:"text_menu",text:["1. Allow \u2014 reply /approve "+o,"2. Deny \u2014 reply /deny "+o].join(`
10
- `),cancelHint:"Cards are not available on this chat. Use /approve or /deny."}:{kind:"text_menu",text:"nothing to approve",cancelHint:""}:String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[]},cancelHint:"prepare-only \u2014 no local grant/session"}:{kind:"text_menu",text:"prepare-only \u2014 no local grant/session",cancelHint:""}}var C,pp,Pa,fp,Gt=$(()=>{Ct();lr();C="UNKNOWN",pp=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),Pa=/[_*[\]`]/g;fp=Object.freeze({token:Fa,launch:Ma,hip3:Ba,hip4:qa,polymarket:Da,twap:ja,bridge:Ha,swap:Wa,approve:zt})});function Kt(e){let n=String(e||"").trim().match(/^\/(approve|deny|pending)(?:@[\w_]+)?(?:\s+([0-9a-fA-F]{4,64}))?\s*$/i);return n?{verb:n[1].toLowerCase(),id:n[2]?n[2].toLowerCase():null}:null}function Yt(e,{platform:t,grant:n,armed:r}){if(!e.length)return{text:"No pending local-signer artifacts.",buttons:Wt({platform:t,hasGrant:!1})};let o=e[0];return{text:e.map(a=>zt({...a,armed:r,grant:n,confidence:r?"high":"medium"})).join(`
6
+ `)}`}function tr(e=[],t=""){let n=(Array.isArray(e)?e:[]).filter(c=>typeof c?.notifyRecipient=="function");if(!n.length)return null;let r=String(t||"").trim().toLowerCase(),o=r?n.filter(c=>String(c.platform||"").toLowerCase()===r):[],i=n.filter(c=>c.platform==="telegram"),a=o.length?o:i.length?i:n;for(let c of a){let l=[...new Set((Array.isArray(c.ownerIds)?c.ownerIds:[]).map(d=>String(d).trim()).filter(Boolean))];if(l.length!==1)continue;let u=ce(String(c.platform||"").toLowerCase(),32);if(u)return Object.freeze({platform:u,recipientId:l[0],target:c})}return null}function nr(e){if(!e||typeof e.target?.notifyRecipient!="function")throw new TypeError("one recipient-bound notification subscription is required");let{target:t,recipientId:n}=e,r=ce(e.platform||t.platform||"unknown",32);return async function(i){let a=ma(i);try{let c=Number(await t.notifyRecipient(n,a,i)),l=Number.isSafeInteger(c)&&c>0?1:0;return{delivered:l,recipient:{platform:r,id:n},error:l?null:"delivery-failed"}}catch{return{delivered:0,recipient:{platform:r,id:n},error:"delivery-failed"}}}}function rr({watchdog:e,intervalMs:t=3e5,setIntervalFn:n=setInterval,clearIntervalFn:r=clearInterval,onError:o=i=>process.stderr.write(`oracle-gateway: held NFT watchdog failed: ${ce(i?.message||i,200)}
7
+ `)}={}){if(typeof e?.tick!="function")throw new TypeError("held NFT watchdog is required");if(!Number.isSafeInteger(t)||t<6e4||t>864e5)throw new TypeError("held NFT watchdog interval is out of range");let i=null,a=!1,c=async()=>{if(a)return{skipped:!0,reason:"tick-in-progress"};a=!0;try{return await e.tick()}catch(l){return o(l),{skipped:!0,reason:"tick-failed"}}finally{a=!1}};return Object.freeze({start(){i===null&&(c(),i=n(c,t),typeof i?.unref=="function"&&i.unref())},stop(){i!==null&&r(i),i=null},run:c})}var Me=$(()=>{});var or={};he(or,{A2ABus:()=>Bt,normalizeName:()=>Be});function Be(e){return String(e||"").trim().toLowerCase().replace(/^@/,"")}var Bt,ir=$(()=>{Bt=class{constructor({maxHops:t=4,historyCap:n=200}={}){this.maxHops=t,this.historyCap=n,this.agents=new Map,this.history=[],this.seq=0}register(t,{role:n="",chains:r=[],handler:o}={}){let i=Be(t);if(!i)throw new Error("a2a: agent name required");if(this.agents.has(i))throw new Error(`a2a: agent '${i}' already registered`);if(typeof o!="function")throw new Error(`a2a: agent '${i}' needs a handler`);return this.agents.set(i,{name:i,role:String(n),chains:r.map(String),handler:o}),this.agents.get(i)}unregister(t){this.agents.delete(Be(t))}roster(){return[...this.agents.values()].map(({name:t,role:n,chains:r})=>({name:t,role:n,chains:r}))}async send({from:t,to:n,text:r,kind:o="consult",hops:i=0}={}){let a=Be(t),c=Be(n);if(!a||!this.agents.has(a))return{ok:!1,error:`a2a: unknown sender '${t}'`};if(!c||!this.agents.has(c))return{ok:!1,error:`a2a: unknown recipient '${n}' (roster: ${[...this.agents.keys()].join(", ")||"empty"})`};if(c===a)return{ok:!1,error:"a2a: self-send refused"};let l=String(r||"").trim().slice(0,8e3);if(!l)return{ok:!1,error:"a2a: empty message"};let u=Number(i)+1;if(u>this.maxHops)return this.record({from:a,to:c,kind:o,dropped:"hop-limit"}),{ok:!1,error:`a2a: hop limit ${this.maxHops} reached \u2014 dropped`};let d={id:`a2a-${Date.now()}-${++this.seq}`,from:a,to:c,kind:String(o),text:l,hops:u,ts:new Date().toISOString()};this.record(d);try{let s=await this.agents.get(c).handler(d);return s&&this.record({id:`${d.id}-reply`,from:c,to:a,kind:"reply",text:String(s).slice(0,8e3),hops:u,ts:new Date().toISOString()}),{ok:!0,reply:s||null,id:d.id}}catch(s){return{ok:!1,error:`a2a: '${c}' handler failed: ${s.message}`}}}record(t){this.history.push(t),this.history.length>this.historyCap&&this.history.splice(0,this.history.length-this.historyCap)}recent(t=20){return this.history.slice(-t)}}});import qe from"node:fs";import ha from"node:os";import Se from"node:path";import{fileURLToPath as ya}from"node:url";function qt(){return process.env.ORACLE_FAKE_HOME||ha.homedir()}function wa(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function Q(){return wa()?process.env.ORACLE_CONFIG_DIR||Se.join(qt(),".config","oracle"):Se.join(qt(),".config","oracle")}function ba(){return Se.join(Q(),"desk.json")}function Sa(){return Se.join(Q(),"env")}function be({force:e=!1}={}){if(be._done&&!e)return be._result||null;be._done=!0;let t={},n=(o,i)=>{if(i==null)return;let a=String(i).trim();a&&(process.env[o]!=null&&String(process.env[o]).trim()!==""||(process.env[o]=a,t[o]=a))};try{let o=Sa();if(qe.existsSync(o))for(let i of qe.readFileSync(o,"utf8").split(/\r?\n/)){let a=i.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!a||a[2].startsWith("#"))continue;let c=a[2];(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),n(a[1],c)}}catch{}try{let o=ba();if(qe.existsSync(o)){let i=JSON.parse(qe.readFileSync(o,"utf8"));i&&typeof i=="object"&&(n("ORACLE_DESK_URL",i.deskUrl||i.dataUrl||i.url),n("ORACLE_DATA_URL",i.dataUrl||i.deskUrl||i.url),n("ORACLE_API_URL",i.apiUrl||i.dataUrl||i.deskUrl),n("ORACLE_PUBLIC_URL",i.publicUrl||i.deskUrl||i.dataUrl),n("ORACLE_EXEC_URL",i.execUrl),n("MAD_DESK_URL",i.deskUrl||i.dataUrl))}}catch{}let r=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return r&&(n("ORACLE_DESK_URL",r),n("ORACLE_DATA_URL",r),n("ORACLE_API_URL",r),n("ORACLE_PUBLIC_URL",r),n("MAD_DESK_URL",r)),be._result=Object.keys(t).length?t:null,be._result}function at(e){return qe.mkdirSync(e,{recursive:!0}),e}var ga,Wd,st=$(()=>{ga=Se.dirname(ya(import.meta.url)),Wd=Se.resolve(ga,"../..");try{be()}catch{}});function ct(e){return String(e||"").trim()||void 0}function xa(e,{required:t=!1}={}){let n=ct(e)?.toLowerCase();if(!n){if(t)throw new Error("model provider is required");return}if(!va.has(n))throw new Error(`unsupported provider: ${n}`);return n}function Ea(e,{required:t=!1}={}){let n=ct(e);if(!n){if(t)throw new Error("model is required");return}if(n.includes("..")||n.startsWith("/")||!/^[a-zA-Z0-9._:/-]{1,200}$/.test(n))throw new Error("invalid model id");return n}function Aa(e){let t=ct(e);if(!t||t.length>2048)throw new Error("invalid custom base URL");let n;try{n=new URL(t)}catch{throw new Error("invalid custom base URL")}let r=n.hostname.toLowerCase().replace(/^\[|\]$/g,""),o=r==="localhost"||r==="127.0.0.1"||r==="::1";if(n.protocol!=="https:"&&!(n.protocol==="http:"&&o)||n.username||n.password||n.search||n.hash)throw new Error("custom base URL must use HTTPS or loopback HTTP without credentials, query, or fragment");return n.toString().replace(/\/+$/,"")}function ar({provider:e,model:t,baseUrl:n}={},{requireModel:r=!1}={}){let o=xa(e),i=Ea(t,{required:r});if(o==="custom")return{provider:o,...i?{model:i}:{},baseUrl:Aa(n)};if(ct(n))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...i?{model:i}:{}}}var va,sr=$(()=>{va=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import xe from"node:fs";import Dt from"node:path";function cr(){return Dt.join(Q(),"model.json")}function ve(e){return String(e||"").trim()||void 0}function lr(e={}){let t=ve(e.backend)?.toLowerCase()||"auto",n=ar({provider:e.provider,model:e.model,baseUrl:e.baseUrl},{requireModel:t==="standalone"}),r=ve(e.apiKeyEnv),o=Number.parseInt(String(e.contextLength||""),10),i=ve(e.reasoningEffort),a=ve(e.computeHost||e.remoteHost),c=ve(e.computeUser||e.remoteUser),l=ve(e.computePath||e.remotePath);if(!ka.has(t))throw new Error(`unsupported backend: ${t}`);if(process.env.ORACLE_PUBLIC_DESKTOP==="1"&&["remote","arch"].includes(t))throw new Error("remote compute backends are disabled in the public desktop");if(r&&!/^[A-Z][A-Z0-9_]*$/.test(r))throw new Error("api key env must be an uppercase environment variable name");if(t==="remote"&&!a)throw new Error("remote backend requires computeHost");return{backend:t,...n,...r?{apiKeyEnv:r}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...i?{reasoningEffort:i}:{},...a?{computeHost:a}:{},...c?{computeUser:c}:{},...l?{computePath:l}:{}}}function Ee(){let e=cr();if(!xe.existsSync(e))return null;try{return lr(JSON.parse(xe.readFileSync(e,"utf8")))}catch{return null}}function jt(e){let t=lr(e),n=cr();at(Dt.dirname(n)),process.platform!=="win32"&&xe.chmodSync(Dt.dirname(n),448);let r=`${n}.${process.pid}.tmp`;return xe.writeFileSync(r,`${JSON.stringify(t,null,2)}
8
+ `,{mode:384}),xe.renameSync(r,n),process.platform!=="win32"&&xe.chmodSync(n,384),t}var ka,ur=$(()=>{st();sr();ka=new Set(["auto","standalone","hermes","remote","arch"])});import{existsSync as _a,readFileSync as Ia}from"node:fs";import{request as Ca}from"node:http";import Ta from"node:path";function Na(e=process.env){let t=String(e.ORACLE_SIGNER_URL||Oa).replace(/\/$/,""),n;try{n=new URL(t)}catch{return null}return n.hostname!=="127.0.0.1"&&n.hostname!=="localhost"&&n.hostname!=="::1"?null:n.origin}function $a(e=process.env){if(e.ORACLE_SIGNER_TOKEN)return String(e.ORACLE_SIGNER_TOKEN);let t=Ta.join(Q(),"signer","signer-token");return _a(t)?Ia(t,"utf8").trim():null}function le(e,{method:t="GET",body:n=null,env:r=process.env,timeoutMs:o=4e3}={}){let i=Na(r),a=$a(r);return!i||!a?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(c=>{let l=new URL(e,i),u=n?Buffer.from(JSON.stringify(n)):null,d=Ca({hostname:l.hostname,port:l.port||80,path:l.pathname,method:t,timeout:o,headers:{authorization:`Bearer ${a}`,origin:i,...u?{"content-type":"application/json","content-length":u.length}:{}}},s=>{let p=[];s.on("data",m=>p.push(m)),s.on("end",()=>{let m=Buffer.concat(p).toString("utf8"),g={};try{g=m?JSON.parse(m):{}}catch{g={error:"signer refused"}}c({httpStatus:s.statusCode,...g})})});d.on("timeout",()=>{d.destroy(),c({ok:!1,error:"local signer timed out"})}),d.on("error",()=>c({ok:!1,error:"local signer is not running"})),u&&d.write(u),d.end()})}var Oa,lt=$(()=>{st();Oa="http://127.0.0.1:9462"});function Ra(e){let t=String(e||"").trim();if(!t||t.includes("ts.net")||!/^https:\/\//i.test(t))return null;try{return new URL(t)}catch{return null}}function dr(e,{coin:t,side:n,sizeUsd:r,leverage:o,venue:i,confirm:a,user:c}={}){let l=Ra(e);if(!l)return null;if(t&&Pa.test(String(t).toUpperCase())&&l.searchParams.set("coin",String(t).toUpperCase()),(n==="long"||n==="short")&&l.searchParams.set("side",n),Number.isFinite(Number(r))&&Number(r)>=1&&l.searchParams.set("size",String(Math.min(1e5,Math.round(Number(r))))),Number.isInteger(Number(o))&&Number(o)>=1&&l.searchParams.set("lev",String(Math.min(50,Number(o)))),i){let u=String(i).toLowerCase()==="hl"?"hyperliquid":String(i).toLowerCase();l.searchParams.set("venue",u)}else l.searchParams.get("venue")||l.searchParams.set("venue","hyperliquid");return l.searchParams.set("view","perps"),l.searchParams.set("build","1"),a&&/^[0-9a-f]{32}$/i.test(String(a))&&l.searchParams.set("confirm",String(a).toLowerCase()),c&&/^0x[0-9a-fA-F]{40}$/.test(String(c))&&l.searchParams.set("user",String(c).toLowerCase()),l.toString()}var Pa,Ht=$(()=>{Pa=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var cp,lp,pr=$(()=>{Ht();cp=Object.freeze([100,50,25]),lp=Object.freeze([100,50,25,10])});function y(e){return B(e)?String(e).replace(La,t=>`\\${t}`):C}function B(e){return e==null?!1:typeof e=="number"?Number.isFinite(e):typeof e=="string"?e.trim()!=="":!0}function G(e){if(!B(e))return C;let t=String(e).replace(/`/g,"");return t===""?C:`\`${t}\``}function ue(e,{decimals:t=2}={}){if(!B(e))return C;let n=Number(e);return Number.isFinite(n)?n.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:t}):C}function D(e,{decimals:t=2}={}){let n=ue(e,{decimals:t});return n===C?C:`${n} USD`}function Vt(e,{decimals:t=2}={}){let n=ue(e,{decimals:t});return n===C?C:`${n}%`}function ut(e){let t=ue(e,{decimals:0});return t===C?C:`${t} bps`}function de(e,t){if(!B(e))return C;let n=Number(t);if(!Number.isInteger(n)||n<0||n>77)return C;let r;try{r=BigInt(typeof e=="string"?e.trim():e)}catch{return C}let o=r<0n,i=o?-r:r,a=10n**BigInt(n),c=(i/a).toString(),l=(i%a).toString().padStart(n,"0").replace(/0+$/,"");return`${o?"-":""}${c}${l?`.${l}`:""}`}function zt(e){if(typeof e=="number"&&Number.isFinite(e))return e<0||e>1?C:e>=.75?"HIGH":e>=.4?"MEDIUM":"LOW";if(typeof e=="string"){let t=e.trim().toUpperCase();if(t==="HIGH"||t==="MEDIUM"||t==="LOW")return t}return C}function ne(e={}){let t=e.chainId;if(!B(t)||!Number.isFinite(Number(t)))return B(e.chain)?y(e.chain):C;let r=Ct(t)?.name||(B(e.chain)?String(e.chain):C);return`${y(r)} (chainId ${Number(t)})`}function fr(e={}){return y(e.venue??e.dex??e.pool?.venue)}function Ua(e){return e==null?"NONE (text card only)":typeof e=="string"?e.trim()?G(e):"NONE (text card only)":e.error||e.ok===!1||e.available===!1?`UNAVAILABLE${B(e.error)?` \u2014 ${y(e.error)}`:""} (text card stands)`:B(e.url)?G(e.url):"NONE (text card only)"}function pe(e={},{now:t=Date.now()}={}){let n=e.grant??e.session??null;if(!n||typeof n!="object")return{allowed:!1,reason:"no local grant/session",actions:[]};if(n.local===!1)return{allowed:!1,reason:"grant is not local",actions:[]};if(n.revoked===!0)return{allowed:!1,reason:"grant revoked",actions:[]};let r=n.expiresAt??n.expiry;if(B(r)){let i=typeof r=="number"?r:Date.parse(r);if(!Number.isFinite(i))return{allowed:!1,reason:"grant expiry unreadable",actions:[]};if(i<=t)return{allowed:!1,reason:"grant expired",actions:[]}}return{allowed:!0,reason:"valid local grant",actions:Array.isArray(n.actions)&&n.actions.length?n.actions.slice():["BUY","SELL"]}}function Fa(e){let t=pe(e);return t.allowed?`${t.actions.map(n=>y(n)).join(" / ")} (${y(t.reason)})`:`prepare-only \u2014 ${y(t.reason)}`}function X(e,t,n={}){let r=[`*${e}*`];for(let o of t){if(!o)continue;let[i,a]=o;r.push(`${i}: ${a==null||a===""?C:a}`)}return r.push(`Chart: ${Ua(n.chart)}`),r.push(`Actions: ${Fa(n)}`),Array.isArray(n.warnings)&&n.warnings.length&&r.push(`Warnings: ${n.warnings.map(o=>y(o)).join("; ")}`),(B(n.source)||B(n.fetchedAt))&&r.push(`Source: ${y(n.source)} at ${y(n.fetchedAt)}`),r.join(`
9
+ `)}function Z(e){let t=zt(e.confidence);return t===C?null:["Confidence",t]}function Ma(e){let t=e.quote;if(!t||typeof t!="object")return[];let n=B(t.decimals)?de(t.amountOutRaw??t.out??t.raw,t.decimals):C;return[["Quote out (raw)",G(t.amountOutRaw??t.out??t.raw)],["Quote out",n===C?C:`${y(n)} ${y(t.symbol??"")}`.trim()]]}function mr(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",C];let n=ut(t.selectedBps),r=ut(t.capBps);return["Auto-slippage",n===C&&r===C?C:`${n} selected, cap ${r}`]}function Ba(e={}){let t=e||{};return X(`ORACLE TOKEN \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",ne(t)],["Venue",fr(t)],["Name",y(t.name)],["Address",G(t.address??t.mint??t.contract)],["Price",D(t.priceUsd,{decimals:8})],["Market cap",D(t.marketCapUsd)],["Liquidity",D(t.liquidityUsd)],["Volume 24h",D(t.volume24hUsd)],["Change 24h",Vt(t.priceChange24h)],["Fee tier",B(t.feeTier)?`${ut(Number(t.feeTier)/100)} (${ue(t.feeTier,{decimals:0})})`:C],["Age",y(t.age)],...Ma(t),mr(t),Z(t)],t)}function qa(e={}){let t=e||{};return X(`ORACLE LAUNCH \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",ne(t)],["Venue",fr(t)],["Address",G(t.address??t.mint??t.contract)],["Pool",G(t.pool?.address??t.poolAddress??t.pool)],["Liquidity",D(t.liquidityUsd)],["Route ready",y(t.routeReady)],["Sellable",y(t.sellable)],["Sell sim",y(t.sellSimulation??t.sellSim)],["Smart wallets",y(t.smartWalletOverlap)],["Risk",y(t.risk??t.riskStatus)],["Prepared ticket",y(t.preparedTicket??t.ticketStatus)],mr(t),Z(t)],t)}function Da(e={}){let t=e||{};return X(`ORACLE HIP-3 \u2014 ${y(t.market??t.coin??t.name)}`,[["Venue",`Hyperliquid builder-dex ${y(t.dexName?`${t.dexName} (${t.dex})`:t.dex)}`],["Market",y(t.market??t.coin)],["Mark",D(t.markPx,{decimals:6})],["Oracle",D(t.oraclePx,{decimals:6})],["Funding",Vt(t.funding,{decimals:6})],["Open interest",D(t.openInterestUsd)],["Depth",y(t.depth)],["Liquidation notes",y(t.liquidationNotes??t.riskNotes)],["Account context",y(t.accountContext)],Z(t)],t)}function ja(e={}){let t=e||{};return X(`ORACLE HIP-4 \u2014 ${y(t.event??t.market??t.name)}`,[["Venue",`Hyperliquid HIP-4 ${y(t.dex??"outcome")}`],["Event",y(t.event)],["Outcome",y(t.outcome)],["Market id",G(t.marketId??t.market)],["Bid",D(t.bid,{decimals:6})],["Ask",D(t.ask,{decimals:6})],["Depth",y(t.depth)],["Edge",Vt(t.edge)],["Position",y(t.position)],Z(t)],t)}function Ha(e={}){let t=e||{};return X(`ORACLE POLYMARKET \u2014 ${y(t.event??t.market??t.name)}`,[["Venue","Polymarket CLOB"],["Event",y(t.event)],["Market",y(t.market)],["Market id",G(t.marketId??t.conditionId??t.tokenId)],["Yes",D(t.yesPrice,{decimals:4})],["No",D(t.noPrice,{decimals:4})],["Best bid / ask",`${D(t.bestBid,{decimals:4})} / ${D(t.bestAsk,{decimals:4})}`],["Volume",D(t.volumeUsd)],["Resolution risk",y(t.resolutionRisk)],["Order intent",y(t.orderIntent)],Z(t)],t)}function Va(e={}){let t=e||{},n=B(t.completedSplits)&&B(t.totalSplits)?`${ue(t.completedSplits,{decimals:0})} / ${ue(t.totalSplits,{decimals:0})}`:C;return X(`ORACLE TWAP \u2014 ${y(t.pair??t.symbol??t.name)}`,[["Chain",ne(t)],["Side",y(t.side??t.direction)],["Amount",`${y(de(t.amountTotal??t.amount,t.decimals??18))} ${y(t.symbol??"")}`.trim()],["Splits",`${ue(t.totalSplits,{decimals:0})} over ${y(t.window)}`],["Progress",n],["Avg price",D(t.averagePrice,{decimals:6})],["Next split",y(t.nextSplitAt)],["Slippage cap",ut(t.slippageBps)],["Status",y(t.status)],Z(t)],t)}function za(e={}){let t=e||{},n=t.approval??t.revokeCheck??{},r=n.needsRevoke&&n.spender?`revoke.cash \u2014 ${y(n.spender)}`:n.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return X(`ORACLE BRIDGE \u2014 ${y(t.pair??t.fromSymbol)} \u2192 ${y(t.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",ne({chainId:t.fromChainId,chain:t.fromChain})],["To chain",ne({chainId:t.toChainId,chain:t.toChain})],["Amount",`${y(de(t.amount,t.fromDecimals??18))} ${y(t.fromSymbol??"")}`.trim()],["Best route",y(t.bestRoute??t.winner)],["Est. received",`${y(de(t.amountOut,t.toDecimals??18))} ${y(t.toSymbol??"")}`.trim()],["Fee",D(t.feeUsd)],["Est. time",y(t.estimatedTime)],["Revoke check",r],["All providers",y(t.providers?.join(", "))],["Preparable",y(t.preparable)],Z(t)],t)}function Wa(e){let n=(Array.isArray(e)?e:[]).slice(1,4).map(r=>{let o=y(r.source??r.venue??r.name),i=r.improvementBps==null&&r.deltaBps==null?null:Number(r.improvementBps??r.deltaBps),a=Number.isFinite(i)?`${Math.abs(i).toFixed(0)} bps behind`:"spread UNKNOWN";return`${o} (${a})`});return n.length?n.join("; "):C}function Ga(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return B(t)?y(t):C}function Ka(e={}){let t=e||{},n=t.swap&&typeof t.swap=="object"?t.swap:t,r=t.bridge&&typeof t.bridge=="object"?t.bridge:null,o=n.best??n.winner??{},i=`${y(t.tokenInSymbol??t.fromSymbol??"IN")} \u2192 ${y(t.tokenOutSymbol??t.toSymbol??"OUT")}`,a=[["Intent",y(t.intent??"swap")],["Chain",ne({chainId:t.chainId??n.chainId,chain:t.chain??n.chain})],["Pair",i],["Amount in",`${y(de(t.amountIn??n.amountIn,t.decimalsIn??18))} ${y(t.tokenInSymbol??"")}`.trim()],["Best swap",y(o.source??o.venue??n.bestRoute??t.bestRoute)],["Net out",`${y(de(o.netOut??o.amountOut??n.amountOut,t.decimalsOut??18))} ${y(t.tokenOutSymbol??"")}`.trim()],["Ranked on",Ga(n)],["Gas accounted",y(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",B(n.improvementBps)?`${y(n.improvementBps)} bps`:C],["Runners-up",Wa(n.routes??t.routes)]];if(r){let c=r.best??r.winner??{};a.push(["Best bridge",y(c.source??r.bestRoute??t.bestBridge)],["Bridge out",`${y(de(c.netOut??c.amountOut??r.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${y(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",ne({chainId:r.toChainId??t.toChainId,chain:r.toChain??t.toChain})],["Est. time",y(r.estimatedTime??c.meta?.durationSeconds)])}else a.push(["Best bridge","same-chain \u2014 use Best swap"]);return a.push(["Preparable",y(t.preparable??o.executionReady)],Z(t)),X(`ORACLE SWAP \u2014 ${i}`,a,t)}function Wt(e={}){let t=e||{};return X("ORACLE APPROVE \u2014 local signer",[["Pending id",G(t.id??(typeof t.digest=="string"?t.digest.slice(0,8):null))],["Surface",y(t.surface)],["Action",y(t.action)],["Chain",ne({chainId:t.chain??t.chainId,chain:t.chainName})],["To",G(t.to??t.destination)],["Value",B(t.value)?y(t.value):C],["Signer",y(t.armed===!0?"running + armed":t.armed===!1?"running, disarmed":"not running")],Z({confidence:t.confidence??(t.armed===!0?"high":"low")})],t)}function Gt({platform:e="telegram",id:t,digest:n,hasGrant:r=!1}={}){let o=String(t||(typeof n=="string"?n.slice(0,8):"")||"").trim();return r?o?String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[[{text:"Allow",callback_data:`oracle:approve:${o}`},{text:"Deny",callback_data:`oracle:deny:${o}`}]]},cancelHint:"Allow signs with the local signer. Deny drops the pending artifact."}:{kind:"text_menu",text:["1. Allow \u2014 reply /approve "+o,"2. Deny \u2014 reply /deny "+o].join(`
10
+ `),cancelHint:"Cards are not available on this chat. Use /approve or /deny."}:{kind:"text_menu",text:"nothing to approve",cancelHint:""}:String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:[]},cancelHint:"prepare-only \u2014 no local grant/session"}:{kind:"text_menu",text:"prepare-only \u2014 no local grant/session",cancelHint:""}}var C,mp,La,hp,Kt=$(()=>{Tt();pr();C="UNKNOWN",mp=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),La=/[_*[\]`]/g;hp=Object.freeze({token:Ba,launch:qa,hip3:Da,hip4:ja,polymarket:Ha,twap:Va,bridge:za,swap:Ka,approve:Wt})});function Yt(e){let n=String(e||"").trim().match(/^\/(approve|deny|pending)(?:@[\w_]+)?(?:\s+([0-9a-fA-F]{4,64}))?\s*$/i);return n?{verb:n[1].toLowerCase(),id:n[2]?n[2].toLowerCase():null}:null}function Jt(e,{platform:t,grant:n,armed:r}){if(!e.length)return{text:"No pending local-signer artifacts.",buttons:Gt({platform:t,hasGrant:!1})};let o=e[0];return{text:e.map(a=>Wt({...a,armed:r,grant:n,confidence:r?"high":"medium"})).join(`
11
11
 
12
- `),buttons:Wt({platform:t,id:o.id,digest:o.digest,hasGrant:pe({grant:n}).allowed})}}async function Jt({platform:e,text:t,grant:n={local:!0},env:r=process.env,ownerProof:o}={}){let i=Kt(t);if(!i)return null;let a=String(e)==="telegram";if(a&&i.verb!=="pending"&&!i.id)return{text:"On Telegram, tap Allow or Deny on the approve card. /approve is only for chats without cards.",buttons:null};if(i.verb==="pending"){let s=await le("/pending",{env:r});if(s.ok===!1||s.error)return{text:`Local signer: ${s.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let p=Array.isArray(s.items)?s.items:[],m=Yt(p,{platform:e,grant:n,armed:s.armed===!0});if(a)return m;if(!p.length)return{text:"No pending local-signer artifacts. /approve is only needed when cards are unavailable.",buttons:null};let g=p.map(w=>`\u2022 ${w.id} ${w.surface}/${w.action} to ${w.to||"n/a"}`);return g.push("Cards are not available here. Reply /approve <id> or /deny <id>."),{text:g.join(`
12
+ `),buttons:Gt({platform:t,id:o.id,digest:o.digest,hasGrant:pe({grant:n}).allowed})}}async function Qt({platform:e,text:t,grant:n={local:!0},env:r=process.env,ownerProof:o}={}){let i=Yt(t);if(!i)return null;let a=String(e)==="telegram";if(a&&i.verb!=="pending"&&!i.id)return{text:"On Telegram, tap Allow or Deny on the approve card. /approve is only for chats without cards.",buttons:null};if(i.verb==="pending"){let s=await le("/pending",{env:r});if(s.ok===!1||s.error)return{text:`Local signer: ${s.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let p=Array.isArray(s.items)?s.items:[],m=Jt(p,{platform:e,grant:n,armed:s.armed===!0});if(a)return m;if(!p.length)return{text:"No pending local-signer artifacts. /approve is only needed when cards are unavailable.",buttons:null};let g=p.map(w=>`\u2022 ${w.id} ${w.surface}/${w.action} to ${w.to||"n/a"}`);return g.push("Cards are not available here. Reply /approve <id> or /deny <id>."),{text:g.join(`
13
13
  `),buttons:null}}let c=i.verb==="approve"?"/ack":"/deny";if(!i.id)return{text:"Usage: /approve <id> (only when approve cards are not available)",buttons:null};let l=await le(c,{method:"POST",body:{id:i.id,...o?{ownerProof:o}:{}},env:r});if(l.httpStatus===404||l.error==="no pending artifact")return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};if(l.ok===!1||l.httpStatus&&l.httpStatus>=400)return{text:`Local signer refused: ${l.error||"not running"}`,buttons:null};if(i.verb==="deny")return{text:`Denied ${l.id||i.id}. Artifact dropped. Nothing signed.`,buttons:null};let u=l.result?.hash||l.result?.txHash||l.result?.transactionHash||l.hash,d=l.id||i.id;return u?{text:`Bought. Local signer executed ${d}.
14
- Tx: \`${u}\``,buttons:null,executed:!0,hash:u}:{text:`Local signer executed ${d}. Check the signer receipt if no hash was returned.`,buttons:null,executed:!0,result:l.result||null}}async function pr({platform:e,data:t,senderId:n,chatId:r,ownerProofAuthority:o,grant:i={local:!0},env:a=process.env}={}){let l=String(t||"").match(/^oracle:(approve|deny):([0-9a-fA-F]{4,64})$/i);if(!l)return null;let u=l[1].toLowerCase()==="approve"?"approve":"deny",d;if(u==="approve"&&o){let p=(await le("/pending",{env:a})).items?.find(m=>m.id===l[2].toLowerCase()||m.digest===l[2].toLowerCase());if(!p)return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};d=o.mint({digest:p.digest,senderId:n,chatId:r,platform:e})}return Jt({platform:e,text:`/${u} ${l[2]}`,grant:i,env:a,ownerProof:d})}var Qt=$(()=>{st();Gt();st()});import{execFile as Ga}from"node:child_process";import{existsSync as Ka,mkdirSync as Ya,readFileSync as fr,realpathSync as Ja,writeFileSync as Qa}from"node:fs";import re from"node:path";import{promisify as Xa}from"node:util";import{fileURLToPath as mr}from"node:url";function ns(e=import.meta.url){try{let t=Ja(mr(e)),n=`${re.sep}node_modules${re.sep}`,r=t.lastIndexOf(n);if(r>0)return{root:t.slice(0,r),managed:!0}}catch{}return{root:null,managed:!1}}function Zt(e=import.meta.url){try{let t=re.dirname(mr(e));for(let n=0;n<8;n+=1){let r=re.join(t,"package.json");if(Ka(r)){let i=JSON.parse(fr(r,"utf8"));if(i?.name===Xt&&i.version)return i.version}let o=re.dirname(t);if(o===t)break;t=o}}catch{return null}return null}function rs(e,t){let n=i=>String(i).replace(/^v/,"").split("-")[0].split(".").map(a=>Number.parseInt(a,10)||0),r=n(e),o=n(t);for(let i=0;i<Math.max(r.length,o.length);i+=1){let a=r[i]??0,c=o[i]??0;if(a>c)return 1;if(a<c)return-1}return 0}function hr(e){let t=e?.stateDir||re.join(process.env.HOME||".",".oracle");return re.join(t,"update-check.json")}function os(e){try{return JSON.parse(fr(hr(e),"utf8"))}catch{return null}}function is(e,t){try{let n=hr(e);Ya(re.dirname(n),{recursive:!0}),Qa(n,`${JSON.stringify(t,null,2)}
15
- `)}catch{}}async function as({timeoutMs:e=4e3}={}){try{let t=new AbortController,n=setTimeout(()=>t.abort(),e),r=await fetch(`${es}/${encodeURIComponent(Xt)}/latest`,{signal:t.signal});return clearTimeout(n),r.ok&&(await r.json())?.version||null}catch{return null}}async function yr({paths:e,force:t=!1,timeoutMs:n=4e3}={}){let r=Zt(),o=t?null:os(e),a=o&&Date.now()-(o.checkedAt||0)<ts?o.latest:null;return a||(a=await as({timeoutMs:n}),a&&is(e,{latest:a,checkedAt:Date.now()})),!r||!a?{current:r,latest:a,updateAvailable:!1,checked:!!a}:{current:r,latest:a,updateAvailable:rs(a,r)>0,checked:!0}}async function gr({version:e="latest",dryRun:t=!1}={}){let{root:n,managed:r}=ns();if(!r||!n)return{ok:!1,reason:"unmanaged",message:`oracle is not running from a resolvable node_modules tree (source checkout or linked dev install).
16
- Update it the same way you installed it \u2014 git pull, or npm install -g @oracle-agent/oracle@latest.`};let o=`${Xt}@${e}`,i=["install","--prefix",n,"--no-audit","--no-fund",o];if(t)return{ok:!0,dryRun:!0,root:n,command:`npm ${i.join(" ")}`};try{let{stdout:a,stderr:c}=await Za("npm",i,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:n,stdout:a,stderr:c}}catch(a){return{ok:!1,reason:"npm-failed",root:n,message:a?.stderr||a?.message||"npm install failed"}}}var Za,Xt,es,ts,wr=$(()=>{Za=Xa(Ga),Xt="@oracle-agent/oracle",es="https://registry.npmjs.org",ts=1440*60*1e3});import ss from"node:fs";import cs from"node:os";import br from"node:path";function Ae(e){return String(e||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function ls(){let e=process.env.ORACLE_CONFIG_DIR||br.join(cs.homedir(),".config","oracle");return br.join(e,"chains.json")}function us(e){if(!e||typeof e!="object")return null;let t=String(e.key??"").trim();if(!t||/[/\\.]/.test(t))return null;let n=Ae(t);if(!vr.test(n))return null;let r=typeof e.chainId=="string"?e.chainId.trim():Number(e.chainId);if(r===""||r===null||r===void 0||typeof r=="number"&&!Number.isFinite(r))return null;let o=typeof e.agent=="string"&&vr.test(e.agent.trim())?e.agent.trim():"oracle";return{key:n,aliases:Array.isArray(e.aliases)?e.aliases.map(Ae).filter(Boolean).slice(0,8):[],chainId:r,name:String(e.name||n).slice(0,60),kind:["evm","svm","utxo","venue","daml"].includes(e.kind)?e.kind:"evm",family:Ae(e.family)||n,agent:o,note:String(e.note||"user-defined").slice(0,80),build:e.build!==!1,source:"user"}}function ds(e=ss.readFileSync){try{let t=JSON.parse(e(ls(),"utf8")),n=Array.isArray(t?.chains)?t.chains:[],r=[],o=new Set;for(let i of n){let a=us(i);!a||o.has(a.key)||(o.add(a.key),r.push(a))}return r}catch{return[]}}function xr(){let e=ds();if(e.length===0)return Sr;let t=new Map(Sr.map(n=>[n.key,n]));for(let n of e)t.set(n.key,n);return[...t.values()]}function ps({buildOnly:e=!1}={}){return xr().filter(t=>e?t.build:!0)}function Be(e){let t=Ae(e);if(!t)return null;for(let n of xr())if(n.key===t||String(n.chainId).toLowerCase()===t||(n.aliases||[]).map(Ae).includes(t)||Ae(n.name)===t)return n;return null}function Er({selectedKey:e=null,buildOnly:t=!1}={}){let n=ps({buildOnly:t}),r=["oracle chains","","pick a build/trade surface:",""];for(let o of n){let i=e&&e===o.key?"*":" ",a=String(o.chainId).padEnd(6),c=o.key.padEnd(12);r.push(`${i} ${c} ${a} ${o.note}`)}return r.push(""),r.push("usage:"),r.push(" /chain list"),r.push(" /chain hyperliquid select"),r.push(" /chain show current"),r.push(" /chain clear unset"),r.push(" oracle chain use base same from shell"),e&&r.push("",`active: ${e}`),r.join(`
14
+ Tx: \`${u}\``,buttons:null,executed:!0,hash:u}:{text:`Local signer executed ${d}. Check the signer receipt if no hash was returned.`,buttons:null,executed:!0,result:l.result||null}}async function hr({platform:e,data:t,senderId:n,chatId:r,ownerProofAuthority:o,grant:i={local:!0},env:a=process.env}={}){let l=String(t||"").match(/^oracle:(approve|deny):([0-9a-fA-F]{4,64})$/i);if(!l)return null;let u=l[1].toLowerCase()==="approve"?"approve":"deny",d;if(u==="approve"&&o){let p=(await le("/pending",{env:a})).items?.find(m=>m.id===l[2].toLowerCase()||m.digest===l[2].toLowerCase());if(!p)return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};d=o.mint({digest:p.digest,senderId:n,chatId:r,platform:e})}return Qt({platform:e,text:`/${u} ${l[2]}`,grant:i,env:a,ownerProof:d})}var Xt=$(()=>{lt();Kt();lt()});import{execFile as Ya}from"node:child_process";import{existsSync as Ja,mkdirSync as Qa,readFileSync as yr,realpathSync as Xa,writeFileSync as Za}from"node:fs";import re from"node:path";import{promisify as es}from"node:util";import{fileURLToPath as gr}from"node:url";function os(e=import.meta.url){try{let t=Xa(gr(e)),n=`${re.sep}node_modules${re.sep}`,r=t.lastIndexOf(n);if(r>0)return{root:t.slice(0,r),managed:!0}}catch{}return{root:null,managed:!1}}function en(e=import.meta.url){try{let t=re.dirname(gr(e));for(let n=0;n<8;n+=1){let r=re.join(t,"package.json");if(Ja(r)){let i=JSON.parse(yr(r,"utf8"));if(i?.name===Zt&&i.version)return i.version}let o=re.dirname(t);if(o===t)break;t=o}}catch{return null}return null}function is(e,t){let n=i=>String(i).replace(/^v/,"").split("-")[0].split(".").map(a=>Number.parseInt(a,10)||0),r=n(e),o=n(t);for(let i=0;i<Math.max(r.length,o.length);i+=1){let a=r[i]??0,c=o[i]??0;if(a>c)return 1;if(a<c)return-1}return 0}function wr(e){let t=e?.stateDir||re.join(process.env.HOME||".",".oracle");return re.join(t,"update-check.json")}function as(e){try{return JSON.parse(yr(wr(e),"utf8"))}catch{return null}}function ss(e,t){try{let n=wr(e);Qa(re.dirname(n),{recursive:!0}),Za(n,`${JSON.stringify(t,null,2)}
15
+ `)}catch{}}async function cs({timeoutMs:e=4e3}={}){try{let t=new AbortController,n=setTimeout(()=>t.abort(),e),r=await fetch(`${ns}/${encodeURIComponent(Zt)}/latest`,{signal:t.signal});return clearTimeout(n),r.ok&&(await r.json())?.version||null}catch{return null}}async function br({paths:e,force:t=!1,timeoutMs:n=4e3}={}){let r=en(),o=t?null:as(e),a=o&&Date.now()-(o.checkedAt||0)<rs?o.latest:null;return a||(a=await cs({timeoutMs:n}),a&&ss(e,{latest:a,checkedAt:Date.now()})),!r||!a?{current:r,latest:a,updateAvailable:!1,checked:!!a}:{current:r,latest:a,updateAvailable:is(a,r)>0,checked:!0}}async function Sr({version:e="latest",dryRun:t=!1}={}){let{root:n,managed:r}=os();if(!r||!n)return{ok:!1,reason:"unmanaged",message:`oracle is not running from a resolvable node_modules tree (source checkout or linked dev install).
16
+ Update it the same way you installed it \u2014 git pull, or npm install -g @oracle-agent/oracle@latest.`};let o=`${Zt}@${e}`,i=["install","--prefix",n,"--no-audit","--no-fund",o];if(t)return{ok:!0,dryRun:!0,root:n,command:`npm ${i.join(" ")}`};try{let{stdout:a,stderr:c}=await ts("npm",i,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:n,stdout:a,stderr:c}}catch(a){return{ok:!1,reason:"npm-failed",root:n,message:a?.stderr||a?.message||"npm install failed"}}}var ts,Zt,ns,rs,vr=$(()=>{ts=es(Ya),Zt="@oracle-agent/oracle",ns="https://registry.npmjs.org",rs=1440*60*1e3});import ls from"node:fs";import us from"node:os";import xr from"node:path";function Ae(e){return String(e||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function ds(){let e=process.env.ORACLE_CONFIG_DIR||xr.join(us.homedir(),".config","oracle");return xr.join(e,"chains.json")}function ps(e){if(!e||typeof e!="object")return null;let t=String(e.key??"").trim();if(!t||/[/\\.]/.test(t))return null;let n=Ae(t);if(!Ar.test(n))return null;let r=typeof e.chainId=="string"?e.chainId.trim():Number(e.chainId);if(r===""||r===null||r===void 0||typeof r=="number"&&!Number.isFinite(r))return null;let o=typeof e.agent=="string"&&Ar.test(e.agent.trim())?e.agent.trim():"oracle";return{key:n,aliases:Array.isArray(e.aliases)?e.aliases.map(Ae).filter(Boolean).slice(0,8):[],chainId:r,name:String(e.name||n).slice(0,60),kind:["evm","svm","utxo","venue","daml"].includes(e.kind)?e.kind:"evm",family:Ae(e.family)||n,agent:o,note:String(e.note||"user-defined").slice(0,80),build:e.build!==!1,source:"user"}}function fs(e=ls.readFileSync){try{let t=JSON.parse(e(ds(),"utf8")),n=Array.isArray(t?.chains)?t.chains:[],r=[],o=new Set;for(let i of n){let a=ps(i);!a||o.has(a.key)||(o.add(a.key),r.push(a))}return r}catch{return[]}}function kr(){let e=fs();if(e.length===0)return Er;let t=new Map(Er.map(n=>[n.key,n]));for(let n of e)t.set(n.key,n);return[...t.values()]}function ms({buildOnly:e=!1}={}){return kr().filter(t=>e?t.build:!0)}function De(e){let t=Ae(e);if(!t)return null;for(let n of kr())if(n.key===t||String(n.chainId).toLowerCase()===t||(n.aliases||[]).map(Ae).includes(t)||Ae(n.name)===t)return n;return null}function _r({selectedKey:e=null,buildOnly:t=!1}={}){let n=ms({buildOnly:t}),r=["oracle chains","","pick a build/trade surface:",""];for(let o of n){let i=e&&e===o.key?"*":" ",a=String(o.chainId).padEnd(6),c=o.key.padEnd(12);r.push(`${i} ${c} ${a} ${o.note}`)}return r.push(""),r.push("usage:"),r.push(" /chain list"),r.push(" /chain hyperliquid select"),r.push(" /chain show current"),r.push(" /chain clear unset"),r.push(" oracle chain use base same from shell"),e&&r.push("",`active: ${e}`),r.join(`
17
17
  `)+`
18
- `}var Sr,vr,en=$(()=>{Sr=Object.freeze([{key:"hyperliquid",aliases:["hl","hyperevm","hype","999"],chainId:999,name:"hyperliquid",kind:"evm",family:"hyperliquid",agent:"hyperliquid-agent",note:"perps \xB7 hip-3/4 \xB7 hyperevm 999",build:!0},{key:"ethereum",aliases:["eth","mainnet","1"],chainId:1,name:"ethereum",kind:"evm",family:"evm",agent:"oracle",note:"l1 \xB7 bridge hub",build:!0},{key:"base",aliases:["8453"],chainId:8453,name:"base",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"arbitrum",aliases:["arb","42161"],chainId:42161,name:"arbitrum",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"optimism",aliases:["op","10"],chainId:10,name:"optimism",kind:"evm",family:"evm",agent:"oracle",note:"op mainnet",build:!0},{key:"polygon",aliases:["matic","137"],chainId:137,name:"polygon",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"bsc",aliases:["bnb","56"],chainId:56,name:"bnb chain",kind:"evm",family:"evm",agent:"oracle",note:"bsc",build:!0},{key:"avalanche",aliases:["avax","43114"],chainId:43114,name:"avalanche",kind:"evm",family:"evm",agent:"oracle",note:"c-chain",build:!0},{key:"abstract",aliases:["abs","2741"],chainId:2741,name:"abstract",kind:"evm",family:"evm",agent:"oracle",note:"open / add agent",build:!0},{key:"stable",aliases:["988"],chainId:988,name:"stable",kind:"evm",family:"stable",agent:"stable-agent",note:"usdt0 gas \xB7 stable agent",build:!0},{key:"robinhood",aliases:["rh","4663"],chainId:4663,name:"robinhood",kind:"evm",family:"robinhood",agent:"robinhood-agent",note:"rh chain 4663",build:!0},{key:"solana",aliases:["sol"],chainId:"SOL",name:"solana",kind:"svm",family:"solana",agent:"solana-agent",note:"jup \xB7 nfts \xB7 dexs",build:!0},{key:"bitcoin",aliases:["btc"],chainId:"BTC",name:"bitcoin",kind:"utxo",family:"bitcoin",agent:"bitcoin-agent",note:"ord \xB7 runes \xB7 l1",build:!0},{key:"canton",aliases:["cc","canton-network","canton-coin","amulet"],chainId:"CC",name:"canton",kind:"daml",family:"canton",agent:"canton-agent",note:"cc reads \xB7 not evm",build:!0},{key:"polymarket",aliases:["poly","polygon-poly"],chainId:137,name:"polymarket",kind:"venue",family:"polymarket",agent:"polymarket-agent",note:"prediction markets (polygon venue)",build:!1}]);vr=/^[a-z0-9][a-z0-9-]*$/});import tn from"node:fs";import fs from"node:path";function Ar(){return fs.join(Q(),"active-chain.json")}function nn(){let e=Ar();if(!tn.existsSync(e))return null;try{let t=JSON.parse(tn.readFileSync(e,"utf8"));if(!t||typeof t!="object"||!t.key)return null;let n=Be(t.key);return n?{key:n.key,chainId:n.chainId,name:n.name,agent:n.agent,selectedAt:t.selectedAt||null}:null}catch{return null}}function kr(e){let t=Be(e);if(!t){let r=new Error(`unknown chain '${e}'`);throw r.code="UNKNOWN_CHAIN",r}ot(Q());let n={key:t.key,chainId:t.chainId,name:t.name,agent:t.agent,selectedAt:new Date().toISOString()};return tn.writeFileSync(Ar(),JSON.stringify(n,null,2)+`
19
- `,{mode:384}),n}var _r=$(()=>{en();it()});import{createHash as ms,randomBytes as Fp}from"node:crypto";import{mkdirSync as hs,readFileSync as ys,writeFileSync as gs}from"node:fs";import{homedir as ws}from"node:os";import{dirname as bs,join as Ir}from"node:path";function De(e=process.env){return Ir(e.ORACLE_CONFIG_DIR||Ir(ws(),".config","oracle"),"telegram-cards.json")}function je(){return{links:{},artifacts:{},threads:{}}}function lt(){return qe}function Cr(e,{readFile:t=ys}={}){try{let n=JSON.parse(String(t(e)));qe={links:n.links&&typeof n.links=="object"?n.links:{},artifacts:n.artifacts&&typeof n.artifacts=="object"?n.artifacts:{},threads:n.threads&&typeof n.threads=="object"?n.threads:{}}}catch{qe=je()}return qe}function ut(e,t=qe,{writeFile:n=gs,mkdir:r=hs}={}){r(bs(e),{recursive:!0,mode:448}),n(e,JSON.stringify(t),{mode:384})}function oe(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function As(e){return ms("sha256").update(String(e)).digest("hex")}function rn(e){if(Array.isArray(e))return e.map(rn);if(!e||typeof e!="object")return e;let t={};for(let[n,r]of Object.entries(e))/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(n)||(t[n]=rn(r));return t}function ks(e){let n=String(e||"").trim().match(/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):([a-z0-9-]{4,40})$/i);return n?{action:n[1].toLowerCase(),artifactId:n[2].toLowerCase()}:null}function Tr({platform:e="telegram",artifactId:t,openUrl:n,hasGrant:r=!1}={}){let o=String(t||"").trim().toLowerCase();if(!on.test(o))return{kind:"text_menu",text:"no artifact to continue",cancelHint:""};let i=[],a=[{text:"TA",callback_data:`oracle:card:ta:${o}`},{text:"FA",callback_data:`oracle:card:fa:${o}`}],c=s=>cr(n,{side:s}),l=c("long"),u=c("short"),d=l&&u?[{text:"LONG",url:l},{text:"SHORT",url:u}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return oe(n)?(i.push([{text:"Open",url:String(n)},a[0]]),i.push(d),i.push(r?[a[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[a[1]])):(i.push(a),i.push(d),r&&i.push([{text:"Prep",callback_data:`oracle:card:prepare:${o}`}])),String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:i.filter(s=>s.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function Or(e={}){let n=[`*${oe(e.title)?y(e.title):"Oracle artifact"}*`,`Kind: ${oe(e.kind)?y(e.kind):C}`,`Id: ${oe(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:C}`,`Summary: ${oe(e.summary)?y(e.summary):C}`],r=Vt(e.confidence);r!==C&&n.push(`Confidence: ${r}`),(oe(e.source)||oe(e.fetchedAt))&&n.push(`Source: ${y(e.source)} at ${y(e.fetchedAt)}`),Array.isArray(e.warnings)&&e.warnings.length&&n.push(`Warnings: ${e.warnings.map(i=>y(i)).join("; ")}`);let o=pe(e);return n.push(o.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${y(o.reason)}`),n.join(`
20
- `)}function _s(e,t={},{now:n=Date.now()}={}){let r=e||je(),o=String(t.id||"").trim().toLowerCase();if(!on.test(o))throw new TypeError("artifact id required");let i={id:o,kind:String(t.kind||"thesis"),title:String(t.title||"Oracle artifact"),summary:String(t.summary||""),openUrl:oe(t.openUrl)?String(t.openUrl):null,confidence:t.confidence,source:t.source||"oracle",fetchedAt:t.fetchedAt||new Date(n).toISOString(),warnings:Array.isArray(t.warnings)?t.warnings.map(String):[],payload:rn(t.payload||{}),createdAt:new Date(n).toISOString()};return r.artifacts[o]=i,i}function an(e,{chatId:t,artifactId:n,now:r=Date.now()}={}){let o=e||je(),i=String(t||"").trim(),a=String(n||"").trim().toLowerCase();if(!i)throw new TypeError("chat id required");if(!on.test(a))throw new TypeError("artifact id required");return o.threads[i]={artifactId:a,updatedAt:r},o.threads[i]}function Nr(e,{chatId:t,text:n}={}){let r=String(t||"").trim(),o=String(n||"").trim();if(!r||!o||/^\//.test(o))return null;let i=e?.threads?.[r];if(!i?.artifactId)return null;let a=e.artifacts?.[i.artifactId];return a?`Continue artifact ${a.id} (${a.kind}). Prior: ${a.summary||a.title}. User: ${o}`:null}function $r(e,{token:t,telegramUserId:n,now:r=Date.now()}={}){let o=e||je(),i=String(t||"").trim(),a=String(n||"").trim();if(!xs.test(i))return{ok:!1,error:"invalid start token"};if(!Es.test(a))return{ok:!1,error:"invalid telegram user"};let c=As(i),l=o.links[c];return l?(delete o.links[c],Number(l.expiresAt)<=r?{ok:!1,error:"start token expired"}:String(l.ownerId)!==a?{ok:!1,error:"start token is bound to a different owner"}:{ok:!0,ownerId:a}):{ok:!1,error:"unknown or already used start token"}}function Pr(e,{data:t,chatId:n,grant:r=null,now:o=Date.now()}={}){let i=ks(t);if(!i)return null;if(!vs.has(i.action))return{text:"That card action is not available.",buttons:null};let a=e?.artifacts?.[i.artifactId];if(!a)return{text:"That artifact is gone. Ask again and I will issue a new card.",buttons:null};n&&an(e,{chatId:n,artifactId:a.id,now:o});let c=pe({grant:r},{now:o}),l=Tr({artifactId:a.id,openUrl:a.openUrl,hasGrant:c.allowed});return i.action==="refresh"?{text:Or(a),buttons:l,prompt:null}:i.action==="deepen"?{text:null,buttons:null,prompt:`Deepen artifact ${a.id} (${a.kind}). Prior: ${a.summary||a.title}. Be terse. Do not sign or broadcast.`}:i.action==="ta"?{text:null,buttons:null,prompt:`TA artifact ${a.id}. Prior: ${a.summary||a.title}. Run deterministic TA on the coin/venue in the artifact (RSI divergence, S/R, candle patterns). Reply in this Telegram chat with the verdict rows and say what was drawn. Do not sign or broadcast.`}:i.action==="fa"?{text:null,buttons:null,prompt:`FA artifact ${a.id}. Prior: ${a.summary||a.title}. Run per-coin FA (funding, OI, book, premium) plus the separate MACRO thesis (M1/M2/Fed BS/net liquidity) if relevant. Cite receipts. Stay in this Telegram chat. Do not sign or broadcast.`}:i.action==="allow"?{text:"Allow is the graph. Open the ticket there and CONFIRM. Telegram did not send.",buttons:null,prompt:null}:i.action==="deny"?{text:`Denied ${a.id}. Ticket cancelled. Nothing signed.`,buttons:null,prompt:null}:i.action==="long"||i.action==="short"?{text:null,buttons:null,prompt:`Open the live graph ticket for a ${i.action} on artifact ${a.id}. Prior: ${a.summary||a.title}. Size from the connected HL account. Execute only on CONFIRM on the graph. Never sign from Telegram.`}:c.allowed?{text:`Queued unsigned prepare for ${a.id}. Nothing signed. Allow/Deny still required.`,buttons:l,prompt:null,prepare:{artifactId:a.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${c.reason}. Deepen and Refresh still work.`,buttons:l,prompt:null}}function Rr(e={},{grant:t=null,now:n=Date.now(),state:r}={}){let o=r||lt(),i=String(e.id||`art-${Math.abs(Number(n)).toString(36)}`).toLowerCase().slice(0,40),a=_s(o,{...e,id:i},{now:n}),c=pe({grant:t},{now:n});return{text:Or({...a,grant:t}),replyMarkup:Tr({artifactId:a.id,openUrl:a.openUrl,hasGrant:c.allowed}).replyMarkup,artifact:a,state:o}}var Ss,vs,on,xs,Es,qe,sn=$(()=>{jt();Gt();Ss=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),vs=new Set(Ss),on=/^[a-z0-9-]{4,40}$/i,xs=/^[0-9a-f]{32}$/,Es=/^\d+$/;qe=je()});var ro={};he(ro,{NON_OWNER_REPLY:()=>_e,buildPersona:()=>Ie,handleSelfUpdate:()=>Dr,isForwarded:()=>jr,isOwnerSender:()=>ke,ownerIdsFor:()=>Br,parseGatewayChainCommand:()=>Qr,parseGatewayCompactCommand:()=>Jr,parseGatewayEffortCommand:()=>Wr,parseGatewayGoalCommand:()=>Yr,parseGatewayHelpCommand:()=>Gr,parseGatewayModelCommand:()=>zr,parseGatewaySetupModelCommand:()=>Ms,parseGatewayStatusCommand:()=>Kr,parsePeerAsk:()=>Zr,parseSelfUpdate:()=>qr,resolveBackendArgv:()=>eo,resolveGatewayModel:()=>Hr,resolveOracleBin:()=>Mr,routePeerConsult:()=>He,routeToAgent:()=>ee});import{spawn as Fr}from"node:child_process";import{dirname as Is,join as ln}from"node:path";import{homedir as Cs}from"node:os";import{mkdirSync as Ts,readFileSync as Os,writeFileSync as Ns,unlinkSync as $s}from"node:fs";import{fileURLToPath as Ps}from"node:url";function Mr({env:e=process.env,moduleUrl:t=import.meta.url}={}){return e.ORACLE_CLI_ENTRY||ln(Is(Ps(t)),"oracle.mjs")}function Br(e,t=process.env){let n=String(t[`ORACLE_OWNER_${String(e).toUpperCase()}`]||""),r=String(t.ORACLE_OWNER_IDS||"");return new Set(`${n},${r}`.split(",").map(o=>o.trim()).filter(Boolean))}function ke({platform:e,senderId:t,extraOwners:n},r=process.env){let o=String(t||"").trim();return o?Br(e,r).has(o)?!0:Array.isArray(n)?n.map(i=>String(i).trim()).filter(Boolean).includes(o):!1:!1}function qr(e){let t=String(e||"").trim();if(!t)return null;let n=t.replace(/^\/update(?:@[\w_]+)?\b/i,"update");return/^(?:oracle\s+)?update\s+--check\s*$/i.test(n)?{checkOnly:!0}:/^(?:oracle\s+)?update\s*$/i.test(n)?{checkOnly:!1}:null}async function Dr(e,{check:t=yr,update:n=gr,versionOf:r=Zt}={}){let o=await t({force:!0});if(e.checkOnly)return o.checked?o.updateAvailable?`oracle ${o.current} \u2192 ${o.latest} available. Send /update to install.`:`oracle ${o.current} is up to date`:`oracle ${o.current||"?"} \u2014 could not reach npm`;if(o.checked&&!o.updateAvailable)return`oracle ${o.current} is already up to date`;let i=o.latest||"latest",a=await n({version:i==="latest"?"latest":i});if(!a.ok)return`oracle update failed: ${a.message}`;let c=r();return[`oracle ${o.current||"?"} \u2192 ${c||i}`,"Restart the gateway to load it: oracle gateway"].join(`
21
- `)}function jr(e={}){return!!(e.forwarded||e.forward_from||e.forward_from_chat||e.forward_origin||e.forward_sender_name||e.forward_date)}function Hr({readConfig:e=Ee}={}){let t=e();return t?t.backend==="hermes"?{ok:!1,error:"model config delegates to hermes; the gateway runs Oracle's native loop. Set a standalone backend: oracle model --backend standalone"}:t.model?{ok:!0,provider:t.provider,model:t.model,reasoningEffort:t.reasoningEffort||null}:{ok:!1,error:"model config has no model \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}:{ok:!1,error:"gateway has no model configured \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}}function zr(e){let n=String(e||"").trim().match(/^\/model(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim();if(!r)return{action:"list"};if(r.toLowerCase()==="show"||r==="?")return{action:"show"};if(r.toLowerCase()==="list")return{action:"list"};let o=r.split(/\s+/),i=Vr[o[0].toLowerCase()];if(i&&o.length===1)return{action:"set",provider:i.provider,model:i.model};if(i&&o.length>=2)return{action:"set",provider:i.provider,model:o.slice(1).join(" ")};if(o.length>=2)return{action:"set",provider:o[0],model:o.slice(1).join(" ")};if(o[0]?.includes(":")){let[a,c]=o[0].split(":");if(a&&c)return{action:"set",provider:a,model:c}}return{action:"usage"}}function Wr(e){let n=String(e||"").trim().match(/^\/(?:effort|reasoning)(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim().toLowerCase();return!r||r==="show"||r==="?"?{action:"show"}:Ls.includes(r)?{action:"set",reasoningEffort:r}:{action:"usage"}}function Us({provider:e,model:t}){let n=Ee()||{},r=Dt({...n,backend:n.backend&&n.backend!=="auto"?n.backend:"standalone",provider:e,model:t});return`model ${r.provider} / ${r.model}
22
- Oracle persona unchanged. Native harness only \u2014 Hermes Telegram uses its own /model.`}function Fs(e){let t=Ee();if(!t)throw new Error("no model configured \u2014 run /model first");return`effort ${Dt({...t,reasoningEffort:e}).reasoningEffort||e}
23
- Native harness only.`}function Lr(){let e=Ee(),t=["Oracle native models (tap /model <id> to switch):"];for(let[n,r]of Object.entries(Vr)){let o=e?.provider===r.provider&&e?.model===r.model?" \u2190 current":"";t.push(`/model ${n} ${r.provider} / ${r.model}${o}`)}return t.push(""),t.push("Add another provider: /setup model"),t.push("Or set exact id: /model <provider> <model-id>"),t.push("/effort low|medium|high"),e?.provider&&(t.push(""),t.push(`current ${e.provider} / ${e.model||"unset"} \xB7 effort ${e.reasoningEffort||"default"}`)),t.join(`
24
- `)}function cn(){let e=Ee();return e?[`backend ${e.backend||"auto"}`,`provider ${e.provider||"unset"}`,`model ${e.model||"unset"}`,`effort ${e.reasoningEffort||"default"}`,"Aliases: claude, codex, grok, openrouter, nous, qwen, glm, deepseek, gemini, kimi, mistral, local, ollama","/effort low|medium|high"].join(`
18
+ `}var Er,Ar,tn=$(()=>{Er=Object.freeze([{key:"hyperliquid",aliases:["hl","hyperevm","hype","999"],chainId:999,name:"hyperliquid",kind:"evm",family:"hyperliquid",agent:"hyperliquid-agent",note:"perps \xB7 hip-3/4 \xB7 hyperevm 999",build:!0},{key:"ethereum",aliases:["eth","mainnet","1"],chainId:1,name:"ethereum",kind:"evm",family:"evm",agent:"oracle",note:"l1 \xB7 bridge hub",build:!0},{key:"base",aliases:["8453"],chainId:8453,name:"base",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"arbitrum",aliases:["arb","42161"],chainId:42161,name:"arbitrum",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"optimism",aliases:["op","10"],chainId:10,name:"optimism",kind:"evm",family:"evm",agent:"oracle",note:"op mainnet",build:!0},{key:"polygon",aliases:["matic","137"],chainId:137,name:"polygon",kind:"evm",family:"evm",agent:"oracle",note:"evm l2",build:!0},{key:"bsc",aliases:["bnb","56"],chainId:56,name:"bnb chain",kind:"evm",family:"evm",agent:"oracle",note:"bsc",build:!0},{key:"avalanche",aliases:["avax","43114"],chainId:43114,name:"avalanche",kind:"evm",family:"evm",agent:"oracle",note:"c-chain",build:!0},{key:"abstract",aliases:["abs","2741"],chainId:2741,name:"abstract",kind:"evm",family:"evm",agent:"oracle",note:"open / add agent",build:!0},{key:"stable",aliases:["988"],chainId:988,name:"stable",kind:"evm",family:"stable",agent:"stable-agent",note:"usdt0 gas \xB7 stable agent",build:!0},{key:"robinhood",aliases:["rh","4663"],chainId:4663,name:"robinhood",kind:"evm",family:"robinhood",agent:"robinhood-agent",note:"rh chain 4663",build:!0},{key:"solana",aliases:["sol"],chainId:"SOL",name:"solana",kind:"svm",family:"solana",agent:"solana-agent",note:"jup \xB7 nfts \xB7 dexs",build:!0},{key:"bitcoin",aliases:["btc"],chainId:"BTC",name:"bitcoin",kind:"utxo",family:"bitcoin",agent:"bitcoin-agent",note:"ord \xB7 runes \xB7 l1",build:!0},{key:"canton",aliases:["cc","canton-network","canton-coin","amulet"],chainId:"CC",name:"canton",kind:"daml",family:"canton",agent:"canton-agent",note:"cc reads \xB7 not evm",build:!0},{key:"polymarket",aliases:["poly","polygon-poly"],chainId:137,name:"polymarket",kind:"venue",family:"polymarket",agent:"polymarket-agent",note:"prediction markets (polygon venue)",build:!1}]);Ar=/^[a-z0-9][a-z0-9-]*$/});import nn from"node:fs";import hs from"node:path";function Ir(){return hs.join(Q(),"active-chain.json")}function rn(){let e=Ir();if(!nn.existsSync(e))return null;try{let t=JSON.parse(nn.readFileSync(e,"utf8"));if(!t||typeof t!="object"||!t.key)return null;let n=De(t.key);return n?{key:n.key,chainId:n.chainId,name:n.name,agent:n.agent,selectedAt:t.selectedAt||null}:null}catch{return null}}function Cr(e){let t=De(e);if(!t){let r=new Error(`unknown chain '${e}'`);throw r.code="UNKNOWN_CHAIN",r}at(Q());let n={key:t.key,chainId:t.chainId,name:t.name,agent:t.agent,selectedAt:new Date().toISOString()};return nn.writeFileSync(Ir(),JSON.stringify(n,null,2)+`
19
+ `,{mode:384}),n}var Tr=$(()=>{tn();st()});import{createHash as ys,randomBytes as Bp}from"node:crypto";import{mkdirSync as gs,readFileSync as ws,writeFileSync as bs}from"node:fs";import{homedir as Ss}from"node:os";import{dirname as vs,join as Or}from"node:path";function He(e=process.env){return Or(e.ORACLE_CONFIG_DIR||Or(Ss(),".config","oracle"),"telegram-cards.json")}function Ve(){return{links:{},artifacts:{},threads:{}}}function dt(){return je}function Nr(e,{readFile:t=ws}={}){try{let n=JSON.parse(String(t(e)));je={links:n.links&&typeof n.links=="object"?n.links:{},artifacts:n.artifacts&&typeof n.artifacts=="object"?n.artifacts:{},threads:n.threads&&typeof n.threads=="object"?n.threads:{}}}catch{je=Ve()}return je}function pt(e,t=je,{writeFile:n=bs,mkdir:r=gs}={}){r(vs(e),{recursive:!0,mode:448}),n(e,JSON.stringify(t),{mode:384})}function oe(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function _s(e){return ys("sha256").update(String(e)).digest("hex")}function on(e){if(Array.isArray(e))return e.map(on);if(!e||typeof e!="object")return e;let t={};for(let[n,r]of Object.entries(e))/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(n)||(t[n]=on(r));return t}function Is(e){let n=String(e||"").trim().match(/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):([a-z0-9-]{4,40})$/i);return n?{action:n[1].toLowerCase(),artifactId:n[2].toLowerCase()}:null}function $r({platform:e="telegram",artifactId:t,openUrl:n,hasGrant:r=!1}={}){let o=String(t||"").trim().toLowerCase();if(!an.test(o))return{kind:"text_menu",text:"no artifact to continue",cancelHint:""};let i=[],a=[{text:"TA",callback_data:`oracle:card:ta:${o}`},{text:"FA",callback_data:`oracle:card:fa:${o}`}],c=s=>dr(n,{side:s}),l=c("long"),u=c("short"),d=l&&u?[{text:"LONG",url:l},{text:"SHORT",url:u}]:[{text:"LONG",callback_data:`oracle:card:long:${o}`},{text:"SHORT",callback_data:`oracle:card:short:${o}`}];return oe(n)?(i.push([{text:"Open",url:String(n)},a[0]]),i.push(d),i.push(r?[a[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[a[1]])):(i.push(a),i.push(d),r&&i.push([{text:"Prep",callback_data:`oracle:card:prepare:${o}`}])),String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:i.filter(s=>s.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function Pr(e={}){let n=[`*${oe(e.title)?y(e.title):"Oracle artifact"}*`,`Kind: ${oe(e.kind)?y(e.kind):C}`,`Id: ${oe(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:C}`,`Summary: ${oe(e.summary)?y(e.summary):C}`],r=zt(e.confidence);r!==C&&n.push(`Confidence: ${r}`),(oe(e.source)||oe(e.fetchedAt))&&n.push(`Source: ${y(e.source)} at ${y(e.fetchedAt)}`),Array.isArray(e.warnings)&&e.warnings.length&&n.push(`Warnings: ${e.warnings.map(i=>y(i)).join("; ")}`);let o=pe(e);return n.push(o.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${y(o.reason)}`),n.join(`
20
+ `)}function Cs(e,t={},{now:n=Date.now()}={}){let r=e||Ve(),o=String(t.id||"").trim().toLowerCase();if(!an.test(o))throw new TypeError("artifact id required");let i={id:o,kind:String(t.kind||"thesis"),title:String(t.title||"Oracle artifact"),summary:String(t.summary||""),openUrl:oe(t.openUrl)?String(t.openUrl):null,confidence:t.confidence,source:t.source||"oracle",fetchedAt:t.fetchedAt||new Date(n).toISOString(),warnings:Array.isArray(t.warnings)?t.warnings.map(String):[],payload:on(t.payload||{}),createdAt:new Date(n).toISOString()};return r.artifacts[o]=i,i}function sn(e,{chatId:t,artifactId:n,now:r=Date.now()}={}){let o=e||Ve(),i=String(t||"").trim(),a=String(n||"").trim().toLowerCase();if(!i)throw new TypeError("chat id required");if(!an.test(a))throw new TypeError("artifact id required");return o.threads[i]={artifactId:a,updatedAt:r},o.threads[i]}function Rr(e,{chatId:t,text:n}={}){let r=String(t||"").trim(),o=String(n||"").trim();if(!r||!o||/^\//.test(o))return null;let i=e?.threads?.[r];if(!i?.artifactId)return null;let a=e.artifacts?.[i.artifactId];return a?`Continue artifact ${a.id} (${a.kind}). Prior: ${a.summary||a.title}. User: ${o}`:null}function Lr(e,{token:t,telegramUserId:n,now:r=Date.now()}={}){let o=e||Ve(),i=String(t||"").trim(),a=String(n||"").trim();if(!As.test(i))return{ok:!1,error:"invalid start token"};if(!ks.test(a))return{ok:!1,error:"invalid telegram user"};let c=_s(i),l=o.links[c];return l?(delete o.links[c],Number(l.expiresAt)<=r?{ok:!1,error:"start token expired"}:String(l.ownerId)!==a?{ok:!1,error:"start token is bound to a different owner"}:{ok:!0,ownerId:a}):{ok:!1,error:"unknown or already used start token"}}function Ur(e,{data:t,chatId:n,grant:r=null,now:o=Date.now()}={}){let i=Is(t);if(!i)return null;if(!Es.has(i.action))return{text:"That card action is not available.",buttons:null};let a=e?.artifacts?.[i.artifactId];if(!a)return{text:"That artifact is gone. Ask again and I will issue a new card.",buttons:null};n&&sn(e,{chatId:n,artifactId:a.id,now:o});let c=pe({grant:r},{now:o}),l=$r({artifactId:a.id,openUrl:a.openUrl,hasGrant:c.allowed});return i.action==="refresh"?{text:Pr(a),buttons:l,prompt:null}:i.action==="deepen"?{text:null,buttons:null,prompt:`Deepen artifact ${a.id} (${a.kind}). Prior: ${a.summary||a.title}. Be terse. Do not sign or broadcast.`}:i.action==="ta"?{text:null,buttons:null,prompt:`TA artifact ${a.id}. Prior: ${a.summary||a.title}. Run deterministic TA on the coin/venue in the artifact (RSI divergence, S/R, candle patterns). Reply in this Telegram chat with the verdict rows and say what was drawn. Do not sign or broadcast.`}:i.action==="fa"?{text:null,buttons:null,prompt:`FA artifact ${a.id}. Prior: ${a.summary||a.title}. Run per-coin FA (funding, OI, book, premium) plus the separate MACRO thesis (M1/M2/Fed BS/net liquidity) if relevant. Cite receipts. Stay in this Telegram chat. Do not sign or broadcast.`}:i.action==="allow"?{text:"Allow is the graph. Open the ticket there and CONFIRM. Telegram did not send.",buttons:null,prompt:null}:i.action==="deny"?{text:`Denied ${a.id}. Ticket cancelled. Nothing signed.`,buttons:null,prompt:null}:i.action==="long"||i.action==="short"?{text:null,buttons:null,prompt:`Open the live graph ticket for a ${i.action} on artifact ${a.id}. Prior: ${a.summary||a.title}. Size from the connected HL account. Execute only on CONFIRM on the graph. Never sign from Telegram.`}:c.allowed?{text:`Queued unsigned prepare for ${a.id}. Nothing signed. Allow/Deny still required.`,buttons:l,prompt:null,prepare:{artifactId:a.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${c.reason}. Deepen and Refresh still work.`,buttons:l,prompt:null}}function Fr(e={},{grant:t=null,now:n=Date.now(),state:r}={}){let o=r||dt(),i=String(e.id||`art-${Math.abs(Number(n)).toString(36)}`).toLowerCase().slice(0,40),a=Cs(o,{...e,id:i},{now:n}),c=pe({grant:t},{now:n});return{text:Pr({...a,grant:t}),replyMarkup:$r({artifactId:a.id,openUrl:a.openUrl,hasGrant:c.allowed}).replyMarkup,artifact:a,state:o}}var xs,Es,an,As,ks,je,cn=$(()=>{Ht();Kt();xs=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),Es=new Set(xs),an=/^[a-z0-9-]{4,40}$/i,As=/^[0-9a-f]{32}$/,ks=/^\d+$/;je=Ve()});var ao={};he(ao,{NON_OWNER_REPLY:()=>_e,buildPersona:()=>Ie,handleSelfUpdate:()=>Vr,isForwarded:()=>zr,isOwnerSender:()=>ke,ownerIdsFor:()=>jr,parseGatewayChainCommand:()=>eo,parseGatewayCompactCommand:()=>Zr,parseGatewayEffortCommand:()=>Yr,parseGatewayGoalCommand:()=>Xr,parseGatewayHelpCommand:()=>Jr,parseGatewayModelCommand:()=>Kr,parseGatewaySetupModelCommand:()=>qs,parseGatewayStatusCommand:()=>Qr,parsePeerAsk:()=>no,parseSelfUpdate:()=>Hr,resolveBackendArgv:()=>ro,resolveGatewayModel:()=>Wr,resolveOracleBin:()=>Dr,routePeerConsult:()=>ze,routeToAgent:()=>ee});import{spawn as qr}from"node:child_process";import{dirname as Ts,join as un}from"node:path";import{homedir as Os}from"node:os";import{mkdirSync as Ns,readFileSync as $s,writeFileSync as Ps,unlinkSync as Rs}from"node:fs";import{fileURLToPath as Ls}from"node:url";function Dr({env:e=process.env,moduleUrl:t=import.meta.url}={}){return e.ORACLE_CLI_ENTRY||un(Ts(Ls(t)),"oracle.mjs")}function jr(e,t=process.env){let n=String(t[`ORACLE_OWNER_${String(e).toUpperCase()}`]||""),r=String(t.ORACLE_OWNER_IDS||"");return new Set(`${n},${r}`.split(",").map(o=>o.trim()).filter(Boolean))}function ke({platform:e,senderId:t,extraOwners:n},r=process.env){let o=String(t||"").trim();return o?jr(e,r).has(o)?!0:Array.isArray(n)?n.map(i=>String(i).trim()).filter(Boolean).includes(o):!1:!1}function Hr(e){let t=String(e||"").trim();if(!t)return null;let n=t.replace(/^\/update(?:@[\w_]+)?\b/i,"update");return/^(?:oracle\s+)?update\s+--check\s*$/i.test(n)?{checkOnly:!0}:/^(?:oracle\s+)?update\s*$/i.test(n)?{checkOnly:!1}:null}async function Vr(e,{check:t=br,update:n=Sr,versionOf:r=en}={}){let o=await t({force:!0});if(e.checkOnly)return o.checked?o.updateAvailable?`oracle ${o.current} \u2192 ${o.latest} available. Send /update to install.`:`oracle ${o.current} is up to date`:`oracle ${o.current||"?"} \u2014 could not reach npm`;if(o.checked&&!o.updateAvailable)return`oracle ${o.current} is already up to date`;let i=o.latest||"latest",a=await n({version:i==="latest"?"latest":i});if(!a.ok)return`oracle update failed: ${a.message}`;let c=r();return[`oracle ${o.current||"?"} \u2192 ${c||i}`,"Restart the gateway to load it: oracle gateway"].join(`
21
+ `)}function zr(e={}){return!!(e.forwarded||e.forward_from||e.forward_from_chat||e.forward_origin||e.forward_sender_name||e.forward_date)}function Wr({readConfig:e=Ee}={}){let t=e();return t?t.backend==="hermes"?{ok:!1,error:"model config delegates to hermes; the gateway runs Oracle's native loop. Set a standalone backend: oracle model --backend standalone"}:t.model?{ok:!0,provider:t.provider,model:t.model,reasoningEffort:t.reasoningEffort||null}:{ok:!1,error:"model config has no model \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}:{ok:!1,error:"gateway has no model configured \u2014 run: oracle model --backend standalone --provider <p> --model <m>"}}function Kr(e){let n=String(e||"").trim().match(/^\/model(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim();if(!r)return{action:"list"};if(r.toLowerCase()==="show"||r==="?")return{action:"show"};if(r.toLowerCase()==="list")return{action:"list"};let o=r.split(/\s+/),i=Gr[o[0].toLowerCase()];if(i&&o.length===1)return{action:"set",provider:i.provider,model:i.model};if(i&&o.length>=2)return{action:"set",provider:i.provider,model:o.slice(1).join(" ")};if(o.length>=2)return{action:"set",provider:o[0],model:o.slice(1).join(" ")};if(o[0]?.includes(":")){let[a,c]=o[0].split(":");if(a&&c)return{action:"set",provider:a,model:c}}return{action:"usage"}}function Yr(e){let n=String(e||"").trim().match(/^\/(?:effort|reasoning)(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim().toLowerCase();return!r||r==="show"||r==="?"?{action:"show"}:Fs.includes(r)?{action:"set",reasoningEffort:r}:{action:"usage"}}function Ms({provider:e,model:t}){let n=Ee()||{},r=jt({...n,backend:n.backend&&n.backend!=="auto"?n.backend:"standalone",provider:e,model:t});return`model ${r.provider} / ${r.model}
22
+ Oracle persona unchanged. Native harness only \u2014 Hermes Telegram uses its own /model.`}function Bs(e){let t=Ee();if(!t)throw new Error("no model configured \u2014 run /model first");return`effort ${jt({...t,reasoningEffort:e}).reasoningEffort||e}
23
+ Native harness only.`}function Mr(){let e=Ee(),t=["Oracle native models (tap /model <id> to switch):"];for(let[n,r]of Object.entries(Gr)){let o=e?.provider===r.provider&&e?.model===r.model?" \u2190 current":"";t.push(`/model ${n} ${r.provider} / ${r.model}${o}`)}return t.push(""),t.push("Add another provider: /setup model"),t.push("Or set exact id: /model <provider> <model-id>"),t.push("/effort low|medium|high"),e?.provider&&(t.push(""),t.push(`current ${e.provider} / ${e.model||"unset"} \xB7 effort ${e.reasoningEffort||"default"}`)),t.join(`
24
+ `)}function ln(){let e=Ee();return e?[`backend ${e.backend||"auto"}`,`provider ${e.provider||"unset"}`,`model ${e.model||"unset"}`,`effort ${e.reasoningEffort||"default"}`,"Aliases: claude, codex, grok, openrouter, nous, qwen, glm, deepseek, gemini, kimi, mistral, local, ollama","/effort low|medium|high"].join(`
25
25
  `):["No standalone model configured.","Use /model openrouter","or /model qwen","or /model glm","or /model nous","or /model <provider> <model-id>"].join(`
26
- `)}function Ms(e){let n=String(e||"").trim().match(/^\/setup(?:\s+model(?:\s+(.+))?)?$/i);if(!n)return null;let r=String(n[1]||"").trim();return r?{action:"hint",provider:r.split(/\s+/)[0]}:{action:"menu"}}function Gr(e){let t=String(e||"").trim();return/^\/(?:help|commands|\?)$/i.test(t)?{action:"help"}:null}function Kr(e){let t=String(e||"").trim();return/^\/(?:status|usage)$/i.test(t)?{action:"status"}:null}function Yr(e){let n=String(e||"").trim().match(/^\/goal(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim();return!r||r.toLowerCase()==="show"?{action:"show"}:/^(clear|done|complete)$/i.test(r)?{action:"clear"}:{action:"set",goal:r}}function Jr(e){let n=String(e||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return n?{action:"compact",focus:String(n[1]||"").trim()}:null}function Qr(e){let n=String(e||"").trim().match(/^\/chain(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim();return!r||r.toLowerCase()==="list"?{action:"list"}:{action:"set",chain:r}}function dn(){return ln(un,"gateway-goal.json")}function Xr(){try{let e=JSON.parse(Os(dn(),"utf8"));return e&&typeof e.goal=="string"?e:null}catch{return null}}function Bs(e){Ts(un,{recursive:!0,mode:448});let t={schemaVersion:1,goal:String(e),updatedAt:new Date().toISOString()};return Ns(dn(),`${JSON.stringify(t,null,2)}
27
- `,{mode:384}),t}function qs(){try{$s(dn())}catch{}}function Ds(){return["Oracle native Telegram \u2014 owner commands","","Start here","/help this list","/commands same as /help","/status model, effort, chain, goal","","Models (like TUI /model)","/model list models you can use now","/model <id> switch: openrouter, nous, qwen, glm, claude, codex, grok, deepseek, gemini, kimi, mistral","/model <provider> <id> set an exact model id","/setup model how to add OpenRouter, Nous Portal, Qwen, GLM, ...","/setup model <id> TTY command to add that provider (never paste keys here)","/effort show current reasoning effort","/effort low|medium|high set effort like Hermes","","Session (like TUI / Hermes)","/goal show pinned objective","/goal <text> pin the session objective","/goal clear clear the objective","/compact [focus] compact context","/compress [focus] alias for /compact","/chain list working chains","/chain <name> switch chain","","Trading / signer","/update install latest Oracle","/approve Allow pending local-signer action","/deny Deny pending local-signer action","","Do not paste API keys into Telegram. Hermes Telegram keeps its own /model."].join(`
28
- `)}function js(){let e=cn(),t=nn(),n=Xr();return[e,`chain ${t?.key||t?.name||"default"}`,`goal ${n?.goal||"unset"}`].join(`
29
- `)}function Zr(e){let t=String(e||"").trim();if(!t)return null;let n=t.match(/^\/ask(?:@[\w_]+)?\s+([\w-]+)\s+([\s\S]+)$/i);return n||(n=t.match(/^@([\w-]+)\s+([\s\S]+)$/)),n?{peer:n[1].toLowerCase(),text:n[2].trim()}:null}function Ie(e={}){let t=[];return e.role&&t.push(String(e.role)),Array.isArray(e.chains)&&e.chains.length&&t.push(`chains: ${e.chains.join(", ")}`),e.persona&&t.push(String(e.persona)),t.join(" \xB7 ")}function eo(e,t,{profile:n}={}){let r=String(e||"oracle").toLowerCase(),o=String(t||"");if(r==="oracle")return{ok:!0,bin:null,args:["chat","-q",o]};if(r==="grok")return{ok:!0,bin:"grok",args:["-p",o]};if(r==="hermes"){let i=[];return n&&i.push("-p",String(n)),i.push("-z",o),{ok:!0,bin:"hermes",args:i}}return r==="claude"?{ok:!0,bin:"claude",args:["-p",o]}:{ok:!1,error:`unknown backend '${e}' (allowed: oracle, grok, hermes, claude)`}}async function He({from:e,text:t,persona:n="",backend:r,profile:o}={}){let i=[`[a2a consult from agent '${e}' \u2014 answer with information only; do not prepare, arm, or execute anything]`,n?`[your role: ${n}]`:"",String(t||"").trim()].filter(Boolean).join(`
30
- `);return no({text:i,backend:r,profile:o,unconfiguredPrefix:"unconfigured: "})}async function ee({platform:e,chatId:t,senderId:n,text:r,userName:o,meta:i={},updater:a,extraOwners:c,bus:l,agentName:u,persona:d,backend:s,profile:p}={}){if(!ke({platform:e,senderId:n,extraOwners:c}))return process.stderr.write(`gateway: denied non-owner sender ${e}:${String(n||"unknown")}
31
- `),_e;if(jr(i))return process.stderr.write(`gateway: dropped forwarded message on ${e}
32
- `),null;let m=qr(r);if(m)return Dr(m,a);let g=zr(r);if(g)try{return g.action==="list"?Lr():g.action==="show"?cn():g.action==="usage"?Lr():Us(g)}catch(S){return`model not saved: ${S.message}`}let w=Wr(r);if(w)try{return w.action==="show"?cn():w.action==="usage"?"usage: /effort low|medium|high":Fs(w.reasoningEffort)}catch(S){return`effort not saved: ${S.message}`}if(Gr(r))return Ds();if(Kr(r))return js();let k=Yr(r);if(k){if(k.action==="show"){let S=Xr();return S?.goal?`goal ${S.goal}`:"goal unset \u2014 /goal <objective>"}return k.action==="clear"?(qs(),"goal cleared"):(Bs(k.goal),`goal pinned: ${k.goal}`)}let E=Jr(r);if(E){let S=E.focus?` Focus: ${E.focus}.`:"";return Ur({platform:e,chatId:t,senderId:n,text:`Compact this session context now.${S} Summarize older turns, keep the current goal, model, chain, and any pending unsigned prepare artifacts. Do not sign or broadcast.`,userName:o,persona:d,backend:s,profile:p})}let N=Qr(r);if(N){if(N.action==="list")return Er({selectedKey:nn()?.key||null});let S=Be(N.chain);return S?(kr(S.key),`chain ${S.key}`):`unknown chain '${N.chain}' \u2014 /chain list`}if(Kt(r)){let S=await Jt({platform:e,text:r,grant:{local:!0}});return S?S.buttons?.kind==="inline_keyboard"?{text:S.text,replyMarkup:S.buttons.replyMarkup}:S.text:null}if(l){let S=Zr(r);if(S){let v=await l.send({from:u||"oracle",to:S.peer,text:S.text,kind:"consult"});return v.ok?v.reply?`[${S.peer}] ${v.reply}`:`[${S.peer}] (no reply)`:v.error}if(/^\/(agents|roster)\b/i.test(String(r||"").trim())){let v=l.roster().map(I=>`\u2022 ${I.name}${I.role?` \u2014 ${I.role}`:""}${I.chains.length?` (${I.chains.join(", ")})`:""}`);return v.length?`Agents on the bus:
33
- ${v.join(`
34
- `)}`:"No peer agents registered."}}let f=r.toLowerCase().trim();return/\b(buy|sell|swap|bridge|send|transfer|balance|portfolio|watch|quote|price)\b/.test(f)?Vs({platform:e,chatId:t,senderId:n,text:r,userName:o}):Ur({platform:e,chatId:t,senderId:n,text:r,userName:o,persona:d,backend:s,profile:p})}function to(e,{timeout:t=12e4}={}){return new Promise(n=>{let r=Fr(process.execPath,[Rs,...e],{stdio:["ignore","pipe","pipe"],timeout:t,env:{...process.env,ORACLE_CONFIG_DIR:un}}),o="",i="";r.stdout.on("data",a=>o+=a.toString()),r.stderr.on("data",a=>i+=a.toString()),r.on("close",a=>n({code:a,out:o.trim(),err:i.trim()}))})}function Hs(e,t,{timeout:n=18e4}={}){return new Promise(r=>{let o=Fr(e,t,{stdio:["ignore","pipe","pipe"],timeout:n,env:{...process.env}}),i="",a="";o.on("error",c=>r({code:127,out:"",err:String(c.message)})),o.stdout.on("data",c=>i+=c.toString()),o.stderr.on("data",c=>a+=c.toString()),o.on("close",c=>r({code:c,out:i.trim(),err:a.trim()}))})}async function Vs({text:e,chatId:t}){let n=await to(["route","swap","--text",e],{timeout:3e4});if(n.code===0&&n.out)try{return zs(JSON.parse(n.out),{chatId:t})}catch{return n.out}return`Trade routing failed. Try: \`${e}\` again.`}async function Ur({text:e,persona:t,backend:n,profile:r}){let o=t?`[your role: ${t}]
35
- ${e}`:e;return no({text:o,backend:n,profile:r,unconfiguredPrefix:"Oracle is not configured yet: "})}async function no({text:e,backend:t,profile:n,unconfiguredPrefix:r}){let o=eo(t,e,{profile:n});if(!o.ok)return`${r}${o.error}`;if(!o.bin){let a=Hr();if(!a.ok)return`${r}${a.error}`;let c=await to(o.args);return c.code===0&&c.out?c.out:c.err||"Oracle could not answer that. Try again."}let i=await Hs(o.bin,o.args);return i.code===0&&i.out?i.out:/ENOENT/.test(i.err)?`${r}backend '${o.bin}' is not installed on this machine`:i.err||`${o.bin} could not answer that. Try again.`}function zs(e,{chatId:t}={}){if(e.error)return`\u274C ${e.error}`;let n=e.quote||e.portfolio||(e.tx?"Unsigned trade prepared. Sign from your own wallet.":"");if(!n&&!e.tx)return JSON.stringify(e,null,2);let r=Rr({id:String(e.artifactId||`trade-${Date.now().toString(36)}`).toLowerCase().slice(0,40),kind:e.tx?"prepared_action":e.quote?"strategy":"thesis",title:e.tx?"Prepared trade":e.quote?"Quote":"Desk update",summary:n,payload:e},{grant:{local:!0}});return t&&an(r.state,{chatId:t,artifactId:r.artifact.id}),ut(De(),r.state),{text:r.text,replyMarkup:r.replyMarkup}}var un,Rs,_e,Vr,Ls,Ce=$(()=>{sr();Qt();wr();en();_r();sn();un=process.env.ORACLE_CONFIG_DIR||ln(Cs(),".config","oracle");Rs=Mr();_e="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";Vr=Object.freeze({claude:{provider:"anthropic-oauth",model:"claude-sonnet-4-20250514"},anthropic:{provider:"anthropic",model:"claude-sonnet-4-6"},codex:{provider:"openai-codex",model:"gpt-5.6-sol"},openai:{provider:"openai",model:"gpt-4.1-mini"},grok:{provider:"xai-oauth",model:"grok-4.6"},xai:{provider:"xai",model:"grok-4.6"},openrouter:{provider:"openrouter",model:"openrouter/auto"},nous:{provider:"nous",model:"moonshotai/kimi-k3"},deepseek:{provider:"deepseek",model:"deepseek-chat"},gemini:{provider:"gemini",model:"gemini-2.5-flash"},kimi:{provider:"kimi",model:"kimi-k3"},mistral:{provider:"mistral",model:"mistral-large-latest"},qwen:{provider:"qwen",model:"qwen-plus"},glm:{provider:"glm",model:"glm-4.5"},local:{provider:"local",model:"Qwen3-8B-Q4_K_M"},llama:{provider:"local",model:"Qwen3-8B-Q4_K_M"},ollama:{provider:"ollama",model:"llama3.2"}}),Ls=Object.freeze(["low","medium","high"])});function Gs(e,t){let n=new Set,r=[];for(let o of Array.isArray(e)?e:[]){let i=typeof o?.digest=="string"?o.digest:null;i&&(n.add(i),t.has(i)||r.push(o))}t.clear();for(let o of n)t.add(o);return r}function oo({onNew:e,intervalMs:t=Ws,env:n=process.env,signerCall:r=le,setIntervalFn:o=setInterval,clearIntervalFn:i=clearInterval}={}){if(typeof e!="function")throw new Error("pending-watch: onNew callback required");let a=new Set,c=!1,l=!1;async function u(){if(!l){l=!0;try{let s=await r("/pending",{env:n});if(!s||s.ok===!1||s.error||!Array.isArray(s.items))return;let p=Gs(s.items,a);if(!c){c=!0;return}if(p.length===0)return;try{await e(p,{armed:s.armed===!0})}catch{}}catch{}finally{l=!1}}}let d=o(u,t);return typeof d?.unref=="function"&&d.unref(),{stop(){i(d)},tick:u}}var Ws,io=$(()=>{st();Ws=4e3});import fe from"node:fs";function Ks(e){if(!e.isFile())throw new Error("local-vault: secret source must be a regular file");if(e.uid!==process.getuid?.())throw new Error("local-vault: secret source must be owned by this user");if(e.nlink!==1)throw new Error("local-vault: refusing hard-linked secret source");if((e.mode&63)!==0)throw new Error("local-vault: secret source must be owner-only (0600)")}function ao(e){let t;try{t=fe.openSync(e,fe.constants.O_RDONLY|fe.constants.O_NOFOLLOW)}catch(n){throw n.code==="ELOOP"?new Error("local-vault: refusing symlink"):n}try{let n=fe.fstatSync(t);if(Ks(n),n.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let r=fe.lstatSync(e);if(r.isSymbolicLink()||r.dev!==n.dev||r.ino!==n.ino)throw new Error("local-vault: secret source changed or is too large");return fe.readFileSync(t,"utf8").replace(/[\r\n]+$/,"")}finally{fe.closeSync(t)}}var af,sf,cf,so=$(()=>{af=Object.freeze({N:1<<17,r:8,p:1}),sf=256*1024*1024,cf=16*1024});import{createHash as Ys,createHmac as co,randomBytes as Js,timingSafeEqual as Qs}from"node:crypto";function po({keyFile:e,approvedTelegramOwners:t,nowMs:n=Date.now}={}){if(!e)throw new Error("cex owner proof: signer policy key required");let r=new Set((t||[]).map(Te).filter(Boolean));if(!r.size)throw new Error("cex owner proof: approved owner context required");let o=new Set,i=c=>{let l=Buffer.from(ao(e));try{return c(l)}finally{l.fill(0)}},a=i(c=>Ys("sha256").update("cex-owner-instance\0").update(c).digest("hex"));return Object.freeze({mint({digest:c,senderId:l,chatId:u,platform:d,ttlMs:s=15e3}={}){let p=Te(l),m=Te(u),g=n();if(d!=="telegram"||!p||m!==p||!r.has(p))throw new Error("cex owner proof: exact Telegram owner DM required");if(!/^[0-9a-f]{64}$/.test(String(c||""))||!Number.isSafeInteger(s)||s<1||s>3e4)throw new Error("cex owner proof: binding refused");let w={version:1,decision:"Allow",digest:c,ownerSenderId:p,telegramChatId:m,audience:lo,instance:a,nonce:Js(16).toString("hex"),issuedAtMs:g,expiresAtMs:g+s},k=i(E=>co("sha256",E).update(uo(w)).digest("hex"));return{claims:w,mac:k}},verify(c,{digest:l}={}){let u=c?.claims,d=n();if(!u||u.version!==1||u.decision!=="Allow"||u.digest!==l||u.audience!==lo||u.instance!==a||!/^[0-9a-f]{32}$/.test(u.nonce||"")||Te(u.ownerSenderId)!==Te(u.telegramChatId)||!r.has(Te(u.ownerSenderId))||!Number.isSafeInteger(u.issuedAtMs)||!Number.isSafeInteger(u.expiresAtMs)||u.expiresAtMs<=d||u.issuedAtMs>d||u.expiresAtMs-u.issuedAtMs>3e4||o.has(u.nonce))return!1;let s=i(p=>co("sha256",p).update(uo(u)).digest("hex"));return Xs(c.mac,s)?(o.add(u.nonce),!0):!1}})}var lo,Te,uo,Xs,fo=$(()=>{so();lo="oracle-local-signer-cex-owner-allow-v1",Te=e=>/^(?:0|[1-9]\d{0,19})$/.test(String(e||""))?String(e):null,uo=e=>JSON.stringify(e),Xs=(e,t)=>{let n=Buffer.from(String(e)),r=Buffer.from(String(t));return n.length===r.length&&Qs(n,r)}});var yo={};he(yo,{buildPersona:()=>Ie,telegram:()=>tc,telegramPendingRecipients:()=>ec});import{join as mo}from"node:path";import{homedir as Zs}from"node:os";function dt(e=process.env){return Cr(De(e)),lt()}function ho(e=process.env){ut(De(e),lt())}function ec({extraOwners:e,env:t=process.env}={}){let n=String(t.ORACLE_OWNER_TELEGRAM||"").split(",").map(o=>o.trim()).filter(Boolean),r=Array.isArray(e)?e.map(o=>String(o).trim()):[];return[...new Set([...n,...r])].filter(o=>/^\d+$/.test(o))}function pn(e,t){if(!t)return;if(typeof t=="string")return e.reply(t,{parse_mode:"Markdown"});let n=t.replyMarkup?{reply_markup:t.replyMarkup}:{};return e.reply(t.text,{parse_mode:"Markdown",...n})}async function tc(e){let{Bot:t}=await import("grammy");dt();let n=new t(e.token),r=String(e.name||"oracle").toLowerCase(),o=Ie(e),i=Array.isArray(e.owners)?e.owners:void 0,a=e.bus;a&&a.register(r,{role:e.role||"",chains:e.chains||[],handler:s=>He({from:s.from,text:s.text,persona:o,backend:e.backend,profile:e.hermesProfile})}),n.command("start",s=>{let p=String(s.from?.id||s.chat.id);if(!ke({platform:"telegram",senderId:p,extraOwners:i}))return s.reply(_e);let m=String(s.match||"").trim();if(m){let g=dt(),w=$r(g,{token:m,telegramUserId:p});return ho(),w.ok?s.reply("Telegram linked to Oracle. Agent artifacts will land as interactive cards. Deepen stays in this thread."):s.reply(`Link failed: ${w.error}`)}return s.reply(`${r} ready. /help lists every native command. /model lists models. /setup model adds OpenRouter, Nous Portal, Qwen, GLM. /effort sets reasoning. /update installs latest.${a?" /agents lists peers.":""}`)}),n.command("update",async s=>{let p=String(s.from?.id||s.chat.id),m=String(s.chat.id);if(!ke({platform:"telegram",senderId:p,extraOwners:i}))return s.reply(_e);if(s.message.forward_origin||s.message.forward_from||s.message.forward_date)return;s.replyWithChatAction("typing").catch(()=>{});let g=await ee({platform:"telegram",chatId:m,senderId:p,text:s.match?`update ${s.match}`.trim():"update",userName:s.from?.username||s.from?.first_name||"user"});if(g)return pn(s,g)}),n.on("message:text",async s=>{let p=String(s.chat.id),m=String(s.from?.id||p),g=s.message.text;try{s.replyWithChatAction("typing").catch(()=>{});let w=dt(),k=Nr(w,{chatId:p,text:g}),E=await ee({platform:"telegram",chatId:p,senderId:m,text:k||g,userName:s.from?.username||s.from?.first_name||"user",extraOwners:i,bus:a,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile,meta:{forward_origin:s.message.forward_origin,forward_from:s.message.forward_from,forward_from_chat:s.message.forward_from_chat,forward_sender_name:s.message.forward_sender_name,forward_date:s.message.forward_date}});E&&await pn(s,E)}catch(w){process.stderr.write(`telegram-gateway[${r}]: ${w.message}
36
- `),await s.reply("Something went wrong. Try again.").catch(()=>{})}}),n.on("callback_query:data",async s=>{let p=String(s.from?.id||"");if(!ke({platform:"telegram",senderId:p,extraOwners:i})){await s.answerCallbackQuery({text:_e.slice(0,180),show_alert:!0}).catch(()=>{});return}let m=String(s.callbackQuery?.data||""),g=String(process.env.ORACLE_OWNER_TELEGRAM||"").split(",").map(N=>N.trim()).filter(Boolean),w=process.env.ORACLE_CONFIG_DIR||mo(Zs(),".config","oracle"),k;try{k=po({keyFile:mo(w,"signer","policy-integrity-key"),approvedTelegramOwners:g})}catch{}let E=await pr({platform:"telegram",data:m,senderId:p,chatId:String(s.chat?.id||""),ownerProofAuthority:k,grant:{local:!0}});if(!E){let N=dt(),b=Pr(N,{data:m,chatId:String(s.chat?.id||""),grant:{local:!0}});if(ho(),!b){await s.answerCallbackQuery().catch(()=>{});return}if(await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),b.prompt){let f=await ee({platform:"telegram",chatId:String(s.chat?.id||""),senderId:p,text:b.prompt,extraOwners:i,bus:a,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile});f&&await pn(s,f);return}if(b.text){let f=b.buttons?.replyMarkup?{reply_markup:b.buttons.replyMarkup}:{};await s.reply(b.text,{parse_mode:"Markdown",...f}).catch(()=>{})}return}await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),E.text&&await s.reply(E.text,{parse_mode:"Markdown"}).catch(()=>{})}),await n.init(),n.start().catch(s=>{process.stderr.write(`telegram-gateway[${r}]: polling stopped: ${String(s?.message||s).slice(0,160)}
37
- `)});let c=we("telegram",{owners:i}).filter(s=>/^\d+$/.test(s)),l=null;return c.length>0&&e.pendingWatch!==!1&&(l=oo({intervalMs:e.pendingWatchIntervalMs,onNew:async(s,{armed:p})=>{let m=Yt(s,{platform:"telegram",grant:{local:!0},armed:p}),g=m.buttons?.replyMarkup?{reply_markup:m.buttons.replyMarkup}:{};for(let w of c)await n.api.sendMessage(w,m.text,{parse_mode:"Markdown",...g}).catch(()=>{})}})),{platform:"telegram",name:r,bot:n,ownerIds:c,notifyRecipient:async(s,p)=>{let m=String(s||"");return c.includes(m)?(await n.api.sendMessage(m,String(p)),1):0},stop:async()=>{l?.stop(),await Promise.resolve(n.stop()).catch(()=>{})},stopPendingWatch:()=>l?.stop()}}var go=$(()=>{Ce();Qt();io();fo();sn();Ue()});var wo={};he(wo,{discord:()=>nc});async function nc(e){let{Client:t,GatewayIntentBits:n}=await import("discord.js"),r=new t({intents:[n.Guilds,n.GuildMessages,n.MessageContent,n.DirectMessages]}),o=String(e.name||"oracle").toLowerCase(),i=Ie(e),a=Array.isArray(e.owners)?e.owners:void 0,c=e.bus;c&&c.register(o,{role:e.role||"",chains:e.chains||[],handler:s=>He({from:s.from,text:s.text,persona:i,backend:e.backend,profile:e.hermesProfile})}),r.on("messageCreate",async s=>{if(s.author.bot)return;let p=s.channel.id,m=s.author.id,g=s.content;try{let w=!s.guild,k=s.mentions.has(r.user.id);if(!w&&!k)return;s.channel.sendTyping().catch(()=>{});let E=await ee({platform:"discord",chatId:p,senderId:m,text:g.replace(`<@${r.user.id}>`,"").trim(),userName:s.author.username,extraOwners:a,bus:c,agentName:o,persona:i,backend:e.backend,profile:e.hermesProfile,meta:{forwarded:s.reference?.type===1||Array.isArray(s.messageSnapshots)&&s.messageSnapshots.length>0}});E&&await s.reply(typeof E=="string"?E:E.text).catch(()=>{})}catch(w){process.stderr.write(`discord-gateway[${o}]: ${w.message}
38
- `)}}),await r.login(e.token);let l=we("discord",e);return{platform:"discord",name:o,client:r,ownerIds:l,notifyRecipient:async(s,p)=>{let m=String(s||"");return l.includes(m)?(await(await r.users.fetch(m)).send(String(p).slice(0,2e3)),1):0},stop:async()=>{await Promise.resolve(r.destroy())}}}var bo=$(()=>{Ce();Ue()});var vo={};he(vo,{whatsapp:()=>ic});import{join as So}from"node:path";import{homedir as rc}from"node:os";async function ic(e){let[{Client:t,LocalAuth:n},{generate:r}]=await Promise.all([import("whatsapp-web.js"),import("qrcode-terminal")]),o=new t({authStrategy:new n({dataPath:So(oc,".wwebjs_auth")}),puppeteer:{headless:!0,args:["--no-sandbox"]}});o.on("qr",l=>{process.stderr.write(`
26
+ `)}function qs(e){let n=String(e||"").trim().match(/^\/setup(?:\s+model(?:\s+(.+))?)?$/i);if(!n)return null;let r=String(n[1]||"").trim();return r?{action:"hint",provider:r.split(/\s+/)[0]}:{action:"menu"}}function Jr(e){let t=String(e||"").trim();return/^\/(?:help|commands|\?)$/i.test(t)?{action:"help"}:null}function Qr(e){let t=String(e||"").trim();return/^\/(?:status|usage)$/i.test(t)?{action:"status"}:null}function Xr(e){let n=String(e||"").trim().match(/^\/goal(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim();return!r||r.toLowerCase()==="show"?{action:"show"}:/^(clear|done|complete)$/i.test(r)?{action:"clear"}:{action:"set",goal:r}}function Zr(e){let n=String(e||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return n?{action:"compact",focus:String(n[1]||"").trim()}:null}function eo(e){let n=String(e||"").trim().match(/^\/chain(?:\s+(.+))?$/i);if(!n)return null;let r=String(n[1]||"").trim();return!r||r.toLowerCase()==="list"?{action:"list"}:{action:"set",chain:r}}function pn(){return un(dn,"gateway-goal.json")}function to(){try{let e=JSON.parse($s(pn(),"utf8"));return e&&typeof e.goal=="string"?e:null}catch{return null}}function Ds(e){Ns(dn,{recursive:!0,mode:448});let t={schemaVersion:1,goal:String(e),updatedAt:new Date().toISOString()};return Ps(pn(),`${JSON.stringify(t,null,2)}
27
+ `,{mode:384}),t}function js(){try{Rs(pn())}catch{}}function Hs(){return["Oracle native Telegram \u2014 owner commands","","Start here","/help this list","/commands same as /help","/status model, effort, chain, goal","","Models (like TUI /model)","/model list models you can use now","/model <id> switch: openrouter, nous, qwen, glm, claude, codex, grok, deepseek, gemini, kimi, mistral","/model <provider> <id> set an exact model id","/setup model how to add OpenRouter, Nous Portal, Qwen, GLM, ...","/setup model <id> TTY command to add that provider (never paste keys here)","/effort show current reasoning effort","/effort low|medium|high set effort like Hermes","","Session (like TUI / Hermes)","/goal show pinned objective","/goal <text> pin the session objective","/goal clear clear the objective","/compact [focus] compact context","/compress [focus] alias for /compact","/chain list working chains","/chain <name> switch chain","","Trading / signer","/update install latest Oracle","/approve Allow pending local-signer action","/deny Deny pending local-signer action","","Do not paste API keys into Telegram. Hermes Telegram keeps its own /model."].join(`
28
+ `)}function Vs(){let e=ln(),t=rn(),n=to();return[e,`chain ${t?.key||t?.name||"default"}`,`goal ${n?.goal||"unset"}`].join(`
29
+ `)}function no(e){let t=String(e||"").trim();if(!t)return null;let n=t.match(/^\/ask(?:@[\w_]+)?\s+([\w-]+)\s+([\s\S]+)$/i);return n||(n=t.match(/^@([\w-]+)\s+([\s\S]+)$/)),n?{peer:n[1].toLowerCase(),text:n[2].trim()}:null}function Ie(e={}){let t=[];return e.role&&t.push(String(e.role)),Array.isArray(e.chains)&&e.chains.length&&t.push(`chains: ${e.chains.join(", ")}`),e.persona&&t.push(String(e.persona)),t.join(" \xB7 ")}function ro(e,t,{profile:n}={}){let r=String(e||"oracle").toLowerCase(),o=String(t||"");if(r==="oracle")return{ok:!0,bin:null,args:["chat","-q",o]};if(r==="grok")return{ok:!0,bin:"grok",args:["-p",o]};if(r==="hermes"){let i=[];return n&&i.push("-p",String(n)),i.push("-z",o),{ok:!0,bin:"hermes",args:i}}return r==="claude"?{ok:!0,bin:"claude",args:["-p",o]}:{ok:!1,error:`unknown backend '${e}' (allowed: oracle, grok, hermes, claude)`}}async function ze({from:e,text:t,persona:n="",backend:r,profile:o}={}){let i=[`[a2a consult from agent '${e}' \u2014 answer with information only; do not prepare, arm, or execute anything]`,n?`[your role: ${n}]`:"",String(t||"").trim()].filter(Boolean).join(`
30
+ `);return io({text:i,backend:r,profile:o,unconfiguredPrefix:"unconfigured: "})}async function ee({platform:e,chatId:t,senderId:n,text:r,userName:o,meta:i={},updater:a,extraOwners:c,bus:l,agentName:u,persona:d,backend:s,profile:p}={}){if(!ke({platform:e,senderId:n,extraOwners:c}))return process.stderr.write(`gateway: denied non-owner sender ${e}:${String(n||"unknown")}
31
+ `),_e;if(zr(i))return process.stderr.write(`gateway: dropped forwarded message on ${e}
32
+ `),null;let m=Hr(r);if(m)return Vr(m,a);let g=Kr(r);if(g)try{return g.action==="list"?Mr():g.action==="show"?ln():g.action==="usage"?Mr():Ms(g)}catch(b){return`model not saved: ${b.message}`}let w=Yr(r);if(w)try{return w.action==="show"?ln():w.action==="usage"?"usage: /effort low|medium|high":Bs(w.reasoningEffort)}catch(b){return`effort not saved: ${b.message}`}if(Jr(r))return Hs();if(Qr(r))return Vs();let E=Xr(r);if(E){if(E.action==="show"){let b=to();return b?.goal?`goal ${b.goal}`:"goal unset \u2014 /goal <objective>"}return E.action==="clear"?(js(),"goal cleared"):(Ds(E.goal),`goal pinned: ${E.goal}`)}let A=Zr(r);if(A){let b=A.focus?` Focus: ${A.focus}.`:"";return Br({platform:e,chatId:t,senderId:n,text:`Compact this session context now.${b} Summarize older turns, keep the current goal, model, chain, and any pending unsigned prepare artifacts. Do not sign or broadcast.`,userName:o,persona:d,backend:s,profile:p})}let T=eo(r);if(T){if(T.action==="list")return _r({selectedKey:rn()?.key||null});let b=De(T.chain);return b?(Cr(b.key),`chain ${b.key}`):`unknown chain '${T.chain}' \u2014 /chain list`}if(Yt(r)){let b=await Qt({platform:e,text:r,grant:{local:!0}});return b?b.buttons?.kind==="inline_keyboard"?{text:b.text,replyMarkup:b.buttons.replyMarkup}:b.text:null}if(l){let b=no(r);if(b){let S=await l.send({from:u||"oracle",to:b.peer,text:b.text,kind:"consult"});return S.ok?S.reply?`[${b.peer}] ${S.reply}`:`[${b.peer}] (no reply)`:S.error}if(/^\/(agents|roster)\b/i.test(String(r||"").trim())){let S=l.roster().map(I=>`\u2022 ${I.name}${I.role?` \u2014 ${I.role}`:""}${I.chains.length?` (${I.chains.join(", ")})`:""}`);return S.length?`Agents on the bus:
33
+ ${S.join(`
34
+ `)}`:"No peer agents registered."}}let f=r.toLowerCase().trim();return/\b(buy|sell|swap|bridge|send|transfer|balance|portfolio|watch|quote|price)\b/.test(f)?Ws({platform:e,chatId:t,senderId:n,text:r,userName:o}):Br({platform:e,chatId:t,senderId:n,text:r,userName:o,persona:d,backend:s,profile:p})}function oo(e,{timeout:t=12e4}={}){return new Promise(n=>{let r=qr(process.execPath,[Us,...e],{stdio:["ignore","pipe","pipe"],timeout:t,env:{...process.env,ORACLE_CONFIG_DIR:dn}}),o="",i="";r.stdout.on("data",a=>o+=a.toString()),r.stderr.on("data",a=>i+=a.toString()),r.on("close",a=>n({code:a,out:o.trim(),err:i.trim()}))})}function zs(e,t,{timeout:n=18e4}={}){return new Promise(r=>{let o=qr(e,t,{stdio:["ignore","pipe","pipe"],timeout:n,env:{...process.env}}),i="",a="";o.on("error",c=>r({code:127,out:"",err:String(c.message)})),o.stdout.on("data",c=>i+=c.toString()),o.stderr.on("data",c=>a+=c.toString()),o.on("close",c=>r({code:c,out:i.trim(),err:a.trim()}))})}async function Ws({text:e,chatId:t}){let n=await oo(["route","swap","--text",e],{timeout:3e4});if(n.code===0&&n.out)try{return Gs(JSON.parse(n.out),{chatId:t})}catch{return n.out}return`Trade routing failed. Try: \`${e}\` again.`}async function Br({text:e,persona:t,backend:n,profile:r}){let o=t?`[your role: ${t}]
35
+ ${e}`:e;return io({text:o,backend:n,profile:r,unconfiguredPrefix:"Oracle is not configured yet: "})}async function io({text:e,backend:t,profile:n,unconfiguredPrefix:r}){let o=ro(t,e,{profile:n});if(!o.ok)return`${r}${o.error}`;if(!o.bin){let a=Wr();if(!a.ok)return`${r}${a.error}`;let c=await oo(o.args);return c.code===0&&c.out?c.out:c.err||"Oracle could not answer that. Try again."}let i=await zs(o.bin,o.args);return i.code===0&&i.out?i.out:/ENOENT/.test(i.err)?`${r}backend '${o.bin}' is not installed on this machine`:i.err||`${o.bin} could not answer that. Try again.`}function Gs(e,{chatId:t}={}){if(e.error)return`\u274C ${e.error}`;let n=e.quote||e.portfolio||(e.tx?"Unsigned trade prepared. Sign from your own wallet.":"");if(!n&&!e.tx)return JSON.stringify(e,null,2);let r=Fr({id:String(e.artifactId||`trade-${Date.now().toString(36)}`).toLowerCase().slice(0,40),kind:e.tx?"prepared_action":e.quote?"strategy":"thesis",title:e.tx?"Prepared trade":e.quote?"Quote":"Desk update",summary:n,payload:e},{grant:{local:!0}});return t&&sn(r.state,{chatId:t,artifactId:r.artifact.id}),pt(He(),r.state),{text:r.text,replyMarkup:r.replyMarkup}}var dn,Us,_e,Gr,Fs,Ce=$(()=>{ur();Xt();vr();tn();Tr();cn();dn=process.env.ORACLE_CONFIG_DIR||un(Os(),".config","oracle");Us=Dr();_e="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";Gr=Object.freeze({claude:{provider:"anthropic-oauth",model:"claude-sonnet-4-20250514"},anthropic:{provider:"anthropic",model:"claude-sonnet-4-6"},codex:{provider:"openai-codex",model:"gpt-5.6-sol"},openai:{provider:"openai",model:"gpt-4.1-mini"},grok:{provider:"xai-oauth",model:"grok-4.6"},xai:{provider:"xai",model:"grok-4.6"},openrouter:{provider:"openrouter",model:"openrouter/auto"},nous:{provider:"nous",model:"moonshotai/kimi-k3"},deepseek:{provider:"deepseek",model:"deepseek-chat"},gemini:{provider:"gemini",model:"gemini-2.5-flash"},kimi:{provider:"kimi",model:"kimi-k3"},mistral:{provider:"mistral",model:"mistral-large-latest"},qwen:{provider:"qwen",model:"qwen-plus"},glm:{provider:"glm",model:"glm-4.5"},local:{provider:"local",model:"Qwen3-8B-Q4_K_M"},llama:{provider:"local",model:"Qwen3-8B-Q4_K_M"},ollama:{provider:"ollama",model:"llama3.2"}}),Fs=Object.freeze(["low","medium","high"])});function Ys(e,t){let n=new Set,r=[];for(let o of Array.isArray(e)?e:[]){let i=typeof o?.digest=="string"?o.digest:null;i&&(n.add(i),t.has(i)||r.push(o))}t.clear();for(let o of n)t.add(o);return r}function so({onNew:e,intervalMs:t=Ks,env:n=process.env,signerCall:r=le,setIntervalFn:o=setInterval,clearIntervalFn:i=clearInterval}={}){if(typeof e!="function")throw new Error("pending-watch: onNew callback required");let a=new Set,c=!1,l=!1;async function u(){if(!l){l=!0;try{let s=await r("/pending",{env:n});if(!s||s.ok===!1||s.error||!Array.isArray(s.items))return;let p=Ys(s.items,a);if(!c){c=!0;return}if(p.length===0)return;try{await e(p,{armed:s.armed===!0})}catch{}}catch{}finally{l=!1}}}let d=o(u,t);return typeof d?.unref=="function"&&d.unref(),{stop(){i(d)},tick:u}}var Ks,co=$(()=>{lt();Ks=4e3});import fe from"node:fs";function Js(e){if(!e.isFile())throw new Error("local-vault: secret source must be a regular file");if(e.uid!==process.getuid?.())throw new Error("local-vault: secret source must be owned by this user");if(e.nlink!==1)throw new Error("local-vault: refusing hard-linked secret source");if((e.mode&63)!==0)throw new Error("local-vault: secret source must be owner-only (0600)")}function lo(e){let t;try{t=fe.openSync(e,fe.constants.O_RDONLY|fe.constants.O_NOFOLLOW)}catch(n){throw n.code==="ELOOP"?new Error("local-vault: refusing symlink"):n}try{let n=fe.fstatSync(t);if(Js(n),n.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let r=fe.lstatSync(e);if(r.isSymbolicLink()||r.dev!==n.dev||r.ino!==n.ino)throw new Error("local-vault: secret source changed or is too large");return fe.readFileSync(t,"utf8").replace(/[\r\n]+$/,"")}finally{fe.closeSync(t)}}var cf,lf,uf,uo=$(()=>{cf=Object.freeze({N:1<<17,r:8,p:1}),lf=256*1024*1024,uf=16*1024});import{createHash as Qs,createHmac as po,randomBytes as Xs,timingSafeEqual as Zs}from"node:crypto";function ho({keyFile:e,approvedTelegramOwners:t,nowMs:n=Date.now}={}){if(!e)throw new Error("cex owner proof: signer policy key required");let r=new Set((t||[]).map(Te).filter(Boolean));if(!r.size)throw new Error("cex owner proof: approved owner context required");let o=new Set,i=c=>{let l=Buffer.from(lo(e));try{return c(l)}finally{l.fill(0)}},a=i(c=>Qs("sha256").update("cex-owner-instance\0").update(c).digest("hex"));return Object.freeze({mint({digest:c,senderId:l,chatId:u,platform:d,ttlMs:s=15e3}={}){let p=Te(l),m=Te(u),g=n();if(d!=="telegram"||!p||m!==p||!r.has(p))throw new Error("cex owner proof: exact Telegram owner DM required");if(!/^[0-9a-f]{64}$/.test(String(c||""))||!Number.isSafeInteger(s)||s<1||s>3e4)throw new Error("cex owner proof: binding refused");let w={version:1,decision:"Allow",digest:c,ownerSenderId:p,telegramChatId:m,audience:fo,instance:a,nonce:Xs(16).toString("hex"),issuedAtMs:g,expiresAtMs:g+s},E=i(A=>po("sha256",A).update(mo(w)).digest("hex"));return{claims:w,mac:E}},verify(c,{digest:l}={}){let u=c?.claims,d=n();if(!u||u.version!==1||u.decision!=="Allow"||u.digest!==l||u.audience!==fo||u.instance!==a||!/^[0-9a-f]{32}$/.test(u.nonce||"")||Te(u.ownerSenderId)!==Te(u.telegramChatId)||!r.has(Te(u.ownerSenderId))||!Number.isSafeInteger(u.issuedAtMs)||!Number.isSafeInteger(u.expiresAtMs)||u.expiresAtMs<=d||u.issuedAtMs>d||u.expiresAtMs-u.issuedAtMs>3e4||o.has(u.nonce))return!1;let s=i(p=>po("sha256",p).update(mo(u)).digest("hex"));return ec(c.mac,s)?(o.add(u.nonce),!0):!1}})}var fo,Te,mo,ec,yo=$(()=>{uo();fo="oracle-local-signer-cex-owner-allow-v1",Te=e=>/^(?:0|[1-9]\d{0,19})$/.test(String(e||""))?String(e):null,mo=e=>JSON.stringify(e),ec=(e,t)=>{let n=Buffer.from(String(e)),r=Buffer.from(String(t));return n.length===r.length&&Zs(n,r)}});var bo={};he(bo,{buildPersona:()=>Ie,telegram:()=>rc,telegramPendingRecipients:()=>nc});import{join as go}from"node:path";import{homedir as tc}from"node:os";function ft(e=process.env){return Nr(He(e)),dt()}function wo(e=process.env){pt(He(e),dt())}function nc({extraOwners:e,env:t=process.env}={}){let n=String(t.ORACLE_OWNER_TELEGRAM||"").split(",").map(o=>o.trim()).filter(Boolean),r=Array.isArray(e)?e.map(o=>String(o).trim()):[];return[...new Set([...n,...r])].filter(o=>/^\d+$/.test(o))}function fn(e,t){if(!t)return;if(typeof t=="string")return e.reply(t,{parse_mode:"Markdown"});let n=t.replyMarkup?{reply_markup:t.replyMarkup}:{};return e.reply(t.text,{parse_mode:"Markdown",...n})}async function rc(e){let{Bot:t}=await import("grammy");ft();let n=new t(e.token),r=String(e.name||"oracle").toLowerCase(),o=Ie(e),i=Array.isArray(e.owners)?e.owners:void 0,a=e.bus;a&&a.register(r,{role:e.role||"",chains:e.chains||[],handler:s=>ze({from:s.from,text:s.text,persona:o,backend:e.backend,profile:e.hermesProfile})}),n.command("start",s=>{let p=String(s.from?.id||s.chat.id);if(!ke({platform:"telegram",senderId:p,extraOwners:i}))return s.reply(_e);let m=String(s.match||"").trim();if(m){let g=ft(),w=Lr(g,{token:m,telegramUserId:p});return wo(),w.ok?s.reply("Telegram linked to Oracle. Agent artifacts will land as interactive cards. Deepen stays in this thread."):s.reply(`Link failed: ${w.error}`)}return s.reply(`${r} ready. /help lists every native command. /model lists models. /setup model adds OpenRouter, Nous Portal, Qwen, GLM. /effort sets reasoning. /update installs latest.${a?" /agents lists peers.":""}`)}),n.command("update",async s=>{let p=String(s.from?.id||s.chat.id),m=String(s.chat.id);if(!ke({platform:"telegram",senderId:p,extraOwners:i}))return s.reply(_e);if(s.message.forward_origin||s.message.forward_from||s.message.forward_date)return;s.replyWithChatAction("typing").catch(()=>{});let g=await ee({platform:"telegram",chatId:m,senderId:p,text:s.match?`update ${s.match}`.trim():"update",userName:s.from?.username||s.from?.first_name||"user"});if(g)return fn(s,g)}),n.on("message:text",async s=>{let p=String(s.chat.id),m=String(s.from?.id||p),g=s.message.text;try{s.replyWithChatAction("typing").catch(()=>{});let w=ft(),E=Rr(w,{chatId:p,text:g}),A=await ee({platform:"telegram",chatId:p,senderId:m,text:E||g,userName:s.from?.username||s.from?.first_name||"user",extraOwners:i,bus:a,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile,meta:{forward_origin:s.message.forward_origin,forward_from:s.message.forward_from,forward_from_chat:s.message.forward_from_chat,forward_sender_name:s.message.forward_sender_name,forward_date:s.message.forward_date}});A&&await fn(s,A)}catch(w){process.stderr.write(`telegram-gateway[${r}]: ${w.message}
36
+ `),await s.reply("Something went wrong. Try again.").catch(()=>{})}}),n.on("callback_query:data",async s=>{let p=String(s.from?.id||"");if(!ke({platform:"telegram",senderId:p,extraOwners:i})){await s.answerCallbackQuery({text:_e.slice(0,180),show_alert:!0}).catch(()=>{});return}let m=String(s.callbackQuery?.data||""),g=String(process.env.ORACLE_OWNER_TELEGRAM||"").split(",").map(T=>T.trim()).filter(Boolean),w=process.env.ORACLE_CONFIG_DIR||go(tc(),".config","oracle"),E;try{E=ho({keyFile:go(w,"signer","policy-integrity-key"),approvedTelegramOwners:g})}catch{}let A=await hr({platform:"telegram",data:m,senderId:p,chatId:String(s.chat?.id||""),ownerProofAuthority:E,grant:{local:!0}});if(!A){let T=ft(),v=Ur(T,{data:m,chatId:String(s.chat?.id||""),grant:{local:!0}});if(wo(),!v){await s.answerCallbackQuery().catch(()=>{});return}if(await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),v.prompt){let f=await ee({platform:"telegram",chatId:String(s.chat?.id||""),senderId:p,text:v.prompt,extraOwners:i,bus:a,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile});f&&await fn(s,f);return}if(v.text){let f=v.buttons?.replyMarkup?{reply_markup:v.buttons.replyMarkup}:{};await s.reply(v.text,{parse_mode:"Markdown",...f}).catch(()=>{})}return}await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),A.text&&await s.reply(A.text,{parse_mode:"Markdown"}).catch(()=>{})}),await n.init(),n.start().catch(s=>{process.stderr.write(`telegram-gateway[${r}]: polling stopped: ${String(s?.message||s).slice(0,160)}
37
+ `)});let c=we("telegram",{owners:i}).filter(s=>/^\d+$/.test(s)),l=null;return c.length>0&&e.pendingWatch!==!1&&(l=so({intervalMs:e.pendingWatchIntervalMs,onNew:async(s,{armed:p})=>{let m=Jt(s,{platform:"telegram",grant:{local:!0},armed:p}),g=m.buttons?.replyMarkup?{reply_markup:m.buttons.replyMarkup}:{};for(let w of c)await n.api.sendMessage(w,m.text,{parse_mode:"Markdown",...g}).catch(()=>{})}})),{platform:"telegram",name:r,bot:n,ownerIds:c,notifyRecipient:async(s,p)=>{let m=String(s||"");return c.includes(m)?(await n.api.sendMessage(m,String(p)),1):0},stop:async()=>{l?.stop(),await Promise.resolve(n.stop()).catch(()=>{})},stopPendingWatch:()=>l?.stop()}}var So=$(()=>{Ce();Xt();co();yo();cn();Me()});var vo={};he(vo,{discord:()=>oc});async function oc(e){let{Client:t,GatewayIntentBits:n}=await import("discord.js"),r=new t({intents:[n.Guilds,n.GuildMessages,n.MessageContent,n.DirectMessages]}),o=String(e.name||"oracle").toLowerCase(),i=Ie(e),a=Array.isArray(e.owners)?e.owners:void 0,c=e.bus;c&&c.register(o,{role:e.role||"",chains:e.chains||[],handler:s=>ze({from:s.from,text:s.text,persona:i,backend:e.backend,profile:e.hermesProfile})}),r.on("messageCreate",async s=>{if(s.author.bot)return;let p=s.channel.id,m=s.author.id,g=s.content;try{let w=!s.guild,E=s.mentions.has(r.user.id);if(!w&&!E)return;s.channel.sendTyping().catch(()=>{});let A=await ee({platform:"discord",chatId:p,senderId:m,text:g.replace(`<@${r.user.id}>`,"").trim(),userName:s.author.username,extraOwners:a,bus:c,agentName:o,persona:i,backend:e.backend,profile:e.hermesProfile,meta:{forwarded:s.reference?.type===1||Array.isArray(s.messageSnapshots)&&s.messageSnapshots.length>0}});A&&await s.reply(typeof A=="string"?A:A.text).catch(()=>{})}catch(w){process.stderr.write(`discord-gateway[${o}]: ${w.message}
38
+ `)}}),await r.login(e.token);let l=we("discord",e);return{platform:"discord",name:o,client:r,ownerIds:l,notifyRecipient:async(s,p)=>{let m=String(s||"");return l.includes(m)?(await(await r.users.fetch(m)).send(String(p).slice(0,2e3)),1):0},stop:async()=>{await Promise.resolve(r.destroy())}}}var xo=$(()=>{Ce();Me()});var Ao={};he(Ao,{whatsapp:()=>sc});import{join as Eo}from"node:path";import{homedir as ic}from"node:os";async function sc(e){let[{Client:t,LocalAuth:n},{generate:r}]=await Promise.all([import("whatsapp-web.js"),import("qrcode-terminal")]),o=new t({authStrategy:new n({dataPath:Eo(ac,".wwebjs_auth")}),puppeteer:{headless:!0,args:["--no-sandbox"]}});o.on("qr",l=>{process.stderr.write(`
39
39
  WhatsApp: scan this QR code in WhatsApp \u2192 Linked Devices:
40
40
 
41
41
  `),r(l,{small:!0}),process.stderr.write(`
42
42
  `)}),o.on("ready",()=>{process.stderr.write(`whatsapp-gateway: connected
43
43
  `)}),o.on("message",async l=>{if(l.fromMe)return;let u=l.from,d=l.author||l.from,s=l.body;try{let p=await ee({platform:"whatsapp",chatId:u,senderId:d,text:s,userName:l._data?.notifyName||"user",meta:{forwarded:l.isForwarded||l._data?.isForwarded,forward_date:l._data?.forwardingScore?!0:void 0}});if(p){let g=(typeof p=="string"?p:p.text).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");await l.reply(g)}}catch(p){process.stderr.write(`whatsapp-gateway: ${p.message}
44
- `)}}),await o.initialize();let i=we("whatsapp",e);return{platform:"whatsapp",client:o,ownerIds:i,notifyRecipient:async(l,u)=>{let d=String(l||"");if(!i.includes(d))return 0;let s=String(u).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");return await o.sendMessage(d,s),1},stop:async()=>{await Promise.resolve(o.destroy()).catch(()=>{})}}}var oc,xo=$(()=>{Ce();Ue();oc=process.env.ORACLE_CONFIG_DIR||So(rc(),".config","oracle")});var Eo={};he(Eo,{signal_:()=>ac});async function ac(e){return process.stderr.write(`signal-gateway: requires signal-cli binary
44
+ `)}}),await o.initialize();let i=we("whatsapp",e);return{platform:"whatsapp",client:o,ownerIds:i,notifyRecipient:async(l,u)=>{let d=String(l||"");if(!i.includes(d))return 0;let s=String(u).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");return await o.sendMessage(d,s),1},stop:async()=>{await Promise.resolve(o.destroy()).catch(()=>{})}}}var ac,ko=$(()=>{Ce();Me();ac=process.env.ORACLE_CONFIG_DIR||Eo(ic(),".config","oracle")});var _o={};he(_o,{signal_:()=>cc});async function cc(e){return process.stderr.write(`signal-gateway: requires signal-cli binary
45
45
  `),process.stderr.write(`signal-gateway: not built yet \u2014 use Telegram or Discord for now
46
- `),{platform:"signal",status:"stub"}}var Ao=$(()=>{Ce()});import{createServer as sc}from"node:http";import{env as Oe}from"node:process";import{join as Ve}from"node:path";import{homedir as cc}from"node:os";import{readFileSync as hn,existsSync as lc,mkdirSync as uc,writeFileSync as dc}from"node:fs";import{createHash as pc,randomBytes as fc}from"node:crypto";import rt from"node:path";import{homedir as Kn}from"node:os";import{readFileSync as Xi}from"node:fs";import{createHash as Zi}from"node:crypto";import O from"node:fs";import ze from"node:path";import{createHash as $o,randomUUID as gn}from"node:crypto";var yt=1,W=class extends Error{constructor(t,n="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=n}};function Ke(e){if(e===null)return"null";if(typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new TypeError("durable store values must contain finite numbers");return JSON.stringify(e)}if(Array.isArray(e))return`[${e.map(Ke).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Ke(e[n])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function wn(e){return $o("sha256").update(Ke(e)).digest("hex")}function We(e){let t=e(),n=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(n))throw new TypeError("clock must return epoch milliseconds, an ISO string, or a Date");return Math.trunc(n)}function Ge(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function bn(e){O.mkdirSync(e,{recursive:!0,mode:448});try{O.chmodSync(e,448)}catch{}}function gt(e){try{let t=O.statSync(e);return{...JSON.parse(O.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function Sn({filePath:e,kind:t,initialData:n,validateData:r,clock:o=()=>Date.now(),maxBytes:i=4*1024*1024,lockStaleMs:a=3e4,lockWaitMs:c=2e3,lockIdFactory:l=()=>gn()}={}){if(typeof e!="string"||e==="")throw new TypeError("filePath is required");if(!/^[a-z][a-z0-9._-]{0,63}$/i.test(String(t)))throw new TypeError("a bounded store kind is required");if(typeof n!="function"||typeof r!="function")throw new TypeError("initialData and validateData are required");if(!Number.isSafeInteger(i)||i<1024)throw new TypeError("maxBytes must be at least 1024");if(!Number.isSafeInteger(a)||a<1e3)throw new TypeError("lockStaleMs must be at least 1000");if(!Number.isSafeInteger(c)||c<0||c>3e4)throw new TypeError("lockWaitMs must be between 0 and 30000");let u=`${e}.lock`;function d(){let b=n();return r(b),{schemaVersion:yt,kind:t,generation:0,data:b}}function s(b){let f;try{f=JSON.parse(b)}catch(v){throw new W(`corrupt ${t} snapshot: invalid JSON (${v.message})`,"STORE_CORRUPT")}if(!f||typeof f!="object"||Array.isArray(f))throw new W(`corrupt ${t} snapshot: root must be an object`,"STORE_CORRUPT");if(f.schemaVersion!==yt)throw new W(`unsupported ${t} schemaVersion ${String(f.schemaVersion)}`,"STORE_SCHEMA");if(f.kind!==t||!Number.isSafeInteger(f.generation)||f.generation<0)throw new W(`corrupt ${t} snapshot metadata`,"STORE_CORRUPT");let{integrity:x,...S}=f;if(typeof x!="string"||!/^[a-f0-9]{64}$/.test(x)||wn(S)!==x)throw new W(`corrupt ${t} snapshot: checksum mismatch`,"STORE_CORRUPT");try{r(f.data)}catch(v){throw new W(`corrupt ${t} snapshot: ${v.message}`,"STORE_CORRUPT")}return S}function p(){if(!O.existsSync(e))return d();let b=O.statSync(e);if(!b.isFile()||b.size>i)throw new W(`${t} snapshot is not a bounded regular file`,"STORE_BOUNDS");try{O.chmodSync(e,384)}catch{}return s(O.readFileSync(e,"utf8"))}function m(){bn(ze.dirname(e));let b=We(o),f=String(l()),x=`${JSON.stringify({schemaVersion:1,lockId:f,pid:process.pid,acquiredAt:b})}
47
- `,S=()=>{let P;try{return P=O.openSync(u,"wx",384),O.writeFileSync(P,x,"utf8"),O.fsyncSync(P),O.closeSync(P),{lockId:f}}catch(h){let _=P!==void 0;if(_)try{O.closeSync(P)}catch{}if(_)try{O.unlinkSync(u)}catch{}if(h?.code!=="EEXIST")throw h;return null}},I=We(o)+c,T=new Int32Array(new SharedArrayBuffer(4));for(;;){let P=S();if(P)return P;let h=We(o),_=gt(u),M=!1;if(_){let q=h-Number(_.acquiredAt??_.mtimeMs);M=Number.isFinite(q)&&q>=a}else try{M=h-O.statSync(u).mtimeMs>=a}catch{M=!1}if(M){let q=gt(u);if(_?q?.lockId===_.lockId:q===null){try{O.unlinkSync(u)}catch(H){if(H?.code!=="ENOENT")throw H}continue}}let R=I-h;if(R<=0)throw new W(`${t} store is busy`,"STORE_BUSY");Atomics.wait(T,0,0,Math.min(10,R))}}function g(b){if(gt(u)?.lockId===b.lockId)try{O.unlinkSync(u)}catch(x){if(x?.code!=="ENOENT")throw x}}function w(b){r(b.data);let f={...b,integrity:wn(b)},x=`${Ke(f)}
48
- `;if(Buffer.byteLength(x)>i)throw new W(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let S=ze.dirname(e);bn(S);let v=ze.join(S,`.${ze.basename(e)}.${process.pid}.${gn()}.tmp`),I;try{I=O.openSync(v,"wx",384),O.writeFileSync(I,x,"utf8"),O.fsyncSync(I),O.closeSync(I),I=void 0,O.renameSync(v,e);try{O.chmodSync(e,384)}catch{}try{let T=O.openSync(S,"r");try{O.fsyncSync(T)}finally{O.closeSync(T)}}catch{}}finally{if(I!==void 0)try{O.closeSync(I)}catch{}try{O.unlinkSync(v)}catch(T){if(T?.code!=="ENOENT")throw T}}}function k(){return Ge(p().data)}function E(){let b=p();return{schemaVersion:b.schemaVersion,kind:b.kind,generation:b.generation,data:Ge(b.data)}}function N(b){if(typeof b!="function")throw new TypeError("mutator must be a function");let f=m();try{let x=p(),S=Ge(x.data),v=b(S,{generation:x.generation,now:We(o)});return r(S),w({schemaVersion:yt,kind:t,generation:x.generation+1,data:S}),Ge(v)}finally{g(f)}}return Object.freeze({filePath:e,read:k,inspect:E,mutate:N})}V();import{getAddress as bi}from"ethers";Pe();V();var Xc=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});V();var el=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),Tt=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Ot=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});Pe();Pe();var di=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}}]}]);V();Pe();V();function $t(e,t="address"){let n=String(e||"").trim();if(!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(n))throw new Error(`solana-rpc: ${t} must be a base58 public key`);return n}V();function ye(e,t="address"){let n=String(e||"").trim();if(!/^(bc1|tb1|bcrt1)[a-z0-9]{20,90}$/i.test(n)&&!/^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(n))throw new Error(`bitcoin-esplora: ${t} must look like a Bitcoin address`);return n}var $n="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function ge({provider:e,defaultUrl:t,hosts:n=[],url:r,strict:o=!1}){let a=(String(r??"").trim()||String(t)).replace(/\/$/,"");if(a===String(t).replace(/\/$/,""))return{baseUrl:a,trusted:!0,host:Pn(t)};let c;try{c=new URL(a)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let l=c.host;if(!l)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Pn(t),...n]).has(l)){let d=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(l);return c.protocol==="http:"&&!d?{baseUrl:a,trusted:!1,host:l,reason:"plaintext http downgrade"}:{baseUrl:a,trusted:!0,host:l}}if(String(process.env[$n]||"")==="1")return{baseUrl:a,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${$n}=1 to permit it)`);return{baseUrl:a,trusted:!1,host:l}}function Pn(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function se(e,t,n){let r={...e};if(!n)return r;for(let[o,i]of Object.entries(t||{}))i&&(r[o]=i);return r}function Rn(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var mi=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function hi(e={}){let t=e.apiKey||process.env.UNISAT_API_KEY||process.env.BESTINSLOT_API_KEY||process.env.BTC_META_API_KEY||"",n=!1;try{let r=Rn(e);if(r){let o=new URL(r).host,i=new URL(r).protocol,a=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(o);n=mi.includes(o)&&(i==="https:"||a)}}catch{n=!1}return se({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},n)}async function yi(e,t={}){let r=await(t.fetchImpl||fetch)(e,{method:"GET",headers:hi(t),signal:AbortSignal.timeout(t.timeoutMs??12e3)}),o=await r.text(),i;try{i=JSON.parse(o)}catch{i=o}if(!r.ok)throw new Error(`bitcoin-meta GET ${e}: HTTP ${r.status} ${String(o).slice(0,160)}`);return i}async function Pt(e={},t={}){let n=ye(e.address||e.addr,"address"),r=Rn(t);if(!r)return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:"no indexer configured \u2014 address-indexed lookups need a keyed indexer (BTC_META_API_URL + UNISAT_API_KEY / BESTINSLOT_API_KEY). ordinals.com recursive is keyless but has no address index.",unknownNotEmpty:!0,keylessAlternatives:["btc_inscription_info (by inscription id)","btc_meta_health"]};let o=Math.min(Number(e.limit||50),200),i=[`${r}/v1/indexer/address/${n}/inscription-data?cursor=0&size=${o}`,`${r}/v1/inscriptions/address/${n}?limit=${o}`,`${r}/address/${n}/inscriptions?limit=${o}`],a=null;for(let c of i)try{let l=await yi(c,t),u=gi(l);return{provider:"bitcoin-meta",address:n,ok:!0,count:u.length,inscriptions:u,source:c}}catch(l){a=l}return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:String(a?.message||a||"all indexer paths failed")}}function gi(e){let t=e?.data?.inscription||e?.data?.detail||e?.data?.list||e?.data||e?.inscriptions||e?.results||(Array.isArray(e)?e:[]);return(Array.isArray(t)?t:[]).map(r=>({id:r.inscriptionId||r.id||r.inscription_id||null,number:r.inscriptionNumber??r.number??null,sat:r.sat||r.satoshi||null,contentType:r.contentType||r.content_type||null,utxo:r.utxo||r.output||(r.txid!=null?`${r.txid}:${r.vout??r.n}`:null),raw:r}))}V();V();V();var Jl=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood",2741:"abstract",solana:"solana"});V();var ou=Object.freeze({1:"https://eth.blockscout.com",10:"https://explorer.optimism.io",137:"https://polygon.blockscout.com",324:"https://zksync.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com",534352:"https://scrollscan.com"}),wi=Object.freeze(["block_number","index"]),iu=new Set([...wi,"items_count","value","hash","inserted_at","fee"]);var Ru=Object.freeze({ETH:"coingecko:ethereum",POL:"coingecko:polygon-ecosystem-token",BNB:"coingecko:binancecoin",AVAX:"coingecko:avalanche-2",HYPE:"coingecko:hyperliquid",USDT0:"coingecko:tether",SOL:"coingecko:solana",BTC:"coingecko:bitcoin"});function Ze(e,...t){for(let n of t){let r=String(e?.[n]||"").trim();if(r)return r}return null}function Ln(e){if(!e)return null;try{return bi(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function Un(e={},t=process.env){let n=e.addresses||{},r=Ln(n.evm||e.evmAddress||Ze(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=n.solana||e.solanaAddress||Ze(t,"ORACLE_SOLANA_ADDRESS"),i=n.bitcoin||e.bitcoinAddress||Ze(t,"ORACLE_BITCOIN_ADDRESS"),a=Ln(n.hyperliquid||e.hyperliquidAddress||Ze(t,"ORACLE_HYPERLIQUID_ADDRESS")||r);return{evm:r,solana:o?$t(o,"portfolio Solana address"):null,bitcoin:i?ye(i,"portfolio Bitcoin address"):null,hyperliquid:a}}V();import{readFileSync as vi,existsSync as xi}from"node:fs";import{getAddress as Ei,Interface as et,TypedDataEncoder as ju,parseUnits as Hu}from"ethers";var Si=300*1e3,Uu=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})();var Ai="https://api.opensea.io/api/v2",ki="fulfillAdvancedOrder(((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 totalOriginalConsiderationItems) parameters,uint120 numerator,uint120 denominator,bytes signature,bytes extraData) advancedOrder,(uint256 orderIndex,uint8 side,uint256 index,uint256 identifier,bytes32[] criteriaProof)[] criteriaResolvers,bytes32 fulfillerConduitKey,address recipient)",Ku=new et([`function ${ki}`]),Yu=new et(["function mintPublic(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity) payable","function mintAllowList(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity,(uint80 mintPrice,uint48 maxTotalMintableByWallet,uint48 startTime,uint48 endTime,uint48 dropStageIndex,uint32 maxTokenSupplyForStage,uint16 feeBps,bool restrictFeeRecipients) mintParams,bytes32[] proof) payable"]),_i=Object.freeze(["blast","base","ethereum","zora","arbitrum","sei","avalanche","polygon","optimism","ape_chain","flow","b3","soneium","ronin","bera_chain","solana","shape","unichain","gunzilla","abstract","animechain","hyperevm","somnia","monad","hyperliquid","megaeth","ink","robinhood","stablechain"]),Ii=new Set(_i),Ci=new Set(["solana","flow"]);function Ti(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!xi(e))return"";try{for(let t of vi(e,"utf8").split(`
49
- `)){let n=t.match(/^\s*OPENSEA_API_KEY\s*=\s*(.+)\s*$/);if(n)return n[1].replace(/^["']|["']$/g,"").trim()}}catch{}return""}function Re(e={}){return e.apiKey?e.apiKey:e.allowAmbientCredentials===!1||e.allowDiskCredentials===!1?e.env?.OPENSEA_API_KEY||e.env?.OPEN_SEA_API_KEY||"":e.env?.OPENSEA_API_KEY||process.env.OPENSEA_API_KEY||process.env.OPEN_SEA_API_KEY||Ti()}function Mn(e={}){return ge({provider:"opensea",defaultUrl:Ai,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function tt(e={}){return Mn(e).baseUrl}function nt(e={}){return se({accept:"application/json"},{"x-api-key":Re(e)},Mn(e).trusted)}function Oi(e){let t=String(e||"ethereum").trim().toLowerCase();if(!Ii.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function Fn(e,t="address"){try{return Ei(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function Bn(e,t=null){let n=String(e||"").trim();if(!n)throw new Error("opensea: account address required");if(t&&!Ci.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(n))return Fn(n,"account address");if(!/^[1-9A-HJ-NP-Za-km-z]{32,64}$/.test(n))throw new Error("opensea: invalid account address");return n}function Ni(e={},t,n){return{chain:t,owner:n,contract:e.contract||null,tokenId:e.identifier==null?null:String(e.identifier),tokenStandard:e.token_standard||null,quantity:e.quantity==null&&e.balance==null?null:String(e.quantity??e.balance),collection:e.collection||null,name:e.name||null,description:e.description||null,imageUrl:e.display_image_url||e.image_url||e.original_image_url||null,originalImageUrl:e.original_image_url||e.image_url||null,animationUrl:e.display_animation_url||e.original_animation_url||null,metadataUrl:e.metadata_url||null,marketplaceUrl:e.opensea_url||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,spam:e.is_disabled===!0,disabled:e.is_disabled===!0,nsfw:e.is_nsfw===!0,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"OpenSea account inventory does not expose trustworthy per-item acquisition cost"}}}async function $i(e,t={}){if(!e)throw new Error("collection slug required");if(!Re(t))throw new Error("OPENSEA_API_KEY required");return z(`${tt(t)}/collections/${encodeURIComponent(e)}`,{headers:nt(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Pi(e,t={}){if(!e)throw new Error("collection slug required");if(!Re(t))throw new Error("OPENSEA_API_KEY required");return z(`${tt(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:nt(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function qn(e,t={}){let n=await $i(e,t),r=n.stats||n.total||{},o=n.floor_price??n.floorPrice??r.floor_price??r.floorPrice??null;if(o==null){let s=await Pi(e,t);r=s?.total||s?.stats||s||{},o=r.floor_price??r.floorPrice??null}let i=(Array.isArray(n.contracts)?n.contracts:[]).map(s=>({chain:String(s?.chain||s?.chain_identifier||n.chain||"").trim().toLowerCase(),address:String(s?.address||s?.contract_address||s?.contract||"").trim()})).filter(s=>s.chain&&s.address),a=String(t.expectedChain||"").trim().toLowerCase(),c=String(t.expectedContract||"").trim(),l=null;if(a&&c){let s=p=>a==="solana"?p:p.toLowerCase();if(l=i.find(p=>p.chain===a&&s(p.address)===s(c))||null,!l)throw new Error("opensea: collection identity does not match held contract")}let u=l?.chain||String(n.chain||"").trim().toLowerCase()||i[0]?.chain||"",d=String(n.floor_price_symbol||n.floorPriceSymbol||r.floor_price_symbol||r.floorPriceSymbol||"").trim().toUpperCase()||null;return{slug:n.collection||e,name:n.name||null,floor:o,chain:u||null,contracts:i,currency:d,totalSupply:n.total_supply??r.total_supply??null,numOwners:n.num_owners??r.num_owners??null,raw:{contracts:i,fees:n.fees,category:n.category}}}async function Lt(e={},t={}){if(!Re(t))throw new Error("OPENSEA_API_KEY required");let n=Oi(e.chain),r=Bn(e.address||e.owner,n),o=Math.min(Math.max(Number(e.pageSize??e.limit??200)||200,1),200),i=Math.min(Math.max(Number(e.maxPages??5)||5,1),25),a=[],c=e.next?String(e.next):null,l=0;do{let u=new URL(`${tt(t)}/chain/${encodeURIComponent(n)}/account/${encodeURIComponent(r)}/nfts`);u.searchParams.set("limit",String(o)),e.collection&&u.searchParams.set("collection",String(e.collection)),c&&u.searchParams.set("next",c);let d=await z(u.toString(),{headers:nt(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let s of Array.isArray(d?.nfts)?d.nfts:[])a.push(Ni(s,n,r));c=d?.next?String(d.next):null,l+=1}while(c&&l<i);return{provider:"opensea-nft",source:"opensea-account-inventory",chain:n,owner:r,count:a.length,pages:l,complete:!c,next:c,nfts:a,exec:!1,readOnly:!0}}async function Dn(e={},t={}){if(!Re(t))throw new Error("OPENSEA_API_KEY required");let n=Bn(e.address||e.owner),r=await z(`${tt(t)}/account/${encodeURIComponent(n)}/pnl`,{headers:nt(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});return{provider:"opensea-nft",source:"opensea-indexed-account-pnl",address:n,scope:"OpenSea-indexed account trading PnL across supported currencies, not per-item NFT cost basis",methodology:"provider-indexed",realizedPnlUsd:r?.realized_pnl_usd??null,unrealizedPnlUsd:r?.unrealized_pnl_usd??null,totalPnlUsd:r?.total_pnl_usd??null,netInvestedUsd:r?.net_invested_usd??null,currentValueUsd:r?.current_value_usd??null,returnPercentage:r?.return_percentage??null,itemLevelPnlAvailable:!1,raw:r,exec:!1,readOnly:!0}}var Ju=Object.freeze({robinhood:4663,ethereum:1,base:8453,arbitrum:42161,optimism:10,polygon:137,avalanche:43114,zora:7777777,blast:81457,sei:1329,ape_chain:33139,b3:8333,soneium:1868,ronin:2020,bera_chain:80094,shape:360,unichain:130,gunzilla:43419,abstract:2741,animechain:69e3,hyperevm:999,somnia:5031,monad:143,megaeth:4326,ink:57073,stablechain:988});var Qu=Object.freeze({OrderComponents:[{name:"offerer",type:"address"},{name:"zone",type:"address"},{name:"offer",type:"OfferItem[]"},{name:"consideration",type:"ConsiderationItem[]"},{name:"orderType",type:"uint8"},{name:"startTime",type:"uint256"},{name:"endTime",type:"uint256"},{name:"zoneHash",type:"bytes32"},{name:"salt",type:"uint256"},{name:"conduitKey",type:"bytes32"},{name:"counter",type:"uint256"}],OfferItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"}],ConsiderationItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"},{name:"recipient",type:"address"}]});var Xu=new et(["function setApprovalForAll(address operator,bool approved)"]),Zu=new et(["function cancel((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 counter)[] orders) returns (bool cancelled)"]);var Li="https://api.satflow.com/v1";function jn(e={}){return ge({provider:"satflow",defaultUrl:Li,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function Ui(e={}){return jn(e).baseUrl}function Hn(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function Fi(e={}){return se({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":Hn(e)},jn(e).trusted)}async function Mi(e,{method:t="GET",body:n,opts:r={}}={}){if(!Hn(r))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${Ui(r)}${e.startsWith("/")?e:`/${e}`}`,c=await(r.fetchImpl||fetch)(i,{method:t,headers:Fi(r),body:n!=null?JSON.stringify(n):void 0,signal:AbortSignal.timeout(r.timeoutMs??2e4)}),l=await c.text(),u;try{u=JSON.parse(l)}catch{u=l}if(!c.ok)throw new Error(`satflow ${t} ${e}: HTTP ${c.status} ${String(l).slice(0,200)}`);return u}async function Vn(e={},t={}){let n=ye(e.address||e.addr,"address"),r=new URLSearchParams({address:n});e.type&&r.set("type",e.type),e.limit!=null&&r.set("limit",String(e.limit)),e.offset!=null&&r.set("offset",String(e.offset));let o=await Mi(`/address/wallet-contents?${r}`,{opts:t});return{provider:"satflow",address:n,contents:o}}V();V();var md=Object.freeze(["i.seadn.io","openseauserdata.com","arweave.net","ipfs.io","nftstorage.link","dweb.link","cloudflare-ipfs.com","ordinals.com","ordinals.g.com","cdn.helius-rpc.com","shdw-drive.genesysgo.net"]);var Bi=[/\bclaim\b/i,/\breward\b/i,/\bairdrop\b/i,/\bvoucher\b/i,/\bwinner\b/i,/\bfree\s*mint\b/i,/\bactivate\b/i,/\bunlock\b/i,/\bverify\b/i,/\bconnect\s+wallet\b/i],qi=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,Di=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function ji(e={}){let t=[],n=String(e.name||""),r=String(e.description||""),o=`${n} ${r}`;qi.test(n)&&t.push("url-in-name");let i=Bi.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),Di.test(n)&&t.push("value-claim-in-name"),/[\u200B-\u200F\u202A-\u202E\uFEFF]/.test(n)&&t.push("invisible-characters"),e.disabled===!0&&t.push("marketplace-disabled");let a=e.estimatedValueUsd==null&&e.estimatedValueSats==null,c=!Array.isArray(e.traits)||e.traits.length===0;a&&c&&i>0&&t.push("valueless-airdrop-with-lure");let l=t.includes("url-in-name")||t.includes("invisible-characters")||t.includes("valueless-airdrop-with-lure")||t.length>=2;return{spam:l,risk:l?"high":t.length>0?"low":"none",reasons:t}}function zn(e={}){let t=ji(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}var Hi=Object.freeze([{chain:"ethereum",chainId:1,family:"evm"},{chain:"optimism",chainId:10,family:"evm"},{chain:"polygon",chainId:137,family:"evm"},{chain:"stablechain",chainId:988,family:"evm"},{chain:"hyperevm",chainId:999,family:"evm"},{chain:"abstract",chainId:2741,family:"evm"},{chain:"robinhood",chainId:4663,family:"evm"},{chain:"base",chainId:8453,family:"evm"},{chain:"arbitrum",chainId:42161,family:"evm"},{chain:"avalanche",chainId:43114,family:"evm"},{chain:"hyperliquid",chainId:null,family:"hyperliquid"}]),Vi=Object.freeze([{family:"evm",chain:"bsc",chainId:56,reason:"OpenSea account inventory does not support BSC"},{family:"cosmos",reason:"requires a chain-specific bech32 address and NFT indexer"},{family:"sui",reason:"owner inventory adapter not installed"},{family:"aptos",reason:"owner inventory adapter not installed"}]);function Ut(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function Le(e,t){let n=await Xe(t);return n.ok?{ok:!0,data:n.data}:{ok:!1,error:`${e}: ${n.error}`.slice(0,300)}}function zi(e){if(Array.isArray(e))return e;for(let t of["items","results","ordinals","inscriptions","data"])if(Array.isArray(e?.[t]))return e[t];return[]}function Wi(e={},t){let n=e.inscription_id||e.inscriptionId||e.id||e.inscription||null;return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:n==null?null:String(n),tokenStandard:"ordinal",collection:e.collection_slug||e.collectionSlug||e.collection?.slug||e.collection||null,name:e.name||e.meta?.name||(n?`Inscription ${n}`:"Bitcoin inscription"),description:e.description||e.meta?.description||null,imageUrl:e.image_url||e.imageUrl||e.content_url||e.contentUrl||e.thumbnail||null,originalImageUrl:e.content_url||e.contentUrl||e.image_url||e.imageUrl||null,animationUrl:null,metadataUrl:e.metadata_url||e.metadataUrl||null,marketplaceUrl:e.marketplace_url||e.marketplaceUrl||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,estimatedValueSats:(e.floor_price_sats??e.price_sats)!=null&&Number.isFinite(Number(e.floor_price_sats??e.price_sats))?Number(e.floor_price_sats??e.price_sats):null,spam:!1,disabled:!1,nsfw:!1,listed:e.listed===!0||e.is_listed===!0,listingId:e.listing_id||e.listingId||null,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||e.updatedAt||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"Satflow wallet inventory does not expose trustworthy acquisition cost"},listingAdapter:"satflow",source:"satflow-wallet-contents"}}function Gi(e,t){return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:String(e),tokenStandard:"ordinal",collection:null,name:`Inscription ${e}`,description:null,imageUrl:null,originalImageUrl:null,animationUrl:null,metadataUrl:null,marketplaceUrl:null,estimatedValueUsd:null,spam:!1,disabled:!1,nsfw:!1,traits:[],updatedAt:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"address indexer returned no acquisition or valuation data"},listingAdapter:"satflow",source:"bitcoin-meta-address-indexer"}}function Wn(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function Ki(e){let t=new Map;if(Array.isArray(e)){for(let n of e)n?.assetKey&&t.set(String(n.assetKey).toLowerCase(),n);return t}if(e&&typeof e=="object")for(let[n,r]of Object.entries(e))t.set(n.toLowerCase(),r);return t}function Yi(e,t){let n=Wn(e),r=t.get(n),o=e.estimatedValueUsd==null?null:Number(e.estimatedValueUsd);if(!r)return{...e,assetKey:n};let i=Number(r.costUsd),a=Number(r.feesUsd??0);if(!Number.isFinite(i)||i<0||!Number.isFinite(a)||a<0)return{...e,assetKey:n,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"invalid user-supplied cost basis"}};let c=Math.round((i+a)*100)/100;return Number.isFinite(o)?{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:a,totalCostUsd:c,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"estimated",methodology:"provider estimated current value minus supplied USD acquisition cost and fees",unrealizedUsd:Math.round((o-c)*100)/100,currentValueUsd:o,totalCostUsd:c,realizedUsd:null}}:{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:a,totalCostUsd:c,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"unavailable",reason:"current NFT valuation is unavailable"}}}function Ji(e){let t=new Map;for(let n of e){let r=Wn(n);t.has(r)||t.set(r,n)}return[...t.values()]}function Qi(e,t){let n=e.filter(i=>i.itemPnl?.status==="estimated"),r=e.length-n.length,o=Math.round(n.reduce((i,a)=>i+Number(a.itemPnl.unrealizedUsd||0),0)*100)/100;return{nftItemPnl:{status:r===0&&e.length?"estimated-complete-for-held-items":n.length?"partial":"unavailable",methodology:"Only items with explicit acquisition cost and provider estimated current value are included",knownUnrealizedUsd:o,knownItems:n.length,unknownItems:r,realizedUsd:null,warning:"Transfers, gifts, airdrops, mints, bridges, gas, royalties, and off-market sales can make cost basis unavailable or incomplete."},providerAccountPnl:t}}async function Gn(e={},t={}){let n=new Date().toISOString(),r=Un(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(f=>String(f).toLowerCase())):null,i=Hi.filter(f=>!o||o.has(f.chain)),a=[],c=[],l=Ut(t,"opensea"),u=r.evm?i.filter(f=>f.family!=="solana"):[],d=await $e(u,4,async f=>({row:f,result:await Le(`opensea-${f.chain}`,()=>Lt({chain:f.chain,address:r.evm,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3)}));for(let{row:f,result:x}of d)if(x.ok){let S=x.data.nfts.map(v=>({...v,family:f.family,chainId:f.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));c.push(...S),a.push({family:f.family,chain:f.chain,chainId:f.chainId,status:x.data.complete?"ok":"partial",count:S.length,complete:x.data.complete,next:x.data.next,source:"opensea"})}else a.push({family:f.family,chain:f.chain,chainId:f.chainId,status:"unavailable",error:x.error,source:"opensea"});if(!r.evm)for(let f of i.filter(x=>x.family!=="solana"))a.push({family:f.family,chain:f.chain,chainId:f.chainId,status:"not-configured",reason:"EVM address missing"});if(r.solana&&(!o||o.has("solana"))){let f=await Le("opensea-solana",()=>Lt({chain:"solana",address:r.solana,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3);if(f.ok){let x=f.data.nfts.map(S=>({...S,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));c.push(...x),a.push({family:"solana",chain:"solana",status:f.data.complete?"ok":"partial",count:x.length,complete:f.data.complete,next:f.data.next,source:"opensea"})}else a.push({family:"solana",chain:"solana",status:"unavailable",error:f.error,source:"opensea"})}else(!o||o.has("solana"))&&a.push({family:"solana",chain:"solana",status:"not-configured",reason:"Solana address missing"});if(r.bitcoin&&(!o||o.has("bitcoin"))){let f=await Le("satflow-wallet-contents",()=>Vn({address:r.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},Ut(t,"satflow")),t.timeoutMs??35e3);if(f.ok){let x=zi(f.data.contents).map(v=>Wi(v,r.bitcoin));c.push(...x);let S=x.length<Number(e.bitcoinLimit??100);a.push({family:"bitcoin",chain:"bitcoin",status:S?"ok":"partial",count:x.length,complete:S,source:"satflow"})}else{let x=await Le("bitcoin-meta-inscriptions",()=>Pt({address:r.bitcoin},Ut(t,"bitcoinMeta")),t.timeoutMs??35e3),S=x.ok&&x.data?.ok&&Array.isArray(x.data.inscriptions)?x.data.inscriptions:[];c.push(...S.map(v=>Gi(v,r.bitcoin))),a.push({family:"bitcoin",chain:"bitcoin",status:S.length?"partial":"unavailable",count:S.length,complete:!1,source:S.length?"bitcoin-meta":"satflow",error:S.length?"Satflow unavailable; fallback has IDs only":f.error})}}else(!o||o.has("bitcoin"))&&a.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let s=[];if(e.includePnl!==!1)for(let f of[...new Set([r.evm,r.solana].filter(Boolean))]){let x=await Le(`opensea-pnl-${f}`,()=>Dn({address:f},l),t.timeoutMs??35e3);s.push(x.ok?{status:"ok",...x.data}:{status:"unavailable",address:f,source:"opensea-indexed-account-pnl",error:x.error})}let p=Ki(e.costBasis),m=Ji(c).map(f=>Yi(f,p)).map(f=>zn(f)),g=m.filter(f=>!f.spam),w=m.filter(f=>f.spam),k=g.filter(f=>f.estimatedValueUsd!=null&&Number.isFinite(Number(f.estimatedValueUsd))),E=Math.round(k.reduce((f,x)=>f+Number(x.estimatedValueUsd),0)*100)/100,N=g.length-k.length,b=a.filter(f=>f.status!=="ok"||f.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:n,addresses:r,coverage:a,unsupported:Vi,inventory:{count:m.length,visibleCount:g.length,flaggedCount:w.length,items:m,visibleItems:g,flaggedItems:w},valuation:{estimatedCurrentValueUsd:E,valuedItems:k.length,unvaluedItems:N,complete:N===0&&b.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:Qi(g,s),listingCoverage:{opensea:"EVM listing actions available with OPENSEA_API_KEY, explicit price/currency/expiry, and user confirmation",satflow:"Bitcoin unsigned listing PSBT available with SATFLOW_API_KEY, explicit price/expiry, and user confirmation",solana:"Magic Eden unsigned list transaction available with MAGICEDEN_API_KEY, explicit SOL price/expiry, and user confirmation",unsupported:"Sui, Aptos, Cosmos, BSC, and unknown marketplaces fail closed"},traitSniperCoverage:{opensea:"Evaluates reveal/trait-floor mispricing only with recent trait sales and volume evidence. Buy intents require local vault signing.",execution:"prepare-only on hosted surfaces; local vault required for purchase"},metadataSafety:{imagesAreUntrusted:!0,animationAndHtmlNotRendered:!0,galleryRasterOnly:!0,missingImagesUsePlaceholders:!0}}}var Yn=1,ea=/^0x[0-9a-f]{40}$/,ta=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,na=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function ra(e=process.env){let t=e.ORACLE_CONFIG_DIR||rt.join(Kn(),".config","oracle");return rt.join(t,"held-nft-pump.v1.json")}function oa(e=process.env){let t=e.ORACLE_CONFIG_DIR||rt.join(Kn(),".config","oracle"),n={};try{let o=JSON.parse(Xi(rt.join(t,"portfolio.json"),"utf8"));n=o&&typeof o=="object"&&!Array.isArray(o)?o.addresses||o:{}}catch{}let r={evm:e.ORACLE_EVM_ADDRESS||n.evm,solana:e.ORACLE_SOLANA_ADDRESS||n.solana};return Object.fromEntries(Object.entries(r).filter(([,o])=>typeof o=="string"&&o.trim()).map(([o,i])=>[o,i.trim()]))}function ia(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function Jn(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function aa(e){let t=e?.quantity??e?.balance??1;if(typeof t!="string"&&typeof t!="number"&&typeof t!="bigint"||!/^\d+$/.test(String(t)))return 0n;let n=BigInt(String(t));return n>0n?n:0n}function sa(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function ca(e){if(!e||e.version!==Yn||!e.collections||typeof e.collections!="object"||Array.isArray(e.collections))throw new TypeError("invalid held NFT pump state");if(!Number.isSafeInteger(e.cursor??0)||(e.cursor??0)<0)throw new TypeError("invalid held NFT pump cursor");if(e.walletFingerprint!==void 0&&!/^[a-f0-9]{64}$/.test(e.walletFingerprint))throw new TypeError("invalid held NFT wallet fingerprint");if(e.walletChanged!==void 0&&typeof e.walletChanged!="boolean")throw new TypeError("invalid held NFT wallet-change marker");let t=e.failures??{};if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("invalid held NFT pump failures");let n=Object.entries(e.collections);if(n.length>1e4||Object.keys(t).length>1e4)throw new TypeError("held NFT pump state exceeds collection bound");for(let[r,o]of n){if(!r||r.length>260||!o||Jn(o.anchorFloor)===null)throw new TypeError("invalid held NFT floor record");if(!Number.isFinite(o.updatedAt)||o.updatedAt<0)throw new TypeError("invalid held NFT update time");if(o.lastAlertAt!==null&&(!Number.isFinite(o.lastAlertAt)||o.lastAlertAt<0))throw new TypeError("invalid held NFT alert time")}for(let r of Object.values(t))if(!r||!Number.isSafeInteger(r.count)||r.count<1||!Number.isFinite(r.nextCheckAt)||r.nextCheckAt<0)throw new TypeError("invalid held NFT provider backoff")}function la(e={}){let t=e?.inventory?.visibleItems??e?.inventory?.items??[],n=new Map;for(let r of Array.isArray(t)?t:[]){if(r?.spam===!0||r?.disabled===!0)continue;let o=String(r?.chain||"").trim().toLowerCase(),i=String(r?.contract||"").trim(),a=o==="solana"?i:i.toLowerCase(),c=String(r?.collection||"").trim().toLowerCase();if(!o||!c||!(o==="solana"?ta.test(a):ea.test(a)))continue;let l=aa(r);if(l===0n)continue;let u=`${o}:${a}`,d=n.get(u);d&&d.slug!==c||n.set(u,{key:u,chain:o,contract:a,slug:c,name:d?.name||String(r?.name||c),heldCountRaw:(d?.heldCountRaw||0n)+l})}return[...n.values()].map(({heldCountRaw:r,...o})=>({...o,heldCount:sa(r)})).sort((r,o)=>r.key.localeCompare(o.key))}function ua(e,t){let n=String(e?.currency||"").trim().toUpperCase();if(!na.test(n))return{ok:!1,reason:"floor-currency-unavailable"};if(e?.chain&&String(e.chain).trim().toLowerCase()!==t.chain)return{ok:!1,reason:"floor-identity-mismatch"};let r=Array.isArray(e?.contracts)?e.contracts:Array.isArray(e?.raw?.contracts)?e.raw.contracts:[],o=t.chain==="solana"?t.contract:t.contract.toLowerCase();return r.some(a=>{let c=String(a?.address||a?.contract_address||a?.contract||"").trim(),l=t.chain==="solana"?c:c.toLowerCase(),u=String(a?.chain||a?.chain_identifier||"").trim().toLowerCase();return l===o&&u===t.chain})?{ok:!0,currency:n}:{ok:!1,reason:"floor-identity-mismatch"}}function da(e,t,n,r,o){let i=Math.round((t/r.anchorFloor-1)*1e4)/100;return Object.freeze({type:"held_nft_floor_pump",category:"price",chain:e.chain,contract:e.contract,slug:e.slug,name:e.name,heldCount:e.heldCount,fromFloor:r.anchorFloor,floor:t,currency:n,changePct:i,observedAt:new Date(o).toISOString(),evidence:Object.freeze({source:"opensea-collection-floor",status:"provider-estimate",chain:e.chain,contract:e.contract,currency:n,observedAt:new Date(o).toISOString(),warning:"Floor is a provider estimate, not an executable bid or guaranteed liquidation value."}),custody:"none",executionAllowed:!1})}function Qn({filePath:e,env:t=process.env,clock:n=()=>Date.now(),inventoryFn:r=Gn,floorFn:o=qn,notifyFn:i=async()=>({delivered:0}),thresholdPct:a=Number(t.ORACLE_NFT_PUMP_THRESHOLD_PCT??15),cooldownMs:c=Number(t.ORACLE_NFT_PUMP_COOLDOWN_HOURS??6)*36e5,maxFloorChecksPerTick:l=Number(t.ORACLE_NFT_PUMP_MAX_FLOORS_PER_TICK??20),inventoryPageSize:u=100,inventoryMaxPages:d=2}={}){if(typeof r!="function"||typeof o!="function"||typeof i!="function")throw new TypeError("held NFT watchdog functions are required");if(!Number.isFinite(a)||a<=0||a>1e3)throw new TypeError("held NFT pump threshold is out of range");if(!Number.isFinite(c)||c<6e4||c>30*864e5)throw new TypeError("held NFT pump cooldown is out of range");if(!Number.isSafeInteger(l)||l<1||l>100)throw new TypeError("held NFT floor budget is out of range");let s=Sn({filePath:e||ra(t),kind:"oracle-held-nft-pump",clock:n,maxBytes:4*1024*1024,initialData:()=>({version:Yn,cursor:0,collections:{},failures:{}}),validateData:ca}),p=!1;function m(w,k){s.mutate(E=>{E.failures||={};let N=Math.min(20,Number(E.failures[w]?.count||0)+1);E.failures[w]={count:N,nextCheckAt:k+Math.min(6*36e5,3e5*2**Math.min(6,N-1))}})}async function g(){if(p)return{skipped:!0,reason:"tick-in-progress",alerts:[],unavailable:[]};p=!0;try{let w=Number(n());if(!Number.isFinite(w))throw new TypeError("held NFT watchdog clock is invalid");let k=oa(t),E=ia(t),N=Zi("sha256").update(JSON.stringify(Object.entries(k).sort())).digest("hex");s.mutate(h=>{let _=!!(h.walletFingerprint&&h.walletFingerprint!==N);_&&(h.collections={},h.failures={},h.cursor=0),h.walletFingerprint=N,h.walletChanged=_});let b=await r({addresses:k,includePnl:!1,pageSize:u,maxPages:d},{env:E}),f=la(b),x=new Set(f.map(h=>h.key)),S=new Set((Array.isArray(b?.coverage)?b.coverage:[]).filter(h=>h?.status==="ok"&&h?.complete===!0).map(h=>String(h.chain||"").toLowerCase()).filter(Boolean));S.size&&s.mutate(h=>{for(let _ of Object.keys(h.collections)){let M=_.slice(0,_.indexOf(":"));S.has(M)&&!x.has(_)&&delete h.collections[_]}for(let _ of Object.keys(h.failures||{})){let M=_.slice(0,_.indexOf(":"));S.has(M)&&!x.has(_)&&delete h.failures[_]}});let v=s.mutate(h=>{let _=f.length?(h.cursor||0)%f.length:0;return h.cursor=f.length?(_+Math.min(l,f.length))%f.length:0,_}),I=[];for(let h=0;h<Math.min(l,f.length);h+=1)I.push(f[(v+h)%f.length]);let T=[],P=[];for(let h of I){let _=s.inspect().data.failures?.[h.key];if(_&&_.nextCheckAt>w){P.push({key:h.key,reason:"floor-provider-backoff"});continue}let M;try{M=await o(h.slug,{env:E,expectedChain:h.chain,expectedContract:h.contract})}catch{m(h.key,w),P.push({key:h.key,reason:"floor-provider-unavailable"});continue}let R=ua(M,h);if(!R.ok){m(h.key,w),P.push({key:h.key,reason:R.reason});continue}let q=Jn(M?.floor);if(q===null){m(h.key,w),P.push({key:h.key,reason:"floor-unavailable"});continue}let j=s.mutate(L=>{L.failures||={},delete L.failures[h.key];let A=L.collections[h.key];if(!A)return L.collections[h.key]={anchorFloor:q,lastAlertAt:null,updatedAt:w,currency:R.currency},null;if(A.updatedAt=w,A.currency!==R.currency)return A.anchorFloor=q,A.currency=R.currency,A.lastAlertAt=null,null;if(q<A.anchorFloor)return A.anchorFloor=q,A.currency=R.currency,null;if((q/A.anchorFloor-1)*100+1e-9<a)return null;if(A.lastAlertAt!==null&&w-A.lastAlertAt<c)return A.anchorFloor=q,A.currency=R.currency,null;let K=da({...h,name:M?.name||h.name},q,R.currency,A,w);return A.anchorFloor=q,A.lastAlertAt=w,A.updatedAt=w,A.currency=R.currency,K});if(!j)continue;let H;try{H=await i(j)}catch{H=null}if(!H||Number(H.delivered||0)!==1){P.push({key:h.key,reason:"notification-delivery-failed"});continue}T.push(j)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:f.length,checkedCollections:I.length,alerts:T,unavailable:P,coverage:b?.coverage??[]}}finally{p=!1}}return Object.freeze({filePath:s.filePath,tick:g,inspect:s.inspect})}Ue();var ft=Oe.ORACLE_CONFIG_DIR||Ve(cc(),".config","oracle"),ko=Ve(ft,"gateway.json");function mc(){return lc(ko)?JSON.parse(hn(ko,"utf8")):{platforms:{}}}function hc(e={},t=Oe){let n=e?.notifications?.heldNftPumps;return n===!1?!1:n===!0?!0:String(t.ORACLE_NFT_PUMP_ENABLED||"")==="1"}function yc({configDir:e=ft,environment:t=Oe}={}){let n=String(t.ORACLE_MESSAGING_PLATFORM||"").trim().toLowerCase();if(n)return n;try{let r=JSON.parse(hn(Ve(e,"messaging.json"),"utf8"));return String(r?.platform||"").trim().toLowerCase()}catch{return""}}function gc(e,t=ft){let n=String(e?.platform||""),r=String(e?.recipientId||"");if(!n||!r)throw new TypeError("recipient-bound held NFT subscription is required");let o=pc("sha256").update(`${n}\0${r}`).digest("hex").slice(0,24);return Ve(t,`held-nft-pump.${o}.v1.json`)}function wc({heldNftPumpLoop:e,platforms:t=[],server:n,exitFn:r=o=>process.exit(o)}={}){let o=null;return async function(){return o||(o=(async()=>{e?.stop?.();for(let a of t)try{await a?.stop?.()}catch{}n?.close&&await new Promise(a=>n.close(()=>a())),r(0)})(),o)}}function fn(e){return e?Array.isArray(e)?e.filter(Boolean):[e]:[]}var bc=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function pt(e,t,n,r){try{r.push(await t(n))}catch(o){let i=bc[e];if(i&&/Cannot find (module|package)|ERR_MODULE_NOT_FOUND/.test(String(o.message))){process.stderr.write(`oracle-gateway: ${e} needs an optional dependency. Install it first:
46
+ `),{platform:"signal",status:"stub"}}var Io=$(()=>{Ce()});import{createServer as lc}from"node:http";import{env as Oe}from"node:process";import{join as We}from"node:path";import{homedir as uc}from"node:os";import{readFileSync as yn,existsSync as dc,mkdirSync as pc,writeFileSync as fc}from"node:fs";import{createHash as mc,randomBytes as hc}from"node:crypto";import it from"node:path";import{homedir as Qn}from"node:os";import{readFileSync as ea}from"node:fs";import{createHash as ta}from"node:crypto";import N from"node:fs";import Ge from"node:path";import{createHash as Ro,randomUUID as bn}from"node:crypto";var wt=1,W=class extends Error{constructor(t,n="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=n}};function Je(e){if(e===null)return"null";if(typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new TypeError("durable store values must contain finite numbers");return JSON.stringify(e)}if(Array.isArray(e))return`[${e.map(Je).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Je(e[n])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function Sn(e){return Ro("sha256").update(Je(e)).digest("hex")}function Ke(e){let t=e(),n=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(n))throw new TypeError("clock must return epoch milliseconds, an ISO string, or a Date");return Math.trunc(n)}function Ye(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function vn(e){N.mkdirSync(e,{recursive:!0,mode:448});try{N.chmodSync(e,448)}catch{}}function bt(e){try{let t=N.statSync(e);return{...JSON.parse(N.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function xn({filePath:e,kind:t,initialData:n,validateData:r,clock:o=()=>Date.now(),maxBytes:i=4*1024*1024,lockStaleMs:a=3e4,lockWaitMs:c=2e3,lockIdFactory:l=()=>bn()}={}){if(typeof e!="string"||e==="")throw new TypeError("filePath is required");if(!/^[a-z][a-z0-9._-]{0,63}$/i.test(String(t)))throw new TypeError("a bounded store kind is required");if(typeof n!="function"||typeof r!="function")throw new TypeError("initialData and validateData are required");if(!Number.isSafeInteger(i)||i<1024)throw new TypeError("maxBytes must be at least 1024");if(!Number.isSafeInteger(a)||a<1e3)throw new TypeError("lockStaleMs must be at least 1000");if(!Number.isSafeInteger(c)||c<0||c>3e4)throw new TypeError("lockWaitMs must be between 0 and 30000");let u=`${e}.lock`;function d(){let v=n();return r(v),{schemaVersion:wt,kind:t,generation:0,data:v}}function s(v){let f;try{f=JSON.parse(v)}catch(S){throw new W(`corrupt ${t} snapshot: invalid JSON (${S.message})`,"STORE_CORRUPT")}if(!f||typeof f!="object"||Array.isArray(f))throw new W(`corrupt ${t} snapshot: root must be an object`,"STORE_CORRUPT");if(f.schemaVersion!==wt)throw new W(`unsupported ${t} schemaVersion ${String(f.schemaVersion)}`,"STORE_SCHEMA");if(f.kind!==t||!Number.isSafeInteger(f.generation)||f.generation<0)throw new W(`corrupt ${t} snapshot metadata`,"STORE_CORRUPT");let{integrity:x,...b}=f;if(typeof x!="string"||!/^[a-f0-9]{64}$/.test(x)||Sn(b)!==x)throw new W(`corrupt ${t} snapshot: checksum mismatch`,"STORE_CORRUPT");try{r(f.data)}catch(S){throw new W(`corrupt ${t} snapshot: ${S.message}`,"STORE_CORRUPT")}return b}function p(){if(!N.existsSync(e))return d();let v=N.statSync(e);if(!v.isFile()||v.size>i)throw new W(`${t} snapshot is not a bounded regular file`,"STORE_BOUNDS");try{N.chmodSync(e,384)}catch{}return s(N.readFileSync(e,"utf8"))}function m(){vn(Ge.dirname(e));let v=Ke(o),f=String(l()),x=`${JSON.stringify({schemaVersion:1,lockId:f,pid:process.pid,acquiredAt:v})}
47
+ `,b=()=>{let P;try{return P=N.openSync(u,"wx",384),N.writeFileSync(P,x,"utf8"),N.fsyncSync(P),N.closeSync(P),{lockId:f}}catch(h){let k=P!==void 0;if(k)try{N.closeSync(P)}catch{}if(k)try{N.unlinkSync(u)}catch{}if(h?.code!=="EEXIST")throw h;return null}},I=Ke(o)+c,O=new Int32Array(new SharedArrayBuffer(4));for(;;){let P=b();if(P)return P;let h=Ke(o),k=bt(u),M=!1;if(k){let q=h-Number(k.acquiredAt??k.mtimeMs);M=Number.isFinite(q)&&q>=a}else try{M=h-N.statSync(u).mtimeMs>=a}catch{M=!1}if(M){let q=bt(u);if(k?q?.lockId===k.lockId:q===null){try{N.unlinkSync(u)}catch(H){if(H?.code!=="ENOENT")throw H}continue}}let R=I-h;if(R<=0)throw new W(`${t} store is busy`,"STORE_BUSY");Atomics.wait(O,0,0,Math.min(10,R))}}function g(v){if(bt(u)?.lockId===v.lockId)try{N.unlinkSync(u)}catch(x){if(x?.code!=="ENOENT")throw x}}function w(v){r(v.data);let f={...v,integrity:Sn(v)},x=`${Je(f)}
48
+ `;if(Buffer.byteLength(x)>i)throw new W(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let b=Ge.dirname(e);vn(b);let S=Ge.join(b,`.${Ge.basename(e)}.${process.pid}.${bn()}.tmp`),I;try{I=N.openSync(S,"wx",384),N.writeFileSync(I,x,"utf8"),N.fsyncSync(I),N.closeSync(I),I=void 0,N.renameSync(S,e);try{N.chmodSync(e,384)}catch{}try{let O=N.openSync(b,"r");try{N.fsyncSync(O)}finally{N.closeSync(O)}}catch{}}finally{if(I!==void 0)try{N.closeSync(I)}catch{}try{N.unlinkSync(S)}catch(O){if(O?.code!=="ENOENT")throw O}}}function E(){return Ye(p().data)}function A(){let v=p();return{schemaVersion:v.schemaVersion,kind:v.kind,generation:v.generation,data:Ye(v.data)}}function T(v){if(typeof v!="function")throw new TypeError("mutator must be a function");let f=m();try{let x=p(),b=Ye(x.data),S=v(b,{generation:x.generation,now:Ke(o)});return r(b),w({schemaVersion:wt,kind:t,generation:x.generation+1,data:b}),Ye(S)}finally{g(f)}}return Object.freeze({filePath:e,read:E,inspect:A,mutate:T})}V();import{getAddress as vi}from"ethers";Le();V();var el=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});V();var nl=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),Ot=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Nt=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});Le();Le();var fi=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}}]}]);V();Le();V();function Pt(e,t="address"){let n=String(e||"").trim();if(!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(n))throw new Error(`solana-rpc: ${t} must be a base58 public key`);return n}V();function ye(e,t="address"){let n=String(e||"").trim();if(!/^(bc1|tb1|bcrt1)[a-z0-9]{20,90}$/i.test(n)&&!/^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(n))throw new Error(`bitcoin-esplora: ${t} must look like a Bitcoin address`);return n}var Ln="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function ge({provider:e,defaultUrl:t,hosts:n=[],url:r,strict:o=!1}){let a=(String(r??"").trim()||String(t)).replace(/\/$/,"");if(a===String(t).replace(/\/$/,""))return{baseUrl:a,trusted:!0,host:Un(t)};let c;try{c=new URL(a)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let l=c.host;if(!l)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Un(t),...n]).has(l)){let d=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(l);return c.protocol==="http:"&&!d?{baseUrl:a,trusted:!1,host:l,reason:"plaintext http downgrade"}:{baseUrl:a,trusted:!0,host:l}}if(String(process.env[Ln]||"")==="1")return{baseUrl:a,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${Ln}=1 to permit it)`);return{baseUrl:a,trusted:!1,host:l}}function Un(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function se(e,t,n){let r={...e};if(!n)return r;for(let[o,i]of Object.entries(t||{}))i&&(r[o]=i);return r}function Fn(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var yi=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function gi(e={}){let t=e.apiKey||process.env.UNISAT_API_KEY||process.env.BESTINSLOT_API_KEY||process.env.BTC_META_API_KEY||"",n=!1;try{let r=Fn(e);if(r){let o=new URL(r).host,i=new URL(r).protocol,a=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(o);n=yi.includes(o)&&(i==="https:"||a)}}catch{n=!1}return se({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},n)}async function wi(e,t={}){let r=await(t.fetchImpl||fetch)(e,{method:"GET",headers:gi(t),signal:AbortSignal.timeout(t.timeoutMs??12e3)}),o=await r.text(),i;try{i=JSON.parse(o)}catch{i=o}if(!r.ok)throw new Error(`bitcoin-meta GET ${e}: HTTP ${r.status} ${String(o).slice(0,160)}`);return i}async function Rt(e={},t={}){let n=ye(e.address||e.addr,"address"),r=Fn(t);if(!r)return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:"no indexer configured \u2014 address-indexed lookups need a keyed indexer (BTC_META_API_URL + UNISAT_API_KEY / BESTINSLOT_API_KEY). ordinals.com recursive is keyless but has no address index.",unknownNotEmpty:!0,keylessAlternatives:["btc_inscription_info (by inscription id)","btc_meta_health"]};let o=Math.min(Number(e.limit||50),200),i=[`${r}/v1/indexer/address/${n}/inscription-data?cursor=0&size=${o}`,`${r}/v1/inscriptions/address/${n}?limit=${o}`,`${r}/address/${n}/inscriptions?limit=${o}`],a=null;for(let c of i)try{let l=await wi(c,t),u=bi(l);return{provider:"bitcoin-meta",address:n,ok:!0,count:u.length,inscriptions:u,source:c}}catch(l){a=l}return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:String(a?.message||a||"all indexer paths failed")}}function bi(e){let t=e?.data?.inscription||e?.data?.detail||e?.data?.list||e?.data||e?.inscriptions||e?.results||(Array.isArray(e)?e:[]);return(Array.isArray(t)?t:[]).map(r=>({id:r.inscriptionId||r.id||r.inscription_id||null,number:r.inscriptionNumber??r.number??null,sat:r.sat||r.satoshi||null,contentType:r.contentType||r.content_type||null,utxo:r.utxo||r.output||(r.txid!=null?`${r.txid}:${r.vout??r.n}`:null),raw:r}))}V();V();V();var Xl=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood",2741:"abstract",solana:"solana"});V();var au=Object.freeze({1:"https://eth.blockscout.com",10:"https://explorer.optimism.io",137:"https://polygon.blockscout.com",324:"https://zksync.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com",534352:"https://scrollscan.com"}),Si=Object.freeze(["block_number","index"]),su=new Set([...Si,"items_count","value","hash","inserted_at","fee"]);var Uu=Object.freeze({ETH:"coingecko:ethereum",POL:"coingecko:polygon-ecosystem-token",BNB:"coingecko:binancecoin",AVAX:"coingecko:avalanche-2",HYPE:"coingecko:hyperliquid",USDT0:"coingecko:tether",SOL:"coingecko:solana",BTC:"coingecko:bitcoin"});function tt(e,...t){for(let n of t){let r=String(e?.[n]||"").trim();if(r)return r}return null}function Mn(e){if(!e)return null;try{return vi(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function Bn(e={},t=process.env){let n=e.addresses||{},r=Mn(n.evm||e.evmAddress||tt(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=n.solana||e.solanaAddress||tt(t,"ORACLE_SOLANA_ADDRESS"),i=n.bitcoin||e.bitcoinAddress||tt(t,"ORACLE_BITCOIN_ADDRESS"),a=Mn(n.hyperliquid||e.hyperliquidAddress||tt(t,"ORACLE_HYPERLIQUID_ADDRESS")||r);return{evm:r,solana:o?Pt(o,"portfolio Solana address"):null,bitcoin:i?ye(i,"portfolio Bitcoin address"):null,hyperliquid:a}}V();import{readFileSync as Ei,existsSync as Ai}from"node:fs";import{getAddress as ki,Interface as nt,TypedDataEncoder as Vu,parseUnits as zu}from"ethers";var xi=300*1e3,Mu=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})();var _i="https://api.opensea.io/api/v2",Ii="fulfillAdvancedOrder(((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 totalOriginalConsiderationItems) parameters,uint120 numerator,uint120 denominator,bytes signature,bytes extraData) advancedOrder,(uint256 orderIndex,uint8 side,uint256 index,uint256 identifier,bytes32[] criteriaProof)[] criteriaResolvers,bytes32 fulfillerConduitKey,address recipient)",Ju=new nt([`function ${Ii}`]),Qu=new nt(["function mintPublic(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity) payable","function mintAllowList(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity,(uint80 mintPrice,uint48 maxTotalMintableByWallet,uint48 startTime,uint48 endTime,uint48 dropStageIndex,uint32 maxTokenSupplyForStage,uint16 feeBps,bool restrictFeeRecipients) mintParams,bytes32[] proof) payable"]),Ci=Object.freeze(["blast","base","ethereum","zora","arbitrum","sei","avalanche","polygon","optimism","ape_chain","flow","b3","soneium","ronin","bera_chain","solana","shape","unichain","gunzilla","abstract","animechain","hyperevm","somnia","monad","hyperliquid","megaeth","ink","robinhood","stablechain"]),Ti=new Set(Ci),Oi=new Set(["solana","flow"]);function Ni(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!Ai(e))return"";try{for(let t of Ei(e,"utf8").split(`
49
+ `)){let n=t.match(/^\s*OPENSEA_API_KEY\s*=\s*(.+)\s*$/);if(n)return n[1].replace(/^["']|["']$/g,"").trim()}}catch{}return""}function Ue(e={}){return e.apiKey?e.apiKey:e.allowAmbientCredentials===!1||e.allowDiskCredentials===!1?e.env?.OPENSEA_API_KEY||e.env?.OPEN_SEA_API_KEY||"":e.env?.OPENSEA_API_KEY||process.env.OPENSEA_API_KEY||process.env.OPEN_SEA_API_KEY||Ni()}function Dn(e={}){return ge({provider:"opensea",defaultUrl:_i,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function rt(e={}){return Dn(e).baseUrl}function ot(e={}){return se({accept:"application/json"},{"x-api-key":Ue(e)},Dn(e).trusted)}function $i(e){let t=String(e||"ethereum").trim().toLowerCase();if(!Ti.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function qn(e,t="address"){try{return ki(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function jn(e,t=null){let n=String(e||"").trim();if(!n)throw new Error("opensea: account address required");if(t&&!Oi.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(n))return qn(n,"account address");if(!/^[1-9A-HJ-NP-Za-km-z]{32,64}$/.test(n))throw new Error("opensea: invalid account address");return n}function Pi(e={},t,n){return{chain:t,owner:n,contract:e.contract||null,tokenId:e.identifier==null?null:String(e.identifier),tokenStandard:e.token_standard||null,quantity:e.quantity==null&&e.balance==null?null:String(e.quantity??e.balance),collection:e.collection||null,name:e.name||null,description:e.description||null,imageUrl:e.display_image_url||e.image_url||e.original_image_url||null,originalImageUrl:e.original_image_url||e.image_url||null,animationUrl:e.display_animation_url||e.original_animation_url||null,metadataUrl:e.metadata_url||null,marketplaceUrl:e.opensea_url||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,spam:e.is_disabled===!0,disabled:e.is_disabled===!0,nsfw:e.is_nsfw===!0,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"OpenSea account inventory does not expose trustworthy per-item acquisition cost"}}}async function Ri(e,t={}){if(!e)throw new Error("collection slug required");if(!Ue(t))throw new Error("OPENSEA_API_KEY required");return z(`${rt(t)}/collections/${encodeURIComponent(e)}`,{headers:ot(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Li(e,t={}){if(!e)throw new Error("collection slug required");if(!Ue(t))throw new Error("OPENSEA_API_KEY required");return z(`${rt(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:ot(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Hn(e,t={}){let n=await Ri(e,t),r=n.stats||n.total||{},o=n.floor_price??n.floorPrice??r.floor_price??r.floorPrice??null;if(o==null){let s=await Li(e,t);r=s?.total||s?.stats||s||{},o=r.floor_price??r.floorPrice??null}let i=(Array.isArray(n.contracts)?n.contracts:[]).map(s=>({chain:String(s?.chain||s?.chain_identifier||n.chain||"").trim().toLowerCase(),address:String(s?.address||s?.contract_address||s?.contract||"").trim()})).filter(s=>s.chain&&s.address),a=String(t.expectedChain||"").trim().toLowerCase(),c=String(t.expectedContract||"").trim(),l=null;if(a&&c){let s=p=>a==="solana"?p:p.toLowerCase();if(l=i.find(p=>p.chain===a&&s(p.address)===s(c))||null,!l)throw new Error("opensea: collection identity does not match held contract")}let u=l?.chain||String(n.chain||"").trim().toLowerCase()||i[0]?.chain||"",d=String(n.floor_price_symbol||n.floorPriceSymbol||r.floor_price_symbol||r.floorPriceSymbol||"").trim().toUpperCase()||null;return{slug:n.collection||e,name:n.name||null,floor:o,chain:u||null,contracts:i,currency:d,totalSupply:n.total_supply??r.total_supply??null,numOwners:n.num_owners??r.num_owners??null,raw:{contracts:i,fees:n.fees,category:n.category}}}async function Ut(e={},t={}){if(!Ue(t))throw new Error("OPENSEA_API_KEY required");let n=$i(e.chain),r=jn(e.address||e.owner,n),o=Math.min(Math.max(Number(e.pageSize??e.limit??200)||200,1),200),i=Math.min(Math.max(Number(e.maxPages??5)||5,1),25),a=[],c=e.next?String(e.next):null,l=0;do{let u=new URL(`${rt(t)}/chain/${encodeURIComponent(n)}/account/${encodeURIComponent(r)}/nfts`);u.searchParams.set("limit",String(o)),e.collection&&u.searchParams.set("collection",String(e.collection)),c&&u.searchParams.set("next",c);let d=await z(u.toString(),{headers:ot(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let s of Array.isArray(d?.nfts)?d.nfts:[])a.push(Pi(s,n,r));c=d?.next?String(d.next):null,l+=1}while(c&&l<i);return{provider:"opensea-nft",source:"opensea-account-inventory",chain:n,owner:r,count:a.length,pages:l,complete:!c,next:c,nfts:a,exec:!1,readOnly:!0}}async function Vn(e={},t={}){if(!Ue(t))throw new Error("OPENSEA_API_KEY required");let n=jn(e.address||e.owner),r=await z(`${rt(t)}/account/${encodeURIComponent(n)}/pnl`,{headers:ot(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});return{provider:"opensea-nft",source:"opensea-indexed-account-pnl",address:n,scope:"OpenSea-indexed account trading PnL across supported currencies, not per-item NFT cost basis",methodology:"provider-indexed",realizedPnlUsd:r?.realized_pnl_usd??null,unrealizedPnlUsd:r?.unrealized_pnl_usd??null,totalPnlUsd:r?.total_pnl_usd??null,netInvestedUsd:r?.net_invested_usd??null,currentValueUsd:r?.current_value_usd??null,returnPercentage:r?.return_percentage??null,itemLevelPnlAvailable:!1,raw:r,exec:!1,readOnly:!0}}var Xu=Object.freeze({robinhood:4663,ethereum:1,base:8453,arbitrum:42161,optimism:10,polygon:137,avalanche:43114,zora:7777777,blast:81457,sei:1329,ape_chain:33139,b3:8333,soneium:1868,ronin:2020,bera_chain:80094,shape:360,unichain:130,gunzilla:43419,abstract:2741,animechain:69e3,hyperevm:999,somnia:5031,monad:143,megaeth:4326,ink:57073,stablechain:988});var Zu=Object.freeze({OrderComponents:[{name:"offerer",type:"address"},{name:"zone",type:"address"},{name:"offer",type:"OfferItem[]"},{name:"consideration",type:"ConsiderationItem[]"},{name:"orderType",type:"uint8"},{name:"startTime",type:"uint256"},{name:"endTime",type:"uint256"},{name:"zoneHash",type:"bytes32"},{name:"salt",type:"uint256"},{name:"conduitKey",type:"bytes32"},{name:"counter",type:"uint256"}],OfferItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"}],ConsiderationItem:[{name:"itemType",type:"uint8"},{name:"token",type:"address"},{name:"identifierOrCriteria",type:"uint256"},{name:"startAmount",type:"uint256"},{name:"endAmount",type:"uint256"},{name:"recipient",type:"address"}]});var ed=new nt(["function setApprovalForAll(address operator,bool approved)"]),td=new nt(["function cancel((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 counter)[] orders) returns (bool cancelled)"]);var Fi="https://api.satflow.com/v1";function zn(e={}){return ge({provider:"satflow",defaultUrl:Fi,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function Mi(e={}){return zn(e).baseUrl}function Wn(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function Bi(e={}){return se({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":Wn(e)},zn(e).trusted)}async function qi(e,{method:t="GET",body:n,opts:r={}}={}){if(!Wn(r))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${Mi(r)}${e.startsWith("/")?e:`/${e}`}`,c=await(r.fetchImpl||fetch)(i,{method:t,headers:Bi(r),body:n!=null?JSON.stringify(n):void 0,signal:AbortSignal.timeout(r.timeoutMs??2e4)}),l=await c.text(),u;try{u=JSON.parse(l)}catch{u=l}if(!c.ok)throw new Error(`satflow ${t} ${e}: HTTP ${c.status} ${String(l).slice(0,200)}`);return u}async function Gn(e={},t={}){let n=ye(e.address||e.addr,"address"),r=new URLSearchParams({address:n});e.type&&r.set("type",e.type),e.limit!=null&&r.set("limit",String(e.limit)),e.offset!=null&&r.set("offset",String(e.offset));let o=await qi(`/address/wallet-contents?${r}`,{opts:t});return{provider:"satflow",address:n,contents:o}}V();V();var yd=Object.freeze(["i.seadn.io","openseauserdata.com","arweave.net","ipfs.io","nftstorage.link","dweb.link","cloudflare-ipfs.com","ordinals.com","ordinals.g.com","cdn.helius-rpc.com","shdw-drive.genesysgo.net"]);var Di=[/\bclaim\b/i,/\breward\b/i,/\bairdrop\b/i,/\bvoucher\b/i,/\bwinner\b/i,/\bfree\s*mint\b/i,/\bactivate\b/i,/\bunlock\b/i,/\bverify\b/i,/\bconnect\s+wallet\b/i],ji=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,Hi=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function Vi(e={}){let t=[],n=String(e.name||""),r=String(e.description||""),o=`${n} ${r}`;ji.test(n)&&t.push("url-in-name");let i=Di.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),Hi.test(n)&&t.push("value-claim-in-name"),/[\u200B-\u200F\u202A-\u202E\uFEFF]/.test(n)&&t.push("invisible-characters"),e.disabled===!0&&t.push("marketplace-disabled");let a=e.estimatedValueUsd==null&&e.estimatedValueSats==null,c=!Array.isArray(e.traits)||e.traits.length===0;a&&c&&i>0&&t.push("valueless-airdrop-with-lure");let l=t.includes("url-in-name")||t.includes("invisible-characters")||t.includes("valueless-airdrop-with-lure")||t.length>=2;return{spam:l,risk:l?"high":t.length>0?"low":"none",reasons:t}}function Kn(e={}){let t=Vi(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}var zi=Object.freeze([{chain:"ethereum",chainId:1,family:"evm"},{chain:"optimism",chainId:10,family:"evm"},{chain:"polygon",chainId:137,family:"evm"},{chain:"stablechain",chainId:988,family:"evm"},{chain:"hyperevm",chainId:999,family:"evm"},{chain:"abstract",chainId:2741,family:"evm"},{chain:"robinhood",chainId:4663,family:"evm"},{chain:"base",chainId:8453,family:"evm"},{chain:"arbitrum",chainId:42161,family:"evm"},{chain:"avalanche",chainId:43114,family:"evm"},{chain:"hyperliquid",chainId:null,family:"hyperliquid"}]),Wi=Object.freeze([{family:"evm",chain:"bsc",chainId:56,reason:"OpenSea account inventory does not support BSC"},{family:"cosmos",reason:"requires a chain-specific bech32 address and NFT indexer"},{family:"sui",reason:"owner inventory adapter not installed"},{family:"aptos",reason:"owner inventory adapter not installed"}]);function Ft(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function Fe(e,t){let n=await et(t);return n.ok?{ok:!0,data:n.data}:{ok:!1,error:`${e}: ${n.error}`.slice(0,300)}}function Gi(e){if(Array.isArray(e))return e;for(let t of["items","results","ordinals","inscriptions","data"])if(Array.isArray(e?.[t]))return e[t];return[]}function Ki(e={},t){let n=e.inscription_id||e.inscriptionId||e.id||e.inscription||null;return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:n==null?null:String(n),tokenStandard:"ordinal",collection:e.collection_slug||e.collectionSlug||e.collection?.slug||e.collection||null,name:e.name||e.meta?.name||(n?`Inscription ${n}`:"Bitcoin inscription"),description:e.description||e.meta?.description||null,imageUrl:e.image_url||e.imageUrl||e.content_url||e.contentUrl||e.thumbnail||null,originalImageUrl:e.content_url||e.contentUrl||e.image_url||e.imageUrl||null,animationUrl:null,metadataUrl:e.metadata_url||e.metadataUrl||null,marketplaceUrl:e.marketplace_url||e.marketplaceUrl||null,estimatedValueUsd:e.estimated_value_usd!=null&&Number.isFinite(Number(e.estimated_value_usd))?Number(e.estimated_value_usd):null,estimatedValueSats:(e.floor_price_sats??e.price_sats)!=null&&Number.isFinite(Number(e.floor_price_sats??e.price_sats))?Number(e.floor_price_sats??e.price_sats):null,spam:!1,disabled:!1,nsfw:!1,listed:e.listed===!0||e.is_listed===!0,listingId:e.listing_id||e.listingId||null,traits:Array.isArray(e.traits)?e.traits:[],updatedAt:e.updated_at||e.updatedAt||null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"Satflow wallet inventory does not expose trustworthy acquisition cost"},listingAdapter:"satflow",source:"satflow-wallet-contents"}}function Yi(e,t){return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:String(e),tokenStandard:"ordinal",collection:null,name:`Inscription ${e}`,description:null,imageUrl:null,originalImageUrl:null,animationUrl:null,metadataUrl:null,marketplaceUrl:null,estimatedValueUsd:null,spam:!1,disabled:!1,nsfw:!1,traits:[],updatedAt:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"address indexer returned no acquisition or valuation data"},listingAdapter:"satflow",source:"bitcoin-meta-address-indexer"}}function Yn(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function Ji(e){let t=new Map;if(Array.isArray(e)){for(let n of e)n?.assetKey&&t.set(String(n.assetKey).toLowerCase(),n);return t}if(e&&typeof e=="object")for(let[n,r]of Object.entries(e))t.set(n.toLowerCase(),r);return t}function Qi(e,t){let n=Yn(e),r=t.get(n),o=e.estimatedValueUsd==null?null:Number(e.estimatedValueUsd);if(!r)return{...e,assetKey:n};let i=Number(r.costUsd),a=Number(r.feesUsd??0);if(!Number.isFinite(i)||i<0||!Number.isFinite(a)||a<0)return{...e,assetKey:n,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"invalid user-supplied cost basis"}};let c=Math.round((i+a)*100)/100;return Number.isFinite(o)?{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:a,totalCostUsd:c,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"estimated",methodology:"provider estimated current value minus supplied USD acquisition cost and fees",unrealizedUsd:Math.round((o-c)*100)/100,currentValueUsd:o,totalCostUsd:c,realizedUsd:null}}:{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:a,totalCostUsd:c,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"unavailable",reason:"current NFT valuation is unavailable"}}}function Xi(e){let t=new Map;for(let n of e){let r=Yn(n);t.has(r)||t.set(r,n)}return[...t.values()]}function Zi(e,t){let n=e.filter(i=>i.itemPnl?.status==="estimated"),r=e.length-n.length,o=Math.round(n.reduce((i,a)=>i+Number(a.itemPnl.unrealizedUsd||0),0)*100)/100;return{nftItemPnl:{status:r===0&&e.length?"estimated-complete-for-held-items":n.length?"partial":"unavailable",methodology:"Only items with explicit acquisition cost and provider estimated current value are included",knownUnrealizedUsd:o,knownItems:n.length,unknownItems:r,realizedUsd:null,warning:"Transfers, gifts, airdrops, mints, bridges, gas, royalties, and off-market sales can make cost basis unavailable or incomplete."},providerAccountPnl:t}}async function Jn(e={},t={}){let n=new Date().toISOString(),r=Bn(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(f=>String(f).toLowerCase())):null,i=zi.filter(f=>!o||o.has(f.chain)),a=[],c=[],l=Ft(t,"opensea"),u=r.evm?i.filter(f=>f.family!=="solana"):[],d=await Re(u,4,async f=>({row:f,result:await Fe(`opensea-${f.chain}`,()=>Ut({chain:f.chain,address:r.evm,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3)}));for(let{row:f,result:x}of d)if(x.ok){let b=x.data.nfts.map(S=>({...S,family:f.family,chainId:f.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));c.push(...b),a.push({family:f.family,chain:f.chain,chainId:f.chainId,status:x.data.complete?"ok":"partial",count:b.length,complete:x.data.complete,next:x.data.next,source:"opensea"})}else a.push({family:f.family,chain:f.chain,chainId:f.chainId,status:"unavailable",error:x.error,source:"opensea"});if(!r.evm)for(let f of i.filter(x=>x.family!=="solana"))a.push({family:f.family,chain:f.chain,chainId:f.chainId,status:"not-configured",reason:"EVM address missing"});if(r.solana&&(!o||o.has("solana"))){let f=await Fe("opensea-solana",()=>Ut({chain:"solana",address:r.solana,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3);if(f.ok){let x=f.data.nfts.map(b=>({...b,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));c.push(...x),a.push({family:"solana",chain:"solana",status:f.data.complete?"ok":"partial",count:x.length,complete:f.data.complete,next:f.data.next,source:"opensea"})}else a.push({family:"solana",chain:"solana",status:"unavailable",error:f.error,source:"opensea"})}else(!o||o.has("solana"))&&a.push({family:"solana",chain:"solana",status:"not-configured",reason:"Solana address missing"});if(r.bitcoin&&(!o||o.has("bitcoin"))){let f=await Fe("satflow-wallet-contents",()=>Gn({address:r.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},Ft(t,"satflow")),t.timeoutMs??35e3);if(f.ok){let x=Gi(f.data.contents).map(S=>Ki(S,r.bitcoin));c.push(...x);let b=x.length<Number(e.bitcoinLimit??100);a.push({family:"bitcoin",chain:"bitcoin",status:b?"ok":"partial",count:x.length,complete:b,source:"satflow"})}else{let x=await Fe("bitcoin-meta-inscriptions",()=>Rt({address:r.bitcoin},Ft(t,"bitcoinMeta")),t.timeoutMs??35e3),b=x.ok&&x.data?.ok&&Array.isArray(x.data.inscriptions)?x.data.inscriptions:[];c.push(...b.map(S=>Yi(S,r.bitcoin))),a.push({family:"bitcoin",chain:"bitcoin",status:b.length?"partial":"unavailable",count:b.length,complete:!1,source:b.length?"bitcoin-meta":"satflow",error:b.length?"Satflow unavailable; fallback has IDs only":f.error})}}else(!o||o.has("bitcoin"))&&a.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let s=[];if(e.includePnl!==!1)for(let f of[...new Set([r.evm,r.solana].filter(Boolean))]){let x=await Fe(`opensea-pnl-${f}`,()=>Vn({address:f},l),t.timeoutMs??35e3);s.push(x.ok?{status:"ok",...x.data}:{status:"unavailable",address:f,source:"opensea-indexed-account-pnl",error:x.error})}let p=Ji(e.costBasis),m=Xi(c).map(f=>Qi(f,p)).map(f=>Kn(f)),g=m.filter(f=>!f.spam),w=m.filter(f=>f.spam),E=g.filter(f=>f.estimatedValueUsd!=null&&Number.isFinite(Number(f.estimatedValueUsd))),A=Math.round(E.reduce((f,x)=>f+Number(x.estimatedValueUsd),0)*100)/100,T=g.length-E.length,v=a.filter(f=>f.status!=="ok"||f.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:n,addresses:r,coverage:a,unsupported:Wi,inventory:{count:m.length,visibleCount:g.length,flaggedCount:w.length,items:m,visibleItems:g,flaggedItems:w},valuation:{estimatedCurrentValueUsd:A,valuedItems:E.length,unvaluedItems:T,complete:T===0&&v.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:Zi(g,s),listingCoverage:{opensea:"EVM listing actions available with OPENSEA_API_KEY, explicit price/currency/expiry, and user confirmation",satflow:"Bitcoin unsigned listing PSBT available with SATFLOW_API_KEY, explicit price/expiry, and user confirmation",solana:"Magic Eden unsigned list transaction available with MAGICEDEN_API_KEY, explicit SOL price/expiry, and user confirmation",unsupported:"Sui, Aptos, Cosmos, BSC, and unknown marketplaces fail closed"},traitSniperCoverage:{opensea:"Evaluates reveal/trait-floor mispricing only with recent trait sales and volume evidence. Buy intents require local vault signing.",execution:"prepare-only on hosted surfaces; local vault required for purchase"},metadataSafety:{imagesAreUntrusted:!0,animationAndHtmlNotRendered:!0,galleryRasterOnly:!0,missingImagesUsePlaceholders:!0}}}var Xn=1,na=/^0x[0-9a-f]{40}$/,ra=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,oa=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function ia(e=process.env){let t=e.ORACLE_CONFIG_DIR||it.join(Qn(),".config","oracle");return it.join(t,"held-nft-pump.v1.json")}function aa(e=process.env){let t=e.ORACLE_CONFIG_DIR||it.join(Qn(),".config","oracle"),n={};try{let o=JSON.parse(ea(it.join(t,"portfolio.json"),"utf8"));n=o&&typeof o=="object"&&!Array.isArray(o)?o.addresses||o:{}}catch{}let r={evm:e.ORACLE_EVM_ADDRESS||n.evm,solana:e.ORACLE_SOLANA_ADDRESS||n.solana};return Object.fromEntries(Object.entries(r).filter(([,o])=>typeof o=="string"&&o.trim()).map(([o,i])=>[o,i.trim()]))}function sa(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function Zn(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function ca(e){let t=e?.quantity??e?.balance??1;if(typeof t!="string"&&typeof t!="number"&&typeof t!="bigint"||!/^\d+$/.test(String(t)))return 0n;let n=BigInt(String(t));return n>0n?n:0n}function la(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function ua(e){if(!e||e.version!==Xn||!e.collections||typeof e.collections!="object"||Array.isArray(e.collections))throw new TypeError("invalid held NFT pump state");if(!Number.isSafeInteger(e.cursor??0)||(e.cursor??0)<0)throw new TypeError("invalid held NFT pump cursor");if(e.walletFingerprint!==void 0&&!/^[a-f0-9]{64}$/.test(e.walletFingerprint))throw new TypeError("invalid held NFT wallet fingerprint");if(e.walletChanged!==void 0&&typeof e.walletChanged!="boolean")throw new TypeError("invalid held NFT wallet-change marker");let t=e.failures??{};if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("invalid held NFT pump failures");let n=Object.entries(e.collections);if(n.length>1e4||Object.keys(t).length>1e4)throw new TypeError("held NFT pump state exceeds collection bound");for(let[r,o]of n){if(!r||r.length>260||!o||Zn(o.anchorFloor)===null)throw new TypeError("invalid held NFT floor record");if(!Number.isFinite(o.updatedAt)||o.updatedAt<0)throw new TypeError("invalid held NFT update time");if(o.lastAlertAt!==null&&(!Number.isFinite(o.lastAlertAt)||o.lastAlertAt<0))throw new TypeError("invalid held NFT alert time")}for(let r of Object.values(t))if(!r||!Number.isSafeInteger(r.count)||r.count<1||!Number.isFinite(r.nextCheckAt)||r.nextCheckAt<0)throw new TypeError("invalid held NFT provider backoff")}function da(e={}){let t=e?.inventory?.visibleItems??e?.inventory?.items??[],n=new Map;for(let r of Array.isArray(t)?t:[]){if(r?.spam===!0||r?.disabled===!0)continue;let o=String(r?.chain||"").trim().toLowerCase(),i=String(r?.contract||"").trim(),a=o==="solana"?i:i.toLowerCase(),c=String(r?.collection||"").trim().toLowerCase();if(!o||!c||!(o==="solana"?ra.test(a):na.test(a)))continue;let l=ca(r);if(l===0n)continue;let u=`${o}:${a}`,d=n.get(u);d&&d.slug!==c||n.set(u,{key:u,chain:o,contract:a,slug:c,name:d?.name||String(r?.name||c),heldCountRaw:(d?.heldCountRaw||0n)+l})}return[...n.values()].map(({heldCountRaw:r,...o})=>({...o,heldCount:la(r)})).sort((r,o)=>r.key.localeCompare(o.key))}function pa(e,t){let n=String(e?.currency||"").trim().toUpperCase();if(!oa.test(n))return{ok:!1,reason:"floor-currency-unavailable"};if(e?.chain&&String(e.chain).trim().toLowerCase()!==t.chain)return{ok:!1,reason:"floor-identity-mismatch"};let r=Array.isArray(e?.contracts)?e.contracts:Array.isArray(e?.raw?.contracts)?e.raw.contracts:[],o=t.chain==="solana"?t.contract:t.contract.toLowerCase();return r.some(a=>{let c=String(a?.address||a?.contract_address||a?.contract||"").trim(),l=t.chain==="solana"?c:c.toLowerCase(),u=String(a?.chain||a?.chain_identifier||"").trim().toLowerCase();return l===o&&u===t.chain})?{ok:!0,currency:n}:{ok:!1,reason:"floor-identity-mismatch"}}function fa(e,t,n,r,o){let i=Math.round((t/r.anchorFloor-1)*1e4)/100;return Object.freeze({type:"held_nft_floor_pump",category:"price",chain:e.chain,contract:e.contract,slug:e.slug,name:e.name,heldCount:e.heldCount,fromFloor:r.anchorFloor,floor:t,currency:n,changePct:i,observedAt:new Date(o).toISOString(),evidence:Object.freeze({source:"opensea-collection-floor",status:"provider-estimate",chain:e.chain,contract:e.contract,currency:n,observedAt:new Date(o).toISOString(),warning:"Floor is a provider estimate, not an executable bid or guaranteed liquidation value."}),custody:"none",executionAllowed:!1})}function er({filePath:e,env:t=process.env,clock:n=()=>Date.now(),inventoryFn:r=Jn,floorFn:o=Hn,notifyFn:i=async()=>({delivered:0}),thresholdPct:a=Number(t.ORACLE_NFT_PUMP_THRESHOLD_PCT??15),cooldownMs:c=Number(t.ORACLE_NFT_PUMP_COOLDOWN_HOURS??6)*36e5,maxFloorChecksPerTick:l=Number(t.ORACLE_NFT_PUMP_MAX_FLOORS_PER_TICK??20),inventoryPageSize:u=100,inventoryMaxPages:d=2}={}){if(typeof r!="function"||typeof o!="function"||typeof i!="function")throw new TypeError("held NFT watchdog functions are required");if(!Number.isFinite(a)||a<=0||a>1e3)throw new TypeError("held NFT pump threshold is out of range");if(!Number.isFinite(c)||c<6e4||c>30*864e5)throw new TypeError("held NFT pump cooldown is out of range");if(!Number.isSafeInteger(l)||l<1||l>100)throw new TypeError("held NFT floor budget is out of range");let s=xn({filePath:e||ia(t),kind:"oracle-held-nft-pump",clock:n,maxBytes:4*1024*1024,initialData:()=>({version:Xn,cursor:0,collections:{},failures:{}}),validateData:ua}),p=!1;function m(w,E){s.mutate(A=>{A.failures||={};let T=Math.min(20,Number(A.failures[w]?.count||0)+1);A.failures[w]={count:T,nextCheckAt:E+Math.min(6*36e5,3e5*2**Math.min(6,T-1))}})}async function g(){if(p)return{skipped:!0,reason:"tick-in-progress",alerts:[],unavailable:[]};p=!0;try{let w=Number(n());if(!Number.isFinite(w))throw new TypeError("held NFT watchdog clock is invalid");let E=aa(t),A=sa(t),T=ta("sha256").update(JSON.stringify(Object.entries(E).sort())).digest("hex");s.mutate(h=>{let k=!!(h.walletFingerprint&&h.walletFingerprint!==T);k&&(h.collections={},h.failures={},h.cursor=0),h.walletFingerprint=T,h.walletChanged=k});let v=await r({addresses:E,includePnl:!1,pageSize:u,maxPages:d},{env:A}),f=da(v),x=new Set(f.map(h=>h.key)),b=new Set((Array.isArray(v?.coverage)?v.coverage:[]).filter(h=>h?.status==="ok"&&h?.complete===!0).map(h=>String(h.chain||"").toLowerCase()).filter(Boolean));b.size&&s.mutate(h=>{for(let k of Object.keys(h.collections)){let M=k.slice(0,k.indexOf(":"));b.has(M)&&!x.has(k)&&delete h.collections[k]}for(let k of Object.keys(h.failures||{})){let M=k.slice(0,k.indexOf(":"));b.has(M)&&!x.has(k)&&delete h.failures[k]}});let S=s.mutate(h=>{let k=f.length?(h.cursor||0)%f.length:0;return h.cursor=f.length?(k+Math.min(l,f.length))%f.length:0,k}),I=[];for(let h=0;h<Math.min(l,f.length);h+=1)I.push(f[(S+h)%f.length]);let O=[],P=[];for(let h of I){let k=s.inspect().data.failures?.[h.key];if(k&&k.nextCheckAt>w){P.push({key:h.key,reason:"floor-provider-backoff"});continue}let M;try{M=await o(h.slug,{env:A,expectedChain:h.chain,expectedContract:h.contract})}catch{m(h.key,w),P.push({key:h.key,reason:"floor-provider-unavailable"});continue}let R=pa(M,h);if(!R.ok){m(h.key,w),P.push({key:h.key,reason:R.reason});continue}let q=Zn(M?.floor);if(q===null){m(h.key,w),P.push({key:h.key,reason:"floor-unavailable"});continue}let j=s.mutate(L=>{L.failures||={},delete L.failures[h.key];let _=L.collections[h.key];if(!_)return L.collections[h.key]={anchorFloor:q,lastAlertAt:null,updatedAt:w,currency:R.currency},null;if(_.updatedAt=w,_.currency!==R.currency)return _.anchorFloor=q,_.currency=R.currency,_.lastAlertAt=null,null;if(q<_.anchorFloor)return _.anchorFloor=q,_.currency=R.currency,null;if((q/_.anchorFloor-1)*100+1e-9<a)return null;if(_.lastAlertAt!==null&&w-_.lastAlertAt<c)return _.anchorFloor=q,_.currency=R.currency,null;let K=fa({...h,name:M?.name||h.name},q,R.currency,_,w);return _.anchorFloor=q,_.lastAlertAt=w,_.updatedAt=w,_.currency=R.currency,K});if(!j)continue;let H;try{H=await i(j)}catch{H=null}if(!H||Number(H.delivered||0)!==1){P.push({key:h.key,reason:"notification-delivery-failed"});continue}O.push(j)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:f.length,checkedCollections:I.length,alerts:O,unavailable:P,coverage:v?.coverage??[]}}finally{p=!1}}return Object.freeze({filePath:s.filePath,tick:g,inspect:s.inspect})}Me();var ht=Oe.ORACLE_CONFIG_DIR||We(uc(),".config","oracle"),Co=We(ht,"gateway.json");function yc(){return dc(Co)?JSON.parse(yn(Co,"utf8")):{platforms:{}}}function gc(e={},t=Oe){let n=e?.notifications?.heldNftPumps;return n===!1?!1:n===!0?!0:String(t.ORACLE_NFT_PUMP_ENABLED||"")==="1"}function wc({configDir:e=ht,environment:t=Oe}={}){let n=String(t.ORACLE_MESSAGING_PLATFORM||"").trim().toLowerCase();if(n)return n;try{let r=JSON.parse(yn(We(e,"messaging.json"),"utf8"));return String(r?.platform||"").trim().toLowerCase()}catch{return""}}function bc(e,t=ht){let n=String(e?.platform||""),r=String(e?.recipientId||"");if(!n||!r)throw new TypeError("recipient-bound held NFT subscription is required");let o=mc("sha256").update(`${n}\0${r}`).digest("hex").slice(0,24);return We(t,`held-nft-pump.${o}.v1.json`)}function Sc({heldNftPumpLoop:e,platforms:t=[],server:n,exitFn:r=o=>process.exit(o)}={}){let o=null;return async function(){return o||(o=(async()=>{e?.stop?.();for(let a of t)try{await a?.stop?.()}catch{}n?.close&&await new Promise(a=>n.close(()=>a())),r(0)})(),o)}}function mn(e){return e?Array.isArray(e)?e.filter(Boolean):[e]:[]}var vc=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function mt(e,t,n,r){try{r.push(await t(n))}catch(o){let i=vc[e];if(i&&/Cannot find (module|package)|ERR_MODULE_NOT_FOUND/.test(String(o.message))){process.stderr.write(`oracle-gateway: ${e} needs an optional dependency. Install it first:
50
50
  npm install -g ${i}
51
51
  `);return}process.stderr.write(`oracle-gateway: ${e} failed to start: ${o.message}
52
- `)}}async function Sc(){let e=mc(),t=[],n=fn(e.platforms?.telegram),r=fn(e.platforms?.discord),o=fn(e.agents),a=n.length+r.length+o.length>1?new(await Promise.resolve().then(()=>(nr(),tr))).A2ABus:null;if(a&&o.length){let{routePeerConsult:s,buildPersona:p}=await Promise.resolve().then(()=>(Ce(),ro));for(let m of o)try{let g=p(m);a.register(m.name,{role:m.role||"",chains:m.chains||[],handler:w=>s({from:w.from,text:w.text,persona:g,backend:m.backend,profile:m.hermesProfile})}),process.stderr.write(`oracle-gateway: headless agent '${m.name}' on bus (backend: ${m.backend||"oracle"})
52
+ `)}}async function xc(){let e=yc(),t=[],n=mn(e.platforms?.telegram),r=mn(e.platforms?.discord),o=mn(e.agents),a=n.length+r.length+o.length>1?new(await Promise.resolve().then(()=>(ir(),or))).A2ABus:null;if(a&&o.length){let{routePeerConsult:s,buildPersona:p}=await Promise.resolve().then(()=>(Ce(),ao));for(let m of o)try{let g=p(m);a.register(m.name,{role:m.role||"",chains:m.chains||[],handler:w=>s({from:w.from,text:w.text,persona:g,backend:m.backend,profile:m.hermesProfile})}),process.stderr.write(`oracle-gateway: headless agent '${m.name}' on bus (backend: ${m.backend||"oracle"})
53
53
  `)}catch(g){process.stderr.write(`oracle-gateway: headless agent '${m.name||"?"}' skipped: ${g.message}
54
- `)}}for(let s of n)await pt("telegram",async()=>(await Promise.resolve().then(()=>(go(),yo))).telegram({...s,bus:a}),e,t);for(let s of r)await pt("discord",async()=>(await Promise.resolve().then(()=>(bo(),wo))).discord({...s,bus:a}),e,t);e.platforms?.whatsapp&&await pt("whatsapp",async s=>(await Promise.resolve().then(()=>(xo(),vo))).whatsapp(s.platforms.whatsapp),e,t),e.platforms?.signal&&await pt("signal",async s=>(await Promise.resolve().then(()=>(Ao(),Eo))).signal_(s.platforms.signal),e,t),t.length===0&&process.stderr.write(`oracle-gateway: no platforms configured. Run 'oracle setup telegram' first.
54
+ `)}}for(let s of n)await mt("telegram",async()=>(await Promise.resolve().then(()=>(So(),bo))).telegram({...s,bus:a}),e,t);for(let s of r)await mt("discord",async()=>(await Promise.resolve().then(()=>(xo(),vo))).discord({...s,bus:a}),e,t);e.platforms?.whatsapp&&await mt("whatsapp",async s=>(await Promise.resolve().then(()=>(ko(),Ao))).whatsapp(s.platforms.whatsapp),e,t),e.platforms?.signal&&await mt("signal",async s=>(await Promise.resolve().then(()=>(Io(),_o))).signal_(s.platforms.signal),e,t),t.length===0&&process.stderr.write(`oracle-gateway: no platforms configured. Run 'oracle setup telegram' first.
55
55
  `),process.stderr.write(`oracle-gateway: ${t.length} platform(s) connected
56
- `);let c=null;if(hc(e,Oe)){let s=Xn(t,yc());if(s){let p=Qn({env:Oe,filePath:gc(s),notifyFn:Zn(s)});c=er({watchdog:p}),c.start(),process.stderr.write(`oracle-gateway: held NFT pump watch active via ${s.platform}
56
+ `);let c=null;if(gc(e,Oe)){let s=tr(t,wc());if(s){let p=er({env:Oe,filePath:bc(s),notifyFn:nr(s)});c=rr({watchdog:p}),c.start(),process.stderr.write(`oracle-gateway: held NFT pump watch active via ${s.platform}
57
57
  `)}else process.stderr.write(`oracle-gateway: held NFT pump disabled \u2014 selected messenger must have exactly one owner
58
- `)}let l=a?Ac():null,u=sc((s,p)=>xc(s,p,{config:e,bus:a,a2aToken:l}));u.listen(Oe.ORACLE_GATEWAY_PORT||9270,"127.0.0.1");let d=wc({heldNftPumpLoop:c,platforms:t,server:u});process.once("SIGINT",()=>{d()}),process.once("SIGTERM",()=>{d()}),a&&process.stderr.write(`oracle-gateway: a2a loopback contract at GET /a2a (token: a2a-token in config dir)
59
- `)}var vc=16384;async function xc(e,t,{config:n,bus:r,a2aToken:o}){let i=new URL(e.url||"/","http://127.0.0.1"),a=(l,u)=>{t.writeHead(l,{"Content-Type":"application/json"}),t.end(JSON.stringify(u))};if(e.method==="GET"&&(i.pathname==="/"||i.pathname==="/health"))return a(200,{status:"ok",platforms:Object.keys(n.platforms||{}),a2a:!!r});if(!i.pathname.startsWith("/a2a"))return a(404,{error:"not found"});if(!r)return a(404,{error:"a2a bus not running (fewer than 2 agents configured)"});if(e.method==="GET"&&i.pathname==="/a2a")return a(200,{contract:"oracle-a2a/1",auth:"Authorization: Bearer <contents of a2a-token in the oracle config dir>",endpoints:["GET /a2a","GET /a2a/agents","POST /a2a/ask {to,text,from?}"],note:"consult-only; loopback-only; peers answer with information, never actions"});let c=String(e.headers.authorization||"");if(!o||c!==`Bearer ${o}`)return a(401,{error:"bad or missing bearer token (read a2a-token in the oracle config dir)"});if(e.method==="GET"&&i.pathname==="/a2a/agents")return a(200,{agents:r.roster()});if(e.method==="POST"&&i.pathname==="/a2a/ask"){let l="";e.on("data",u=>{l+=u,l.length>vc&&e.destroy()}),e.on("end",async()=>{try{let u=JSON.parse(l||"{}"),d=Ec(u.from);r.agents.has(d)||r.register(d,{role:"loopback client",handler:async()=>null});let s=await r.send({from:d,to:u.to,text:u.text,kind:"consult"});return a(s.ok?200:400,s)}catch(u){return a(400,{ok:!1,error:`bad request: ${u.message}`})}});return}return a(404,{error:"not found"})}function Ec(e){return String(e||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function Ac(e=ft){let t=Ve(e,"a2a-token");try{let r=hn(t,"utf8").trim();if(r)return r}catch{}let n=fc(24).toString("hex");return uc(e,{recursive:!0}),dc(t,`${n}
60
- `,{mode:384}),n}var{pathToFileURL:kc}=await import("node:url"),{realpathSync:_c}=await import("node:fs"),_o=process.argv[1],mn=!1;if(_o)try{mn=import.meta.url===kc(_c(_o)).href}catch{mn=!1}mn&&Sc().catch(e=>{process.stderr.write(`oracle-gateway: ${e.message}
61
- `),process.exit(1)});export{wc as createGatewayShutdown,Ac as ensureA2AToken,hc as heldNftPumpEnabled,gc as heldNftSubscriptionStatePath,yc as preferredMessagingPlatform,xc as serveHttp,fn as toEntries};
58
+ `)}let l=a?_c():null,u=lc((s,p)=>Ac(s,p,{config:e,bus:a,a2aToken:l}));u.listen(Oe.ORACLE_GATEWAY_PORT||9270,"127.0.0.1");let d=Sc({heldNftPumpLoop:c,platforms:t,server:u});process.once("SIGINT",()=>{d()}),process.once("SIGTERM",()=>{d()}),a&&process.stderr.write(`oracle-gateway: a2a loopback contract at GET /a2a (token: a2a-token in config dir)
59
+ `)}var Ec=16384;async function Ac(e,t,{config:n,bus:r,a2aToken:o}){let i=new URL(e.url||"/","http://127.0.0.1"),a=(l,u)=>{t.writeHead(l,{"Content-Type":"application/json"}),t.end(JSON.stringify(u))};if(e.method==="GET"&&(i.pathname==="/"||i.pathname==="/health"))return a(200,{status:"ok",platforms:Object.keys(n.platforms||{}),a2a:!!r});if(!i.pathname.startsWith("/a2a"))return a(404,{error:"not found"});if(!r)return a(404,{error:"a2a bus not running (fewer than 2 agents configured)"});if(e.method==="GET"&&i.pathname==="/a2a")return a(200,{contract:"oracle-a2a/1",auth:"Authorization: Bearer <contents of a2a-token in the oracle config dir>",endpoints:["GET /a2a","GET /a2a/agents","POST /a2a/ask {to,text,from?}"],note:"consult-only; loopback-only; peers answer with information, never actions"});let c=String(e.headers.authorization||"");if(!o||c!==`Bearer ${o}`)return a(401,{error:"bad or missing bearer token (read a2a-token in the oracle config dir)"});if(e.method==="GET"&&i.pathname==="/a2a/agents")return a(200,{agents:r.roster()});if(e.method==="POST"&&i.pathname==="/a2a/ask"){let l="";e.on("data",u=>{l+=u,l.length>Ec&&e.destroy()}),e.on("end",async()=>{try{let u=JSON.parse(l||"{}"),d=kc(u.from);r.agents.has(d)||r.register(d,{role:"loopback client",handler:async()=>null});let s=await r.send({from:d,to:u.to,text:u.text,kind:"consult"});return a(s.ok?200:400,s)}catch(u){return a(400,{ok:!1,error:`bad request: ${u.message}`})}});return}return a(404,{error:"not found"})}function kc(e){return String(e||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function _c(e=ht){let t=We(e,"a2a-token");try{let r=yn(t,"utf8").trim();if(r)return r}catch{}let n=hc(24).toString("hex");return pc(e,{recursive:!0}),fc(t,`${n}
60
+ `,{mode:384}),n}var{pathToFileURL:Ic}=await import("node:url"),{realpathSync:Cc}=await import("node:fs"),To=process.argv[1],hn=!1;if(To)try{hn=import.meta.url===Ic(Cc(To)).href}catch{hn=!1}hn&&xc().catch(e=>{process.stderr.write(`oracle-gateway: ${e.message}
61
+ `),process.exit(1)});export{Sc as createGatewayShutdown,_c as ensureA2AToken,gc as heldNftPumpEnabled,bc as heldNftSubscriptionStatePath,wc as preferredMessagingPlatform,Ac as serveHttp,mn as toEntries};