@oracle-agent/oracle 0.35.42 → 0.35.43

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 (42) hide show
  1. package/dist/agent-sessions.mjs +25 -24
  2. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  3. package/dist/bin/desk-server.mjs +27 -27
  4. package/dist/bin/oracle-data-mcp.mjs +18 -18
  5. package/dist/bin/oracle-gateway.mjs +44 -44
  6. package/dist/bin/oracle-launch-radar-shadow.mjs +6 -6
  7. package/dist/bin/oracle-public-server.mjs +5 -5
  8. package/dist/bin/oracle-route.mjs +16 -16
  9. package/dist/bin/oracle.mjs +12 -12
  10. package/dist/cli/commands/agent-session.mjs +27 -26
  11. package/dist/cli/commands/chat.mjs +245 -224
  12. package/dist/cli/commands/eval.mjs +181 -161
  13. package/dist/cli/commands/mint.mjs +11 -11
  14. package/dist/cli/commands/model.mjs +249 -228
  15. package/dist/cli/commands/sign.mjs +14 -14
  16. package/dist/cli/commands/signer.mjs +22 -22
  17. package/dist/cli/commands/swap.mjs +13 -13
  18. package/dist/cli/commands/venues.mjs +2 -2
  19. package/dist/data/desk-data.mjs +25 -25
  20. package/dist/index.mjs +46 -46
  21. package/dist/launch-radar/index.mjs +5 -5
  22. package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
  23. package/dist/local-signer/index.mjs +3 -3
  24. package/dist/local-signer/runtime.mjs +19 -19
  25. package/dist/router/prepare-route.mjs +3 -3
  26. package/dist/task.mjs +2 -2
  27. package/dist/teams/index.mjs +6 -6
  28. package/dist/tui/standalone-client.mjs +115 -95
  29. package/package.json +1 -1
  30. package/public/oracle-splash/docs/browser-and-web/index.html +2 -2
  31. package/public/oracle-splash/docs/connectors/index.html +2 -2
  32. package/public/oracle-splash/docs/getting-started/index.html +2 -2
  33. package/public/oracle-splash/docs/index.html +3 -3
  34. package/public/oracle-splash/docs/reference/index.html +2 -2
  35. package/public/oracle-splash/docs/security/index.html +2 -2
  36. package/public/oracle-splash/docs/using-oracle/index.html +2 -2
  37. package/public/oracle-splash/eval/benchmarks/evm-escrow-20260827.json +170 -0
  38. package/public/oracle-splash/eval/eval-story.css +722 -0
  39. package/public/oracle-splash/eval/eval-story.js +198 -0
  40. package/public/oracle-splash/eval/index.html +49 -11
  41. package/public/oracle-splash/eval/live-eval.js +546 -0
  42. package/server.json +2 -2
@@ -1,61 +1,61 @@
1
1
  #!/usr/bin/env node
2
- var Bo=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 ye=(e,t)=>{for(var n in t)Bo(e,n,{get:t[n],enumerable:!0})};import ae from"node:net";import Do from"node:dns";function Xe(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 xt(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 Et(e){if(ae.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(ae.isIPv6(e)){let t=Xe(e);if(!t)return!1;let n=Xe("::ffff:0:0");return xt(t,n,96)?Et([...t.slice(12)].join(".")):xt(t,Xe("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>xt(t,Xe(o),i)):!1}return!1}function Ho(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(jo.has(n)||n.endsWith(".localhost")||n.endsWith(".internal"))return{ok:!1,error:`refused internal host ${n}`};let r=ae.isIP(n);return r!==0&&!Et(n)?{ok:!1,error:`refused private address ${n}`}:{ok:!0,url:t,host:n,isLiteralIp:r!==0}}async function At(e,{lookupFn:t=Do.promises.lookup}={}){let n=Ho(e);if(!n.ok)return n;if(n.isLiteralIp)return{ok:!0,url:n.url,addresses:[{address:n.host,family:ae.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=>!Et(o.address))?{ok:!1,error:`refused: ${n.host} resolves to a non-public address`}:{ok:!0,url:n.url,addresses:r}}async function kt({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||(ae.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(ae.isIP(p))return[{address:p,family:ae.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=Vo((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 Vo(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[_t]=Object.freeze({pin:t}),e}function It(e){return typeof e=="function"&&typeof e[_t]?.pin=="function"}function kn(e,t,n){if(!It(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[_t].pin(t,n)}var jo,_t,_n=$(()=>{jo=new Set(["localhost","metadata.google.internal","metadata.goog"]);_t=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as zo}from"node:crypto";import{types as J}from"node:util";function F(e){return te(`HTTP JSON body refused: ${e}`)}function ei(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 ti(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(ei(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 ni(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 ri(){return Object.assign(Object.create(null),{Accept:"application/json"})}function oi(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 ii(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Ze(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=Nn.get(e);return t||(t=$n,$n+=1,Nn.set(e,t)),`reference:${t}`}function Pn(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?ai.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 Rn(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(Pn);if(!n||typeof n!="object")return!1;if(Object.hasOwn(n,"jsonrpc")||Object.hasOwn(n,"method"))return Pn(n);let r=Object.hasOwn(n,"type")?n.type:null;return typeof r=="string"&&si.has(r)&&(!Object.hasOwn(n,"action")||n.action==null)&&(!Object.hasOwn(n,"signature")||n.signature==null)&&(!Object.hasOwn(n,"nonce")||n.nonce==null)}function ci(e,t,n,r={},o=null){let i=zo("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 li(e,t){let n=Number(t);return Number.isFinite(n)&&n>0?Math.min(n*1e3,Cn):Math.min(250*2**e,Cn)+Math.floor(Math.random()*100)}function te(e,t={}){let n=new Error(e);return n.retryable=!1,Object.assign(n,t),n}function Tt(e,t,n){return te(`HTTP response from ${e} exceeded maxResponseBytes ${n} (${t})`,{oversize:!0})}function se(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function di(e){return e?e.byteLength??e.length??0:0}async function pi(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&&(se(e),!r))throw Tt(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 Tt(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+=di(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 Tt(n,`streamed ${l} bytes`,t);let d=Buffer.concat(c);return(u?d.subarray(0,t):d).toString("utf8")}function fi(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function mi(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=et}){let E=null,A=t,T=a?{lookupFn:a}:{};if(l&&!c&&!It(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 x=new AbortController,f=setTimeout(()=>x.abort(),i),S=m?On?On([m,x.signal]):m:x.signal,b=async(v,{status:I=null}={})=>{let O=await At(v,T);if(!O.ok)throw te(I==null?`HTTP refused ${v}: ${O.error}`:`HTTP redirect to ${v} ${O.error}`,I==null?{}:{status:I});let P=new URL(v).hostname;if(c){if(E&&(await E.close(),E=null),!E)try{E=await kt({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})}E.pin(P,O.addresses),A=E.fetch}else kn(A,P,O.addresses);return O};try{let v=String(e),I=Object.assign(Object.create(null),r||{});l&&await b(v);for(let O=0;O<=w;O+=1){let P=Object.assign(Object.create(null),{method:n,headers:I,body:o,signal:S,redirect:"manual",dispatcher:void 0}),h=await A(v,P);if((g==="error"||w===0)&&h.status>=300&&h.status<400)throw se(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)&&Rn(n,o);if(n!=="GET"&&n!=="HEAD"&&!R){se(h);let L=new Error(`HTTP ${h.status} ${n} ${v} redirected non-idempotent request`);throw L.status=h.status,L}if(O===w)throw se(h),te(`HTTP ${h.status} ${n} redirect budget exhausted`,{status:h.status,redirectRefused:!0});let q=h.headers?.get?.("location"),V;try{V=oi(q,v)}catch(L){throw se(h),L}let z=!ii(V,v);if(se(h),z&&n==="POST"){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L}if(z&&d){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L.retryable=!1,L}if(z&&(I=ri(I)),l)await b(V,{status:h.status});else if(z){let L=await At(V,T);if(!L.ok){let _=new Error(`HTTP redirect from ${v} ${L.error}`);throw _.status=h.status,_.retryable=!1,_}c&&L.addresses?.length&&(E||(E=await kt(s?{importUndici:s}:{})),E&&(E.pin(new URL(V).hostname,L.addresses),A=E.fetch))}v=V;continue}if(typeof p=="function")try{await p(h,{url:v})}catch(R){throw se(h),te(R?.message||String(R))}let k=await pi(h,u,{url:v,onOversize:()=>x.abort()}),M=fi(k);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??k.slice(0,300),R}return M??k}throw new Error(`HTTP redirect loop for ${e}`)}catch(v){if(x.signal.aborted&&!Le(m)){let I=v&&(typeof v=="object"||typeof v=="function")&&!J.isProxy(v)?v: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 v}finally{clearTimeout(f),E&&await E.close()}}async function j(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>et))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${et}`);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??et;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{Le(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=ni(A),x=Object.assign(Object.create(null),T);Object.keys(x).some(_=>_.toLowerCase()==="accept")||(x.Accept="application/json");let f=r("body");f!=null&&typeof f!="string"&&(Object.keys(x).find(U=>U.toLowerCase()==="content-type")||(x["Content-Type"]="application/json"),f=ti(f));let S=a??Go,b=r("lookupFn"),v=!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<=S;U++){k&&Jo.call(k);try{return await mi(e,{fetchImpl:g,method:E,headers:x,body:f,timeoutMs:w,lookupFn:b,realFetch:v,untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:O,importUndici:P,validateResponse:h,signal:k,redirectPolicy:u,maxRedirects:d})}catch(K){_=K;let he=bt=>{if(!K||typeof K!="object"&&typeof K!="function"||J.isProxy(K))return;let Pe=Object.getOwnPropertyDescriptor(K,bt);return Pe&&Object.hasOwn(Pe,"value")?Pe.value:void 0},wt=he("status"),Uo=he("oracleTimeout")===!0||he("name")==="AbortError"||he("name")==="TimeoutError"||Le(k),Fo=new Set([408,425,429]),Mo=he("retryable")===!1?!1:wt!=null?Fo.has(wt)||Wo.has(wt)&&In.has(E):!Uo&&In.has(E);if(U===S||!Mo)throw K;let bn=li(U,he("retryAfter"));k?await new Promise((bt,Pe)=>{let Sn,Re=()=>{clearTimeout(Sn),Tn.call(k,"abort",Re),Pe(Xo(k)||new DOMException("Aborted","AbortError"))};if(Le(k)){Re();return}Sn=setTimeout(()=>{Tn.call(k,"abort",Re),bt()},bn),Qo.call(k,"abort",Re,{once:!0}),Le(k)&&Re()}):await ui(bn)}}throw _};if(!(r("dedupe")!==!1&&!k&&Rn(E,f)))return R();let V=ci(E,e,x,{untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:O,redirectPolicy:u,maxRedirects:d,timeoutMs:w,retries:S,fetchImpl:Ze(g),realFetch:v,lookupFn:Ze(b),importUndici:Ze(P),validateResponse:Ze(h)},f),z=Ct.get(V);if(z)return z;let L=R().finally(()=>Ct.delete(V));return Ct.set(V,L),L}async function tt(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 Ue(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 Wo,In,Go,Cn,Ko,Yo,Jo,Qo,Tn,On,Le,Xo,Zo,et,Jc,Y,Ct,Nn,$n,ai,si,ui,H=$(()=>{_n();Wo=new Set([408,425,429,500,502,503,504]),In=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Go=2,Cn=4e3,Ko=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Yo=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Jo=AbortSignal.prototype.throwIfAborted,Qo=EventTarget.prototype.addEventListener,Tn=EventTarget.prototype.removeEventListener,On=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,Le=e=>e?Ko.call(e):!1,Xo=e=>e?Yo.call(e):void 0,Zo=new Set([301,302,303,307,308]),et=3,Jc=64*1024,Y=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});Ct=new Map,Nn=new WeakMap,$n=1;ai=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),si=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);ui=e=>new Promise(t=>setTimeout(t,e))});function Nt(e){return Si.get(Number(e))||null}var Bn,Si,$t=$(()=>{Bn={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(Bn).map(e=>[e.chainId,e]))});import{Interface as vi,getAddress as pl}from"ethers";var fl,Fe=$(()=>{H();$t();fl=new vi(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});function le(e,t=160){return String(e??"").replace(/[\u0000-\u001f\u007f]/g," ").slice(0,t)}function qt(e){let t=Number(e);return Number.isFinite(t)?t:null}function Se(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 Aa(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",n=qt(e.fromFloor),r=qt(e.floor),o=qt(e.changePct),i=le(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
2
+ var jo=Object.defineProperty;var T=(e,t,n)=>()=>{if(n)throw n[0];try{return e&&(t=e(e=0)),t}catch(r){throw n=[r],r}};var ye=(e,t)=>{for(var n in t)jo(e,n,{get:t[n],enumerable:!0})};import se from"node:net";import Vo from"node:dns";function Ze(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let n=d=>{if(!d)return[];let a=d.split(":"),p=a.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;a.splice(a.length-1,1,(m[0]<<8|m[1]).toString(16),(m[2]<<8|m[3]).toString(16))}return a.some(m=>!/^[0-9a-f]{1,4}$/.test(m))?null:a.map(m=>Number.parseInt(m,16))},[r,o]=t.split("::"),i=n(r),s=n(o);if(!i||!s)return null;let c=t.includes("::"),l=8-i.length-s.length;if(!c&&l!==0||c&&l<1)return null;let u=[...i,...Array(Math.max(0,l)).fill(0),...s];return u.length!==8?null:Uint8Array.from(u.flatMap(d=>[d>>8,d&255]))}function xt(e,t,n){let r=Math.floor(n/8),o=n%8;for(let s=0;s<r;s+=1)if(e[s]!==t[s])return!1;if(!o)return!0;let i=255<<8-o;return(e[r]&i)===(t[r]&i)}function At(e){if(se.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(se.isIPv6(e)){let t=Ze(e);if(!t)return!1;let n=Ze("::ffff:0:0");return xt(t,n,96)?At([...t.slice(12)].join(".")):xt(t,Ze("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>xt(t,Ze(o),i)):!1}return!1}function Wo(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(zo.has(n)||n.endsWith(".localhost")||n.endsWith(".internal"))return{ok:!1,error:`refused internal host ${n}`};let r=se.isIP(n);return r!==0&&!At(n)?{ok:!1,error:`refused private address ${n}`}:{ok:!0,url:t,host:n,isLiteralIp:r!==0}}async function kt(e,{lookupFn:t=Vo.promises.lookup}={}){let n=Wo(e);if(!n.ok)return n;if(n.isLiteralIp)return{ok:!0,url:n.url,addresses:[{address:n.host,family:se.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=>!At(o.address))?{ok:!1,error:`refused: ${n.host} resolves to a non-public address`}:{ok:!0,url:n.url,addresses:r}}async function It({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let n,r;try{let a=await t();n=a.Agent,r=a.fetch}catch(a){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${a?.message||a}`);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=a=>String(a).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=a=>(Array.isArray(a)?a:[a]).map(p=>typeof p=="string"?{address:p}:p).filter(p=>p&&p.address).map(p=>({address:p.address,family:p.family||(se.isIPv6(p.address)?6:4)})),c=(a,p,m)=>{i.set(o(a),s(typeof p=="string"?[{address:p,family:m}]:p))},l=a=>{let p=o(a);if(se.isIP(p))return[{address:p,family:se.isIPv6(p)?6:4}];let m=i.get(p);if(!m||!m.length)throw new Error(`refused: unpinned host ${a} during pinned fetch`);return m},u=new n({connect:{lookup(a,p,m){let g;try{g=l(a)}catch(w){return m(w)}return p?.all?m(null,g):m(null,g[0].address,g[0].family)}}}),d=Go((a,p={})=>r(a,{...p,dispatcher:u}),c);return{dispatcher:u,fetch:d,pin:c,resolve:l,async close(){try{await u.destroy()}catch{}}}}function Go(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[_t]=Object.freeze({pin:t}),e}function Ct(e){return typeof e=="function"&&typeof e[_t]?.pin=="function"}function In(e,t,n){if(!Ct(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[_t].pin(t,n)}var zo,_t,_n=T(()=>{zo=new Set(["localhost","metadata.google.internal","metadata.goog"]);_t=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as Ko}from"node:crypto";import{types as J}from"node:util";function F(e){return te(`HTTP JSON body refused: ${e}`)}function ri(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 oi(e){let t=[],n=0,r=0,o=0,i=0,s=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,a)=>{if(r+=1,r>Y.nodes)throw F("node limit exceeded");if(a>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(ri(d))throw F("unsupported exotic object");if(s.has(d))throw F("cyclic value");s.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 O=Object.getOwnPropertyDescriptor(d,String(A));if(!O||!Object.hasOwn(O,"value")||O.enumerable!==!0)throw F("array entries must be dense enumerable own data")}let x=0;for(let A in d){if(i+=1,i>Y.fields)throw F("enumeration limit exceeded");if(Object.hasOwn(d,A)&&(x+=1,x>d.length))throw F("named array fields are unsupported")}if(x!==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,a+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],a+1);c("}")}finally{s.delete(d)}};return u(e,0),t.join("")}function ii(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 s=i.value;if(s==null||["object","function","symbol"].includes(typeof s))throw new TypeError("HTTP header values must be scalar");t[r]=String(s)}return t}function si(){return Object.assign(Object.create(null),{Accept:"application/json"})}function ai(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 ci(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function et(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=$n.get(e);return t||(t=Pn,Pn+=1,$n.set(e,t)),`reference:${t}`}function Rn(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?li.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 Ln(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(Rn);if(!n||typeof n!="object")return!1;if(Object.hasOwn(n,"jsonrpc")||Object.hasOwn(n,"method"))return Rn(n);let r=Object.hasOwn(n,"type")?n.type:null;return typeof r=="string"&&ui.has(r)&&(!Object.hasOwn(n,"action")||n.action==null)&&(!Object.hasOwn(n,"signature")||n.signature==null)&&(!Object.hasOwn(n,"nonce")||n.nonce==null)}function di(e,t,n,r={},o=null){let i=Ko("sha256"),s=(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
+ `)};s("method",e),s("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)=>{s(`header-name-${u}`,l.name),s(`header-value-${u}`,l.value)}),s("body",o??"-");for(let l of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])s(`context-${l}`,r[l]??"-");return i.digest("hex")}function pi(e,t){let n=Number(t);return Number.isFinite(n)&&n>0?Math.min(n*1e3,Tn):Math.min(250*2**e,Tn)+Math.floor(Math.random()*100)}function te(e,t={}){let n=new Error(e);return n.retryable=!1,Object.assign(n,t),n}function Ot(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 mi(e){return e?e.byteLength??e.length??0:0}async function hi(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 Ot(n,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let a=await e.text(),p=Buffer.byteLength(a,"utf8");if(p>t){if(!r)throw Ot(n,`body ${p} bytes`,t);return Buffer.from(a,"utf8").subarray(0,t).toString("utf8")}return a}let c=[],l=0,u=!1;try{for(;;){let{value:a,done:p}=await s.read();if(p)break;if(a&&(c.push(Buffer.from(a)),l+=mi(a),l>t)){u=!0;break}}}finally{if(u)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!r))throw Ot(n,`streamed ${l} bytes`,t);let d=Buffer.concat(c);return(u?d.subarray(0,t):d).toString("utf8")}function yi(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function gi(e,{fetchImpl:t,method:n,headers:r,body:o,timeoutMs:i,lookupFn:s,realFetch:c,untrustedUrl:l=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:d=!1,importUndici:a,validateResponse:p,signal:m,redirectPolicy:g="follow",maxRedirects:w=tt}){let x=null,A=t,O=s?{lookupFn:s}:{};if(l&&!c&&!Ct(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),S=m?Nn?Nn([m,v.signal]):m:v.signal,b=async(E,{status:_=null}={})=>{let N=await kt(E,O);if(!N.ok)throw te(_==null?`HTTP refused ${E}: ${N.error}`:`HTTP redirect to ${E} ${N.error}`,_==null?{}:{status:_});let P=new URL(E).hostname;if(c){if(x&&(await x.close(),x=null),!x)try{x=await It({requireUndici:!0,...a?{importUndici:a}:{}})}catch(h){throw te(_==null?`HTTP refused ${E}: ${h?.message||h}`:`HTTP redirect to ${E} refused: ${h?.message||h}`,_==null?{}:{status:_})}x.pin(P,N.addresses),A=x.fetch}else In(A,P,N.addresses);return N};try{let E=String(e),_=Object.assign(Object.create(null),r||{});l&&await b(E);for(let N=0;N<=w;N+=1){let P=Object.assign(Object.create(null),{method:n,headers:_,body:o,signal:S,redirect:"manual",dispatcher:void 0}),h=await A(E,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(ni.has(h.status)){let R=d===!0&&n==="POST"&&[307,308].includes(h.status)&&Ln(n,o);if(n!=="GET"&&n!=="HEAD"&&!R){ae(h);let L=new Error(`HTTP ${h.status} ${n} ${E} redirected non-idempotent request`);throw L.status=h.status,L}if(N===w)throw ae(h),te(`HTTP ${h.status} ${n} redirect budget exhausted`,{status:h.status,redirectRefused:!0});let D=h.headers?.get?.("location"),V;try{V=ai(D,E)}catch(L){throw ae(h),L}let z=!ci(V,E);if(ae(h),z&&n==="POST"){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L}if(z&&d){let L=new Error(`HTTP ${h.status} ${n} cross-origin redirect refused`);throw L.status=h.status,L.retryable=!1,L}if(z&&(_=si(_)),l)await b(V,{status:h.status});else if(z){let L=await kt(V,O);if(!L.ok){let I=new Error(`HTTP redirect from ${E} ${L.error}`);throw I.status=h.status,I.retryable=!1,I}c&&L.addresses?.length&&(x||(x=await It(a?{importUndici:a}:{})),x&&(x.pin(new URL(V).hostname,L.addresses),A=x.fetch))}E=V;continue}if(typeof p=="function")try{await p(h,{url:E})}catch(R){throw ae(h),te(R?.message||String(R))}let k=await hi(h,u,{url:E,onOversize:()=>v.abort()}),M=yi(k);if(!h.ok){let R=new Error(`HTTP ${h.status} ${n} ${E}`);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(E){if(v.signal.aborted&&!Ue(m)){let _=E&&(typeof E=="object"||typeof E=="function")&&!J.isProxy(E)?E:null,N=_?Object.getOwnPropertyDescriptor(_,"oversize"):null;if(!(N&&Object.hasOwn(N,"value")&&N.value===!0))try{if(!_)throw new TypeError("unsafe rejection");Object.defineProperties(_,{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 E}finally{clearTimeout(f),x&&await x.close()}}async function j(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 I of Object.getOwnPropertyNames(t)){let U=Object.getOwnPropertyDescriptor(t,I);if(!(I==="toJSON"&&U&&Object.hasOwn(U,"value")&&U.value===void 0)){if(!n.has(I))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=I=>{if(t==null||!Object.hasOwn(t,I))return;let U=Object.getOwnPropertyDescriptor(t,I);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 s=r("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>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>tt))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${tt}`);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??tt;for(let I of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let U=r(I);if(U!==void 0&&typeof U!="boolean")throw new TypeError(`HTTP ${I} must be boolean`)}let a=r("maxResponseBytes");if(a!==void 0&&(!Number.isInteger(a)||a<1||a>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{Ue(p)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let I of["importUndici","lookupFn","validateResponse"]){let U=r(I);if(U!==void 0&&typeof U!="function")throw new TypeError(`HTTP ${I} 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,x=(o||"GET").toUpperCase(),A=r("headers"),O=ii(A),v=Object.assign(Object.create(null),O);Object.keys(v).some(I=>I.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=oi(f));let S=s??Jo,b=r("lookupFn"),E=!m,_=r("untrustedUrl")===!0,N=r("sameOriginRedirectsOnly")===!0,P=r("importUndici"),h=r("validateResponse"),k=p,M=a??null,R=async()=>{let I;for(let U=0;U<=S;U++){k&&Zo.call(k);try{return await gi(e,{fetchImpl:g,method:x,headers:v,body:f,timeoutMs:w,lookupFn:b,realFetch:E,untrustedUrl:_,maxResponseBytes:M,sameOriginRedirectsOnly:N,importUndici:P,validateResponse:h,signal:k,redirectPolicy:u,maxRedirects:d})}catch(K){I=K;let he=St=>{if(!K||typeof K!="object"&&typeof K!="function"||J.isProxy(K))return;let Re=Object.getOwnPropertyDescriptor(K,St);return Re&&Object.hasOwn(Re,"value")?Re.value:void 0},bt=he("status"),Bo=he("oracleTimeout")===!0||he("name")==="AbortError"||he("name")==="TimeoutError"||Ue(k),Do=new Set([408,425,429]),qo=he("retryable")===!1?!1:bt!=null?Do.has(bt)||Yo.has(bt)&&Cn.has(x):!Bo&&Cn.has(x);if(U===S||!qo)throw K;let Sn=pi(U,he("retryAfter"));k?await new Promise((St,Re)=>{let En,Le=()=>{clearTimeout(En),On.call(k,"abort",Le),Re(ti(k)||new DOMException("Aborted","AbortError"))};if(Ue(k)){Le();return}En=setTimeout(()=>{On.call(k,"abort",Le),St()},Sn),ei.call(k,"abort",Le,{once:!0}),Ue(k)&&Le()}):await fi(Sn)}}throw I};if(!(r("dedupe")!==!1&&!k&&Ln(x,f)))return R();let V=di(x,e,v,{untrustedUrl:_,maxResponseBytes:M,sameOriginRedirectsOnly:N,redirectPolicy:u,maxRedirects:d,timeoutMs:w,retries:S,fetchImpl:et(g),realFetch:E,lookupFn:et(b),importUndici:et(P),validateResponse:et(h)},f),z=Tt.get(V);if(z)return z;let L=R().finally(()=>Tt.delete(V));return Tt.set(V,L),L}async function nt(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 Fe(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),s=0;return await Promise.all(Array.from({length:o},async()=>{for(;s<r.length;){let c=s++;i[c]=await n(r[c],c)}})),i}var Yo,Cn,Jo,Tn,Qo,Xo,Zo,ei,On,Nn,Ue,ti,ni,tt,Zc,Y,Tt,$n,Pn,li,ui,fi,H=T(()=>{_n();Yo=new Set([408,425,429,500,502,503,504]),Cn=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Jo=2,Tn=4e3,Qo=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Xo=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Zo=AbortSignal.prototype.throwIfAborted,ei=EventTarget.prototype.addEventListener,On=EventTarget.prototype.removeEventListener,Nn=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,Ue=e=>e?Qo.call(e):!1,ti=e=>e?Xo.call(e):void 0,ni=new Set([301,302,303,307,308]),tt=3,Zc=64*1024,Y=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});Tt=new Map,$n=new WeakMap,Pn=1;li=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),ui=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);fi=e=>new Promise(t=>setTimeout(t,e))});function $t(e){return xi.get(Number(e))||null}var Dn,xi,Pt=T(()=>{Dn={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}},xi=new Map(Object.values(Dn).map(e=>[e.chainId,e]))});import{Interface as Ai,getAddress as hl}from"ethers";var yl,Me=T(()=>{H();Pt();yl=new Ai(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});var Li,nd,be=T(()=>{Li=300*1e3,nd=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});function le(e,t=160){return String(e??"").replace(/[\u0000-\u001f\u007f]/g," ").slice(0,t)}function qt(e){let t=Number(e);return Number.isFinite(t)?t:null}function Ee(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(s=>s.trim()).filter(Boolean))]}function _s(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",n=qt(e.fromFloor),r=qt(e.floor),o=qt(e.changePct),i=le(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
4
4
 
5
5
  ${[`Collection: ${le(e.name||e.slug||"Unknown")}`,`Chain: ${le(e.chain||"unknown")}`,`You hold: ${t}`,`Floor: ${n??"unknown"} \u2192 ${r??"unknown"} ${i}`,`Move: ${o===null?"unknown":`+${o}%`}`,`Contract: ${le(e.contract||"unknown",64)}`,"Evidence: provider-estimated floor; not an executable bid or guaranteed liquidation value."].join(`
6
- `)}`}function sr(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=le(String(c.platform||"").toLowerCase(),32);if(u)return Object.freeze({platform:u,recipientId:l[0],target:c})}return null}function cr(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=le(e.platform||t.platform||"unknown",32);return async function(i){let a=Aa(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 lr({watchdog:e,intervalMs:t=3e5,setIntervalFn:n=setInterval,clearIntervalFn:r=clearInterval,onError:o=i=>process.stderr.write(`oracle-gateway: held NFT watchdog failed: ${le(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 Be=$(()=>{});var ur={};ye(ur,{A2ABus:()=>Dt,normalizeName:()=>qe});function qe(e){return String(e||"").trim().toLowerCase().replace(/^@/,"")}var Dt,dr=$(()=>{Dt=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=qe(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(qe(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=qe(t),c=qe(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 De from"node:fs";import ka from"node:os";import xe from"node:path";import{fileURLToPath as _a}from"node:url";function jt(){return process.env.ORACLE_FAKE_HOME||ka.homedir()}function Ca(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function Q(){return Ca()?process.env.ORACLE_CONFIG_DIR||xe.join(jt(),".config","oracle"):xe.join(jt(),".config","oracle")}function Ta(){return xe.join(Q(),"desk.json")}function Oa(){return xe.join(Q(),"env")}function ve({force:e=!1}={}){if(ve._done&&!e)return ve._result||null;ve._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=Oa();if(De.existsSync(o))for(let i of De.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=Ta();if(De.existsSync(o)){let i=JSON.parse(De.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)),ve._result=Object.keys(t).length?t:null,ve._result}function ct(e){return De.mkdirSync(e,{recursive:!0}),e}var Ia,cp,lt=$(()=>{Ia=xe.dirname(_a(import.meta.url)),cp=xe.resolve(Ia,"../..");try{ve()}catch{}});function ut(e){return String(e||"").trim()||void 0}function $a(e,{required:t=!1}={}){let n=ut(e)?.toLowerCase();if(!n){if(t)throw new Error("model provider is required");return}if(!Na.has(n))throw new Error(`unsupported provider: ${n}`);return n}function Pa(e,{required:t=!1}={}){let n=ut(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 Ra(e){let t=ut(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 pr({provider:e,model:t,baseUrl:n}={},{requireModel:r=!1}={}){let o=$a(e),i=Pa(t,{required:r});if(o==="custom")return{provider:o,...i?{model:i}:{},baseUrl:Ra(n)};if(ut(n))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...i?{model:i}:{}}}var Na,fr=$(()=>{Na=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import Ae from"node:fs";import Ht from"node:path";function mr(){return Ht.join(Q(),"model.json")}function Ee(e){return String(e||"").trim()||void 0}function hr(e={}){let t=Ee(e.backend)?.toLowerCase()||"auto",n=pr({provider:e.provider,model:e.model,baseUrl:e.baseUrl},{requireModel:t==="standalone"}),r=Ee(e.apiKeyEnv),o=Number.parseInt(String(e.contextLength||""),10),i=Object.fromEntries(Object.entries(e.contextByModel||{}).filter(([,d])=>Number.isSafeInteger(d)&&d>0)),a=Ee(e.reasoningEffort),c=Ee(e.computeHost||e.remoteHost),l=Ee(e.computeUser||e.remoteUser),u=Ee(e.computePath||e.remotePath);if(!La.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"&&!c)throw new Error("remote backend requires computeHost");return{backend:t,...n,...r?{apiKeyEnv:r}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...Object.keys(i).length?{contextByModel:i}:{},...a?{reasoningEffort:a}:{},...c?{computeHost:c}:{},...l?{computeUser:l}:{},...u?{computePath:u}:{}}}function ke(){let e=mr();if(!Ae.existsSync(e))return null;try{return hr(JSON.parse(Ae.readFileSync(e,"utf8")))}catch{return null}}function Vt(e){let t=hr(e),n=mr();ct(Ht.dirname(n)),process.platform!=="win32"&&Ae.chmodSync(Ht.dirname(n),448);let r=`${n}.${process.pid}.tmp`;return Ae.writeFileSync(r,`${JSON.stringify(t,null,2)}
8
- `,{mode:384}),Ae.renameSync(r,n),process.platform!=="win32"&&Ae.chmodSync(n,384),t}var La,yr=$(()=>{lt();fr();La=new Set(["auto","standalone","hermes","remote","arch"])});import{existsSync as Ua,readFileSync as Fa}from"node:fs";import{request as Ma}from"node:http";import Ba from"node:path";function Da(e=process.env){let t=String(e.ORACLE_SIGNER_URL||qa).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 ja(e=process.env){if(e.ORACLE_SIGNER_TOKEN)return String(e.ORACLE_SIGNER_TOKEN);let t=Ba.join(Q(),"signer","signer-token");return Ua(t)?Fa(t,"utf8").trim():null}function ue(e,{method:t="GET",body:n=null,env:r=process.env,timeoutMs:o=4e3}={}){let i=Da(r),a=ja(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=Ma({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 qa,dt=$(()=>{lt();qa="http://127.0.0.1:9462"});function Va(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 gr(e,{coin:t,side:n,sizeUsd:r,leverage:o,venue:i,confirm:a,user:c}={}){let l=Va(e);if(!l)return null;if(t&&Ha.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 Ha,zt=$(()=>{Ha=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var Ap,kp,wr=$(()=>{zt();Ap=Object.freeze([100,50,25]),kp=Object.freeze([100,50,25,10])});function y(e){return B(e)?String(e).replace(za,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 de(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=de(e,{decimals:t});return n===C?C:`${n} USD`}function Wt(e,{decimals:t=2}={}){let n=de(e,{decimals:t});return n===C?C:`${n}%`}function pt(e){let t=de(e,{decimals:0});return t===C?C:`${t} bps`}function pe(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 Gt(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 re(e={}){let t=e.chainId;if(!B(t)||!Number.isFinite(Number(t)))return B(e.chain)?y(e.chain):C;let r=Nt(t)?.name||(B(e.chain)?String(e.chain):C);return`${y(r)} (chainId ${Number(t)})`}function br(e={}){return y(e.venue??e.dex??e.pool?.venue)}function Wa(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 fe(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 Ga(e){let t=fe(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: ${Wa(n.chart)}`),r.push(`Actions: ${Ga(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=Gt(e.confidence);return t===C?null:["Confidence",t]}function Ka(e){let t=e.quote;if(!t||typeof t!="object")return[];let n=B(t.decimals)?pe(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 Sr(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",C];let n=pt(t.selectedBps),r=pt(t.capBps);return["Auto-slippage",n===C&&r===C?C:`${n} selected, cap ${r}`]}function Ya(e={}){let t=e||{};return X(`ORACLE TOKEN \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",re(t)],["Venue",br(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",Wt(t.priceChange24h)],["Fee tier",B(t.feeTier)?`${pt(Number(t.feeTier)/100)} (${de(t.feeTier,{decimals:0})})`:C],["Age",y(t.age)],...Ka(t),Sr(t),Z(t)],t)}function Ja(e={}){let t=e||{};return X(`ORACLE LAUNCH \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",re(t)],["Venue",br(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)],Sr(t),Z(t)],t)}function Qa(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",Wt(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 Xa(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",Wt(t.edge)],["Position",y(t.position)],Z(t)],t)}function Za(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 es(e={}){let t=e||{},n=B(t.completedSplits)&&B(t.totalSplits)?`${de(t.completedSplits,{decimals:0})} / ${de(t.totalSplits,{decimals:0})}`:C;return X(`ORACLE TWAP \u2014 ${y(t.pair??t.symbol??t.name)}`,[["Chain",re(t)],["Side",y(t.side??t.direction)],["Amount",`${y(pe(t.amountTotal??t.amount,t.decimals??18))} ${y(t.symbol??"")}`.trim()],["Splits",`${de(t.totalSplits,{decimals:0})} over ${y(t.window)}`],["Progress",n],["Avg price",D(t.averagePrice,{decimals:6})],["Next split",y(t.nextSplitAt)],["Slippage cap",pt(t.slippageBps)],["Status",y(t.status)],Z(t)],t)}function ts(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",re({chainId:t.fromChainId,chain:t.fromChain})],["To chain",re({chainId:t.toChainId,chain:t.toChain})],["Amount",`${y(pe(t.amount,t.fromDecimals??18))} ${y(t.fromSymbol??"")}`.trim()],["Best route",y(t.bestRoute??t.winner)],["Est. received",`${y(pe(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 ns(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 rs(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return B(t)?y(t):C}function os(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",re({chainId:t.chainId??n.chainId,chain:t.chain??n.chain})],["Pair",i],["Amount in",`${y(pe(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(pe(o.netOut??o.amountOut??n.amountOut,t.decimalsOut??18))} ${y(t.tokenOutSymbol??"")}`.trim()],["Ranked on",rs(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",ns(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(pe(c.netOut??c.amountOut??r.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${y(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",re({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 Kt(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",re({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 Yt({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,Op,za,Np,Jt=$(()=>{$t();wr();C="UNKNOWN",Op=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),za=/[_*[\]`]/g;Np=Object.freeze({token:Ya,launch:Ja,hip3:Qa,hip4:Xa,polymarket:Za,twap:es,bridge:ts,swap:os,approve:Kt})});function Qt(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 Xt(e,{platform:t,grant:n,armed:r}){if(!e.length)return{text:"No pending local-signer artifacts.",buttons:Yt({platform:t,hasGrant:!1})};let o=e[0];return{text:e.map(a=>Kt({...a,armed:r,grant:n,confidence:r?"high":"medium"})).join(`
6
+ `)}`}function cr(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"),s=o.length?o:i.length?i:n;for(let c of s){let l=[...new Set((Array.isArray(c.ownerIds)?c.ownerIds:[]).map(d=>String(d).trim()).filter(Boolean))];if(l.length!==1)continue;let u=le(String(c.platform||"").toLowerCase(),32);if(u)return Object.freeze({platform:u,recipientId:l[0],target:c})}return null}function lr(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=le(e.platform||t.platform||"unknown",32);return async function(i){let s=_s(i);try{let c=Number(await t.notifyRecipient(n,s,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 ur({watchdog:e,intervalMs:t=3e5,setIntervalFn:n=setInterval,clearIntervalFn:r=clearInterval,onError:o=i=>process.stderr.write(`oracle-gateway: held NFT watchdog failed: ${le(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,s=!1,c=async()=>{if(s)return{skipped:!0,reason:"tick-in-progress"};s=!0;try{return await e.tick()}catch(l){return o(l),{skipped:!0,reason:"tick-failed"}}finally{s=!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 De=T(()=>{});var dr={};ye(dr,{A2ABus:()=>jt,normalizeName:()=>qe});function qe(e){return String(e||"").trim().toLowerCase().replace(/^@/,"")}var jt,pr=T(()=>{jt=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=qe(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(qe(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 s=qe(t),c=qe(n);if(!s||!this.agents.has(s))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===s)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:s,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:s,to:c,kind:String(o),text:l,hops:u,ts:new Date().toISOString()};this.record(d);try{let a=await this.agents.get(c).handler(d);return a&&this.record({id:`${d.id}-reply`,from:c,to:s,kind:"reply",text:String(a).slice(0,8e3),hops:u,ts:new Date().toISOString()}),{ok:!0,reply:a||null,id:d.id}}catch(a){return{ok:!1,error:`a2a: '${c}' handler failed: ${a.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 je from"node:fs";import Cs from"node:os";import xe from"node:path";import{fileURLToPath as Ts}from"node:url";function Ht(){return process.env.ORACLE_FAKE_HOME||Cs.homedir()}function Ns(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function Q(){return Ns()?process.env.ORACLE_CONFIG_DIR||xe.join(Ht(),".config","oracle"):xe.join(Ht(),".config","oracle")}function $s(){return xe.join(Q(),"desk.json")}function Ps(){return xe.join(Q(),"env")}function ve({force:e=!1}={}){if(ve._done&&!e)return ve._result||null;ve._done=!0;let t={},n=(o,i)=>{if(i==null)return;let s=String(i).trim();s&&(process.env[o]!=null&&String(process.env[o]).trim()!==""||(process.env[o]=s,t[o]=s))};try{let o=Ps();if(je.existsSync(o))for(let i of je.readFileSync(o,"utf8").split(/\r?\n/)){let s=i.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!s||s[2].startsWith("#"))continue;let c=s[2];(c.startsWith('"')&&c.endsWith('"')||c.startsWith("'")&&c.endsWith("'"))&&(c=c.slice(1,-1)),n(s[1],c)}}catch{}try{let o=$s();if(je.existsSync(o)){let i=JSON.parse(je.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)),ve._result=Object.keys(t).length?t:null,ve._result}function lt(e){return je.mkdirSync(e,{recursive:!0}),e}var Os,dp,ut=T(()=>{Os=xe.dirname(Ts(import.meta.url)),dp=xe.resolve(Os,"../..");try{ve()}catch{}});function dt(e){return String(e||"").trim()||void 0}function Ls(e,{required:t=!1}={}){let n=dt(e)?.toLowerCase();if(!n){if(t)throw new Error("model provider is required");return}if(!Rs.has(n))throw new Error(`unsupported provider: ${n}`);return n}function Us(e,{required:t=!1}={}){let n=dt(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 Fs(e){let t=dt(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 fr({provider:e,model:t,baseUrl:n}={},{requireModel:r=!1}={}){let o=Ls(e),i=Us(t,{required:r});if(o==="custom")return{provider:o,...i?{model:i}:{},baseUrl:Fs(n)};if(dt(n))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...i?{model:i}:{}}}var Rs,mr=T(()=>{Rs=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import ke from"node:fs";import Vt from"node:path";function hr(){return Vt.join(Q(),"model.json")}function Ae(e){return String(e||"").trim()||void 0}function yr(e={}){let t=Ae(e.backend)?.toLowerCase()||"auto",n=fr({provider:e.provider,model:e.model,baseUrl:e.baseUrl},{requireModel:t==="standalone"}),r=Ae(e.apiKeyEnv),o=Number.parseInt(String(e.contextLength||""),10),i=Object.fromEntries(Object.entries(e.contextByModel||{}).filter(([,d])=>Number.isSafeInteger(d)&&d>0)),s=Ae(e.reasoningEffort),c=Ae(e.computeHost||e.remoteHost),l=Ae(e.computeUser||e.remoteUser),u=Ae(e.computePath||e.remotePath);if(!Ms.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"&&!c)throw new Error("remote backend requires computeHost");return{backend:t,...n,...r?{apiKeyEnv:r}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...Object.keys(i).length?{contextByModel:i}:{},...s?{reasoningEffort:s}:{},...c?{computeHost:c}:{},...l?{computeUser:l}:{},...u?{computePath:u}:{}}}function Ie(){let e=hr();if(!ke.existsSync(e))return null;try{return yr(JSON.parse(ke.readFileSync(e,"utf8")))}catch{return null}}function zt(e){let t=yr(e),n=hr();lt(Vt.dirname(n)),process.platform!=="win32"&&ke.chmodSync(Vt.dirname(n),448);let r=`${n}.${process.pid}.tmp`;return ke.writeFileSync(r,`${JSON.stringify(t,null,2)}
8
+ `,{mode:384}),ke.renameSync(r,n),process.platform!=="win32"&&ke.chmodSync(n,384),t}var Ms,gr=T(()=>{ut();mr();Ms=new Set(["auto","standalone","hermes","remote","arch"])});var wr=T(()=>{});var kp,Ip,_p,Cp,br=T(()=>{wr();be();kp=Object.freeze({NONE:"none",PREPARE_CHECKSUM:"prepare-checksum",PREPARE_HMAC:"prepare-hmac"}),Ip=Object.freeze(["signature","signedTx","signedTransaction","rawTransaction","signedPayload","signedRaw"]),_p=Object.freeze(["txid","txHash","transactionHash","broadcastHash"]),Cp=Object.freeze(["tee-attestation","remote-attestation","hardware-enclave","trusted-execution-environment","execution-authorization","signature","broadcast"])});import{existsSync as Bs,readFileSync as Ds}from"node:fs";import{request as qs}from"node:http";import js from"node:path";function Vs(e=process.env){let t=String(e.ORACLE_SIGNER_URL||Hs).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 zs(e=process.env){if(e.ORACLE_SIGNER_TOKEN)return String(e.ORACLE_SIGNER_TOKEN);let t=js.join(Q(),"signer","signer-token");return Bs(t)?Ds(t,"utf8").trim():null}function ue(e,{method:t="GET",body:n=null,env:r=process.env,timeoutMs:o=4e3}={}){let i=Vs(r),s=zs(r);return!i||!s?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=qs({hostname:l.hostname,port:l.port||80,path:l.pathname,method:t,timeout:o,headers:{authorization:`Bearer ${s}`,origin:i,...u?{"content-type":"application/json","content-length":u.length}:{}}},a=>{let p=[];a.on("data",m=>p.push(m)),a.on("end",()=>{let m=Buffer.concat(p).toString("utf8"),g={};try{g=m?JSON.parse(m):{}}catch{g={error:"signer refused"}}c({httpStatus:a.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 Hs,pt=T(()=>{ut();br();Hs="http://127.0.0.1:9462"});function Gs(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 Sr(e,{coin:t,side:n,sizeUsd:r,leverage:o,venue:i,confirm:s,user:c}={}){let l=Gs(e);if(!l)return null;if(t&&Ws.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"),s&&/^[0-9a-f]{32}$/i.test(String(s))&&l.searchParams.set("confirm",String(s).toLowerCase()),c&&/^0x[0-9a-fA-F]{40}$/.test(String(c))&&l.searchParams.set("user",String(c).toLowerCase()),l.toString()}var Ws,Wt=T(()=>{Ws=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var Dp,qp,Er=T(()=>{Wt();Dp=Object.freeze([100,50,25]),qp=Object.freeze([100,50,25,10])});function y(e){return B(e)?String(e).replace(Ks,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 de(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 q(e,{decimals:t=2}={}){let n=de(e,{decimals:t});return n===C?C:`${n} USD`}function Gt(e,{decimals:t=2}={}){let n=de(e,{decimals:t});return n===C?C:`${n}%`}function ft(e){let t=de(e,{decimals:0});return t===C?C:`${t} bps`}function pe(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,s=10n**BigInt(n),c=(i/s).toString(),l=(i%s).toString().padStart(n,"0").replace(/0+$/,"");return`${o?"-":""}${c}${l?`.${l}`:""}`}function Kt(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 re(e={}){let t=e.chainId;if(!B(t)||!Number.isFinite(Number(t)))return B(e.chain)?y(e.chain):C;let r=$t(t)?.name||(B(e.chain)?String(e.chain):C);return`${y(r)} (chainId ${Number(t)})`}function vr(e={}){return y(e.venue??e.dex??e.pool?.venue)}function Ys(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 fe(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 Js(e){let t=fe(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,s]=o;r.push(`${i}: ${s==null||s===""?C:s}`)}return r.push(`Chart: ${Ys(n.chart)}`),r.push(`Actions: ${Js(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=Kt(e.confidence);return t===C?null:["Confidence",t]}function Qs(e){let t=e.quote;if(!t||typeof t!="object")return[];let n=B(t.decimals)?pe(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 xr(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",C];let n=ft(t.selectedBps),r=ft(t.capBps);return["Auto-slippage",n===C&&r===C?C:`${n} selected, cap ${r}`]}function Xs(e={}){let t=e||{};return X(`ORACLE TOKEN \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",re(t)],["Venue",vr(t)],["Name",y(t.name)],["Address",G(t.address??t.mint??t.contract)],["Price",q(t.priceUsd,{decimals:8})],["Market cap",q(t.marketCapUsd)],["Liquidity",q(t.liquidityUsd)],["Volume 24h",q(t.volume24hUsd)],["Change 24h",Gt(t.priceChange24h)],["Fee tier",B(t.feeTier)?`${ft(Number(t.feeTier)/100)} (${de(t.feeTier,{decimals:0})})`:C],["Age",y(t.age)],...Qs(t),xr(t),Z(t)],t)}function Zs(e={}){let t=e||{};return X(`ORACLE LAUNCH \u2014 ${y(t.symbol??t.token??t.name)}`,[["Chain",re(t)],["Venue",vr(t)],["Address",G(t.address??t.mint??t.contract)],["Pool",G(t.pool?.address??t.poolAddress??t.pool)],["Liquidity",q(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)],xr(t),Z(t)],t)}function ea(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",q(t.markPx,{decimals:6})],["Oracle",q(t.oraclePx,{decimals:6})],["Funding",Gt(t.funding,{decimals:6})],["Open interest",q(t.openInterestUsd)],["Depth",y(t.depth)],["Liquidation notes",y(t.liquidationNotes??t.riskNotes)],["Account context",y(t.accountContext)],Z(t)],t)}function ta(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",q(t.bid,{decimals:6})],["Ask",q(t.ask,{decimals:6})],["Depth",y(t.depth)],["Edge",Gt(t.edge)],["Position",y(t.position)],Z(t)],t)}function na(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",q(t.yesPrice,{decimals:4})],["No",q(t.noPrice,{decimals:4})],["Best bid / ask",`${q(t.bestBid,{decimals:4})} / ${q(t.bestAsk,{decimals:4})}`],["Volume",q(t.volumeUsd)],["Resolution risk",y(t.resolutionRisk)],["Order intent",y(t.orderIntent)],Z(t)],t)}function ra(e={}){let t=e||{},n=B(t.completedSplits)&&B(t.totalSplits)?`${de(t.completedSplits,{decimals:0})} / ${de(t.totalSplits,{decimals:0})}`:C;return X(`ORACLE TWAP \u2014 ${y(t.pair??t.symbol??t.name)}`,[["Chain",re(t)],["Side",y(t.side??t.direction)],["Amount",`${y(pe(t.amountTotal??t.amount,t.decimals??18))} ${y(t.symbol??"")}`.trim()],["Splits",`${de(t.totalSplits,{decimals:0})} over ${y(t.window)}`],["Progress",n],["Avg price",q(t.averagePrice,{decimals:6})],["Next split",y(t.nextSplitAt)],["Slippage cap",ft(t.slippageBps)],["Status",y(t.status)],Z(t)],t)}function oa(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",re({chainId:t.fromChainId,chain:t.fromChain})],["To chain",re({chainId:t.toChainId,chain:t.toChain})],["Amount",`${y(pe(t.amount,t.fromDecimals??18))} ${y(t.fromSymbol??"")}`.trim()],["Best route",y(t.bestRoute??t.winner)],["Est. received",`${y(pe(t.amountOut,t.toDecimals??18))} ${y(t.toSymbol??"")}`.trim()],["Fee",q(t.feeUsd)],["Est. time",y(t.estimatedTime)],["Revoke check",r],["All providers",y(t.providers?.join(", "))],["Preparable",y(t.preparable)],Z(t)],t)}function ia(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),s=Number.isFinite(i)?`${Math.abs(i).toFixed(0)} bps behind`:"spread UNKNOWN";return`${o} (${s})`});return n.length?n.join("; "):C}function sa(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return B(t)?y(t):C}function aa(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")}`,s=[["Intent",y(t.intent??"swap")],["Chain",re({chainId:t.chainId??n.chainId,chain:t.chain??n.chain})],["Pair",i],["Amount in",`${y(pe(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(pe(o.netOut??o.amountOut??n.amountOut,t.decimalsOut??18))} ${y(t.tokenOutSymbol??"")}`.trim()],["Ranked on",sa(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",ia(n.routes??t.routes)]];if(r){let c=r.best??r.winner??{};s.push(["Best bridge",y(c.source??r.bestRoute??t.bestBridge)],["Bridge out",`${y(pe(c.netOut??c.amountOut??r.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${y(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",re({chainId:r.toChainId??t.toChainId,chain:r.toChain??t.toChain})],["Est. time",y(r.estimatedTime??c.meta?.durationSeconds)])}else s.push(["Best bridge","same-chain \u2014 use Best swap"]);return s.push(["Preparable",y(t.preparable??o.executionReady)],Z(t)),X(`ORACLE SWAP \u2014 ${i}`,s,t)}function Yt(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",re({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 Jt({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,Wp,Ks,Gp,Qt=T(()=>{Pt();Er();C="UNKNOWN",Wp=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),Ks=/[_*[\]`]/g;Gp=Object.freeze({token:Xs,launch:Zs,hip3:ea,hip4:ta,polymarket:na,twap:ra,bridge:oa,swap:aa,approve:Yt})});function Xt(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 Zt(e,{platform:t,grant:n,armed:r}){if(!e.length)return{text:"No pending local-signer artifacts.",buttons:Jt({platform:t,hasGrant:!1})};let o=e[0];return{text:e.map(s=>Yt({...s,armed:r,grant:n,confidence:r?"high":"medium"})).join(`
11
11
 
12
- `),buttons:Yt({platform:t,id:o.id,digest:o.digest,hasGrant:fe({grant:n}).allowed})}}async function Zt({platform:e,text:t,grant:n={local:!0},env:r=process.env,ownerProof:o}={}){let i=Qt(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 ue("/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=Xt(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:Jt({platform:t,id:o.id,digest:o.digest,hasGrant:fe({grant:n}).allowed})}}async function en({platform:e,text:t,grant:n={local:!0},env:r=process.env,ownerProof:o}={}){let i=Xt(t);if(!i)return null;let s=String(e)==="telegram";if(s&&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 a=await ue("/pending",{env:r});if(a.ok===!1||a.error)return{text:`Local signer: ${a.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let p=Array.isArray(a.items)?a.items:[],m=Zt(p,{platform:e,grant:n,armed:a.armed===!0});if(s)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 ue(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 vr({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 ue("/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 Zt({platform:e,text:`/${u} ${l[2]}`,grant:i,env:a,ownerProof:d})}var en=$(()=>{dt();Jt();dt()});import{execFile as is}from"node:child_process";import{existsSync as as,mkdirSync as ss,readFileSync as xr,realpathSync as cs,writeFileSync as ls}from"node:fs";import oe from"node:path";import{promisify as us}from"node:util";import{fileURLToPath as Er}from"node:url";function ms(e=import.meta.url){try{let t=cs(Er(e)),n=`${oe.sep}node_modules${oe.sep}`,r=t.lastIndexOf(n);if(r>0)return{root:t.slice(0,r),managed:!0}}catch{}return{root:null,managed:!1}}function nn(e=import.meta.url){try{let t=oe.dirname(Er(e));for(let n=0;n<8;n+=1){let r=oe.join(t,"package.json");if(as(r)){let i=JSON.parse(xr(r,"utf8"));if(i?.name===tn&&i.version)return i.version}let o=oe.dirname(t);if(o===t)break;t=o}}catch{return null}return null}function hs(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 Ar(e){let t=e?.stateDir||oe.join(process.env.HOME||".",".oracle");return oe.join(t,"update-check.json")}function ys(e){try{return JSON.parse(xr(Ar(e),"utf8"))}catch{return null}}function gs(e,t){try{let n=Ar(e);ss(oe.dirname(n),{recursive:!0}),ls(n,`${JSON.stringify(t,null,2)}
15
- `)}catch{}}async function ws({timeoutMs:e=4e3}={}){try{let t=new AbortController,n=setTimeout(()=>t.abort(),e),r=await fetch(`${ps}/${encodeURIComponent(tn)}/latest`,{signal:t.signal});return clearTimeout(n),r.ok&&(await r.json())?.version||null}catch{return null}}async function kr({paths:e,force:t=!1,timeoutMs:n=4e3}={}){let r=nn(),o=t?null:ys(e),a=o&&Date.now()-(o.checkedAt||0)<fs?o.latest:null;return a||(a=await ws({timeoutMs:n}),a&&gs(e,{latest:a,checkedAt:Date.now()})),!r||!a?{current:r,latest:a,updateAvailable:!1,checked:!!a}:{current:r,latest:a,updateAvailable:hs(a,r)>0,checked:!0}}async function _r({version:e="latest",dryRun:t=!1}={}){let{root:n,managed:r}=ms();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=`${tn}@${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 ds("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 ds,tn,ps,fs,Ir=$(()=>{ds=us(is),tn="@oracle-agent/oracle",ps="https://registry.npmjs.org",fs=1440*60*1e3});import bs from"node:fs";import Ss from"node:os";import Cr from"node:path";function _e(e){return String(e||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function vs(){let e=process.env.ORACLE_CONFIG_DIR||Cr.join(Ss.homedir(),".config","oracle");return Cr.join(e,"chains.json")}function xs(e){if(!e||typeof e!="object")return null;let t=String(e.key??"").trim();if(!t||/[/\\.]/.test(t))return null;let n=_e(t);if(!Or.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"&&Or.test(e.agent.trim())?e.agent.trim():"oracle";return{key:n,aliases:Array.isArray(e.aliases)?e.aliases.map(_e).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:_e(e.family)||n,agent:o,note:String(e.note||"user-defined").slice(0,80),build:e.build!==!1,source:"user"}}function Es(e=bs.readFileSync){try{let t=JSON.parse(e(vs(),"utf8")),n=Array.isArray(t?.chains)?t.chains:[],r=[],o=new Set;for(let i of n){let a=xs(i);!a||o.has(a.key)||(o.add(a.key),r.push(a))}return r}catch{return[]}}function Nr(){let e=Es();if(e.length===0)return Tr;let t=new Map(Tr.map(n=>[n.key,n]));for(let n of e)t.set(n.key,n);return[...t.values()]}function As({buildOnly:e=!1}={}){return Nr().filter(t=>e?t.build:!0)}function je(e){let t=_e(e);if(!t)return null;for(let n of Nr())if(n.key===t||String(n.chainId).toLowerCase()===t||(n.aliases||[]).map(_e).includes(t)||_e(n.name)===t)return n;return null}function $r({selectedKey:e=null,buildOnly:t=!1}={}){let n=As({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 Ar({platform:e,data:t,senderId:n,chatId:r,ownerProofAuthority:o,grant:i={local:!0},env:s=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 ue("/pending",{env:s})).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 en({platform:e,text:`/${u} ${l[2]}`,grant:i,env:s,ownerProof:d})}var tn=T(()=>{pt();Qt();pt()});import{execFile as ca}from"node:child_process";import{existsSync as la,mkdirSync as ua,readFileSync as kr,realpathSync as da,writeFileSync as pa}from"node:fs";import oe from"node:path";import{promisify as fa}from"node:util";import{fileURLToPath as Ir}from"node:url";function ga(e=import.meta.url){try{let t=da(Ir(e)),n=`${oe.sep}node_modules${oe.sep}`,r=t.lastIndexOf(n);if(r>0)return{root:t.slice(0,r),managed:!0}}catch{}return{root:null,managed:!1}}function rn(e=import.meta.url){try{let t=oe.dirname(Ir(e));for(let n=0;n<8;n+=1){let r=oe.join(t,"package.json");if(la(r)){let i=JSON.parse(kr(r,"utf8"));if(i?.name===nn&&i.version)return i.version}let o=oe.dirname(t);if(o===t)break;t=o}}catch{return null}return null}function wa(e,t){let n=i=>String(i).replace(/^v/,"").split("-")[0].split(".").map(s=>Number.parseInt(s,10)||0),r=n(e),o=n(t);for(let i=0;i<Math.max(r.length,o.length);i+=1){let s=r[i]??0,c=o[i]??0;if(s>c)return 1;if(s<c)return-1}return 0}function _r(e){let t=e?.stateDir||oe.join(process.env.HOME||".",".oracle");return oe.join(t,"update-check.json")}function ba(e){try{return JSON.parse(kr(_r(e),"utf8"))}catch{return null}}function Sa(e,t){try{let n=_r(e);ua(oe.dirname(n),{recursive:!0}),pa(n,`${JSON.stringify(t,null,2)}
15
+ `)}catch{}}async function Ea({timeoutMs:e=4e3}={}){try{let t=new AbortController,n=setTimeout(()=>t.abort(),e),r=await fetch(`${ha}/${encodeURIComponent(nn)}/latest`,{signal:t.signal});return clearTimeout(n),r.ok&&(await r.json())?.version||null}catch{return null}}async function Cr({paths:e,force:t=!1,timeoutMs:n=4e3}={}){let r=rn(),o=t?null:ba(e),s=o&&Date.now()-(o.checkedAt||0)<ya?o.latest:null;return s||(s=await Ea({timeoutMs:n}),s&&Sa(e,{latest:s,checkedAt:Date.now()})),!r||!s?{current:r,latest:s,updateAvailable:!1,checked:!!s}:{current:r,latest:s,updateAvailable:wa(s,r)>0,checked:!0}}async function Tr({version:e="latest",dryRun:t=!1}={}){let{root:n,managed:r}=ga();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=`${nn}@${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:s,stderr:c}=await ma("npm",i,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:n,stdout:s,stderr:c}}catch(s){return{ok:!1,reason:"npm-failed",root:n,message:s?.stderr||s?.message||"npm install failed"}}}var ma,nn,ha,ya,Or=T(()=>{ma=fa(ca),nn="@oracle-agent/oracle",ha="https://registry.npmjs.org",ya=1440*60*1e3});import va from"node:fs";import xa from"node:os";import Nr from"node:path";function _e(e){return String(e||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function Aa(){let e=process.env.ORACLE_CONFIG_DIR||Nr.join(xa.homedir(),".config","oracle");return Nr.join(e,"chains.json")}function ka(e){if(!e||typeof e!="object")return null;let t=String(e.key??"").trim();if(!t||/[/\\.]/.test(t))return null;let n=_e(t);if(!Pr.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"&&Pr.test(e.agent.trim())?e.agent.trim():"oracle";return{key:n,aliases:Array.isArray(e.aliases)?e.aliases.map(_e).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:_e(e.family)||n,agent:o,note:String(e.note||"user-defined").slice(0,80),build:e.build!==!1,source:"user"}}function Ia(e=va.readFileSync){try{let t=JSON.parse(e(Aa(),"utf8")),n=Array.isArray(t?.chains)?t.chains:[],r=[],o=new Set;for(let i of n){let s=ka(i);!s||o.has(s.key)||(o.add(s.key),r.push(s))}return r}catch{return[]}}function Rr(){let e=Ia();if(e.length===0)return $r;let t=new Map($r.map(n=>[n.key,n]));for(let n of e)t.set(n.key,n);return[...t.values()]}function _a({buildOnly:e=!1}={}){return Rr().filter(t=>e?t.build:!0)}function He(e){let t=_e(e);if(!t)return null;for(let n of Rr())if(n.key===t||String(n.chainId).toLowerCase()===t||(n.aliases||[]).map(_e).includes(t)||_e(n.name)===t)return n;return null}function Lr({selectedKey:e=null,buildOnly:t=!1}={}){let n=_a({buildOnly:t}),r=["oracle chains","","pick a build/trade surface:",""];for(let o of n){let i=e&&e===o.key?"*":" ",s=String(o.chainId).padEnd(6),c=o.key.padEnd(12);r.push(`${i} ${c} ${s} ${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 Tr,Or,rn=$(()=>{Tr=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}]);Or=/^[a-z0-9][a-z0-9-]*$/});import on from"node:fs";import ks from"node:path";function Pr(){return ks.join(Q(),"active-chain.json")}function an(){let e=Pr();if(!on.existsSync(e))return null;try{let t=JSON.parse(on.readFileSync(e,"utf8"));if(!t||typeof t!="object"||!t.key)return null;let n=je(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 Rr(e){let t=je(e);if(!t){let r=new Error(`unknown chain '${e}'`);throw r.code="UNKNOWN_CHAIN",r}ct(Q());let n={key:t.key,chainId:t.chainId,name:t.name,agent:t.agent,selectedAt:new Date().toISOString()};return on.writeFileSync(Pr(),JSON.stringify(n,null,2)+`
19
- `,{mode:384}),n}var Lr=$(()=>{rn();lt()});import{createHash as _s,randomBytes as tf}from"node:crypto";import{mkdirSync as Is,readFileSync as Cs,writeFileSync as Ts}from"node:fs";import{homedir as Os}from"node:os";import{dirname as Ns,join as Ur}from"node:path";function Ve(e=process.env){return Ur(e.ORACLE_CONFIG_DIR||Ur(Os(),".config","oracle"),"telegram-cards.json")}function ze(){return{links:{},artifacts:{},threads:{}}}function ft(){return He}function Fr(e,{readFile:t=Cs}={}){try{let n=JSON.parse(String(t(e)));He={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{He=ze()}return He}function mt(e,t=He,{writeFile:n=Ts,mkdir:r=Is}={}){r(Ns(e),{recursive:!0,mode:448}),n(e,JSON.stringify(t),{mode:384})}function ie(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function Us(e){return _s("sha256").update(String(e)).digest("hex")}function sn(e){if(Array.isArray(e))return e.map(sn);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]=sn(r));return t}function Fs(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 Mr({platform:e="telegram",artifactId:t,openUrl:n,hasGrant:r=!1}={}){let o=String(t||"").trim().toLowerCase();if(!cn.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=>gr(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 ie(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 Br(e={}){let n=[`*${ie(e.title)?y(e.title):"Oracle artifact"}*`,`Kind: ${ie(e.kind)?y(e.kind):C}`,`Id: ${ie(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:C}`,`Summary: ${ie(e.summary)?y(e.summary):C}`],r=Gt(e.confidence);r!==C&&n.push(`Confidence: ${r}`),(ie(e.source)||ie(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=fe(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 Ms(e,t={},{now:n=Date.now()}={}){let r=e||ze(),o=String(t.id||"").trim().toLowerCase();if(!cn.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:ie(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:sn(t.payload||{}),createdAt:new Date(n).toISOString()};return r.artifacts[o]=i,i}function ln(e,{chatId:t,artifactId:n,now:r=Date.now()}={}){let o=e||ze(),i=String(t||"").trim(),a=String(n||"").trim().toLowerCase();if(!i)throw new TypeError("chat id required");if(!cn.test(a))throw new TypeError("artifact id required");return o.threads[i]={artifactId:a,updatedAt:r},o.threads[i]}function qr(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 Dr(e,{token:t,telegramUserId:n,now:r=Date.now()}={}){let o=e||ze(),i=String(t||"").trim(),a=String(n||"").trim();if(!Rs.test(i))return{ok:!1,error:"invalid start token"};if(!Ls.test(a))return{ok:!1,error:"invalid telegram user"};let c=Us(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 jr(e,{data:t,chatId:n,grant:r=null,now:o=Date.now()}={}){let i=Fs(t);if(!i)return null;if(!Ps.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&&ln(e,{chatId:n,artifactId:a.id,now:o});let c=fe({grant:r},{now:o}),l=Mr({artifactId:a.id,openUrl:a.openUrl,hasGrant:c.allowed});return i.action==="refresh"?{text:Br(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 Hr(e={},{grant:t=null,now:n=Date.now(),state:r}={}){let o=r||ft(),i=String(e.id||`art-${Math.abs(Number(n)).toString(36)}`).toLowerCase().slice(0,40),a=Ms(o,{...e,id:i},{now:n}),c=fe({grant:t},{now:n});return{text:Br({...a,grant:t}),replyMarkup:Mr({artifactId:a.id,openUrl:a.openUrl,hasGrant:c.allowed}).replyMarkup,artifact:a,state:o}}var $s,Ps,cn,Rs,Ls,He,un=$(()=>{zt();Jt();$s=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),Ps=new Set($s),cn=/^[a-z0-9-]{4,40}$/i,Rs=/^[0-9a-f]{32}$/,Ls=/^\d+$/;He=ze()});var fo={};ye(fo,{NON_OWNER_REPLY:()=>Ce,buildPersona:()=>Te,handleSelfUpdate:()=>Jr,isForwarded:()=>Qr,isOwnerSender:()=>Ie,ownerIdsFor:()=>Kr,parseGatewayChainCommand:()=>ao,parseGatewayCompactCommand:()=>io,parseGatewayEffortCommand:()=>to,parseGatewayGoalCommand:()=>oo,parseGatewayHelpCommand:()=>no,parseGatewayModelCommand:()=>eo,parseGatewaySetupModelCommand:()=>Js,parseGatewayStatusCommand:()=>ro,parsePeerAsk:()=>co,parseSelfUpdate:()=>Yr,resolveBackendArgv:()=>lo,resolveGatewayModel:()=>Xr,resolveOracleBin:()=>Gr,routePeerConsult:()=>We,routeToAgent:()=>ee});import{spawn as Wr}from"node:child_process";import{dirname as Bs,join as pn}from"node:path";import{homedir as qs}from"node:os";import{mkdirSync as Ds,readFileSync as js,writeFileSync as Hs,unlinkSync as Vs}from"node:fs";import{fileURLToPath as zs}from"node:url";function Gr({env:e=process.env,moduleUrl:t=import.meta.url}={}){return e.ORACLE_CLI_ENTRY||pn(Bs(zs(t)),"oracle.mjs")}function Kr(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 Ie({platform:e,senderId:t,extraOwners:n},r=process.env){let o=String(t||"").trim();return o?Kr(e,r).has(o)?!0:Array.isArray(n)?n.map(i=>String(i).trim()).filter(Boolean).includes(o):!1:!1}function Yr(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 Jr(e,{check:t=kr,update:n=_r,versionOf:r=nn}={}){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 Qr(e={}){return!!(e.forwarded||e.forward_from||e.forward_from_chat||e.forward_origin||e.forward_sender_name||e.forward_date)}function Xr({readConfig:e=ke}={}){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 eo(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=Zr[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 to(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"}:Gs.includes(r)?{action:"set",reasoningEffort:r}:{action:"usage"}}function Ks({provider:e,model:t}){let n=ke()||{},r=Vt({...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 Ys(e){let t=ke();if(!t)throw new Error("no model configured \u2014 run /model first");return`effort ${Vt({...t,reasoningEffort:e}).reasoningEffort||e}
23
- Native harness only.`}function Vr(){let e=ke(),t=["Oracle native models (tap /model <id> to switch):"];for(let[n,r]of Object.entries(Zr)){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 dn(){let e=ke();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 $r,Pr,on=T(()=>{$r=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}]);Pr=/^[a-z0-9][a-z0-9-]*$/});import sn from"node:fs";import Ca from"node:path";function Ur(){return Ca.join(Q(),"active-chain.json")}function an(){let e=Ur();if(!sn.existsSync(e))return null;try{let t=JSON.parse(sn.readFileSync(e,"utf8"));if(!t||typeof t!="object"||!t.key)return null;let n=He(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 Fr(e){let t=He(e);if(!t){let r=new Error(`unknown chain '${e}'`);throw r.code="UNKNOWN_CHAIN",r}lt(Q());let n={key:t.key,chainId:t.chainId,name:t.name,agent:t.agent,selectedAt:new Date().toISOString()};return sn.writeFileSync(Ur(),JSON.stringify(n,null,2)+`
19
+ `,{mode:384}),n}var Mr=T(()=>{on();ut()});import{createHash as Ta,randomBytes as wf}from"node:crypto";import{mkdirSync as Oa,readFileSync as Na,writeFileSync as $a}from"node:fs";import{homedir as Pa}from"node:os";import{dirname as Ra,join as Br}from"node:path";function ze(e=process.env){return Br(e.ORACLE_CONFIG_DIR||Br(Pa(),".config","oracle"),"telegram-cards.json")}function We(){return{links:{},artifacts:{},threads:{}}}function mt(){return Ve}function Dr(e,{readFile:t=Na}={}){try{let n=JSON.parse(String(t(e)));Ve={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{Ve=We()}return Ve}function ht(e,t=Ve,{writeFile:n=$a,mkdir:r=Oa}={}){r(Ra(e),{recursive:!0,mode:448}),n(e,JSON.stringify(t),{mode:384})}function ie(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function Ba(e){return Ta("sha256").update(String(e)).digest("hex")}function cn(e){if(Array.isArray(e))return e.map(cn);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]=cn(r));return t}function Da(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 qr({platform:e="telegram",artifactId:t,openUrl:n,hasGrant:r=!1}={}){let o=String(t||"").trim().toLowerCase();if(!ln.test(o))return{kind:"text_menu",text:"no artifact to continue",cancelHint:""};let i=[],s=[{text:"TA",callback_data:`oracle:card:ta:${o}`},{text:"FA",callback_data:`oracle:card:fa:${o}`}],c=a=>Sr(n,{side:a}),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 ie(n)?(i.push([{text:"Open",url:String(n)},s[0]]),i.push(d),i.push(r?[s[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[s[1]])):(i.push(s),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(a=>a.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function jr(e={}){let n=[`*${ie(e.title)?y(e.title):"Oracle artifact"}*`,`Kind: ${ie(e.kind)?y(e.kind):C}`,`Id: ${ie(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:C}`,`Summary: ${ie(e.summary)?y(e.summary):C}`],r=Kt(e.confidence);r!==C&&n.push(`Confidence: ${r}`),(ie(e.source)||ie(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=fe(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 qa(e,t={},{now:n=Date.now()}={}){let r=e||We(),o=String(t.id||"").trim().toLowerCase();if(!ln.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:ie(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:cn(t.payload||{}),createdAt:new Date(n).toISOString()};return r.artifacts[o]=i,i}function un(e,{chatId:t,artifactId:n,now:r=Date.now()}={}){let o=e||We(),i=String(t||"").trim(),s=String(n||"").trim().toLowerCase();if(!i)throw new TypeError("chat id required");if(!ln.test(s))throw new TypeError("artifact id required");return o.threads[i]={artifactId:s,updatedAt:r},o.threads[i]}function Hr(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 s=e.artifacts?.[i.artifactId];return s?`Continue artifact ${s.id} (${s.kind}). Prior: ${s.summary||s.title}. User: ${o}`:null}function Vr(e,{token:t,telegramUserId:n,now:r=Date.now()}={}){let o=e||We(),i=String(t||"").trim(),s=String(n||"").trim();if(!Fa.test(i))return{ok:!1,error:"invalid start token"};if(!Ma.test(s))return{ok:!1,error:"invalid telegram user"};let c=Ba(i),l=o.links[c];return l?(delete o.links[c],Number(l.expiresAt)<=r?{ok:!1,error:"start token expired"}:String(l.ownerId)!==s?{ok:!1,error:"start token is bound to a different owner"}:{ok:!0,ownerId:s}):{ok:!1,error:"unknown or already used start token"}}function zr(e,{data:t,chatId:n,grant:r=null,now:o=Date.now()}={}){let i=Da(t);if(!i)return null;if(!Ua.has(i.action))return{text:"That card action is not available.",buttons:null};let s=e?.artifacts?.[i.artifactId];if(!s)return{text:"That artifact is gone. Ask again and I will issue a new card.",buttons:null};n&&un(e,{chatId:n,artifactId:s.id,now:o});let c=fe({grant:r},{now:o}),l=qr({artifactId:s.id,openUrl:s.openUrl,hasGrant:c.allowed});return i.action==="refresh"?{text:jr(s),buttons:l,prompt:null}:i.action==="deepen"?{text:null,buttons:null,prompt:`Deepen artifact ${s.id} (${s.kind}). Prior: ${s.summary||s.title}. Be terse. Do not sign or broadcast.`}:i.action==="ta"?{text:null,buttons:null,prompt:`TA artifact ${s.id}. Prior: ${s.summary||s.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 ${s.id}. Prior: ${s.summary||s.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 ${s.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 ${s.id}. Prior: ${s.summary||s.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 ${s.id}. Nothing signed. Allow/Deny still required.`,buttons:l,prompt:null,prepare:{artifactId:s.id,unsigned:!0,broadcast:!1}}:{text:`Prepare blocked \u2014 ${c.reason}. Deepen and Refresh still work.`,buttons:l,prompt:null}}function Wr(e={},{grant:t=null,now:n=Date.now(),state:r}={}){let o=r||mt(),i=String(e.id||`art-${Math.abs(Number(n)).toString(36)}`).toLowerCase().slice(0,40),s=qa(o,{...e,id:i},{now:n}),c=fe({grant:t},{now:n});return{text:jr({...s,grant:t}),replyMarkup:qr({artifactId:s.id,openUrl:s.openUrl,hasGrant:c.allowed}).replyMarkup,artifact:s,state:o}}var La,Ua,ln,Fa,Ma,Ve,dn=T(()=>{Wt();Qt();La=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),Ua=new Set(La),ln=/^[a-z0-9-]{4,40}$/i,Fa=/^[0-9a-f]{32}$/,Ma=/^\d+$/;Ve=We()});var yo={};ye(yo,{NON_OWNER_REPLY:()=>Te,buildPersona:()=>Oe,handleSelfUpdate:()=>Zr,isForwarded:()=>eo,isOwnerSender:()=>Ce,ownerIdsFor:()=>Qr,parseGatewayChainCommand:()=>lo,parseGatewayCompactCommand:()=>co,parseGatewayEffortCommand:()=>oo,parseGatewayGoalCommand:()=>ao,parseGatewayHelpCommand:()=>io,parseGatewayModelCommand:()=>ro,parseGatewaySetupModelCommand:()=>Za,parseGatewayStatusCommand:()=>so,parsePeerAsk:()=>po,parseSelfUpdate:()=>Xr,resolveBackendArgv:()=>fo,resolveGatewayModel:()=>to,resolveOracleBin:()=>Jr,routePeerConsult:()=>Ge,routeToAgent:()=>ee});import{spawn as Yr}from"node:child_process";import{dirname as ja,join as fn}from"node:path";import{homedir as Ha}from"node:os";import{mkdirSync as Va,readFileSync as za,writeFileSync as Wa,unlinkSync as Ga}from"node:fs";import{fileURLToPath as Ka}from"node:url";function Jr({env:e=process.env,moduleUrl:t=import.meta.url}={}){return e.ORACLE_CLI_ENTRY||fn(ja(Ka(t)),"oracle.mjs")}function Qr(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 Ce({platform:e,senderId:t,extraOwners:n},r=process.env){let o=String(t||"").trim();return o?Qr(e,r).has(o)?!0:Array.isArray(n)?n.map(i=>String(i).trim()).filter(Boolean).includes(o):!1:!1}function Xr(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 Zr(e,{check:t=Cr,update:n=Tr,versionOf:r=rn}={}){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",s=await n({version:i==="latest"?"latest":i});if(!s.ok)return`oracle update failed: ${s.message}`;let c=r();return[`oracle ${o.current||"?"} \u2192 ${c||i}`,"Restart the gateway to load it: oracle gateway"].join(`
21
+ `)}function eo(e={}){return!!(e.forwarded||e.forward_from||e.forward_from_chat||e.forward_origin||e.forward_sender_name||e.forward_date)}function to({readConfig:e=Ie}={}){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 ro(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=no[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[s,c]=o[0].split(":");if(s&&c)return{action:"set",provider:s,model:c}}return{action:"usage"}}function oo(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"}:Ja.includes(r)?{action:"set",reasoningEffort:r}:{action:"usage"}}function Qa({provider:e,model:t}){let n=Ie()||{},r=zt({...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 Xa(e){let t=Ie();if(!t)throw new Error("no model configured \u2014 run /model first");return`effort ${zt({...t,reasoningEffort:e}).reasoningEffort||e}
23
+ Native harness only.`}function Gr(){let e=Ie(),t=["Oracle native models (tap /model <id> to switch):"];for(let[n,r]of Object.entries(no)){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 pn(){let e=Ie();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 Js(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 no(e){let t=String(e||"").trim();return/^\/(?:help|commands|\?)$/i.test(t)?{action:"help"}:null}function ro(e){let t=String(e||"").trim();return/^\/(?:status|usage)$/i.test(t)?{action:"status"}:null}function oo(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 io(e){let n=String(e||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return n?{action:"compact",focus:String(n[1]||"").trim()}:null}function ao(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 mn(){return pn(fn,"gateway-goal.json")}function so(){try{let e=JSON.parse(js(mn(),"utf8"));return e&&typeof e.goal=="string"?e:null}catch{return null}}function Qs(e){Ds(fn,{recursive:!0,mode:448});let t={schemaVersion:1,goal:String(e),updatedAt:new Date().toISOString()};return Hs(mn(),`${JSON.stringify(t,null,2)}
27
- `,{mode:384}),t}function Xs(){try{Vs(mn())}catch{}}function Zs(){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 ec(){let e=dn(),t=an(),n=so();return[e,`chain ${t?.key||t?.name||"default"}`,`goal ${n?.goal||"unset"}`].join(`
29
- `)}function co(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 Te(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 lo(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 We({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 po({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(!Ie({platform:e,senderId:n,extraOwners:c}))return process.stderr.write(`gateway: denied non-owner sender ${e}:${String(n||"unknown")}
31
- `),Ce;if(Qr(i))return process.stderr.write(`gateway: dropped forwarded message on ${e}
32
- `),null;let m=Yr(r);if(m)return Jr(m,a);let g=eo(r);if(g)try{return g.action==="list"?Vr():g.action==="show"?dn():g.action==="usage"?Vr():Ks(g)}catch(b){return`model not saved: ${b.message}`}let w=to(r);if(w)try{return w.action==="show"?dn():w.action==="usage"?"usage: /effort low|medium|high":Ys(w.reasoningEffort)}catch(b){return`effort not saved: ${b.message}`}if(no(r))return Zs();if(ro(r))return ec();let E=oo(r);if(E){if(E.action==="show"){let b=so();return b?.goal?`goal ${b.goal}`:"goal unset \u2014 /goal <objective>"}return E.action==="clear"?(Xs(),"goal cleared"):(Qs(E.goal),`goal pinned: ${E.goal}`)}let A=io(r);if(A){let b=A.focus?` Focus: ${A.focus}.`:"";return zr({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=ao(r);if(T){if(T.action==="list")return $r({selectedKey:an()?.key||null});let b=je(T.chain);return b?(Rr(b.key),`chain ${b.key}`):`unknown chain '${T.chain}' \u2014 /chain list`}if(Qt(r)){let b=await Zt({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=co(r);if(b){let v=await l.send({from:u||"oracle",to:b.peer,text:b.text,kind:"consult"});return v.ok?v.reply?`[${b.peer}] ${v.reply}`:`[${b.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)?nc({platform:e,chatId:t,senderId:n,text:r,userName:o}):zr({platform:e,chatId:t,senderId:n,text:r,userName:o,persona:d,backend:s,profile:p})}function uo(e,{timeout:t=12e4}={}){return new Promise(n=>{let r=Wr(process.execPath,[Ws,...e],{stdio:["ignore","pipe","pipe"],timeout:t,env:{...process.env,ORACLE_CONFIG_DIR:fn,ORACLE_TOOL_SURFACE:"research-x-telegram"}}),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 tc(e,t,{timeout:n=18e4}={}){return new Promise(r=>{let o=Wr(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 nc({text:e,chatId:t}){let n=await uo(["route","swap","--text",e],{timeout:3e4});if(n.code===0&&n.out)try{return rc(JSON.parse(n.out),{chatId:t})}catch{return n.out}return`Trade routing failed. Try: \`${e}\` again.`}async function zr({text:e,persona:t,backend:n,profile:r}){let o=t?`[your role: ${t}]
35
- ${e}`:e;return po({text:o,backend:n,profile:r,unconfiguredPrefix:"Oracle is not configured yet: "})}async function po({text:e,backend:t,profile:n,unconfiguredPrefix:r}){let o=lo(t,e,{profile:n});if(!o.ok)return`${r}${o.error}`;if(!o.bin){let a=Xr();if(!a.ok)return`${r}${a.error}`;let c=await uo(o.args);return c.code===0&&c.out?c.out:c.err||"Oracle could not answer that. Try again."}let i=await tc(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 rc(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=Hr({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&&ln(r.state,{chatId:t,artifactId:r.artifact.id}),mt(Ve(),r.state),{text:r.text,replyMarkup:r.replyMarkup}}var fn,Ws,Ce,Zr,Gs,Oe=$(()=>{yr();en();Ir();rn();Lr();un();fn=process.env.ORACLE_CONFIG_DIR||pn(qs(),".config","oracle");Ws=Gr();Ce="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";Zr=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"}}),Gs=Object.freeze(["low","medium","high"])});function ic(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 mo({onNew:e,intervalMs:t=oc,env:n=process.env,signerCall:r=ue,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=ic(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 oc,ho=$(()=>{dt();oc=4e3});import me from"node:fs";function ac(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 yo(e){let t;try{t=me.openSync(e,me.constants.O_RDONLY|me.constants.O_NOFOLLOW)}catch(n){throw n.code==="ELOOP"?new Error("local-vault: refusing symlink"):n}try{let n=me.fstatSync(t);if(ac(n),n.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let r=me.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 me.readFileSync(t,"utf8").replace(/[\r\n]+$/,"")}finally{me.closeSync(t)}}var Af,kf,_f,go=$(()=>{Af=Object.freeze({N:1<<17,r:8,p:1}),kf=256*1024*1024,_f=16*1024});import{createHash as sc,createHmac as wo,randomBytes as cc,timingSafeEqual as lc}from"node:crypto";function vo({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(Ne).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(yo(e));try{return c(l)}finally{l.fill(0)}},a=i(c=>sc("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=Ne(l),m=Ne(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:bo,instance:a,nonce:cc(16).toString("hex"),issuedAtMs:g,expiresAtMs:g+s},E=i(A=>wo("sha256",A).update(So(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!==bo||u.instance!==a||!/^[0-9a-f]{32}$/.test(u.nonce||"")||Ne(u.ownerSenderId)!==Ne(u.telegramChatId)||!r.has(Ne(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=>wo("sha256",p).update(So(u)).digest("hex"));return uc(c.mac,s)?(o.add(u.nonce),!0):!1}})}var bo,Ne,So,uc,xo=$(()=>{go();bo="oracle-local-signer-cex-owner-allow-v1",Ne=e=>/^(?:0|[1-9]\d{0,19})$/.test(String(e||""))?String(e):null,So=e=>JSON.stringify(e),uc=(e,t)=>{let n=Buffer.from(String(e)),r=Buffer.from(String(t));return n.length===r.length&&lc(n,r)}});var ko={};ye(ko,{buildPersona:()=>Te,telegram:()=>fc,telegramPendingRecipients:()=>pc});import{join as Eo}from"node:path";import{homedir as dc}from"node:os";function ht(e=process.env){return Fr(Ve(e)),ft()}function Ao(e=process.env){mt(Ve(e),ft())}function pc({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 hn(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 fc(e){let{Bot:t}=await import("grammy");ht();let n=new t(e.token),r=String(e.name||"oracle").toLowerCase(),o=Te(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=>We({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(!Ie({platform:"telegram",senderId:p,extraOwners:i}))return s.reply(Ce);let m=String(s.match||"").trim();if(m){let g=ht(),w=Dr(g,{token:m,telegramUserId:p});return Ao(),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(!Ie({platform:"telegram",senderId:p,extraOwners:i}))return s.reply(Ce);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 hn(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=ht(),E=qr(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 hn(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(!Ie({platform:"telegram",senderId:p,extraOwners:i})){await s.answerCallbackQuery({text:Ce.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||Eo(dc(),".config","oracle"),E;try{E=vo({keyFile:Eo(w,"signer","policy-integrity-key"),approvedTelegramOwners:g})}catch{}let A=await vr({platform:"telegram",data:m,senderId:p,chatId:String(s.chat?.id||""),ownerProofAuthority:E,grant:{local:!0}});if(!A){let T=ht(),x=jr(T,{data:m,chatId:String(s.chat?.id||""),grant:{local:!0}});if(Ao(),!x){await s.answerCallbackQuery().catch(()=>{});return}if(await s.answerCallbackQuery({text:"ok"}).catch(()=>{}),x.prompt){let f=await ee({platform:"telegram",chatId:String(s.chat?.id||""),senderId:p,text:x.prompt,extraOwners:i,bus:a,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile});f&&await hn(s,f);return}if(x.text){let f=x.buttons?.replyMarkup?{reply_markup:x.buttons.replyMarkup}:{};await s.reply(x.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=Se("telegram",{owners:i}).filter(s=>/^\d+$/.test(s)),l=null;return c.length>0&&e.pendingWatch!==!1&&(l=mo({intervalMs:e.pendingWatchIntervalMs,onNew:async(s,{armed:p})=>{let m=Xt(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 _o=$(()=>{Oe();en();ho();xo();un();Be()});var Io={};ye(Io,{discord:()=>mc});async function mc(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=Te(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=>We({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=Se("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 Co=$(()=>{Oe();Be()});var Oo={};ye(Oo,{whatsapp:()=>gc});import{join as To}from"node:path";import{homedir as hc}from"node:os";async function gc(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:To(yc,".wwebjs_auth")}),puppeteer:{headless:!0,args:["--no-sandbox"]}});o.on("qr",l=>{process.stderr.write(`
26
+ `)}function Za(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 io(e){let t=String(e||"").trim();return/^\/(?:help|commands|\?)$/i.test(t)?{action:"help"}:null}function so(e){let t=String(e||"").trim();return/^\/(?:status|usage)$/i.test(t)?{action:"status"}:null}function ao(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 co(e){let n=String(e||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return n?{action:"compact",focus:String(n[1]||"").trim()}:null}function lo(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 hn(){return fn(mn,"gateway-goal.json")}function uo(){try{let e=JSON.parse(za(hn(),"utf8"));return e&&typeof e.goal=="string"?e:null}catch{return null}}function ec(e){Va(mn,{recursive:!0,mode:448});let t={schemaVersion:1,goal:String(e),updatedAt:new Date().toISOString()};return Wa(hn(),`${JSON.stringify(t,null,2)}
27
+ `,{mode:384}),t}function tc(){try{Ga(hn())}catch{}}function nc(){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 rc(){let e=pn(),t=an(),n=uo();return[e,`chain ${t?.key||t?.name||"default"}`,`goal ${n?.goal||"unset"}`].join(`
29
+ `)}function po(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 Oe(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 fo(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 Ge({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 ho({text:i,backend:r,profile:o,unconfiguredPrefix:"unconfigured: "})}async function ee({platform:e,chatId:t,senderId:n,text:r,userName:o,meta:i={},updater:s,extraOwners:c,bus:l,agentName:u,persona:d,backend:a,profile:p}={}){if(!Ce({platform:e,senderId:n,extraOwners:c}))return process.stderr.write(`gateway: denied non-owner sender ${e}:${String(n||"unknown")}
31
+ `),Te;if(eo(i))return process.stderr.write(`gateway: dropped forwarded message on ${e}
32
+ `),null;let m=Xr(r);if(m)return Zr(m,s);let g=ro(r);if(g)try{return g.action==="list"?Gr():g.action==="show"?pn():g.action==="usage"?Gr():Qa(g)}catch(b){return`model not saved: ${b.message}`}let w=oo(r);if(w)try{return w.action==="show"?pn():w.action==="usage"?"usage: /effort low|medium|high":Xa(w.reasoningEffort)}catch(b){return`effort not saved: ${b.message}`}if(io(r))return nc();if(so(r))return rc();let x=ao(r);if(x){if(x.action==="show"){let b=uo();return b?.goal?`goal ${b.goal}`:"goal unset \u2014 /goal <objective>"}return x.action==="clear"?(tc(),"goal cleared"):(ec(x.goal),`goal pinned: ${x.goal}`)}let A=co(r);if(A){let b=A.focus?` Focus: ${A.focus}.`:"";return Kr({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:a,profile:p})}let O=lo(r);if(O){if(O.action==="list")return Lr({selectedKey:an()?.key||null});let b=He(O.chain);return b?(Fr(b.key),`chain ${b.key}`):`unknown chain '${O.chain}' \u2014 /chain list`}if(Xt(r)){let b=await en({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=po(r);if(b){let E=await l.send({from:u||"oracle",to:b.peer,text:b.text,kind:"consult"});return E.ok?E.reply?`[${b.peer}] ${E.reply}`:`[${b.peer}] (no reply)`:E.error}if(/^\/(agents|roster)\b/i.test(String(r||"").trim())){let E=l.roster().map(_=>`\u2022 ${_.name}${_.role?` \u2014 ${_.role}`:""}${_.chains.length?` (${_.chains.join(", ")})`:""}`);return E.length?`Agents on the bus:
33
+ ${E.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)?ic({platform:e,chatId:t,senderId:n,text:r,userName:o}):Kr({platform:e,chatId:t,senderId:n,text:r,userName:o,persona:d,backend:a,profile:p})}function mo(e,{timeout:t=12e4}={}){return new Promise(n=>{let r=Yr(process.execPath,[Ya,...e],{stdio:["ignore","pipe","pipe"],timeout:t,env:{...process.env,ORACLE_CONFIG_DIR:mn,ORACLE_TOOL_SURFACE:"research-x-telegram"}}),o="",i="";r.stdout.on("data",s=>o+=s.toString()),r.stderr.on("data",s=>i+=s.toString()),r.on("close",s=>n({code:s,out:o.trim(),err:i.trim()}))})}function oc(e,t,{timeout:n=18e4}={}){return new Promise(r=>{let o=Yr(e,t,{stdio:["ignore","pipe","pipe"],timeout:n,env:{...process.env}}),i="",s="";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=>s+=c.toString()),o.on("close",c=>r({code:c,out:i.trim(),err:s.trim()}))})}async function ic({text:e,chatId:t}){let n=await mo(["route","swap","--text",e],{timeout:3e4});if(n.code===0&&n.out)try{return sc(JSON.parse(n.out),{chatId:t})}catch{return n.out}return`Trade routing failed. Try: \`${e}\` again.`}async function Kr({text:e,persona:t,backend:n,profile:r}){let o=t?`[your role: ${t}]
35
+ ${e}`:e;return ho({text:o,backend:n,profile:r,unconfiguredPrefix:"Oracle is not configured yet: "})}async function ho({text:e,backend:t,profile:n,unconfiguredPrefix:r}){let o=fo(t,e,{profile:n});if(!o.ok)return`${r}${o.error}`;if(!o.bin){let s=to();if(!s.ok)return`${r}${s.error}`;let c=await mo(o.args);return c.code===0&&c.out?c.out:c.err||"Oracle could not answer that. Try again."}let i=await oc(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 sc(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=Wr({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&&un(r.state,{chatId:t,artifactId:r.artifact.id}),ht(ze(),r.state),{text:r.text,replyMarkup:r.replyMarkup}}var mn,Ya,Te,no,Ja,Ne=T(()=>{gr();tn();Or();on();Mr();dn();mn=process.env.ORACLE_CONFIG_DIR||fn(Ha(),".config","oracle");Ya=Jr();Te="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";no=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"}}),Ja=Object.freeze(["low","medium","high"])});function cc(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 go({onNew:e,intervalMs:t=ac,env:n=process.env,signerCall:r=ue,setIntervalFn:o=setInterval,clearIntervalFn:i=clearInterval}={}){if(typeof e!="function")throw new Error("pending-watch: onNew callback required");let s=new Set,c=!1,l=!1;async function u(){if(!l){l=!0;try{let a=await r("/pending",{env:n});if(!a||a.ok===!1||a.error||!Array.isArray(a.items))return;let p=cc(a.items,s);if(!c){c=!0;return}if(p.length===0)return;try{await e(p,{armed:a.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 ac,wo=T(()=>{pt();ac=4e3});import me from"node:fs";function lc(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 bo(e){let t;try{t=me.openSync(e,me.constants.O_RDONLY|me.constants.O_NOFOLLOW)}catch(n){throw n.code==="ELOOP"?new Error("local-vault: refusing symlink"):n}try{let n=me.fstatSync(t);if(lc(n),n.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let r=me.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 me.readFileSync(t,"utf8").replace(/[\r\n]+$/,"")}finally{me.closeSync(t)}}var Df,qf,jf,So=T(()=>{Df=Object.freeze({N:1<<17,r:8,p:1}),qf=256*1024*1024,jf=16*1024});import{createHash as uc,createHmac as Eo,randomBytes as dc,timingSafeEqual as pc}from"node:crypto";function Ao({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($e).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(bo(e));try{return c(l)}finally{l.fill(0)}},s=i(c=>uc("sha256").update("cex-owner-instance\0").update(c).digest("hex"));return Object.freeze({mint({digest:c,senderId:l,chatId:u,platform:d,ttlMs:a=15e3}={}){let p=$e(l),m=$e(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(a)||a<1||a>3e4)throw new Error("cex owner proof: binding refused");let w={version:1,decision:"Allow",digest:c,ownerSenderId:p,telegramChatId:m,audience:vo,instance:s,nonce:dc(16).toString("hex"),issuedAtMs:g,expiresAtMs:g+a},x=i(A=>Eo("sha256",A).update(xo(w)).digest("hex"));return{claims:w,mac:x}},verify(c,{digest:l}={}){let u=c?.claims,d=n();if(!u||u.version!==1||u.decision!=="Allow"||u.digest!==l||u.audience!==vo||u.instance!==s||!/^[0-9a-f]{32}$/.test(u.nonce||"")||$e(u.ownerSenderId)!==$e(u.telegramChatId)||!r.has($e(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 a=i(p=>Eo("sha256",p).update(xo(u)).digest("hex"));return fc(c.mac,a)?(o.add(u.nonce),!0):!1}})}var vo,$e,xo,fc,ko=T(()=>{So();vo="oracle-local-signer-cex-owner-allow-v1",$e=e=>/^(?:0|[1-9]\d{0,19})$/.test(String(e||""))?String(e):null,xo=e=>JSON.stringify(e),fc=(e,t)=>{let n=Buffer.from(String(e)),r=Buffer.from(String(t));return n.length===r.length&&pc(n,r)}});var Co={};ye(Co,{buildPersona:()=>Oe,telegram:()=>yc,telegramPendingRecipients:()=>hc});import{join as Io}from"node:path";import{homedir as mc}from"node:os";function yt(e=process.env){return Dr(ze(e)),mt()}function _o(e=process.env){ht(ze(e),mt())}function hc({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 yn(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 yc(e){let{Bot:t}=await import("grammy");yt();let n=new t(e.token),r=String(e.name||"oracle").toLowerCase(),o=Oe(e),i=Array.isArray(e.owners)?e.owners:void 0,s=e.bus;s&&s.register(r,{role:e.role||"",chains:e.chains||[],handler:a=>Ge({from:a.from,text:a.text,persona:o,backend:e.backend,profile:e.hermesProfile})}),n.command("start",a=>{let p=String(a.from?.id||a.chat.id);if(!Ce({platform:"telegram",senderId:p,extraOwners:i}))return a.reply(Te);let m=String(a.match||"").trim();if(m){let g=yt(),w=Vr(g,{token:m,telegramUserId:p});return _o(),w.ok?a.reply("Telegram linked to Oracle. Agent artifacts will land as interactive cards. Deepen stays in this thread."):a.reply(`Link failed: ${w.error}`)}return a.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.${s?" /agents lists peers.":""}`)}),n.command("update",async a=>{let p=String(a.from?.id||a.chat.id),m=String(a.chat.id);if(!Ce({platform:"telegram",senderId:p,extraOwners:i}))return a.reply(Te);if(a.message.forward_origin||a.message.forward_from||a.message.forward_date)return;a.replyWithChatAction("typing").catch(()=>{});let g=await ee({platform:"telegram",chatId:m,senderId:p,text:a.match?`update ${a.match}`.trim():"update",userName:a.from?.username||a.from?.first_name||"user"});if(g)return yn(a,g)}),n.on("message:text",async a=>{let p=String(a.chat.id),m=String(a.from?.id||p),g=a.message.text;try{a.replyWithChatAction("typing").catch(()=>{});let w=yt(),x=Hr(w,{chatId:p,text:g}),A=await ee({platform:"telegram",chatId:p,senderId:m,text:x||g,userName:a.from?.username||a.from?.first_name||"user",extraOwners:i,bus:s,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile,meta:{forward_origin:a.message.forward_origin,forward_from:a.message.forward_from,forward_from_chat:a.message.forward_from_chat,forward_sender_name:a.message.forward_sender_name,forward_date:a.message.forward_date}});A&&await yn(a,A)}catch(w){process.stderr.write(`telegram-gateway[${r}]: ${w.message}
36
+ `),await a.reply("Something went wrong. Try again.").catch(()=>{})}}),n.on("callback_query:data",async a=>{let p=String(a.from?.id||"");if(!Ce({platform:"telegram",senderId:p,extraOwners:i})){await a.answerCallbackQuery({text:Te.slice(0,180),show_alert:!0}).catch(()=>{});return}let m=String(a.callbackQuery?.data||""),g=String(process.env.ORACLE_OWNER_TELEGRAM||"").split(",").map(O=>O.trim()).filter(Boolean),w=process.env.ORACLE_CONFIG_DIR||Io(mc(),".config","oracle"),x;try{x=Ao({keyFile:Io(w,"signer","policy-integrity-key"),approvedTelegramOwners:g})}catch{}let A=await Ar({platform:"telegram",data:m,senderId:p,chatId:String(a.chat?.id||""),ownerProofAuthority:x,grant:{local:!0}});if(!A){let O=yt(),v=zr(O,{data:m,chatId:String(a.chat?.id||""),grant:{local:!0}});if(_o(),!v){await a.answerCallbackQuery().catch(()=>{});return}if(await a.answerCallbackQuery({text:"ok"}).catch(()=>{}),v.prompt){let f=await ee({platform:"telegram",chatId:String(a.chat?.id||""),senderId:p,text:v.prompt,extraOwners:i,bus:s,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile});f&&await yn(a,f);return}if(v.text){let f=v.buttons?.replyMarkup?{reply_markup:v.buttons.replyMarkup}:{};await a.reply(v.text,{parse_mode:"Markdown",...f}).catch(()=>{})}return}await a.answerCallbackQuery({text:"ok"}).catch(()=>{}),A.text&&await a.reply(A.text,{parse_mode:"Markdown"}).catch(()=>{})}),await n.init(),n.start().catch(a=>{process.stderr.write(`telegram-gateway[${r}]: polling stopped: ${String(a?.message||a).slice(0,160)}
37
+ `)});let c=Ee("telegram",{owners:i}).filter(a=>/^\d+$/.test(a)),l=null;return c.length>0&&e.pendingWatch!==!1&&(l=go({intervalMs:e.pendingWatchIntervalMs,onNew:async(a,{armed:p})=>{let m=Zt(a,{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(a,p)=>{let m=String(a||"");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 To=T(()=>{Ne();tn();wo();ko();dn();De()});var Oo={};ye(Oo,{discord:()=>gc});async function gc(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=Oe(e),s=Array.isArray(e.owners)?e.owners:void 0,c=e.bus;c&&c.register(o,{role:e.role||"",chains:e.chains||[],handler:a=>Ge({from:a.from,text:a.text,persona:i,backend:e.backend,profile:e.hermesProfile})}),r.on("messageCreate",async a=>{if(a.author.bot)return;let p=a.channel.id,m=a.author.id,g=a.content;try{let w=!a.guild,x=a.mentions.has(r.user.id);if(!w&&!x)return;a.channel.sendTyping().catch(()=>{});let A=await ee({platform:"discord",chatId:p,senderId:m,text:g.replace(`<@${r.user.id}>`,"").trim(),userName:a.author.username,extraOwners:s,bus:c,agentName:o,persona:i,backend:e.backend,profile:e.hermesProfile,meta:{forwarded:a.reference?.type===1||Array.isArray(a.messageSnapshots)&&a.messageSnapshots.length>0}});A&&await a.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=Ee("discord",e);return{platform:"discord",name:o,client:r,ownerIds:l,notifyRecipient:async(a,p)=>{let m=String(a||"");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 No=T(()=>{Ne();De()});var Po={};ye(Po,{whatsapp:()=>Sc});import{join as $o}from"node:path";import{homedir as wc}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:$o(bc,".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
- `)}),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=Se("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 yc,No=$(()=>{Oe();Be();yc=process.env.ORACLE_CONFIG_DIR||To(hc(),".config","oracle")});var $o={};ye($o,{signal_:()=>wc});async function wc(e){return process.stderr.write(`signal-gateway: requires signal-cli binary
43
+ `)}),o.on("message",async l=>{if(l.fromMe)return;let u=l.from,d=l.author||l.from,a=l.body;try{let p=await ee({platform:"whatsapp",chatId:u,senderId:d,text:a,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=Ee("whatsapp",e);return{platform:"whatsapp",client:o,ownerIds:i,notifyRecipient:async(l,u)=>{let d=String(l||"");if(!i.includes(d))return 0;let a=String(u).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");return await o.sendMessage(d,a),1},stop:async()=>{await Promise.resolve(o.destroy()).catch(()=>{})}}}var bc,Ro=T(()=>{Ne();De();bc=process.env.ORACLE_CONFIG_DIR||$o(wc(),".config","oracle")});var Lo={};ye(Lo,{signal_:()=>Ec});async function Ec(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 Po=$(()=>{Oe()});import{createServer as bc}from"node:http";import{env as $e}from"node:process";import{join as Ge}from"node:path";import{homedir as Sc}from"node:os";import{readFileSync as wn,existsSync as vc,mkdirSync as xc,writeFileSync as Ec}from"node:fs";import{createHash as Ac,randomBytes as kc}from"node:crypto";import st from"node:path";import{homedir as rr}from"node:os";import{readFileSync as ua}from"node:fs";import{createHash as da}from"node:crypto";import N from"node:fs";import Ke from"node:path";import{createHash as qo,randomUUID as vn}from"node:crypto";var St=1,W=class extends Error{constructor(t,n="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=n}};function Qe(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(Qe).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Qe(e[n])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function xn(e){return qo("sha256").update(Qe(e)).digest("hex")}function Ye(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 Je(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function En(e){N.mkdirSync(e,{recursive:!0,mode:448});try{N.chmodSync(e,448)}catch{}}function vt(e){try{let t=N.statSync(e);return{...JSON.parse(N.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function An({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=()=>vn()}={}){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 x=n();return r(x),{schemaVersion:St,kind:t,generation:0,data:x}}function s(x){let f;try{f=JSON.parse(x)}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!==St)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:S,...b}=f;if(typeof S!="string"||!/^[a-f0-9]{64}$/.test(S)||xn(b)!==S)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 b}function p(){if(!N.existsSync(e))return d();let x=N.statSync(e);if(!x.isFile()||x.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(){En(Ke.dirname(e));let x=Ye(o),f=String(l()),S=`${JSON.stringify({schemaVersion:1,lockId:f,pid:process.pid,acquiredAt:x})}
47
- `,b=()=>{let P;try{return P=N.openSync(u,"wx",384),N.writeFileSync(P,S,"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=Ye(o)+c,O=new Int32Array(new SharedArrayBuffer(4));for(;;){let P=b();if(P)return P;let h=Ye(o),k=vt(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=vt(u);if(k?q?.lockId===k.lockId:q===null){try{N.unlinkSync(u)}catch(z){if(z?.code!=="ENOENT")throw z}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(x){if(vt(u)?.lockId===x.lockId)try{N.unlinkSync(u)}catch(S){if(S?.code!=="ENOENT")throw S}}function w(x){r(x.data);let f={...x,integrity:xn(x)},S=`${Qe(f)}
48
- `;if(Buffer.byteLength(S)>i)throw new W(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let b=Ke.dirname(e);En(b);let v=Ke.join(b,`.${Ke.basename(e)}.${process.pid}.${vn()}.tmp`),I;try{I=N.openSync(v,"wx",384),N.writeFileSync(I,S,"utf8"),N.fsyncSync(I),N.closeSync(I),I=void 0,N.renameSync(v,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(v)}catch(O){if(O?.code!=="ENOENT")throw O}}}function E(){return Je(p().data)}function A(){let x=p();return{schemaVersion:x.schemaVersion,kind:x.kind,generation:x.generation,data:Je(x.data)}}function T(x){if(typeof x!="function")throw new TypeError("mutator must be a function");let f=m();try{let S=p(),b=Je(S.data),v=x(b,{generation:S.generation,now:Ye(o)});return r(b),w({schemaVersion:St,kind:t,generation:S.generation+1,data:b}),Je(v)}finally{g(f)}}return Object.freeze({filePath:e,read:E,inspect:A,mutate:T})}H();H();import{getAddress as wi}from"ethers";import{types as Ln}from"node:util";function Ot(e){if(!e||typeof e!="object"||Ln.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function ne(e,t="provider response",n=0){if(n>64)throw new Error(`${t} exceeds the JSON nesting bound`);if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(Array.isArray(e)){if(Ln.isProxy(e)||e.length>1e5)throw new Error(`${t} contains an invalid array`);let o=new Array(e.length);for(let i=0;i<e.length;i+=1){let a=Object.getOwnPropertyDescriptor(e,String(i));if(!a||!Object.hasOwn(a,"value"))throw new Error(`${t} arrays must contain dense own data`);o[i]=ne(a.value,t,n+1)}return o}if(!Ot(e))throw new Error(`${t} contains a non-JSON value`);let r=Object.create(null);for(let o of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,o);if(!i||!Object.hasOwn(i,"value"))throw new Error(`${t} objects must contain own data`);r[o]=ne(i.value,t,n+1)}return r}var hi=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,yi=/[<>&`*_~[\]()|\\]/g,gi=/[\u0000-\u001F\u007F]/g;function nt(e,{max:t=32,fallback:n=""}={}){return e==null?n:String(e).normalize("NFKC").replace(hi,"").replace(gi,"").replace(yi,"").replace(/\s+/g," ").trim().slice(0,t).trim()||n}var Un=Object.freeze({1:"https://eth.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com"}),Fn=e=>!!Un[e];function bi(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("invalid NFT cursor");let t=new URLSearchParams;for(let[n,r]of Object.entries(e)){if(!(n==="token_contract_address_hash"?/^0x[\da-f]{40}$/i.test(String(r)):n==="token_type"?["ERC-721","ERC-1155","ERC-404"].includes(r):["token_id","items_count"].includes(n)&&/^\d{1,100}$/.test(String(r))))throw new Error("invalid NFT cursor");t.set(n,String(r))}if(!t.size)throw new Error("empty NFT cursor");return t.toString()}async function Mn(e={},t={}){let n=wi(e.address),r=Un[e.chainId];if(!r)throw new Error("Blockscout NFT chain not verified");let o=Math.min(3,Math.max(1,Math.trunc(Number(e.maxPages)||3))),i=[],a=[],c=new Set,l=null,u="",d=0,s=!1;for(;d<o;)try{let p=ne(await j(`${r}/api/v2/addresses/${n}/nft${u?`?${u}`:""}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??8e3,maxResponseBytes:2e6,redirectPolicy:"error",headers:{accept:"application/json","user-agent":"OraclePortfolio/1.0"}}),"blockscout NFT inventory");if(!Array.isArray(p?.items))throw new Error("invalid NFT inventory response");d++;for(let g of p.items.slice(0,50)){let w=g.token;if(!/^0x[\da-f]{40}$/i.test(w?.address_hash||"")||!/^\d+$/.test(String(g.id??"")))throw new Error("invalid NFT identity");if(!["ERC-721","ERC-1155","ERC-404"].includes(w.type))throw new Error("invalid NFT standard");if(g.owner?.hash&&g.owner.hash.toLowerCase()!==n.toLowerCase())throw new Error("NFT owner mismatch");i.push({chain:e.chain,chainId:e.chainId,family:"evm",owner:n,contract:w.address_hash,tokenId:String(g.id),tokenStandard:w.type,collection:nt(w.name,{max:160,fallback:w.address_hash}),name:nt(g.metadata?.name||w.name,{max:160,fallback:`NFT ${g.id}`}),imageUrl:g.image_url||null,estimatedValueUsd:null,spam:["scam","spam"].includes(w.reputation)||w.is_spam===!0,source:"blockscout-owner-inventory",listingAdapter:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"owner indexer provides no acquisition cost"}})}if(p.items.length>50)throw new Error("NFT provider page exceeds 50 item bound");let m=p.next_page_params??null;if(!m){l=null,s=!0;break}if(l=null,u=bi(m),l=Object.fromEntries(new URLSearchParams(u)),c.has(u))throw new Error("repeated NFT cursor");c.add(u)}catch(p){if(a.push(`blockscout: ${p.message}`.slice(0,300)),!d)throw p;break}return{nfts:i,complete:s,next:l,pages:d,truncated:!s,errors:a}}import{getAddress as Ni}from"ethers";Fe();H();var wl=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});H();var Sl=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),Pt=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Rt=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});Fe();Fe();var Ai=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}}]}]);H();Fe();H();function Lt(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}H();function ge(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 Dn="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function we({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:jn(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([jn(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[Dn]||"")==="1")return{baseUrl:a,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${Dn}=1 to permit it)`);return{baseUrl:a,trusted:!1,host:l}}function jn(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function ce(e,t,n){let r={...e};if(!n)return r;for(let[o,i]of Object.entries(t||{}))i&&(r[o]=i);return r}function Hn(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var _i=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function Ii(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=Hn(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=_i.includes(o)&&(i==="https:"||a)}}catch{n=!1}return ce({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},n)}async function Ci(e,t={}){let r=await(t.fetchImpl||fetch)(e,{method:"GET",headers:Ii(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 Ut(e={},t={}){let n=ge(e.address||e.addr,"address"),r=Hn(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 Ci(c,t),u=Ti(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 Ti(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}))}H();H();H();var hu=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood",2741:"abstract",solana:"solana"});H();var vu=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"}),Oi=Object.freeze(["block_number","index"]),xu=new Set([...Oi,"items_count","value","hash","inserted_at","fee"]);var Qu=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 rt(e,...t){for(let n of t){let r=String(e?.[n]||"").trim();if(r)return r}return null}function Vn(e){if(!e)return null;try{return Ni(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function zn(e={},t=process.env){let n=e.addresses||{},r=Vn(n.evm||e.evmAddress||rt(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=n.solana||e.solanaAddress||rt(t,"ORACLE_SOLANA_ADDRESS"),i=n.bitcoin||e.bitcoinAddress||rt(t,"ORACLE_BITCOIN_ADDRESS"),a=Vn(n.hyperliquid||e.hyperliquidAddress||rt(t,"ORACLE_HYPERLIQUID_ADDRESS")||r);return{evm:r,solana:o?Lt(o,"portfolio Solana address"):null,bitcoin:i?ge(i,"portfolio Bitcoin address"):null,hyperliquid:a}}H();import{readFileSync as Pi,existsSync as Ri}from"node:fs";import{getAddress as Li,Interface as ot,TypedDataEncoder as id,parseUnits as ad}from"ethers";var $i=300*1e3,Zu=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})();var Ui="https://api.opensea.io/api/v2",Fi="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)",dd=new ot([`function ${Fi}`]),pd=new ot(["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"]),Mi=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"]),Bi=new Set(Mi),qi=new Set(["solana","flow"]);function Di(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!Ri(e))return"";try{for(let t of Pi(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 Me(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||Di()}function Gn(e={}){return we({provider:"opensea",defaultUrl:Ui,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function it(e={}){return Gn(e).baseUrl}function at(e={}){return ce({accept:"application/json"},{"x-api-key":Me(e)},Gn(e).trusted)}function ji(e){let t=String(e||"ethereum").trim().toLowerCase();if(!Bi.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function Wn(e,t="address"){try{return Li(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function Kn(e,t=null){let n=String(e||"").trim();if(!n)throw new Error("opensea: account address required");if(t&&!qi.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(n))return Wn(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 Hi(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 Vi(e,t={}){if(!e)throw new Error("collection slug required");if(!Me(t))throw new Error("OPENSEA_API_KEY required");return j(`${it(t)}/collections/${encodeURIComponent(e)}`,{headers:at(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function zi(e,t={}){if(!e)throw new Error("collection slug required");if(!Me(t))throw new Error("OPENSEA_API_KEY required");return j(`${it(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:at(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Yn(e,t={}){let n=await Vi(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 zi(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 Mt(e={},t={}){if(!Me(t))throw new Error("OPENSEA_API_KEY required");let n=ji(e.chain),r=Kn(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(`${it(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 j(u.toString(),{headers:at(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let s of Array.isArray(d?.nfts)?d.nfts:[])a.push(Hi(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 Jn(e={},t={}){if(!Me(t))throw new Error("OPENSEA_API_KEY required");let n=Kn(e.address||e.owner),r=await j(`${it(t)}/account/${encodeURIComponent(n)}/pnl`,{headers:at(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 fd=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 md=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 hd=new ot(["function setApprovalForAll(address operator,bool approved)"]),yd=new ot(["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 Gi="https://api.satflow.com/v1";function Qn(e={}){return we({provider:"satflow",defaultUrl:Gi,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function Ki(e={}){return Qn(e).baseUrl}function Xn(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function Yi(e={}){return ce({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":Xn(e)},Qn(e).trusted)}async function Ji(e,{method:t="GET",body:n,opts:r={}}={}){if(!Xn(r))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${Ki(r)}${e.startsWith("/")?e:`/${e}`}`,c=await(r.fetchImpl||fetch)(i,{method:t,headers:Yi(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 Zn(e={},t={}){let n=ge(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 Ji(`/address/wallet-contents?${r}`,{opts:t});return{provider:"satflow",address:n,contents:o}}H();H();var Nd=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 Qi=[/\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],Xi=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,Zi=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function ea(e={}){let t=[],n=String(e.name||""),r=String(e.description||""),o=`${n} ${r}`;Xi.test(n)&&t.push("url-in-name");let i=Qi.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),Zi.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 er(e={}){let t=ea(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}var ta=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"}]),na=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 Bt(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function be(e,t){let n=await tt(t);return n.ok?{ok:!0,data:n.data}:{ok:!1,error:`${e}: ${n.error}`.slice(0,300)}}function ra(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 oa(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 ia(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 tr(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function aa(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 sa(e,t){let n=tr(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 ca(e){let t=new Map;for(let n of e){let r=tr(n);t.has(r)||t.set(r,n)}return[...t.values()]}function la(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 nr(e={},t={}){let n=new Date().toISOString(),r=zn(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(f=>String(f).toLowerCase())):null,i=ta.filter(f=>!o||o.has(f.chain)),a=[],c=[],l=Bt(t,"opensea"),u=r.evm?i.filter(f=>f.family!=="solana"):[],d=await Ue(u,4,async f=>({row:f,result:await be(`opensea-${f.chain}`,()=>Mt({chain:f.chain,address:r.evm,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3)}));for(let{row:f,result:S}of d)if(S.ok){let b=S.data.nfts.map(v=>({...v,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:S.data.complete?"ok":"partial",count:b.length,complete:S.data.complete,next:S.data.next,source:"opensea"})}else{let b=Fn(f.chainId)?await be(`blockscout-${f.chain}`,()=>Mn({chain:f.chain,chainId:f.chainId,address:r.evm,maxPages:e.maxPages},{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})):null;b?.ok?(c.push(...b.data.nfts),a.push({...f,status:b.data.complete?"ok":"partial",count:b.data.nfts.length,complete:b.data.complete,next:b.data.next,truncated:b.data.truncated,source:"blockscout",errors:[S.error,...b.data.errors]})):a.push({...f,status:"unavailable",count:null,complete:!1,error:S.error,errors:[S.error,...b?[b.error]:[]],source:"opensea"})}if(!r.evm)for(let f of i.filter(S=>S.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 be("opensea-solana",()=>Mt({chain:"solana",address:r.solana,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3);if(f.ok){let S=f.data.nfts.map(b=>({...b,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));c.push(...S),a.push({family:"solana",chain:"solana",status:f.data.complete?"ok":"partial",count:S.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 be("satflow-wallet-contents",()=>Zn({address:r.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},Bt(t,"satflow")),t.timeoutMs??35e3);if(f.ok){let S=ra(f.data.contents).map(v=>oa(v,r.bitcoin));c.push(...S);let b=S.length<Number(e.bitcoinLimit??100);a.push({family:"bitcoin",chain:"bitcoin",status:b?"ok":"partial",count:S.length,complete:b,source:"satflow"})}else{let S=await be("bitcoin-meta-inscriptions",()=>Ut({address:r.bitcoin},Bt(t,"bitcoinMeta")),t.timeoutMs??35e3),b=S.ok&&S.data?.ok&&Array.isArray(S.data.inscriptions)?S.data.inscriptions:[];c.push(...b.map(v=>ia(v,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 S=await be(`opensea-pnl-${f}`,()=>Jn({address:f},l),t.timeoutMs??35e3);s.push(S.ok?{status:"ok",...S.data}:{status:"unavailable",address:f,source:"opensea-indexed-account-pnl",error:S.error})}let p=aa(e.costBasis),m=ca(c).map(f=>sa(f,p)).map(f=>er(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,S)=>f+Number(S.estimatedValueUsd),0)*100)/100,T=g.length-E.length,x=a.filter(f=>f.status!=="ok"||f.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:n,addresses:r,coverage:a,unsupported:na,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&&x.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:la(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 or=1,pa=/^0x[0-9a-f]{40}$/,fa=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,ma=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function ha(e=process.env){let t=e.ORACLE_CONFIG_DIR||st.join(rr(),".config","oracle");return st.join(t,"held-nft-pump.v1.json")}function ya(e=process.env){let t=e.ORACLE_CONFIG_DIR||st.join(rr(),".config","oracle"),n={};try{let o=JSON.parse(ua(st.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 ga(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function ir(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function wa(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 ba(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function Sa(e){if(!e||e.version!==or||!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||ir(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 va(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"?fa.test(a):pa.test(a)))continue;let l=wa(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:ba(r)})).sort((r,o)=>r.key.localeCompare(o.key))}function xa(e,t){let n=String(e?.currency||"").trim().toUpperCase();if(!ma.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 Ea(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 ar({filePath:e,env:t=process.env,clock:n=()=>Date.now(),inventoryFn:r=nr,floorFn:o=Yn,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=An({filePath:e||ha(t),kind:"oracle-held-nft-pump",clock:n,maxBytes:4*1024*1024,initialData:()=>({version:or,cursor:0,collections:{},failures:{}}),validateData:Sa}),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=ya(t),A=ga(t),T=da("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 x=await r({addresses:E,includePnl:!1,pageSize:u,maxPages:d},{env:A}),f=va(x),S=new Set(f.map(h=>h.key)),b=new Set((Array.isArray(x?.coverage)?x.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)&&!S.has(k)&&delete h.collections[k]}for(let k of Object.keys(h.failures||{})){let M=k.slice(0,k.indexOf(":"));b.has(M)&&!S.has(k)&&delete h.failures[k]}});let v=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[(v+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=xa(M,h);if(!R.ok){m(h.key,w),P.push({key:h.key,reason:R.reason});continue}let q=ir(M?.floor);if(q===null){m(h.key,w),P.push({key:h.key,reason:"floor-unavailable"});continue}let V=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=Ea({...h,name:M?.name||h.name},q,R.currency,_,w);return _.anchorFloor=q,_.lastAlertAt=w,_.updatedAt=w,_.currency=R.currency,K});if(!V)continue;let z;try{z=await i(V)}catch{z=null}if(!z||Number(z.delivered||0)!==1){P.push({key:h.key,reason:"notification-delivery-failed"});continue}O.push(V)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:f.length,checkedCollections:I.length,alerts:O,unavailable:P,coverage:x?.coverage??[]}}finally{p=!1}}return Object.freeze({filePath:s.filePath,tick:g,inspect:s.inspect})}Be();var gt=$e.ORACLE_CONFIG_DIR||Ge(Sc(),".config","oracle"),Ro=Ge(gt,"gateway.json");function _c(){return vc(Ro)?JSON.parse(wn(Ro,"utf8")):{platforms:{}}}function Ic(e={},t=$e){let n=e?.notifications?.heldNftPumps;return n===!1?!1:n===!0?!0:String(t.ORACLE_NFT_PUMP_ENABLED||"")==="1"}function Cc({configDir:e=gt,environment:t=$e}={}){let n=String(t.ORACLE_MESSAGING_PLATFORM||"").trim().toLowerCase();if(n)return n;try{let r=JSON.parse(wn(Ge(e,"messaging.json"),"utf8"));return String(r?.platform||"").trim().toLowerCase()}catch{return""}}function Tc(e,t=gt){let n=String(e?.platform||""),r=String(e?.recipientId||"");if(!n||!r)throw new TypeError("recipient-bound held NFT subscription is required");let o=Ac("sha256").update(`${n}\0${r}`).digest("hex").slice(0,24);return Ge(t,`held-nft-pump.${o}.v1.json`)}function Oc({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 yn(e){return e?Array.isArray(e)?e.filter(Boolean):[e]:[]}var Nc=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function yt(e,t,n,r){try{r.push(await t(n))}catch(o){let i=Nc[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 Uo=T(()=>{Ne()});import{createServer as vc}from"node:http";import{env as Pe}from"node:process";import{join as Ke}from"node:path";import{homedir as xc}from"node:os";import{readFileSync as bn,existsSync as Ac,mkdirSync as kc,writeFileSync as Ic}from"node:fs";import{createHash as _c,randomBytes as Cc}from"node:crypto";import ct from"node:path";import{homedir as or}from"node:os";import{readFileSync as fs}from"node:fs";import{createHash as ms}from"node:crypto";import $ from"node:fs";import Ye from"node:path";import{createHash as Ho,randomUUID as vn}from"node:crypto";var Et=1,W=class extends Error{constructor(t,n="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=n}};function Xe(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(Xe).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${Xe(e[n])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function xn(e){return Ho("sha256").update(Xe(e)).digest("hex")}function Je(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 Qe(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function An(e){$.mkdirSync(e,{recursive:!0,mode:448});try{$.chmodSync(e,448)}catch{}}function vt(e){try{let t=$.statSync(e);return{...JSON.parse($.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function kn({filePath:e,kind:t,initialData:n,validateData:r,clock:o=()=>Date.now(),maxBytes:i=4*1024*1024,lockStaleMs:s=3e4,lockWaitMs:c=2e3,lockIdFactory:l=()=>vn()}={}){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(s)||s<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:Et,kind:t,generation:0,data:v}}function a(v){let f;try{f=JSON.parse(v)}catch(E){throw new W(`corrupt ${t} snapshot: invalid JSON (${E.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!==Et)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:S,...b}=f;if(typeof S!="string"||!/^[a-f0-9]{64}$/.test(S)||xn(b)!==S)throw new W(`corrupt ${t} snapshot: checksum mismatch`,"STORE_CORRUPT");try{r(f.data)}catch(E){throw new W(`corrupt ${t} snapshot: ${E.message}`,"STORE_CORRUPT")}return b}function p(){if(!$.existsSync(e))return d();let v=$.statSync(e);if(!v.isFile()||v.size>i)throw new W(`${t} snapshot is not a bounded regular file`,"STORE_BOUNDS");try{$.chmodSync(e,384)}catch{}return a($.readFileSync(e,"utf8"))}function m(){An(Ye.dirname(e));let v=Je(o),f=String(l()),S=`${JSON.stringify({schemaVersion:1,lockId:f,pid:process.pid,acquiredAt:v})}
47
+ `,b=()=>{let P;try{return P=$.openSync(u,"wx",384),$.writeFileSync(P,S,"utf8"),$.fsyncSync(P),$.closeSync(P),{lockId:f}}catch(h){let k=P!==void 0;if(k)try{$.closeSync(P)}catch{}if(k)try{$.unlinkSync(u)}catch{}if(h?.code!=="EEXIST")throw h;return null}},_=Je(o)+c,N=new Int32Array(new SharedArrayBuffer(4));for(;;){let P=b();if(P)return P;let h=Je(o),k=vt(u),M=!1;if(k){let D=h-Number(k.acquiredAt??k.mtimeMs);M=Number.isFinite(D)&&D>=s}else try{M=h-$.statSync(u).mtimeMs>=s}catch{M=!1}if(M){let D=vt(u);if(k?D?.lockId===k.lockId:D===null){try{$.unlinkSync(u)}catch(z){if(z?.code!=="ENOENT")throw z}continue}}let R=_-h;if(R<=0)throw new W(`${t} store is busy`,"STORE_BUSY");Atomics.wait(N,0,0,Math.min(10,R))}}function g(v){if(vt(u)?.lockId===v.lockId)try{$.unlinkSync(u)}catch(S){if(S?.code!=="ENOENT")throw S}}function w(v){r(v.data);let f={...v,integrity:xn(v)},S=`${Xe(f)}
48
+ `;if(Buffer.byteLength(S)>i)throw new W(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let b=Ye.dirname(e);An(b);let E=Ye.join(b,`.${Ye.basename(e)}.${process.pid}.${vn()}.tmp`),_;try{_=$.openSync(E,"wx",384),$.writeFileSync(_,S,"utf8"),$.fsyncSync(_),$.closeSync(_),_=void 0,$.renameSync(E,e);try{$.chmodSync(e,384)}catch{}try{let N=$.openSync(b,"r");try{$.fsyncSync(N)}finally{$.closeSync(N)}}catch{}}finally{if(_!==void 0)try{$.closeSync(_)}catch{}try{$.unlinkSync(E)}catch(N){if(N?.code!=="ENOENT")throw N}}}function x(){return Qe(p().data)}function A(){let v=p();return{schemaVersion:v.schemaVersion,kind:v.kind,generation:v.generation,data:Qe(v.data)}}function O(v){if(typeof v!="function")throw new TypeError("mutator must be a function");let f=m();try{let S=p(),b=Qe(S.data),E=v(b,{generation:S.generation,now:Je(o)});return r(b),w({schemaVersion:Et,kind:t,generation:S.generation+1,data:b}),Qe(E)}finally{g(f)}}return Object.freeze({filePath:e,read:x,inspect:A,mutate:O})}H();H();import{getAddress as Ei}from"ethers";import{types as Un}from"node:util";function Nt(e){if(!e||typeof e!="object"||Un.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function ne(e,t="provider response",n=0){if(n>64)throw new Error(`${t} exceeds the JSON nesting bound`);if(e===null||typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return e;if(Array.isArray(e)){if(Un.isProxy(e)||e.length>1e5)throw new Error(`${t} contains an invalid array`);let o=new Array(e.length);for(let i=0;i<e.length;i+=1){let s=Object.getOwnPropertyDescriptor(e,String(i));if(!s||!Object.hasOwn(s,"value"))throw new Error(`${t} arrays must contain dense own data`);o[i]=ne(s.value,t,n+1)}return o}if(!Nt(e))throw new Error(`${t} contains a non-JSON value`);let r=Object.create(null);for(let o of Object.keys(e)){let i=Object.getOwnPropertyDescriptor(e,o);if(!i||!Object.hasOwn(i,"value"))throw new Error(`${t} objects must contain own data`);r[o]=ne(i.value,t,n+1)}return r}var wi=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,bi=/[<>&`*_~[\]()|\\]/g,Si=/[\u0000-\u001F\u007F]/g;function rt(e,{max:t=32,fallback:n=""}={}){return e==null?n:String(e).normalize("NFKC").replace(wi,"").replace(Si,"").replace(bi,"").replace(/\s+/g," ").trim().slice(0,t).trim()||n}var Fn=Object.freeze({1:"https://eth.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com"}),Mn=e=>!!Fn[e];function vi(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("invalid NFT cursor");let t=new URLSearchParams;for(let[n,r]of Object.entries(e)){if(!(n==="token_contract_address_hash"?/^0x[\da-f]{40}$/i.test(String(r)):n==="token_type"?["ERC-721","ERC-1155","ERC-404"].includes(r):["token_id","items_count"].includes(n)&&/^\d{1,100}$/.test(String(r))))throw new Error("invalid NFT cursor");t.set(n,String(r))}if(!t.size)throw new Error("empty NFT cursor");return t.toString()}async function Bn(e={},t={}){let n=Ei(e.address),r=Fn[e.chainId];if(!r)throw new Error("Blockscout NFT chain not verified");let o=Math.min(3,Math.max(1,Math.trunc(Number(e.maxPages)||3))),i=[],s=[],c=new Set,l=null,u="",d=0,a=!1;for(;d<o;)try{let p=ne(await j(`${r}/api/v2/addresses/${n}/nft${u?`?${u}`:""}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??8e3,maxResponseBytes:2e6,redirectPolicy:"error",headers:{accept:"application/json","user-agent":"OraclePortfolio/1.0"}}),"blockscout NFT inventory");if(!Array.isArray(p?.items))throw new Error("invalid NFT inventory response");d++;for(let g of p.items.slice(0,50)){let w=g.token;if(!/^0x[\da-f]{40}$/i.test(w?.address_hash||"")||!/^\d+$/.test(String(g.id??"")))throw new Error("invalid NFT identity");if(!["ERC-721","ERC-1155","ERC-404"].includes(w.type))throw new Error("invalid NFT standard");if(g.owner?.hash&&g.owner.hash.toLowerCase()!==n.toLowerCase())throw new Error("NFT owner mismatch");i.push({chain:e.chain,chainId:e.chainId,family:"evm",owner:n,contract:w.address_hash,tokenId:String(g.id),tokenStandard:w.type,collection:rt(w.name,{max:160,fallback:w.address_hash}),name:rt(g.metadata?.name||w.name,{max:160,fallback:`NFT ${g.id}`}),imageUrl:g.image_url||null,estimatedValueUsd:null,spam:["scam","spam"].includes(w.reputation)||w.is_spam===!0,source:"blockscout-owner-inventory",listingAdapter:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"owner indexer provides no acquisition cost"}})}if(p.items.length>50)throw new Error("NFT provider page exceeds 50 item bound");let m=p.next_page_params??null;if(!m){l=null,a=!0;break}if(l=null,u=vi(m),l=Object.fromEntries(new URLSearchParams(u)),c.has(u))throw new Error("repeated NFT cursor");c.add(u)}catch(p){if(s.push(`blockscout: ${p.message}`.slice(0,300)),!d)throw p;break}return{nfts:i,complete:a,next:l,pages:d,truncated:!a,errors:s}}import{getAddress as Ri}from"ethers";Me();H();var El=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});H();var xl=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),Rt=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Lt=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});Me();Me();var _i=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}}]}]);H();Me();H();function Ut(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}H();function ge(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 jn="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function we({provider:e,defaultUrl:t,hosts:n=[],url:r,strict:o=!1}){let s=(String(r??"").trim()||String(t)).replace(/\/$/,"");if(s===String(t).replace(/\/$/,""))return{baseUrl:s,trusted:!0,host:Hn(t)};let c;try{c=new URL(s)}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([Hn(t),...n]).has(l)){let d=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(l);return c.protocol==="http:"&&!d?{baseUrl:s,trusted:!1,host:l,reason:"plaintext http downgrade"}:{baseUrl:s,trusted:!0,host:l}}if(String(process.env[jn]||"")==="1")return{baseUrl:s,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${jn}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:l}}function Hn(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function ce(e,t,n){let r={...e};if(!n)return r;for(let[o,i]of Object.entries(t||{}))i&&(r[o]=i);return r}function Vn(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var Ti=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function Oi(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=Vn(e);if(r){let o=new URL(r).host,i=new URL(r).protocol,s=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(o);n=Ti.includes(o)&&(i==="https:"||s)}}catch{n=!1}return ce({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},n)}async function Ni(e,t={}){let r=await(t.fetchImpl||fetch)(e,{method:"GET",headers:Oi(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 Ft(e={},t={}){let n=ge(e.address||e.addr,"address"),r=Vn(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}`],s=null;for(let c of i)try{let l=await Ni(c,t),u=$i(l);return{provider:"bitcoin-meta",address:n,ok:!0,count:u.length,inscriptions:u,source:c}}catch(l){s=l}return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:String(s?.message||s||"all indexer paths failed")}}function $i(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}))}H();H();H();var wu=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood",2741:"abstract",solana:"solana"});H();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"}),Pi=Object.freeze(["block_number","index"]),ku=new Set([...Pi,"items_count","value","hash","inserted_at","fee"]);var ed=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 ot(e,...t){for(let n of t){let r=String(e?.[n]||"").trim();if(r)return r}return null}function zn(e){if(!e)return null;try{return Ri(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function Wn(e={},t=process.env){let n=e.addresses||{},r=zn(n.evm||e.evmAddress||ot(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=n.solana||e.solanaAddress||ot(t,"ORACLE_SOLANA_ADDRESS"),i=n.bitcoin||e.bitcoinAddress||ot(t,"ORACLE_BITCOIN_ADDRESS"),s=zn(n.hyperliquid||e.hyperliquidAddress||ot(t,"ORACLE_HYPERLIQUID_ADDRESS")||r);return{evm:r,solana:o?Ut(o,"portfolio Solana address"):null,bitcoin:i?ge(i,"portfolio Bitcoin address"):null,hyperliquid:s}}H();import{readFileSync as Ui,existsSync as Fi}from"node:fs";import{getAddress as Mi,Interface as it,TypedDataEncoder as cd,parseUnits as ld}from"ethers";be();var Bi="https://api.opensea.io/api/v2",Di="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)",md=new it([`function ${Di}`]),hd=new it(["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"]),qi=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"]),ji=new Set(qi),Hi=new Set(["solana","flow"]);function Vi(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!Fi(e))return"";try{for(let t of Ui(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 Be(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||Vi()}function Kn(e={}){return we({provider:"opensea",defaultUrl:Bi,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function st(e={}){return Kn(e).baseUrl}function at(e={}){return ce({accept:"application/json"},{"x-api-key":Be(e)},Kn(e).trusted)}function zi(e){let t=String(e||"ethereum").trim().toLowerCase();if(!ji.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function Gn(e,t="address"){try{return Mi(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function Yn(e,t=null){let n=String(e||"").trim();if(!n)throw new Error("opensea: account address required");if(t&&!Hi.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(n))return Gn(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 Wi(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 Gi(e,t={}){if(!e)throw new Error("collection slug required");if(!Be(t))throw new Error("OPENSEA_API_KEY required");return j(`${st(t)}/collections/${encodeURIComponent(e)}`,{headers:at(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Ki(e,t={}){if(!e)throw new Error("collection slug required");if(!Be(t))throw new Error("OPENSEA_API_KEY required");return j(`${st(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:at(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Jn(e,t={}){let n=await Gi(e,t),r=n.stats||n.total||{},o=n.floor_price??n.floorPrice??r.floor_price??r.floorPrice??null;if(o==null){let a=await Ki(e,t);r=a?.total||a?.stats||a||{},o=r.floor_price??r.floorPrice??null}let i=(Array.isArray(n.contracts)?n.contracts:[]).map(a=>({chain:String(a?.chain||a?.chain_identifier||n.chain||"").trim().toLowerCase(),address:String(a?.address||a?.contract_address||a?.contract||"").trim()})).filter(a=>a.chain&&a.address),s=String(t.expectedChain||"").trim().toLowerCase(),c=String(t.expectedContract||"").trim(),l=null;if(s&&c){let a=p=>s==="solana"?p:p.toLowerCase();if(l=i.find(p=>p.chain===s&&a(p.address)===a(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 Bt(e={},t={}){if(!Be(t))throw new Error("OPENSEA_API_KEY required");let n=zi(e.chain),r=Yn(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),s=[],c=e.next?String(e.next):null,l=0;do{let u=new URL(`${st(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 j(u.toString(),{headers:at(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let a of Array.isArray(d?.nfts)?d.nfts:[])s.push(Wi(a,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:s.length,pages:l,complete:!c,next:c,nfts:s,exec:!1,readOnly:!0}}async function Qn(e={},t={}){if(!Be(t))throw new Error("OPENSEA_API_KEY required");let n=Yn(e.address||e.owner),r=await j(`${st(t)}/account/${encodeURIComponent(n)}/pnl`,{headers:at(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 yd=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 gd=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 wd=new it(["function setApprovalForAll(address operator,bool approved)"]),bd=new it(["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)"]);be();var Ji="https://api.satflow.com/v1";function Xn(e={}){return we({provider:"satflow",defaultUrl:Ji,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function Qi(e={}){return Xn(e).baseUrl}function Zn(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function Xi(e={}){return ce({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":Zn(e)},Xn(e).trusted)}async function Zi(e,{method:t="GET",body:n,opts:r={}}={}){if(!Zn(r))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${Qi(r)}${e.startsWith("/")?e:`/${e}`}`,c=await(r.fetchImpl||fetch)(i,{method:t,headers:Xi(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 er(e={},t={}){let n=ge(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 Zi(`/address/wallet-contents?${r}`,{opts:t});return{provider:"satflow",address:n,contents:o}}H();be();H();var Rd=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 es=[/\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],ts=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,ns=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function rs(e={}){let t=[],n=String(e.name||""),r=String(e.description||""),o=`${n} ${r}`;ts.test(n)&&t.push("url-in-name");let i=es.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),ns.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 s=e.estimatedValueUsd==null&&e.estimatedValueSats==null,c=!Array.isArray(e.traits)||e.traits.length===0;s&&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 tr(e={}){let t=rs(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}be();var os=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"}]),is=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 Dt(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function Se(e,t){let n=await nt(t);return n.ok?{ok:!0,data:n.data}:{ok:!1,error:`${e}: ${n.error}`.slice(0,300)}}function ss(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 as(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 cs(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 nr(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function ls(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 us(e,t){let n=nr(e),r=t.get(n),o=e.estimatedValueUsd==null?null:Number(e.estimatedValueUsd);if(!r)return{...e,assetKey:n};let i=Number(r.costUsd),s=Number(r.feesUsd??0);if(!Number.isFinite(i)||i<0||!Number.isFinite(s)||s<0)return{...e,assetKey:n,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"invalid user-supplied cost basis"}};let c=Math.round((i+s)*100)/100;return Number.isFinite(o)?{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:s,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:s,totalCostUsd:c,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"unavailable",reason:"current NFT valuation is unavailable"}}}function ds(e){let t=new Map;for(let n of e){let r=nr(n);t.has(r)||t.set(r,n)}return[...t.values()]}function ps(e,t){let n=e.filter(i=>i.itemPnl?.status==="estimated"),r=e.length-n.length,o=Math.round(n.reduce((i,s)=>i+Number(s.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 rr(e={},t={}){let n=new Date().toISOString(),r=Wn(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(f=>String(f).toLowerCase())):null,i=os.filter(f=>!o||o.has(f.chain)),s=[],c=[],l=Dt(t,"opensea"),u=r.evm?i.filter(f=>f.family!=="solana"):[],d=await Fe(u,4,async f=>({row:f,result:await Se(`opensea-${f.chain}`,()=>Bt({chain:f.chain,address:r.evm,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3)}));for(let{row:f,result:S}of d)if(S.ok){let b=S.data.nfts.map(E=>({...E,family:f.family,chainId:f.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));c.push(...b),s.push({family:f.family,chain:f.chain,chainId:f.chainId,status:S.data.complete?"ok":"partial",count:b.length,complete:S.data.complete,next:S.data.next,source:"opensea"})}else{let b=Mn(f.chainId)?await Se(`blockscout-${f.chain}`,()=>Bn({chain:f.chain,chainId:f.chainId,address:r.evm,maxPages:e.maxPages},{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})):null;b?.ok?(c.push(...b.data.nfts),s.push({...f,status:b.data.complete?"ok":"partial",count:b.data.nfts.length,complete:b.data.complete,next:b.data.next,truncated:b.data.truncated,source:"blockscout",errors:[S.error,...b.data.errors]})):s.push({...f,status:"unavailable",count:null,complete:!1,error:S.error,errors:[S.error,...b?[b.error]:[]],source:"opensea"})}if(!r.evm)for(let f of i.filter(S=>S.family!=="solana"))s.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 Se("opensea-solana",()=>Bt({chain:"solana",address:r.solana,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3);if(f.ok){let S=f.data.nfts.map(b=>({...b,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));c.push(...S),s.push({family:"solana",chain:"solana",status:f.data.complete?"ok":"partial",count:S.length,complete:f.data.complete,next:f.data.next,source:"opensea"})}else s.push({family:"solana",chain:"solana",status:"unavailable",error:f.error,source:"opensea"})}else(!o||o.has("solana"))&&s.push({family:"solana",chain:"solana",status:"not-configured",reason:"Solana address missing"});if(r.bitcoin&&(!o||o.has("bitcoin"))){let f=await Se("satflow-wallet-contents",()=>er({address:r.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},Dt(t,"satflow")),t.timeoutMs??35e3);if(f.ok){let S=ss(f.data.contents).map(E=>as(E,r.bitcoin));c.push(...S);let b=S.length<Number(e.bitcoinLimit??100);s.push({family:"bitcoin",chain:"bitcoin",status:b?"ok":"partial",count:S.length,complete:b,source:"satflow"})}else{let S=await Se("bitcoin-meta-inscriptions",()=>Ft({address:r.bitcoin},Dt(t,"bitcoinMeta")),t.timeoutMs??35e3),b=S.ok&&S.data?.ok&&Array.isArray(S.data.inscriptions)?S.data.inscriptions:[];c.push(...b.map(E=>cs(E,r.bitcoin))),s.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"))&&s.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let a=[];if(e.includePnl!==!1)for(let f of[...new Set([r.evm,r.solana].filter(Boolean))]){let S=await Se(`opensea-pnl-${f}`,()=>Qn({address:f},l),t.timeoutMs??35e3);a.push(S.ok?{status:"ok",...S.data}:{status:"unavailable",address:f,source:"opensea-indexed-account-pnl",error:S.error})}let p=ls(e.costBasis),m=ds(c).map(f=>us(f,p)).map(f=>tr(f)),g=m.filter(f=>!f.spam),w=m.filter(f=>f.spam),x=g.filter(f=>f.estimatedValueUsd!=null&&Number.isFinite(Number(f.estimatedValueUsd))),A=Math.round(x.reduce((f,S)=>f+Number(S.estimatedValueUsd),0)*100)/100,O=g.length-x.length,v=s.filter(f=>f.status!=="ok"||f.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:n,addresses:r,coverage:s,unsupported:is,inventory:{count:m.length,visibleCount:g.length,flaggedCount:w.length,items:m,visibleItems:g,flaggedItems:w},valuation:{estimatedCurrentValueUsd:A,valuedItems:x.length,unvaluedItems:O,complete:O===0&&v.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:ps(g,a),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 ir=1,hs=/^0x[0-9a-f]{40}$/,ys=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,gs=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function ws(e=process.env){let t=e.ORACLE_CONFIG_DIR||ct.join(or(),".config","oracle");return ct.join(t,"held-nft-pump.v1.json")}function bs(e=process.env){let t=e.ORACLE_CONFIG_DIR||ct.join(or(),".config","oracle"),n={};try{let o=JSON.parse(fs(ct.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 Ss(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function sr(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function Es(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 vs(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function xs(e){if(!e||e.version!==ir||!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||sr(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 As(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(),s=o==="solana"?i:i.toLowerCase(),c=String(r?.collection||"").trim().toLowerCase();if(!o||!c||!(o==="solana"?ys.test(s):hs.test(s)))continue;let l=Es(r);if(l===0n)continue;let u=`${o}:${s}`,d=n.get(u);d&&d.slug!==c||n.set(u,{key:u,chain:o,contract:s,slug:c,name:d?.name||String(r?.name||c),heldCountRaw:(d?.heldCountRaw||0n)+l})}return[...n.values()].map(({heldCountRaw:r,...o})=>({...o,heldCount:vs(r)})).sort((r,o)=>r.key.localeCompare(o.key))}function ks(e,t){let n=String(e?.currency||"").trim().toUpperCase();if(!gs.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(s=>{let c=String(s?.address||s?.contract_address||s?.contract||"").trim(),l=t.chain==="solana"?c:c.toLowerCase(),u=String(s?.chain||s?.chain_identifier||"").trim().toLowerCase();return l===o&&u===t.chain})?{ok:!0,currency:n}:{ok:!1,reason:"floor-identity-mismatch"}}function Is(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 ar({filePath:e,env:t=process.env,clock:n=()=>Date.now(),inventoryFn:r=rr,floorFn:o=Jn,notifyFn:i=async()=>({delivered:0}),thresholdPct:s=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(s)||s<=0||s>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 a=kn({filePath:e||ws(t),kind:"oracle-held-nft-pump",clock:n,maxBytes:4*1024*1024,initialData:()=>({version:ir,cursor:0,collections:{},failures:{}}),validateData:xs}),p=!1;function m(w,x){a.mutate(A=>{A.failures||={};let O=Math.min(20,Number(A.failures[w]?.count||0)+1);A.failures[w]={count:O,nextCheckAt:x+Math.min(6*36e5,3e5*2**Math.min(6,O-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 x=bs(t),A=Ss(t),O=ms("sha256").update(JSON.stringify(Object.entries(x).sort())).digest("hex");a.mutate(h=>{let k=!!(h.walletFingerprint&&h.walletFingerprint!==O);k&&(h.collections={},h.failures={},h.cursor=0),h.walletFingerprint=O,h.walletChanged=k});let v=await r({addresses:x,includePnl:!1,pageSize:u,maxPages:d},{env:A}),f=As(v),S=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&&a.mutate(h=>{for(let k of Object.keys(h.collections)){let M=k.slice(0,k.indexOf(":"));b.has(M)&&!S.has(k)&&delete h.collections[k]}for(let k of Object.keys(h.failures||{})){let M=k.slice(0,k.indexOf(":"));b.has(M)&&!S.has(k)&&delete h.failures[k]}});let E=a.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}),_=[];for(let h=0;h<Math.min(l,f.length);h+=1)_.push(f[(E+h)%f.length]);let N=[],P=[];for(let h of _){let k=a.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=ks(M,h);if(!R.ok){m(h.key,w),P.push({key:h.key,reason:R.reason});continue}let D=sr(M?.floor);if(D===null){m(h.key,w),P.push({key:h.key,reason:"floor-unavailable"});continue}let V=a.mutate(L=>{L.failures||={},delete L.failures[h.key];let I=L.collections[h.key];if(!I)return L.collections[h.key]={anchorFloor:D,lastAlertAt:null,updatedAt:w,currency:R.currency},null;if(I.updatedAt=w,I.currency!==R.currency)return I.anchorFloor=D,I.currency=R.currency,I.lastAlertAt=null,null;if(D<I.anchorFloor)return I.anchorFloor=D,I.currency=R.currency,null;if((D/I.anchorFloor-1)*100+1e-9<s)return null;if(I.lastAlertAt!==null&&w-I.lastAlertAt<c)return I.anchorFloor=D,I.currency=R.currency,null;let K=Is({...h,name:M?.name||h.name},D,R.currency,I,w);return I.anchorFloor=D,I.lastAlertAt=w,I.updatedAt=w,I.currency=R.currency,K});if(!V)continue;let z;try{z=await i(V)}catch{z=null}if(!z||Number(z.delivered||0)!==1){P.push({key:h.key,reason:"notification-delivery-failed"});continue}N.push(V)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:f.length,checkedCollections:_.length,alerts:N,unavailable:P,coverage:v?.coverage??[]}}finally{p=!1}}return Object.freeze({filePath:a.filePath,tick:g,inspect:a.inspect})}De();var wt=Pe.ORACLE_CONFIG_DIR||Ke(xc(),".config","oracle"),Fo=Ke(wt,"gateway.json");function Tc(){return Ac(Fo)?JSON.parse(bn(Fo,"utf8")):{platforms:{}}}function Oc(e={},t=Pe){let n=e?.notifications?.heldNftPumps;return n===!1?!1:n===!0?!0:String(t.ORACLE_NFT_PUMP_ENABLED||"")==="1"}function Nc({configDir:e=wt,environment:t=Pe}={}){let n=String(t.ORACLE_MESSAGING_PLATFORM||"").trim().toLowerCase();if(n)return n;try{let r=JSON.parse(bn(Ke(e,"messaging.json"),"utf8"));return String(r?.platform||"").trim().toLowerCase()}catch{return""}}function $c(e,t=wt){let n=String(e?.platform||""),r=String(e?.recipientId||"");if(!n||!r)throw new TypeError("recipient-bound held NFT subscription is required");let o=_c("sha256").update(`${n}\0${r}`).digest("hex").slice(0,24);return Ke(t,`held-nft-pump.${o}.v1.json`)}function Pc({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 s of t)try{await s?.stop?.()}catch{}n?.close&&await new Promise(s=>n.close(()=>s())),r(0)})(),o)}}function gn(e){return e?Array.isArray(e)?e.filter(Boolean):[e]:[]}var Rc=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function gt(e,t,n,r){try{r.push(await t(n))}catch(o){let i=Rc[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 $c(){let e=_c(),t=[],n=yn(e.platforms?.telegram),r=yn(e.platforms?.discord),o=yn(e.agents),a=n.length+r.length+o.length>1?new(await Promise.resolve().then(()=>(dr(),ur))).A2ABus:null;if(a&&o.length){let{routePeerConsult:s,buildPersona:p}=await Promise.resolve().then(()=>(Oe(),fo));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 Lc(){let e=Tc(),t=[],n=gn(e.platforms?.telegram),r=gn(e.platforms?.discord),o=gn(e.agents),s=n.length+r.length+o.length>1?new(await Promise.resolve().then(()=>(pr(),dr))).A2ABus:null;if(s&&o.length){let{routePeerConsult:a,buildPersona:p}=await Promise.resolve().then(()=>(Ne(),yo));for(let m of o)try{let g=p(m);s.register(m.name,{role:m.role||"",chains:m.chains||[],handler:w=>a({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 yt("telegram",async()=>(await Promise.resolve().then(()=>(_o(),ko))).telegram({...s,bus:a}),e,t);for(let s of r)await yt("discord",async()=>(await Promise.resolve().then(()=>(Co(),Io))).discord({...s,bus:a}),e,t);e.platforms?.whatsapp&&await yt("whatsapp",async s=>(await Promise.resolve().then(()=>(No(),Oo))).whatsapp(s.platforms.whatsapp),e,t),e.platforms?.signal&&await yt("signal",async s=>(await Promise.resolve().then(()=>(Po(),$o))).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 a of n)await gt("telegram",async()=>(await Promise.resolve().then(()=>(To(),Co))).telegram({...a,bus:s}),e,t);for(let a of r)await gt("discord",async()=>(await Promise.resolve().then(()=>(No(),Oo))).discord({...a,bus:s}),e,t);e.platforms?.whatsapp&&await gt("whatsapp",async a=>(await Promise.resolve().then(()=>(Ro(),Po))).whatsapp(a.platforms.whatsapp),e,t),e.platforms?.signal&&await gt("signal",async a=>(await Promise.resolve().then(()=>(Uo(),Lo))).signal_(a.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(Ic(e,$e)){let s=sr(t,Cc());if(s){let p=ar({env:$e,filePath:Tc(s),notifyFn:cr(s)});c=lr({watchdog:p}),c.start(),process.stderr.write(`oracle-gateway: held NFT pump watch active via ${s.platform}
56
+ `);let c=null;if(Oc(e,Pe)){let a=cr(t,Nc());if(a){let p=ar({env:Pe,filePath:$c(a),notifyFn:lr(a)});c=ur({watchdog:p}),c.start(),process.stderr.write(`oracle-gateway: held NFT pump watch active via ${a.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?Uc():null,u=bc((s,p)=>Rc(s,p,{config:e,bus:a,a2aToken:l}));u.listen($e.ORACLE_GATEWAY_PORT||9270,"127.0.0.1");let d=Oc({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 Pc=16384;async function Rc(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>Pc&&e.destroy()}),e.on("end",async()=>{try{let u=JSON.parse(l||"{}"),d=Lc(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 Lc(e){return String(e||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function Uc(e=gt){let t=Ge(e,"a2a-token");try{let r=wn(t,"utf8").trim();if(r)return r}catch{}let n=kc(24).toString("hex");return xc(e,{recursive:!0}),Ec(t,`${n}
60
- `,{mode:384}),n}var{pathToFileURL:Fc}=await import("node:url"),{realpathSync:Mc}=await import("node:fs"),Lo=process.argv[1],gn=!1;if(Lo)try{gn=import.meta.url===Fc(Mc(Lo)).href}catch{gn=!1}gn&&$c().catch(e=>{process.stderr.write(`oracle-gateway: ${e.message}
61
- `),process.exit(1)});export{Oc as createGatewayShutdown,Uc as ensureA2AToken,Ic as heldNftPumpEnabled,Tc as heldNftSubscriptionStatePath,Cc as preferredMessagingPlatform,Rc as serveHttp,yn as toEntries};
58
+ `)}let l=s?Bc():null,u=vc((a,p)=>Fc(a,p,{config:e,bus:s,a2aToken:l}));u.listen(Pe.ORACLE_GATEWAY_PORT||9270,"127.0.0.1");let d=Pc({heldNftPumpLoop:c,platforms:t,server:u});process.once("SIGINT",()=>{d()}),process.once("SIGTERM",()=>{d()}),s&&process.stderr.write(`oracle-gateway: a2a loopback contract at GET /a2a (token: a2a-token in config dir)
59
+ `)}var Uc=16384;async function Fc(e,t,{config:n,bus:r,a2aToken:o}){let i=new URL(e.url||"/","http://127.0.0.1"),s=(l,u)=>{t.writeHead(l,{"Content-Type":"application/json"}),t.end(JSON.stringify(u))};if(e.method==="GET"&&(i.pathname==="/"||i.pathname==="/health"))return s(200,{status:"ok",platforms:Object.keys(n.platforms||{}),a2a:!!r});if(!i.pathname.startsWith("/a2a"))return s(404,{error:"not found"});if(!r)return s(404,{error:"a2a bus not running (fewer than 2 agents configured)"});if(e.method==="GET"&&i.pathname==="/a2a")return s(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 s(401,{error:"bad or missing bearer token (read a2a-token in the oracle config dir)"});if(e.method==="GET"&&i.pathname==="/a2a/agents")return s(200,{agents:r.roster()});if(e.method==="POST"&&i.pathname==="/a2a/ask"){let l="";e.on("data",u=>{l+=u,l.length>Uc&&e.destroy()}),e.on("end",async()=>{try{let u=JSON.parse(l||"{}"),d=Mc(u.from);r.agents.has(d)||r.register(d,{role:"loopback client",handler:async()=>null});let a=await r.send({from:d,to:u.to,text:u.text,kind:"consult"});return s(a.ok?200:400,a)}catch(u){return s(400,{ok:!1,error:`bad request: ${u.message}`})}});return}return s(404,{error:"not found"})}function Mc(e){return String(e||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function Bc(e=wt){let t=Ke(e,"a2a-token");try{let r=bn(t,"utf8").trim();if(r)return r}catch{}let n=Cc(24).toString("hex");return kc(e,{recursive:!0}),Ic(t,`${n}
60
+ `,{mode:384}),n}var{pathToFileURL:Dc}=await import("node:url"),{realpathSync:qc}=await import("node:fs"),Mo=process.argv[1],wn=!1;if(Mo)try{wn=import.meta.url===Dc(qc(Mo)).href}catch{wn=!1}wn&&Lc().catch(e=>{process.stderr.write(`oracle-gateway: ${e.message}
61
+ `),process.exit(1)});export{Pc as createGatewayShutdown,Bc as ensureA2AToken,Oc as heldNftPumpEnabled,$c as heldNftSubscriptionStatePath,Nc as preferredMessagingPlatform,Fc as serveHttp,gn as toEntries};