@oracle-agent/oracle 0.35.45 → 0.35.47

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 (69) hide show
  1. package/dist/agent-sessions.mjs +19 -19
  2. package/dist/artifacts/token-dashboard.mjs +1 -0
  3. package/dist/assets/graphics/oracle_card.py +60 -0
  4. package/dist/assets/graphics/pnl-samples.mjs +22 -0
  5. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  6. package/dist/assets/skills/web-research.md +6 -2
  7. package/dist/automation-plan.d.mts +63 -0
  8. package/dist/automation-plan.mjs +1 -0
  9. package/dist/bin/desk-server.mjs +34 -31
  10. package/dist/bin/oracle-data-mcp.mjs +20 -19
  11. package/dist/bin/oracle-gateway.mjs +49 -48
  12. package/dist/bin/oracle-investigate.mjs +4 -4
  13. package/dist/bin/oracle-launch-radar-shadow.mjs +6 -6
  14. package/dist/bin/oracle-mev-arb-shadow.mjs +6 -6
  15. package/dist/bin/oracle-mev-shadow.mjs +6 -6
  16. package/dist/bin/oracle-public-server.mjs +5 -5
  17. package/dist/bin/oracle-route.mjs +16 -16
  18. package/dist/bin/oracle-scan.mjs +6 -6
  19. package/dist/bin/oracle-telegram-mcp.mjs +13 -12
  20. package/dist/chains.mjs +1 -1
  21. package/dist/cli/commands/account.mjs +11 -11
  22. package/dist/cli/commands/agent-session.mjs +21 -21
  23. package/dist/cli/commands/chat.mjs +216 -214
  24. package/dist/cli/commands/data.mjs +38 -35
  25. package/dist/cli/commands/doctor.mjs +5 -5
  26. package/dist/cli/commands/eval.mjs +147 -143
  27. package/dist/cli/commands/farm.mjs +6 -6
  28. package/dist/cli/commands/follow.mjs +48 -37
  29. package/dist/cli/commands/mint.mjs +12 -11
  30. package/dist/cli/commands/model.mjs +219 -217
  31. package/dist/cli/commands/quickstart.mjs +6 -6
  32. package/dist/cli/commands/receipt.mjs +5 -5
  33. package/dist/cli/commands/resolve.mjs +5 -5
  34. package/dist/cli/commands/session-vault.mjs +3 -3
  35. package/dist/cli/commands/snipe.mjs +9 -9
  36. package/dist/cli/commands/swap.mjs +11 -11
  37. package/dist/cli/commands/telegram.mjs +11 -10
  38. package/dist/cli/commands/venues.mjs +2 -2
  39. package/dist/data/chart-artifact.mjs +2 -0
  40. package/dist/data/desk-data.mjs +32 -29
  41. package/dist/data/holder-table.mjs +3 -0
  42. package/dist/data/market-tape.mjs +1 -0
  43. package/dist/data/names.mjs +3 -3
  44. package/dist/data/providers/farming.mjs +2 -2
  45. package/dist/data/providers/lp-destination-discovery.mjs +4 -4
  46. package/dist/index.mjs +50 -47
  47. package/dist/investigator/index.mjs +2 -2
  48. package/dist/launch-radar/index.mjs +5 -5
  49. package/dist/lp/index.mjs +5 -0
  50. package/dist/nft/universal-mint-router.mjs +4 -4
  51. package/dist/notifications/contract-watchman.mjs +4 -0
  52. package/dist/notifications/index.mjs +7 -7
  53. package/dist/router/index.mjs +3 -3
  54. package/dist/router/prepare-bridge.mjs +2 -2
  55. package/dist/router/prepare-route.mjs +3 -3
  56. package/dist/scanner/index.mjs +3 -3
  57. package/dist/strategy/index.mjs +5 -3
  58. package/dist/telegram/chart-card.mjs +5 -0
  59. package/dist/telegram/market-commands.mjs +2 -0
  60. package/dist/tui/standalone-client.mjs +77 -76
  61. package/package.json +10 -1
  62. package/public/oracle-splash/docs/browser-and-web/index.html +3 -3
  63. package/public/oracle-splash/docs/connectors/index.html +3 -3
  64. package/public/oracle-splash/docs/getting-started/index.html +2 -2
  65. package/public/oracle-splash/docs/index.html +3 -3
  66. package/public/oracle-splash/docs/reference/index.html +2 -2
  67. package/public/oracle-splash/docs/security/index.html +2 -2
  68. package/public/oracle-splash/docs/using-oracle/index.html +2 -2
  69. package/server.json +2 -2
@@ -1,61 +1,62 @@
1
1
  #!/usr/bin/env node
2
- var Go=Object.defineProperty;var T=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var ye=(e,t)=>{for(var r in t)Go(e,r,{get:t[r],enumerable:!0})};import{AsyncLocalStorage as Yo}from"node:async_hooks";function tt(e){let t=Jo.getStore();if(!t||t.closed||!Xo.includes(e))return null;if(t.spans.length>=Qo)return t.droppedSpans++,null;let r={stage:e,startMs:t.now()-t.start,durationMs:null,outcome:"pending",status:null};return t.spans.push(r),(n,o=null)=>{t.closed||r.durationMs!==null||(r.durationMs=Math.max(0,t.now()-t.start-r.startMs),r.outcome=n==="succeeded"?"succeeded":"failed",r.status=Number.isInteger(o)&&o>=100&&o<=599?o:null)}}var Jo,Xo,Qo,Cr=T(()=>{Jo=new Yo,Xo=["http","retry","shared"],Qo=512});import se from"node:net";import Zo from"node:dns";function rt(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=d=>{if(!d)return[];let c=d.split(":"),h=c.at(-1);if(h?.includes(".")){let p=h.split(".").map(Number);if(p.length!==4||p.some(f=>!Number.isInteger(f)||f<0||f>255))return null;c.splice(c.length-1,1,(p[0]<<8|p[1]).toString(16),(p[2]<<8|p[3]).toString(16))}return c.some(p=>!/^[0-9a-f]{1,4}$/.test(p))?null:c.map(p=>Number.parseInt(p,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let a=t.includes("::"),l=8-i.length-s.length;if(!a&&l!==0||a&&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 kt(e,t,r){let n=Math.floor(r/8),o=r%8;for(let s=0;s<n;s+=1)if(e[s]!==t[s])return!1;if(!o)return!0;let i=255<<8-o;return(e[n]&i)===(t[n]&i)}function _t(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=rt(e);if(!t)return!1;let r=rt("::ffff:0:0");return kt(t,r,96)?_t([...t.slice(12)].join(".")):kt(t,rt("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>kt(t,rt(o),i)):!1}return!1}function ti(e){let t;try{t=new URL(String(e))}catch{return{ok:!1,error:`not a valid URL: ${String(e).slice(0,120)}`}}if(t.protocol!=="http:"&&t.protocol!=="https:")return{ok:!1,error:`refused protocol ${t.protocol} (only http/https)`};let r=t.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(ei.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=se.isIP(r);return n!==0&&!_t(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function It(e,{lookupFn:t=Zo.promises.lookup}={}){let r=ti(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:se.isIPv6(r.host)?6:4}]};let n;if(process.env.ORACLE_HOSTED_EGRESS_PROXY)return{ok:!0,url:r.url,addresses:[]};try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(o=>!_t(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}function ri(e=process.env){let t=e.ORACLE_HOSTED_EGRESS_PROXY||"";if(!t)return null;let r;try{r=new URL(t)}catch{throw new Error("egress-guard: ORACLE_HOSTED_EGRESS_PROXY is not a URL")}if(r.protocol!=="http:"||!["127.0.0.1","::1","localhost","[::1]"].includes(r.hostname)||!r.port||r.username||r.password)throw new Error("egress-guard: egress proxy must be an exact loopback http origin");let n=e.ORACLE_HOSTED_EGRESS_TOKEN||"";if(!/^[A-Za-z0-9_-]{43}$/.test(n))throw new Error("egress-guard: egress proxy token is missing");return{uri:r.origin,token:n}}async function Ct({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n,o;try{o=await t(),r=o.Agent,n=o.fetch}catch(p){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${p?.message||p}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let i=p=>String(p).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),s=new Map,a=p=>(Array.isArray(p)?p:[p]).map(f=>typeof f=="string"?{address:f}:f).filter(f=>f&&f.address).map(f=>({address:f.address,family:f.family||(se.isIPv6(f.address)?6:4)})),l=(p,f,w)=>{s.set(i(p),a(typeof f=="string"?[{address:f,family:w}]:f))},u=p=>{let f=i(p);if(se.isIP(f))return[{address:f,family:se.isIPv6(f)?6:4}];let w=s.get(f);if(!w||!w.length)throw new Error(`refused: unpinned host ${p} during pinned fetch`);return w},d=ri(),c=d&&typeof o.ProxyAgent=="function"?new o.ProxyAgent({uri:d.uri,token:`Bearer ${d.token}`,connectTimeout:1e4}):new r({connect:{lookup(p,f,w){let S;try{S=u(p)}catch(A){return w(A)}return f?.all?w(null,S):w(null,S[0].address,S[0].family)}}}),h=ni((p,f={})=>n(p,{...f,dispatcher:c}),l);return{dispatcher:c,fetch:h,pin:l,resolve:u,async close(){try{await c.destroy()}catch{}}}}function ni(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[Tt]=Object.freeze({pin:t}),e}function Ot(e){return typeof e=="function"&&typeof e[Tt]?.pin=="function"}function Tr(e,t,r){if(!Ot(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Tt].pin(t,r)}var ei,Tt,Or=T(()=>{ei=new Set(["localhost","metadata.google.internal","metadata.goog"]);Tt=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as oi}from"node:crypto";import{types as J}from"node:util";function F(e){return te(`HTTP JSON body refused: ${e}`)}function fi(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 mi(e){let t=[],r=0,n=0,o=0,i=0,s=new WeakSet,a=d=>{if(r+=Buffer.byteLength(d,"utf8"),r>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,c)=>{if(n+=1,n>Y.nodes)throw F("node limit exceeded");if(c>Y.depth)throw F("depth limit exceeded");if(d===null){a("null");return}if(typeof d=="string"){a(l(d));return}if(typeof d=="boolean"){a(d?"true":"false");return}if(typeof d=="number"){if(!Number.isFinite(d))throw F("non-finite number");a(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(fi(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 f=Object.getPrototypeOf(d),w=0;for(;f!==null;){if(J.isProxy(f))throw F("proxy array prototype");if(w+=1,w>Y.depth)throw F("array prototype depth limit exceeded");f=Object.getPrototypeOf(f)}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 S=0;for(let A in d){if(i+=1,i>Y.fields)throw F("enumeration limit exceeded");if(Object.hasOwn(d,A)&&(S+=1,S>d.length))throw F("named array fields are unsupported")}if(S!==d.length)throw F("array entries must be dense enumerable own data");a("[");for(let A=0;A<d.length;A+=1)A&&a(","),u(Object.getOwnPropertyDescriptor(d,String(A)).value,c+1);a("]");return}let h=Object.getPrototypeOf(d);if(h!==Object.prototype&&h!==null)throw F("non-plain object");let p=[];for(let f in d){if(i+=1,i>Y.fields)throw F("enumeration limit exceeded");if(!Object.hasOwn(d,f))continue;if(o+=1,o>Y.fields)throw F("field limit exceeded");let w=Object.getOwnPropertyDescriptor(d,f);if(!w||!Object.hasOwn(w,"value")||w.enumerable!==!0)throw F("object fields must be enumerable own data");p.push([f,w.value])}a("{");for(let f=0;f<p.length;f+=1)f&&a(","),a(l(p[f][0])),a(":"),u(p[f][1],c+1);a("}")}finally{s.delete(d)}};return u(e,0),t.join("")}function hi(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 r=new Set;for(let n of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(n))throw new TypeError("HTTP header names must be valid tokens");let o=n.toLowerCase();if(r.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");r.add(o);let i=Object.getOwnPropertyDescriptor(e,n);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[n]=String(s)}return t}function yi(){return Object.assign(Object.create(null),{Accept:"application/json"})}function gi(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let r=new URL(String(e),String(t));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${r.protocol}`);return r.toString()}function wi(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function nt(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=Lr.get(e);return t||(t=Ur,Ur+=1,Lr.set(e,t)),`reference:${t}`}function Fr(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?bi.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 Mr(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}if(Array.isArray(r))return r.length>0&&r.every(Fr);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return Fr(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&Si.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function Ei(e,t,r,n={},o=null){let i=oi("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(r||{}).map((l,u)=>({name:l.toLowerCase(),order:u,value:String(r[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}`,n[l]??"-");return i.digest("hex")}function vi(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,$r):Math.min(250*2**e,$r)+Math.floor(Math.random()*100)}function te(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function $t(e,t,r){return te(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function ae(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function Ai(e){return e?e.byteLength??e.length??0:0}async function ki(e,t,{url:r,truncate:n=!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),!n))throw $t(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let c=await e.text(),h=Buffer.byteLength(c,"utf8");if(h>t){if(!n)throw $t(r,`body ${h} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let a=[],l=0,u=!1;try{for(;;){let{value:c,done:h}=await s.read();if(h)break;if(c&&(a.push(Buffer.from(c)),l+=Ai(c),l>t)){u=!0;break}}}finally{if(u)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!n))throw $t(r,`streamed ${l} bytes`,t);let d=Buffer.concat(a);return(u?d.subarray(0,t):d).toString("utf8")}function _i(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Ii(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:l=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:d=!1,importUndici:c,validateResponse:h,signal:p,redirectPolicy:f="follow",maxRedirects:w=ot}){let S=null,A=t,O=s?{lookupFn:s}:{};if(l&&!a&&!Ot(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,m=setTimeout(()=>x.abort(),i),E=p?Rr?Rr([p,x.signal]):p:x.signal,b=async(v,{status:I=null}={})=>{let N=await It(v,O);if(!N.ok)throw te(I==null?`HTTP refused ${v}: ${N.error}`:`HTTP redirect to ${v} ${N.error}`,I==null?{}:{status:I});let R=new URL(v).hostname;if(a){if(S&&(await S.close(),S=null),!S)try{S=await Ct({requireUndici:!0,...c?{importUndici:c}:{}})}catch(y){throw te(I==null?`HTTP refused ${v}: ${y?.message||y}`:`HTTP redirect to ${v} refused: ${y?.message||y}`,I==null?{}:{status:I})}S.pin(R,N.addresses),A=S.fetch}else Tr(A,R,N.addresses);return N};try{let v=String(e),I=Object.assign(Object.create(null),n||{});l&&await b(v);for(let N=0;N<=w;N+=1){let R=Object.assign(Object.create(null),{method:r,headers:I,body:o,signal:E,redirect:"manual",dispatcher:void 0}),y=await A(v,R);if((f==="error"||w===0)&&y.status>=300&&y.status<400)throw ae(y),te(`HTTP ${y.status} ${r} redirect refused`,{status:y.status,redirectRefused:!0});if(pi.has(y.status)){let L=d===!0&&r==="POST"&&[307,308].includes(y.status)&&Mr(r,o);if(r!=="GET"&&r!=="HEAD"&&!L){ae(y);let U=new Error(`HTTP ${y.status} ${r} ${v} redirected non-idempotent request`);throw U.status=y.status,U}if(N===w)throw ae(y),te(`HTTP ${y.status} ${r} redirect budget exhausted`,{status:y.status,redirectRefused:!0});let D=y.headers?.get?.("location"),V;try{V=gi(D,v)}catch(U){throw ae(y),U}let z=!wi(V,v);if(ae(y),z&&r==="POST"){let U=new Error(`HTTP ${y.status} ${r} cross-origin redirect refused`);throw U.status=y.status,U}if(z&&d){let U=new Error(`HTTP ${y.status} ${r} cross-origin redirect refused`);throw U.status=y.status,U.retryable=!1,U}if(z&&(I=yi(I)),l)await b(V,{status:y.status});else if(z){let U=await It(V,O);if(!U.ok){let k=new Error(`HTTP redirect from ${v} ${U.error}`);throw k.status=y.status,k.retryable=!1,k}a&&U.addresses?.length&&(S||(S=await Ct(c?{importUndici:c}:{})),S&&(S.pin(new URL(V).hostname,U.addresses),A=S.fetch))}v=V;continue}if(typeof h=="function")try{await h(y,{url:v})}catch(L){throw ae(y),te(L?.message||String(L))}let _=await ki(y,u,{url:v,onOversize:()=>x.abort()}),M=_i(_);if(!y.ok){let L=new Error(`HTTP ${y.status} ${r} ${v}`);throw L.status=y.status,L.retryAfter=y.headers?.get?.("retry-after")??null,L.body=M??_.slice(0,300),L}return M??_}throw new Error(`HTTP redirect loop for ${e}`)}catch(v){if(x.signal.aborted&&!Ue(p)){let I=v&&(typeof v=="object"||typeof v=="function")&&!J.isProxy(v)?v:null,N=I?Object.getOwnPropertyDescriptor(I,"oversize"):null;if(!(N&&Object.hasOwn(N,"value")&&N.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 y=new Error("HTTP request timed out");throw Object.defineProperties(y,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),y}}throw v}finally{clearTimeout(m),S&&await S.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 r=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let k of Object.getOwnPropertyNames(t)){let $=Object.getOwnPropertyDescriptor(t,k);if(!(k==="toJSON"&&$&&Object.hasOwn($,"value")&&$.value===void 0)){if(!r.has(k))throw new TypeError("HTTP options contain unknown fields");if(!$||!$.enumerable||!Object.hasOwn($,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=k=>{if(t==null||!Object.hasOwn(t,k))return;let $=Object.getOwnPropertyDescriptor(t,k);if(!$||!Object.hasOwn($,"value"))throw new TypeError("HTTP options must contain own data properties");return $.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=n("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let i=n("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let s=n("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>10))throw new TypeError("HTTP retries must be a bounded integer");let a=n("redirectPolicy");if(a!==void 0&&a!=="follow"&&a!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let l=n("maxRedirects");if(l!==void 0&&(!Number.isInteger(l)||l<0||l>ot))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${ot}`);if(a==="error"&&l!==void 0&&l!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=a??"follow",d=u==="error"?0:l??ot;for(let k of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let $=n(k);if($!==void 0&&typeof $!="boolean")throw new TypeError(`HTTP ${k} must be boolean`)}let c=n("maxResponseBytes");if(c!==void 0&&(!Number.isInteger(c)||c<1||c>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let h=n("signal");if(h!==void 0){if(J.isProxy(h)||!(h instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{Ue(h)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let k of["importUndici","lookupFn","validateResponse"]){let $=n(k);if($!==void 0&&typeof $!="function")throw new TypeError(`HTTP ${k} must be a function`)}let p=n("fetchImpl"),f=p||globalThis.fetch;if(typeof f!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let w=i??12e3,S=(o||"GET").toUpperCase(),A=n("headers"),O=hi(A),x=Object.assign(Object.create(null),O);Object.keys(x).some(k=>k.toLowerCase()==="accept")||(x.Accept="application/json");let m=n("body");m!=null&&typeof m!="string"&&(Object.keys(x).find($=>$.toLowerCase()==="content-type")||(x["Content-Type"]="application/json"),m=mi(m));let E=s??si,b=n("lookupFn"),v=!p,I=n("untrustedUrl")===!0,N=n("sameOriginRedirectsOnly")===!0,R=n("importUndici"),y=n("validateResponse"),_=h,M=c??null,L=async()=>{let k;for(let $=0;$<=E;$++){_&&li.call(_);let Ye=tt("http");try{let K=await Ii(e,{fetchImpl:f,method:S,headers:x,body:m,timeoutMs:w,lookupFn:b,realFetch:v,untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:N,importUndici:R,validateResponse:y,signal:_,redirectPolicy:u,maxRedirects:d});return Ye?.("succeeded"),K}catch(K){k=K;let he=vt=>{if(!K||typeof K!="object"&&typeof K!="function"||J.isProxy(K))return;let Re=Object.getOwnPropertyDescriptor(K,vt);return Re&&Object.hasOwn(Re,"value")?Re.value:void 0},Je=he("status");Ye?.("failed",Je);let Ho=he("oracleTimeout")===!0||he("name")==="AbortError"||he("name")==="TimeoutError"||Ue(_),Vo=new Set([408,425,429]),zo=he("retryable")===!1?!1:Je!=null?Vo.has(Je)||ii.has(Je)&&Nr.has(S):!Ho&&Nr.has(S);if($===E||!zo)throw K;let Er=vi($,he("retryAfter")),Wo=tt("retry"),vr=!1;try{_?await new Promise((vt,Re)=>{let xr,Le=()=>{clearTimeout(xr),Pr.call(_,"abort",Le),Re(di(_)||new DOMException("Aborted","AbortError"))};if(Ue(_)){Le();return}xr=setTimeout(()=>{Pr.call(_,"abort",Le),vt()},Er),ui.call(_,"abort",Le,{once:!0}),Ue(_)&&Le()}):await xi(Er),vr=!0}finally{Wo?.(vr?"succeeded":"failed")}}}throw k};if(!(n("dedupe")!==!1&&!_&&Mr(S,m)))return L();let V=Ei(S,e,x,{untrustedUrl:I,maxResponseBytes:M,sameOriginRedirectsOnly:N,redirectPolicy:u,maxRedirects:d,timeoutMs:w,retries:E,fetchImpl:nt(f),realFetch:v,lookupFn:nt(b),importUndici:nt(R),validateResponse:nt(y)},m),z=Nt.get(V);if(z){let k=tt("shared");try{let $=await z;return k?.("succeeded"),$}catch($){throw k?.("failed"),$}}let U=L().finally(()=>Nt.delete(V));return Nt.set(V,U),U}async function it(e){let t=Date.now();try{let r=await e();return{ok:!0,ms:Date.now()-t,data:r}}catch(r){return{ok:!1,ms:Date.now()-t,error:String(r.message||r),status:r.status??null}}}async function Fe(e,t,r){let n=Array.from(e),o=Math.max(1,Math.min(Number(t)||1,n.length||1)),i=new Array(n.length),s=0;return await Promise.all(Array.from({length:o},async()=>{for(;s<n.length;){let a=s++;i[a]=await r(n[a],a)}})),i}var ii,Nr,si,$r,ai,ci,li,ui,Pr,Rr,Ue,di,pi,ot,pl,Y,Nt,Lr,Ur,bi,Si,xi,H=T(()=>{Cr();Or();ii=new Set([408,425,429,500,502,503,504]),Nr=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),si=2,$r=4e3,ai=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,ci=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,li=AbortSignal.prototype.throwIfAborted,ui=EventTarget.prototype.addEventListener,Pr=EventTarget.prototype.removeEventListener,Rr=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,Ue=e=>e?ai.call(e):!1,di=e=>e?ci.call(e):void 0,pi=new Set([301,302,303,307,308]),ot=3,pl=64*1024,Y=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});Nt=new Map,Lr=new WeakMap,Ur=1;bi=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"]);xi=e=>new Promise(t=>setTimeout(t,e))});function Rt(e){return Pi.get(Number(e))||null}var Hr,Pi,Lt=T(()=>{Hr={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Pi=new Map(Object.values(Hr).map(e=>[e.chainId,e]))});import{Interface as Ri,getAddress as Cl}from"ethers";var Tl,Me=T(()=>{H();Lt();Tl=new Ri(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});var zi,hd,be=T(()=>{zi=300*1e3,hd=(()=>{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 Ht(e){let t=Number(e);return Number.isFinite(t)?t:null}function Ee(e,t={},r=process.env){let n=String(e||"").trim().toUpperCase().replace(/[^A-Z0-9]/g,"");if(!n)return[];let o=String(r[`ORACLE_OWNER_${n}`]||"").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 Fs(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",r=Ht(e.fromFloor),n=Ht(e.floor),o=Ht(e.changePct),i=le(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
2
+ var ts=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 _e=(e,t)=>{for(var n in t)ts(e,n,{get:t[n],enumerable:!0})};import{AsyncLocalStorage as rs}from"node:async_hooks";function pt(e){let t=os.getStore();if(!t||t.closed||!is.includes(e))return null;if(t.spans.length>=ss)return t.droppedSpans++,null;let n={stage:e,startMs:t.now()-t.start,durationMs:null,outcome:"pending",status:null};return t.spans.push(n),(r,o=null)=>{t.closed||n.durationMs!==null||(n.durationMs=Math.max(0,t.now()-t.start-n.startMs),n.outcome=r==="succeeded"?"succeeded":"failed",n.status=Number.isInteger(o)&&o>=100&&o<=599?o:null)}}var os,is,ss,Zn=_(()=>{os=new rs,is=["http","retry","shared"],ss=512});import ye from"node:net";import as from"node:dns";function ft(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let n=d=>{if(!d)return[];let c=d.split(":"),f=c.at(-1);if(f?.includes(".")){let m=f.split(".").map(Number);if(m.length!==4||m.some(p=>!Number.isInteger(p)||p<0||p>255))return null;c.splice(c.length-1,1,(m[0]<<8|m[1]).toString(16),(m[2]<<8|m[3]).toString(16))}return c.some(m=>!/^[0-9a-f]{1,4}$/.test(m))?null:c.map(m=>Number.parseInt(m,16))},[r,o]=t.split("::"),i=n(r),s=n(o);if(!i||!s)return null;let a=t.includes("::"),l=8-i.length-s.length;if(!a&&l!==0||a&&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 Ht(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 zt(e){if(ye.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(ye.isIPv6(e)){let t=ft(e);if(!t)return!1;let n=ft("::ffff:0:0");return Ht(t,n,96)?zt([...t.slice(12)].join(".")):Ht(t,ft("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>Ht(t,ft(o),i)):!1}return!1}function ls(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(cs.has(n)||n.endsWith(".localhost")||n.endsWith(".internal"))return{ok:!1,error:`refused internal host ${n}`};let r=ye.isIP(n);return r!==0&&!zt(n)?{ok:!1,error:`refused private address ${n}`}:{ok:!0,url:t,host:n,isLiteralIp:r!==0}}async function Vt(e,{lookupFn:t=as.promises.lookup}={}){let n=ls(e);if(!n.ok)return n;if(n.isLiteralIp)return{ok:!0,url:n.url,addresses:[{address:n.host,family:ye.isIPv6(n.host)?6:4}]};let r;if(process.env.ORACLE_HOSTED_EGRESS_PROXY)return{ok:!0,url:n.url,addresses:[]};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=>!zt(o.address))?{ok:!1,error:`refused: ${n.host} resolves to a non-public address`}:{ok:!0,url:n.url,addresses:r}}function us(e=process.env){let t=e.ORACLE_HOSTED_EGRESS_PROXY||"";if(!t)return null;let n;try{n=new URL(t)}catch{throw new Error("egress-guard: ORACLE_HOSTED_EGRESS_PROXY is not a URL")}if(n.protocol!=="http:"||!["127.0.0.1","::1","localhost","[::1]"].includes(n.hostname)||!n.port||n.username||n.password)throw new Error("egress-guard: egress proxy must be an exact loopback http origin");let r=e.ORACLE_HOSTED_EGRESS_TOKEN||"";if(!/^[A-Za-z0-9_-]{43}$/.test(r))throw new Error("egress-guard: egress proxy token is missing");return{uri:n.origin,token:r}}async function Kt({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let n,r,o;try{o=await t(),n=o.Agent,r=o.fetch}catch(m){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${m?.message||m}`);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 i=m=>String(m).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),s=new Map,a=m=>(Array.isArray(m)?m:[m]).map(p=>typeof p=="string"?{address:p}:p).filter(p=>p&&p.address).map(p=>({address:p.address,family:p.family||(ye.isIPv6(p.address)?6:4)})),l=(m,p,y)=>{s.set(i(m),a(typeof p=="string"?[{address:p,family:y}]:p))},u=m=>{let p=i(m);if(ye.isIP(p))return[{address:p,family:ye.isIPv6(p)?6:4}];let y=s.get(p);if(!y||!y.length)throw new Error(`refused: unpinned host ${m} during pinned fetch`);return y},d=us(),c=d&&typeof o.ProxyAgent=="function"?new o.ProxyAgent({uri:d.uri,token:`Bearer ${d.token}`,connectTimeout:1e4}):new n({connect:{lookup(m,p,y){let S;try{S=u(m)}catch(v){return y(v)}return p?.all?y(null,S):y(null,S[0].address,S[0].family)}}}),f=ds((m,p={})=>r(m,{...p,dispatcher:c}),l);return{dispatcher:c,fetch:f,pin:l,resolve:u,async close(){try{await c.destroy()}catch{}}}}function ds(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[Wt]=Object.freeze({pin:t}),e}function Gt(e){return typeof e=="function"&&typeof e[Wt]?.pin=="function"}function er(e,t,n){if(!Gt(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Wt].pin(t,n)}var cs,Wt,tr=_(()=>{cs=new Set(["localhost","metadata.google.internal","metadata.goog"]);Wt=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as ps}from"node:crypto";import{types as oe}from"node:util";function U(e){return ue(`HTTP JSON body refused: ${e}`)}function xs(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 oe[t]=="function"&&oe[t](e))}function Es(e){let t=[],n=0,r=0,o=0,i=0,s=new WeakSet,a=d=>{if(n+=Buffer.byteLength(d,"utf8"),n>re.bytes)throw U("serialized byte limit exceeded");t.push(d)},l=d=>{if(Buffer.byteLength(d,"utf8")>re.bytes)throw U("serialized byte limit exceeded");return JSON.stringify(d)},u=(d,c)=>{if(r+=1,r>re.nodes)throw U("node limit exceeded");if(c>re.depth)throw U("depth limit exceeded");if(d===null){a("null");return}if(typeof d=="string"){a(l(d));return}if(typeof d=="boolean"){a(d?"true":"false");return}if(typeof d=="number"){if(!Number.isFinite(d))throw U("non-finite number");a(Object.is(d,-0)?"0":String(d));return}if(typeof d!="object")throw U("unsupported non-JSON value");if(oe.isProxy(d))throw U("proxy value");if(xs(d))throw U("unsupported exotic object");if(s.has(d))throw U("cyclic value");s.add(d);try{if(Object.getOwnPropertySymbols(d).length>0)throw U("symbol-keyed fields are unsupported");if(Array.isArray(d)){let p=Object.getPrototypeOf(d),y=0;for(;p!==null;){if(oe.isProxy(p))throw U("proxy array prototype");if(y+=1,y>re.depth)throw U("array prototype depth limit exceeded");p=Object.getPrototypeOf(p)}if(d.length>re.arrayLength)throw U("array length limit exceeded");for(let v=0;v<d.length;v+=1){let N=Object.getOwnPropertyDescriptor(d,String(v));if(!N||!Object.hasOwn(N,"value")||N.enumerable!==!0)throw U("array entries must be dense enumerable own data")}let S=0;for(let v in d){if(i+=1,i>re.fields)throw U("enumeration limit exceeded");if(Object.hasOwn(d,v)&&(S+=1,S>d.length))throw U("named array fields are unsupported")}if(S!==d.length)throw U("array entries must be dense enumerable own data");a("[");for(let v=0;v<d.length;v+=1)v&&a(","),u(Object.getOwnPropertyDescriptor(d,String(v)).value,c+1);a("]");return}let f=Object.getPrototypeOf(d);if(f!==Object.prototype&&f!==null)throw U("non-plain object");let m=[];for(let p in d){if(i+=1,i>re.fields)throw U("enumeration limit exceeded");if(!Object.hasOwn(d,p))continue;if(o+=1,o>re.fields)throw U("field limit exceeded");let y=Object.getOwnPropertyDescriptor(d,p);if(!y||!Object.hasOwn(y,"value")||y.enumerable!==!0)throw U("object fields must be enumerable own data");m.push([p,y.value])}a("{");for(let p=0;p<m.length;p+=1)p&&a(","),a(l(m[p][0])),a(":"),u(m[p][1],c+1);a("}")}finally{s.delete(d)}};return u(e,0),t.join("")}function ks(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(oe.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 vs(){return Object.assign(Object.create(null),{Accept:"application/json"})}function As(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 Is(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function mt(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=sr.get(e);return t||(t=ar,ar+=1,sr.set(e,t)),`reference:${t}`}function cr(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?_s.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 lr(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(cr);if(!n||typeof n!="object")return!1;if(Object.hasOwn(n,"jsonrpc")||Object.hasOwn(n,"method"))return cr(n);let r=Object.hasOwn(n,"type")?n.type:null;return typeof r=="string"&&Cs.has(r)&&(!Object.hasOwn(n,"action")||n.action==null)&&(!Object.hasOwn(n,"signature")||n.signature==null)&&(!Object.hasOwn(n,"nonce")||n.nonce==null)}function Os(e,t,n,r={},o=null){let i=ps("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 Ns(e,t){let n=Number(t);return Number.isFinite(n)&&n>0?Math.min(n*1e3,rr):Math.min(250*2**e,rr)+Math.floor(Math.random()*100)}function ue(e,t={}){let n=new Error(e);return n.retryable=!1,Object.assign(n,t),n}function Jt(e,t,n){return ue(`HTTP response from ${e} exceeded maxResponseBytes ${n} (${t})`,{oversize:!0})}function ge(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function $s(e){return e?e.byteLength??e.length??0:0}async function Ps(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&&(ge(e),!r))throw Jt(n,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let c=await e.text(),f=Buffer.byteLength(c,"utf8");if(f>t){if(!r)throw Jt(n,`body ${f} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let a=[],l=0,u=!1;try{for(;;){let{value:c,done:f}=await s.read();if(f)break;if(c&&(a.push(Buffer.from(c)),l+=$s(c),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 Jt(n,`streamed ${l} bytes`,t);let d=Buffer.concat(a);return(u?d.subarray(0,t):d).toString("utf8")}function Rs(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Ls(e,{fetchImpl:t,method:n,headers:r,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:l=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:d=!1,importUndici:c,validateResponse:f,signal:m,redirectPolicy:p="follow",maxRedirects:y=ht}){let S=null,v=t,N=s?{lookupFn:s}:{};if(l&&!a&&!Gt(v))throw ue(`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 E=new AbortController,h=setTimeout(()=>E.abort(),i),x=m?ir?ir([m,E.signal]):m:E.signal,b=async(k,{status:C=null}={})=>{let T=await Vt(k,N);if(!T.ok)throw ue(C==null?`HTTP refused ${k}: ${T.error}`:`HTTP redirect to ${k} ${T.error}`,C==null?{}:{status:C});let L=new URL(k).hostname;if(a){if(S&&(await S.close(),S=null),!S)try{S=await Kt({requireUndici:!0,...c?{importUndici:c}:{}})}catch(w){throw ue(C==null?`HTTP refused ${k}: ${w?.message||w}`:`HTTP redirect to ${k} refused: ${w?.message||w}`,C==null?{}:{status:C})}S.pin(L,T.addresses),v=S.fetch}else er(v,L,T.addresses);return T};try{let k=String(e),C=Object.assign(Object.create(null),r||{});l&&await b(k);for(let T=0;T<=y;T+=1){let L=Object.assign(Object.create(null),{method:n,headers:C,body:o,signal:x,redirect:"manual",dispatcher:void 0}),w=await v(k,L);if((p==="error"||y===0)&&w.status>=300&&w.status<400)throw ge(w),ue(`HTTP ${w.status} ${n} redirect refused`,{status:w.status,redirectRefused:!0});if(Ss.has(w.status)){let M=d===!0&&n==="POST"&&[307,308].includes(w.status)&&lr(n,o);if(n!=="GET"&&n!=="HEAD"&&!M){ge(w);let F=new Error(`HTTP ${w.status} ${n} ${k} redirected non-idempotent request`);throw F.status=w.status,F}if(T===y)throw ge(w),ue(`HTTP ${w.status} ${n} redirect budget exhausted`,{status:w.status,redirectRefused:!0});let q=w.headers?.get?.("location"),K;try{K=As(q,k)}catch(F){throw ge(w),F}let W=!Is(K,k);if(ge(w),W&&n==="POST"){let F=new Error(`HTTP ${w.status} ${n} cross-origin redirect refused`);throw F.status=w.status,F}if(W&&d){let F=new Error(`HTTP ${w.status} ${n} cross-origin redirect refused`);throw F.status=w.status,F.retryable=!1,F}if(W&&(C=vs(C)),l)await b(K,{status:w.status});else if(W){let F=await Vt(K,N);if(!F.ok){let A=new Error(`HTTP redirect from ${k} ${F.error}`);throw A.status=w.status,A.retryable=!1,A}a&&F.addresses?.length&&(S||(S=await Kt(c?{importUndici:c}:{})),S&&(S.pin(new URL(K).hostname,F.addresses),v=S.fetch))}k=K;continue}if(typeof f=="function")try{await f(w,{url:k})}catch(M){throw ge(w),ue(M?.message||String(M))}let I=await Ps(w,u,{url:k,onOversize:()=>E.abort()}),B=Rs(I);if(!w.ok){let M=new Error(`HTTP ${w.status} ${n} ${k}`);throw M.status=w.status,M.retryAfter=w.headers?.get?.("retry-after")??null,M.body=B??I.slice(0,300),M}return B??I}throw new Error(`HTTP redirect loop for ${e}`)}catch(k){if(E.signal.aborted&&!We(m)){let C=k&&(typeof k=="object"||typeof k=="function")&&!oe.isProxy(k)?k:null,T=C?Object.getOwnPropertyDescriptor(C,"oversize"):null;if(!(T&&Object.hasOwn(T,"value")&&T.value===!0))try{if(!C)throw new TypeError("unsafe rejection");Object.defineProperties(C,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let w=new Error("HTTP request timed out");throw Object.defineProperties(w,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),w}}throw k}finally{clearTimeout(h),S&&await S.close()}}async function z(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&oe.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let n=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let A of Object.getOwnPropertyNames(t)){let $=Object.getOwnPropertyDescriptor(t,A);if(!(A==="toJSON"&&$&&Object.hasOwn($,"value")&&$.value===void 0)){if(!n.has(A))throw new TypeError("HTTP options contain unknown fields");if(!$||!$.enumerable||!Object.hasOwn($,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let r=A=>{if(t==null||!Object.hasOwn(t,A))return;let $=Object.getOwnPropertyDescriptor(t,A);if(!$||!Object.hasOwn($,"value"))throw new TypeError("HTTP options must contain own data properties");return $.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 a=r("redirectPolicy");if(a!==void 0&&a!=="follow"&&a!=="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>ht))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${ht}`);if(a==="error"&&l!==void 0&&l!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=a??"follow",d=u==="error"?0:l??ht;for(let A of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let $=r(A);if($!==void 0&&typeof $!="boolean")throw new TypeError(`HTTP ${A} must be boolean`)}let c=r("maxResponseBytes");if(c!==void 0&&(!Number.isInteger(c)||c<1||c>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let f=r("signal");if(f!==void 0){if(oe.isProxy(f)||!(f instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{We(f)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let A of["importUndici","lookupFn","validateResponse"]){let $=r(A);if($!==void 0&&typeof $!="function")throw new TypeError(`HTTP ${A} must be a function`)}let m=r("fetchImpl"),p=m||globalThis.fetch;if(typeof p!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let y=i??12e3,S=(o||"GET").toUpperCase(),v=r("headers"),N=ks(v),E=Object.assign(Object.create(null),N);Object.keys(E).some(A=>A.toLowerCase()==="accept")||(E.Accept="application/json");let h=r("body");h!=null&&typeof h!="string"&&(Object.keys(E).find($=>$.toLowerCase()==="content-type")||(E["Content-Type"]="application/json"),h=Es(h));let x=s??ms,b=r("lookupFn"),k=!m,C=r("untrustedUrl")===!0,T=r("sameOriginRedirectsOnly")===!0,L=r("importUndici"),w=r("validateResponse"),I=f,B=c??null,M=async()=>{let A;for(let $=0;$<=x;$++){I&&gs.call(I);let st=pt("http");try{let ne=await Ls(e,{fetchImpl:p,method:S,headers:E,body:h,timeoutMs:y,lookupFn:b,realFetch:k,untrustedUrl:C,maxResponseBytes:B,sameOriginRedirectsOnly:T,importUndici:L,validateResponse:w,signal:I,redirectPolicy:u,maxRedirects:d});return st?.("succeeded"),ne}catch(ne){A=ne;let Ie=Dt=>{if(!ne||typeof ne!="object"&&typeof ne!="function"||oe.isProxy(ne))return;let Ve=Object.getOwnPropertyDescriptor(ne,Dt);return Ve&&Object.hasOwn(Ve,"value")?Ve.value:void 0},at=Ie("status");st?.("failed",at);let Xi=Ie("oracleTimeout")===!0||Ie("name")==="AbortError"||Ie("name")==="TimeoutError"||We(I),Qi=new Set([408,425,429]),Zi=Ie("retryable")===!1?!1:at!=null?Qi.has(at)||fs.has(at)&&nr.has(S):!Xi&&nr.has(S);if($===x||!Zi)throw ne;let Kn=Ns($,Ie("retryAfter")),es=pt("retry"),Wn=!1;try{I?await new Promise((Dt,Ve)=>{let Gn,Ke=()=>{clearTimeout(Gn),or.call(I,"abort",Ke),Ve(bs(I)||new DOMException("Aborted","AbortError"))};if(We(I)){Ke();return}Gn=setTimeout(()=>{or.call(I,"abort",Ke),Dt()},Kn),ws.call(I,"abort",Ke,{once:!0}),We(I)&&Ke()}):await Ts(Kn),Wn=!0}finally{es?.(Wn?"succeeded":"failed")}}}throw A};if(!(r("dedupe")!==!1&&!I&&lr(S,h)))return M();let K=Os(S,e,E,{untrustedUrl:C,maxResponseBytes:B,sameOriginRedirectsOnly:T,redirectPolicy:u,maxRedirects:d,timeoutMs:y,retries:x,fetchImpl:mt(p),realFetch:k,lookupFn:mt(b),importUndici:mt(L),validateResponse:mt(w)},h),W=Yt.get(K);if(W){let A=pt("shared");try{let $=await W;return A?.("succeeded"),$}catch($){throw A?.("failed"),$}}let F=M().finally(()=>Yt.delete(K));return Yt.set(K,F),F}async function yt(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 Ge(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 a=s++;i[a]=await n(r[a],a)}})),i}var fs,nr,ms,rr,hs,ys,gs,ws,or,ir,We,bs,Ss,ht,Gu,re,Yt,sr,ar,_s,Cs,Ts,V=_(()=>{Zn();tr();fs=new Set([408,425,429,500,502,503,504]),nr=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),ms=2,rr=4e3,hs=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,ys=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,gs=AbortSignal.prototype.throwIfAborted,ws=EventTarget.prototype.addEventListener,or=EventTarget.prototype.removeEventListener,ir=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,We=e=>e?hs.call(e):!1,bs=e=>e?ys.call(e):void 0,Ss=new Set([301,302,303,307,308]),ht=3,Gu=64*1024,re=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});Yt=new Map,sr=new WeakMap,ar=1;_s=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),Cs=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);Ts=e=>new Promise(t=>setTimeout(t,e))});var Qt,mr=_(()=>{Qt={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}}});function Zt(e){return qs.get(Number(e))||null}var qs,en=_(()=>{mr();qs=new Map(Object.values(Qt).map(e=>[e.chainId,e]))});import{Interface as js,getAddress as pd}from"ethers";var fd,Ce=_(()=>{V();en();fd=new js(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"])});var tn=_(()=>{});var wd,wt=_(()=>{V();tn();wd=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"})});var sn,an=_(()=>{sn=Object.freeze([{key:"ethereum",chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://etherscan.io",dexscreenerSlug:"ethereum",venueKind:"uniswap-v3",wrappedNative:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",stableQuoteAssets:["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","0xdAC17F958D2ee523a2206206994597C13D831ec7"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.71 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}}]},{key:"optimism",chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://optimistic.etherscan.io",dexscreenerSlug:"optimism",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85","0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1905.23 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}}]},{key:"bsc",chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],nativeCurrency:{symbol:"BNB",decimals:18},explorer:"https://bscscan.com",dexscreenerSlug:"bsc",venueKind:"uniswap-v3",wrappedNative:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",stableQuoteAssets:["0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d","0x55d398326f99059fF775485246999027B3197955"],venues:[{kind:"quoter",address:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WBNB->USDC fee 500 quoted 413.86 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}},{kind:"router",address:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}}]},{key:"polygon",chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],nativeCurrency:{symbol:"POL",decimals:18},explorer:"https://polygonscan.com",dexscreenerSlug:"polygon",venueKind:"uniswap-v3",wrappedNative:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",stableQuoteAssets:["0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359","0xc2132D05D31c914a87C6611C10748AEb04B58e8F"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WMATIC->USDC fee 500 quoted 0.0720 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}}]},{key:"stable",chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],nativeCurrency:{symbol:"USDT0",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x5d442b349590a6048Eb2dC0eC346cAA5F47A9ab5",venues:[{kind:"quoter",address:"0xb070179E7032CdA868b53e6C1742F80c9e940d1A",label:"Uniswap V3 QuoterV2 (canonical)",verified:{method:"Stable is on the OFFICIAL Uniswap v3 Deployments List (governance-recognised 2026-05-12, UAC process completed 2026-04, deployed by Protofire), so this is a canonical deployment rather than a fork. eth_getCode returned 8273 bytes, the same size as the canonical quoter on the seven already-verified chains. Functional probe on a live pool (TOAST -> USDT0, fee 10000): 100 in -> 0.000003, 1000 -> 0.000031, 10000 -> 0.000319 USDT0. Output scales monotonically with input, which is a working quoter answering, not a revert. Two of three sampled pools carry non-zero liquidity. NOTE: the pools discovered so far are thin, so real routing size is limited -- the venue is proved, deep liquidity is not.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:988}},{kind:"router",address:"0x32eaf9B5d5F2CD7361c5012890C943D7de84C22a",label:"Uniswap SwapRouter02 (canonical)",verified:{method:"eth_getCode returned 24497 bytes. Cross-checked on-chain rather than trusted from docs: router.factory() returns 0x88f0a512ef09175d456bc9547f914f48c013e4aa, the same v3 core factory that created the pools quoted above, and router.WETH9() returns the wrappedNative recorded on this chain entry. Address published in the Stable docs DEX reference and the Uniswap deployments list.",source:"docs.stable.xyz/en/reference/dexes + on-chain factory()/WETH9() round-trip",date:"2026-08-05",chainId:988}}]},{key:"hyperevm",chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],nativeCurrency:{symbol:"HYPE",decimals:18},dexscreenerSlug:"hyperevm",venueKind:"uniswap-v3",wrappedNative:"0x5555555555555555555555555555555555555555",venues:[{kind:"quoter",address:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",label:"HyperSwap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle(1 WHYPE -> USDT0) returned live output on all four fee tiers (100: 57.3385, 500: 57.4187, 3000: 57.3237, 10000: 56.1963 USDT0). Decimals read on-chain: WHYPE 18, USDT0 6. Best tier checked against an INDEPENDENT control the same minute -- Hyperliquid allMids put HYPE at 57.3205, so the pool is 0.171% from the perp mid, which is the right shape for fee plus impact rather than a wrong contract or a decimals bug.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}},{kind:"router",address:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D",label:"HyperSwap V3 SwapRouter",verified:{method:"eth_getCode returned 12070 bytes, and it is the router paired with the quoter proved above -- the same pair already shipped in UNI_V3_VENUES[999].hyperswap, which is the map the quote/prepare path actually routes through.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}}]},{key:"abstract",chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x3439153EB7AF838Ad19d56E1571FBD09333C2809",venues:[{kind:"quoter",address:"0x728BD3eC25D5EDBafebB84F3d67367Cd9EBC7693",label:"Uniswap V3 QuoterV2 (Abstract deployment)",verified:{method:"Abstract is a ZK-stack chain, so CREATE2 addresses differ and the canonical Uniswap addresses are NOT valid here -- probing them returns codesize 0, which is what previously made this chain look like it had no V3 at all. Found the real deployment from live traffic instead: scanned recent Swap(...) logs, took the busiest pool, read pool.factory() = 0xa1160e73b63f322ae88cc2d8e700833e71d0b2a1, then enumerated that factory's deployer (0xf3d63166F0Ca56C3c1A3508FcE03Ff0Cf3Fb691e) and probed each of its 56 contracts with a real quoteExactInputSingle call. Exactly one answered: 1 WETH -> 1846.475731 USDC.e at fee 500. Independent sanity check: the pool's own slot0() spot price is 1873.11 USDC.e per WETH, so the quoter sits ~1.4% below spot, the right shape for fee plus price impact on this size.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:2741}},{kind:"router",address:"0x7712FA47387542819d4E35A23f8116C90C18767C",label:"Uniswap SwapRouter02 (Abstract deployment)",verified:{method:"eth_getCode returned 167392 bytes and the runtime contains the exactInputSingle selector. router.factory() matches the factory proved above and router.WETH9() matches the wrappedNative on this entry. Chosen over its byte-identical twin (0xfD6257F4...) because this is the address real users actually route through: it appeared as tx.to on live swaps against the WETH/USDC.e pool.",source:"on-chain factory()/WETH9() round-trip + live swap tx.to sampling",date:"2026-08-05",chainId:2741}}]},{key:"robinhood",chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC","ROBINHOOD_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},dexscreenerSlug:"robinhood",venueKind:"uniswap-v3",wrappedNative:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",stableQuoteAssets:["0x5fc5360d0400a0fd4f2af552add042d716f1d168"],venues:[{kind:"quoter",address:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDG fee 100 quoted 1866.58 USDG, and USDG->CASHCAT fee 10000 quoted a live amount). A contract that correctly prices known pairs IS a working V3 quoter",source:"live eth_call against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"router",address:"0xcaf681a66d020601342297493863e78c959e5cb2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode (24497 bytes) on this chain and the paired quoter at the same deployment passed a live functional quote",source:"live eth_getCode against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"factory",address:"0x1f7d7550b1b028f7571e69a784071f0205fd2efa",label:"Uniswap V3 Factory",verified:{method:"eth_getCode returned real bytecode (24535 bytes) and a PoolCreated log scan over this factory returned 76 pools in ~9000 recent blocks",source:"live eth_getLogs against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}}]},{key:"base",chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://basescan.org",dexscreenerSlug:"base",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],venues:[{kind:"quoter",address:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",label:"Uniswap V3 QuoterV2 (Base)",verified:{method:"functional probe: quoteExactInputSingle returned WETH->USDC at fee 500 = 1908.44 USDC, a live sane price. The canonical mainnet quoter address also has bytecode on Base but does NOT price this pair, which is exactly the false positive a codesize-only check accepts",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router",address:"0x2626664c2603336E57B271c5C0b26F421741e481",label:"Uniswap V3 SwapRouter02 (Base)",verified:{method:"eth_getCode returned real bytecode and the paired Base quoter passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router-v2",address:"0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",label:"Uniswap V2 Router02 (Base)",verified:{method:"eth_getCode returned 17891 bytes; live getAmountsOut on WETH->USDC round-tripped to 98.75% (2x0.30% fee + impact)",source:"https://docs.uniswap.org/contracts/v2/reference/smart-contracts/v2-deployments",date:"2026-07-30",chainId:8453}}]},{key:"arbitrum",chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://arbiscan.io",dexscreenerSlug:"arbitrum",venueKind:"uniswap-v3",wrappedNative:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",stableQuoteAssets:["0xaf88d065e77c8cC2239327C5EDb3A432268e5831","0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.72 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}}]},{key:"avalanche",chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],nativeCurrency:{symbol:"AVAX",decimals:18},explorer:"https://snowtrace.io",dexscreenerSlug:"avalanche",venueKind:"uniswap-v3",wrappedNative:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",stableQuoteAssets:["0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"],venues:[{kind:"quoter",address:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WAVAX->USDC fee 500 quoted 6.48 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}},{kind:"router",address:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}}]}])});var wr,un=_(()=>{wr=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"})});import{createHash as Qs,createHmac as Zs,timingSafeEqual as rf}from"node:crypto";function dn(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(dn).join(",")}]`:`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${dn(e[n])}`).join(",")}}`}function xr(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function kr(e=process.env){return xr(process.env)||xr(e)}function na(e){let{prepareHash:t,prepareMac:n,note:r,...o}=e||{};return o}function vr(e){let t=na(e);return Qs("sha256").update(dn(t)).digest("hex")}function Ar(e,t=kr()){return t?Zs("sha256",t).update(String(e)).digest("hex"):""}function be(e,{provider:t,kind:n,env:r=process.env,nowMs:o=Date.now(),expiresAtMs:i}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let s=Object.prototype.hasOwnProperty.call(e,"oraclePrepared");if(s&&typeof e.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let a={...e,provider:e.provider||t,kind:e.kind||n,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:s?e.oraclePrepared:!0};if(!a.provider)throw new Error("stampPrepared: provider required");if(!a.kind)throw new Error("stampPrepared: kind required");let l=Number(o),u=i==null?l+Er:Number(i),d=u-l;if(!Number.isSafeInteger(l)||!Number.isSafeInteger(u)||d<=0||d>ta)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let f={...a,preparedAt:l,expiresAt:u,prepareVersion:ea},m=vr(f),p=kr(r),y=p?Ar(m,p):void 0,S={...f,prepareHash:m};return y&&(S.prepareMac=y),S}var ea,Er,ta,pe=_(()=>{ea=2,Er=300*1e3,ta=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});function Se(e,t=160){return String(e??"").replace(/[\u0000-\u001f\u007f]/g," ").slice(0,t)}function mn(e){let t=Number(e);return Number.isFinite(t)?t:null}function $e(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 Ga(e={}){let t=typeof e.heldCount=="string"&&/^\d+$/.test(e.heldCount)?e.heldCount:Number.isSafeInteger(Number(e.heldCount))?String(Number(e.heldCount)):"unknown",n=mn(e.fromFloor),r=mn(e.floor),o=mn(e.changePct),i=Se(e.currency||"unknown",16);return`ORACLE NFT \u2014 YOUR BAG IS PUMPING
4
4
 
5
- ${[`Collection: ${le(e.name||e.slug||"Unknown")}`,`Chain: ${le(e.chain||"unknown")}`,`You hold: ${t}`,`Floor: ${r??"unknown"} \u2192 ${n??"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 pn(e=[],t=""){let r=(Array.isArray(e)?e:[]).filter(a=>typeof a?.notifyRecipient=="function");if(!r.length)return null;let n=String(t||"").trim().toLowerCase(),o=n?r.filter(a=>String(a.platform||"").toLowerCase()===n):[],i=r.filter(a=>a.platform==="telegram"),s=o.length?o:i.length?i:r;for(let a of s){let l=[...new Set((Array.isArray(a.ownerIds)?a.ownerIds:[]).map(d=>String(d).trim()).filter(Boolean))];if(l.length!==1)continue;let u=le(String(a.platform||"").toLowerCase(),32);if(u)return Object.freeze({platform:u,recipientId:l[0],target:a})}return null}function fn(e){if(!e||typeof e.target?.notifyRecipient!="function")throw new TypeError("one recipient-bound notification subscription is required");let{target:t,recipientId:r}=e,n=le(e.platform||t.platform||"unknown",32);return async function(i){let s=Fs(i);try{let a=Number(await t.notifyRecipient(r,s,i)),l=Number.isSafeInteger(a)&&a>0?1:0;return{delivered:l,recipient:{platform:n,id:r},error:l?null:"delivery-failed"}}catch{return{delivered:0,recipient:{platform:n,id:r},error:"delivery-failed"}}}}function mn({watchdog:e,intervalMs:t=3e5,setIntervalFn:r=setInterval,clearIntervalFn:n=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,a=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&&(a(),i=r(a,t),typeof i?.unref=="function"&&i.unref())},stop(){i!==null&&n(i),i=null},run:a})}var De=T(()=>{});var hn={};ye(hn,{A2ABus:()=>Vt,normalizeName:()=>qe});function qe(e){return String(e||"").trim().toLowerCase().replace(/^@/,"")}var Vt,yn=T(()=>{Vt=class{constructor({maxHops:t=4,historyCap:r=200}={}){this.maxHops=t,this.historyCap=r,this.agents=new Map,this.history=[],this.seq=0}register(t,{role:r="",chains:n=[],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(r),chains:n.map(String),handler:o}),this.agents.get(i)}unregister(t){this.agents.delete(qe(t))}roster(){return[...this.agents.values()].map(({name:t,role:r,chains:n})=>({name:t,role:r,chains:n}))}async send({from:t,to:r,text:n,kind:o="consult",hops:i=0}={}){let s=qe(t),a=qe(r);if(!s||!this.agents.has(s))return{ok:!1,error:`a2a: unknown sender '${t}'`};if(!a||!this.agents.has(a))return{ok:!1,error:`a2a: unknown recipient '${r}' (roster: ${[...this.agents.keys()].join(", ")||"empty"})`};if(a===s)return{ok:!1,error:"a2a: self-send refused"};let l=String(n||"").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:a,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:a,kind:String(o),text:l,hops:u,ts:new Date().toISOString()};this.record(d);try{let c=await this.agents.get(a).handler(d);return c&&this.record({id:`${d.id}-reply`,from:a,to:s,kind:"reply",text:String(c).slice(0,8e3),hops:u,ts:new Date().toISOString()}),{ok:!0,reply:c||null,id:d.id}}catch(c){return{ok:!1,error:`a2a: '${a}' handler failed: ${c.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 Ms from"node:os";import xe from"node:path";import{fileURLToPath as Bs}from"node:url";function zt(){return process.env.ORACLE_FAKE_HOME||Ms.homedir()}function qs(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function X(){return qs()?process.env.ORACLE_CONFIG_DIR||xe.join(zt(),".config","oracle"):xe.join(zt(),".config","oracle")}function js(){return xe.join(X(),"desk.json")}function Hs(){return xe.join(X(),"env")}function ve({force:e=!1}={}){if(ve._done&&!e)return ve._result||null;ve._done=!0;let t={},r=(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=Hs();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 a=s[2];(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),r(s[1],a)}}catch{}try{let o=js();if(je.existsSync(o)){let i=JSON.parse(je.readFileSync(o,"utf8"));i&&typeof i=="object"&&(r("ORACLE_DESK_URL",i.deskUrl||i.dataUrl||i.url),r("ORACLE_DATA_URL",i.dataUrl||i.deskUrl||i.url),r("ORACLE_API_URL",i.apiUrl||i.dataUrl||i.deskUrl),r("ORACLE_PUBLIC_URL",i.publicUrl||i.deskUrl||i.dataUrl),r("ORACLE_EXEC_URL",i.execUrl),r("MAD_DESK_URL",i.deskUrl||i.dataUrl))}}catch{}let n=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return n&&(r("ORACLE_DESK_URL",n),r("ORACLE_DATA_URL",n),r("ORACLE_API_URL",n),r("ORACLE_PUBLIC_URL",n),r("MAD_DESK_URL",n)),ve._result=Object.keys(t).length?t:null,ve._result}function pt(e){return je.mkdirSync(e,{recursive:!0}),e}var Ds,Ap,ft=T(()=>{Ds=xe.dirname(Bs(import.meta.url)),Ap=xe.resolve(Ds,"../..");try{ve()}catch{}});function mt(e){return String(e||"").trim()||void 0}function zs(e,{required:t=!1}={}){let r=mt(e)?.toLowerCase();if(!r){if(t)throw new Error("model provider is required");return}if(!Vs.has(r))throw new Error(`unsupported provider: ${r}`);return r}function Ws(e,{required:t=!1}={}){let r=mt(e);if(!r){if(t)throw new Error("model is required");return}if(r.includes("..")||r.startsWith("/")||!/^[a-zA-Z0-9._:/-]{1,200}$/.test(r))throw new Error("invalid model id");return r}function Gs(e){let t=mt(e);if(!t||t.length>2048)throw new Error("invalid custom base URL");let r;try{r=new URL(t)}catch{throw new Error("invalid custom base URL")}let n=r.hostname.toLowerCase().replace(/^\[|\]$/g,""),o=n==="localhost"||n==="127.0.0.1"||n==="::1";if(r.protocol!=="https:"&&!(r.protocol==="http:"&&o)||r.username||r.password||r.search||r.hash)throw new Error("custom base URL must use HTTPS or loopback HTTP without credentials, query, or fragment");return r.toString().replace(/\/+$/,"")}function gn({provider:e,model:t,baseUrl:r}={},{requireModel:n=!1}={}){let o=zs(e),i=Ws(t,{required:n});if(o==="custom")return{provider:o,...i?{model:i}:{},baseUrl:Gs(r)};if(mt(r))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...i?{model:i}:{}}}var Vs,wn=T(()=>{Vs=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 Wt from"node:path";function bn(){return Wt.join(X(),"model.json")}function Ae(e){return String(e||"").trim()||void 0}function Sn(e={}){let t=Ae(e.backend)?.toLowerCase()||"auto",r=gn({provider:e.provider,model:e.model,baseUrl:e.baseUrl},{requireModel:t==="standalone"}),n=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),a=Ae(e.computeHost||e.remoteHost),l=Ae(e.computeUser||e.remoteUser),u=Ae(e.computePath||e.remotePath);if(!Ks.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(n&&!/^[A-Z][A-Z0-9_]*$/.test(n))throw new Error("api key env must be an uppercase environment variable name");if(t==="remote"&&!a)throw new Error("remote backend requires computeHost");return{backend:t,...r,...n?{apiKeyEnv:n}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...Object.keys(i).length?{contextByModel:i}:{},...s?{reasoningEffort:s}:{},...a?{computeHost:a}:{},...l?{computeUser:l}:{},...u?{computePath:u}:{}}}function _e(){let e=bn();if(!ke.existsSync(e))return null;try{return Sn(JSON.parse(ke.readFileSync(e,"utf8")))}catch{return null}}function Gt(e){let t=Sn(e),r=bn();pt(Wt.dirname(r)),process.platform!=="win32"&&ke.chmodSync(Wt.dirname(r),448);let n=`${r}.${process.pid}.tmp`;return ke.writeFileSync(n,`${JSON.stringify(t,null,2)}
8
- `,{mode:384}),ke.renameSync(n,r),process.platform!=="win32"&&ke.chmodSync(r,384),t}var Ks,En=T(()=>{ft();wn();Ks=new Set(["auto","standalone","hermes","remote","arch"])});var vn=T(()=>{});var Mp,Bp,Dp,qp,xn=T(()=>{vn();be();Mp=Object.freeze({NONE:"none",PREPARE_CHECKSUM:"prepare-checksum",PREPARE_HMAC:"prepare-hmac"}),Bp=Object.freeze(["signature","signedTx","signedTransaction","rawTransaction","signedPayload","signedRaw"]),Dp=Object.freeze(["txid","txHash","transactionHash","broadcastHash"]),qp=Object.freeze(["tee-attestation","remote-attestation","hardware-enclave","trusted-execution-environment","execution-authorization","signature","broadcast"])});import{existsSync as Ys,readFileSync as Js}from"node:fs";import{request as Xs}from"node:http";import Qs from"node:path";function ea(e=process.env){let t=String(e.ORACLE_SIGNER_URL||Zs).replace(/\/$/,""),r;try{r=new URL(t)}catch{return null}return r.hostname!=="127.0.0.1"&&r.hostname!=="localhost"&&r.hostname!=="::1"?null:r.origin}function ta(e=process.env){if(e.ORACLE_SIGNER_TOKEN)return String(e.ORACLE_SIGNER_TOKEN);let t=Qs.join(X(),"signer","signer-token");return Ys(t)?Js(t,"utf8").trim():null}function ue(e,{method:t="GET",body:r=null,env:n=process.env,timeoutMs:o=4e3}={}){let i=ea(n),s=ta(n);return!i||!s?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(a=>{let l=new URL(e,i),u=r?Buffer.from(JSON.stringify(r)):null,d=Xs({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}:{}}},c=>{let h=[];c.on("data",p=>h.push(p)),c.on("end",()=>{let p=Buffer.concat(h).toString("utf8"),f={};try{f=p?JSON.parse(p):{}}catch{f={error:"signer refused"}}a({httpStatus:c.statusCode,...f})})});d.on("timeout",()=>{d.destroy(),a({ok:!1,error:"local signer timed out"})}),d.on("error",()=>a({ok:!1,error:"local signer is not running"})),u&&d.write(u),d.end()})}var Zs,ht=T(()=>{ft();xn();Zs="http://127.0.0.1:9462"});function na(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 An(e,{coin:t,side:r,sizeUsd:n,leverage:o,venue:i,confirm:s,user:a}={}){let l=na(e);if(!l)return null;if(t&&ra.test(String(t).toUpperCase())&&l.searchParams.set("coin",String(t).toUpperCase()),(r==="long"||r==="short")&&l.searchParams.set("side",r),Number.isFinite(Number(n))&&Number(n)>=1&&l.searchParams.set("size",String(Math.min(1e5,Math.round(Number(n))))),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()),a&&/^0x[0-9a-fA-F]{40}$/.test(String(a))&&l.searchParams.set("user",String(a).toLowerCase()),l.toString()}var ra,Kt=T(()=>{ra=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var Zp,ef,kn=T(()=>{Kt();Zp=Object.freeze([100,50,25]),ef=Object.freeze([100,50,25,10])});function g(e){return B(e)?String(e).replace(oa,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 r=Number(e);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:t}):C}function q(e,{decimals:t=2}={}){let r=de(e,{decimals:t});return r===C?C:`${r} USD`}function Yt(e,{decimals:t=2}={}){let r=de(e,{decimals:t});return r===C?C:`${r}%`}function yt(e){let t=de(e,{decimals:0});return t===C?C:`${t} bps`}function pe(e,t){if(!B(e))return C;let r=Number(t);if(!Number.isInteger(r)||r<0||r>77)return C;let n;try{n=BigInt(typeof e=="string"?e.trim():e)}catch{return C}let o=n<0n,i=o?-n:n,s=10n**BigInt(r),a=(i/s).toString(),l=(i%s).toString().padStart(r,"0").replace(/0+$/,"");return`${o?"-":""}${a}${l?`.${l}`:""}`}function Jt(e){if(typeof e=="number"&&Number.isFinite(e))return e<0||e>1?C:e>=.75?"HIGH":e>=.4?"MEDIUM":"LOW";if(typeof e=="string"){let t=e.trim().toUpperCase();if(t==="HIGH"||t==="MEDIUM"||t==="LOW")return t}return C}function ne(e={}){let t=e.chainId;if(!B(t)||!Number.isFinite(Number(t)))return B(e.chain)?g(e.chain):C;let n=Rt(t)?.name||(B(e.chain)?String(e.chain):C);return`${g(n)} (chainId ${Number(t)})`}function _n(e={}){return g(e.venue??e.dex??e.pool?.venue)}function ia(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 ${g(e.error)}`:""} (text card stands)`:B(e.url)?G(e.url):"NONE (text card only)"}function fe(e={},{now:t=Date.now()}={}){let r=e.grant??e.session??null;if(!r||typeof r!="object")return{allowed:!1,reason:"no local grant/session",actions:[]};if(r.local===!1)return{allowed:!1,reason:"grant is not local",actions:[]};if(r.revoked===!0)return{allowed:!1,reason:"grant revoked",actions:[]};let n=r.expiresAt??r.expiry;if(B(n)){let i=typeof n=="number"?n:Date.parse(n);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(r.actions)&&r.actions.length?r.actions.slice():["BUY","SELL"]}}function sa(e){let t=fe(e);return t.allowed?`${t.actions.map(r=>g(r)).join(" / ")} (${g(t.reason)})`:`prepare-only \u2014 ${g(t.reason)}`}function Q(e,t,r={}){let n=[`*${e}*`];for(let o of t){if(!o)continue;let[i,s]=o;n.push(`${i}: ${s==null||s===""?C:s}`)}return n.push(`Chart: ${ia(r.chart)}`),n.push(`Actions: ${sa(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>g(o)).join("; ")}`),(B(r.source)||B(r.fetchedAt))&&n.push(`Source: ${g(r.source)} at ${g(r.fetchedAt)}`),n.join(`
9
- `)}function Z(e){let t=Jt(e.confidence);return t===C?null:["Confidence",t]}function aa(e){let t=e.quote;if(!t||typeof t!="object")return[];let r=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",r===C?C:`${g(r)} ${g(t.symbol??"")}`.trim()]]}function In(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",C];let r=yt(t.selectedBps),n=yt(t.capBps);return["Auto-slippage",r===C&&n===C?C:`${r} selected, cap ${n}`]}function ca(e={}){let t=e||{};return Q(`ORACLE TOKEN \u2014 ${g(t.symbol??t.token??t.name)}`,[["Chain",ne(t)],["Venue",_n(t)],["Name",g(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",Yt(t.priceChange24h)],["Fee tier",B(t.feeTier)?`${yt(Number(t.feeTier)/100)} (${de(t.feeTier,{decimals:0})})`:C],["Age",g(t.age)],...aa(t),In(t),Z(t)],t)}function la(e={}){let t=e||{};return Q(`ORACLE LAUNCH \u2014 ${g(t.symbol??t.token??t.name)}`,[["Chain",ne(t)],["Venue",_n(t)],["Address",G(t.address??t.mint??t.contract)],["Pool",G(t.pool?.address??t.poolAddress??t.pool)],["Liquidity",q(t.liquidityUsd)],["Route ready",g(t.routeReady)],["Sellable",g(t.sellable)],["Sell sim",g(t.sellSimulation??t.sellSim)],["Smart wallets",g(t.smartWalletOverlap)],["Risk",g(t.risk??t.riskStatus)],["Prepared ticket",g(t.preparedTicket??t.ticketStatus)],In(t),Z(t)],t)}function ua(e={}){let t=e||{};return Q(`ORACLE HIP-3 \u2014 ${g(t.market??t.coin??t.name)}`,[["Venue",`Hyperliquid builder-dex ${g(t.dexName?`${t.dexName} (${t.dex})`:t.dex)}`],["Market",g(t.market??t.coin)],["Mark",q(t.markPx,{decimals:6})],["Oracle",q(t.oraclePx,{decimals:6})],["Funding",Yt(t.funding,{decimals:6})],["Open interest",q(t.openInterestUsd)],["Depth",g(t.depth)],["Liquidation notes",g(t.liquidationNotes??t.riskNotes)],["Account context",g(t.accountContext)],Z(t)],t)}function da(e={}){let t=e||{};return Q(`ORACLE HIP-4 \u2014 ${g(t.event??t.market??t.name)}`,[["Venue",`Hyperliquid HIP-4 ${g(t.dex??"outcome")}`],["Event",g(t.event)],["Outcome",g(t.outcome)],["Market id",G(t.marketId??t.market)],["Bid",q(t.bid,{decimals:6})],["Ask",q(t.ask,{decimals:6})],["Depth",g(t.depth)],["Edge",Yt(t.edge)],["Position",g(t.position)],Z(t)],t)}function pa(e={}){let t=e||{};return Q(`ORACLE POLYMARKET \u2014 ${g(t.event??t.market??t.name)}`,[["Venue","Polymarket CLOB"],["Event",g(t.event)],["Market",g(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",g(t.resolutionRisk)],["Order intent",g(t.orderIntent)],Z(t)],t)}function fa(e={}){let t=e||{},r=B(t.completedSplits)&&B(t.totalSplits)?`${de(t.completedSplits,{decimals:0})} / ${de(t.totalSplits,{decimals:0})}`:C;return Q(`ORACLE TWAP \u2014 ${g(t.pair??t.symbol??t.name)}`,[["Chain",ne(t)],["Side",g(t.side??t.direction)],["Amount",`${g(pe(t.amountTotal??t.amount,t.decimals??18))} ${g(t.symbol??"")}`.trim()],["Splits",`${de(t.totalSplits,{decimals:0})} over ${g(t.window)}`],["Progress",r],["Avg price",q(t.averagePrice,{decimals:6})],["Next split",g(t.nextSplitAt)],["Slippage cap",yt(t.slippageBps)],["Status",g(t.status)],Z(t)],t)}function ma(e={}){let t=e||{},r=t.approval??t.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${g(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return Q(`ORACLE BRIDGE \u2014 ${g(t.pair??t.fromSymbol)} \u2192 ${g(t.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",ne({chainId:t.fromChainId,chain:t.fromChain})],["To chain",ne({chainId:t.toChainId,chain:t.toChain})],["Amount",`${g(pe(t.amount,t.fromDecimals??18))} ${g(t.fromSymbol??"")}`.trim()],["Best route",g(t.bestRoute??t.winner)],["Est. received",`${g(pe(t.amountOut,t.toDecimals??18))} ${g(t.toSymbol??"")}`.trim()],["Fee",q(t.feeUsd)],["Est. time",g(t.estimatedTime)],["Revoke check",n],["All providers",g(t.providers?.join(", "))],["Preparable",g(t.preparable)],Z(t)],t)}function ha(e){let r=(Array.isArray(e)?e:[]).slice(1,4).map(n=>{let o=g(n.source??n.venue??n.name),i=n.improvementBps==null&&n.deltaBps==null?null:Number(n.improvementBps??n.deltaBps),s=Number.isFinite(i)?`${Math.abs(i).toFixed(0)} bps behind`:"spread UNKNOWN";return`${o} (${s})`});return r.length?r.join("; "):C}function ya(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return B(t)?g(t):C}function ga(e={}){let t=e||{},r=t.swap&&typeof t.swap=="object"?t.swap:t,n=t.bridge&&typeof t.bridge=="object"?t.bridge:null,o=r.best??r.winner??{},i=`${g(t.tokenInSymbol??t.fromSymbol??"IN")} \u2192 ${g(t.tokenOutSymbol??t.toSymbol??"OUT")}`,s=[["Intent",g(t.intent??"swap")],["Chain",ne({chainId:t.chainId??r.chainId,chain:t.chain??r.chain})],["Pair",i],["Amount in",`${g(pe(t.amountIn??r.amountIn,t.decimalsIn??18))} ${g(t.tokenInSymbol??"")}`.trim()],["Best swap",g(o.source??o.venue??r.bestRoute??t.bestRoute)],["Net out",`${g(pe(o.netOut??o.amountOut??r.amountOut,t.decimalsOut??18))} ${g(t.tokenOutSymbol??"")}`.trim()],["Ranked on",ya(r)],["Gas accounted",g(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",B(r.improvementBps)?`${g(r.improvementBps)} bps`:C],["Runners-up",ha(r.routes??t.routes)]];if(n){let a=n.best??n.winner??{};s.push(["Best bridge",g(a.source??n.bestRoute??t.bestBridge)],["Bridge out",`${g(pe(a.netOut??a.amountOut??n.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${g(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",ne({chainId:n.toChainId??t.toChainId,chain:n.toChain??t.toChain})],["Est. time",g(n.estimatedTime??a.meta?.durationSeconds)])}else s.push(["Best bridge","same-chain \u2014 use Best swap"]);return s.push(["Preparable",g(t.preparable??o.executionReady)],Z(t)),Q(`ORACLE SWAP \u2014 ${i}`,s,t)}function Xt(e={}){let t=e||{};return Q("ORACLE APPROVE \u2014 local signer",[["Pending id",G(t.id??(typeof t.digest=="string"?t.digest.slice(0,8):null))],["Surface",g(t.surface)],["Action",g(t.action)],["Chain",ne({chainId:t.chain??t.chainId,chain:t.chainName})],["To",G(t.to??t.destination)],["Value",B(t.value)?g(t.value):C],["Signer",g(t.armed===!0?"running + armed":t.armed===!1?"running, disarmed":"not running")],Z({confidence:t.confidence??(t.armed===!0?"high":"low")})],t)}function Qt({platform:e="telegram",id:t,digest:r,hasGrant:n=!1}={}){let o=String(t||(typeof r=="string"?r.slice(0,8):"")||"").trim();return n?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,sf,oa,af,Zt=T(()=>{Lt();kn();C="UNKNOWN",sf=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),oa=/[_*[\]`]/g;af=Object.freeze({token:ca,launch:la,hip3:ua,hip4:da,polymarket:pa,twap:fa,bridge:ma,swap:ga,approve:Xt})});function er(e){let r=String(e||"").trim().match(/^\/(approve|deny|pending)(?:@[\w_]+)?(?:\s+([0-9a-fA-F]{4,64}))?\s*$/i);return r?{verb:r[1].toLowerCase(),id:r[2]?r[2].toLowerCase():null}:null}function tr(e,{platform:t,grant:r,armed:n}){if(!e.length)return{text:"No pending local-signer artifacts.",buttons:Qt({platform:t,hasGrant:!1})};let o=e[0];return{text:e.map(s=>Xt({...s,armed:n,grant:r,confidence:n?"high":"medium"})).join(`
5
+ ${[`Collection: ${Se(e.name||e.slug||"Unknown")}`,`Chain: ${Se(e.chain||"unknown")}`,`You hold: ${t}`,`Floor: ${n??"unknown"} \u2192 ${r??"unknown"} ${i}`,`Move: ${o===null?"unknown":`+${o}%`}`,`Contract: ${Se(e.contract||"unknown",64)}`,"Evidence: provider-estimated floor; not an executable bid or guaranteed liquidation value."].join(`
6
+ `)}`}function qr(e=[],t=""){let n=(Array.isArray(e)?e:[]).filter(a=>typeof a?.notifyRecipient=="function");if(!n.length)return null;let r=String(t||"").trim().toLowerCase(),o=r?n.filter(a=>String(a.platform||"").toLowerCase()===r):[],i=n.filter(a=>a.platform==="telegram"),s=o.length?o:i.length?i:n;for(let a of s){let l=[...new Set((Array.isArray(a.ownerIds)?a.ownerIds:[]).map(d=>String(d).trim()).filter(Boolean))];if(l.length!==1)continue;let u=Se(String(a.platform||"").toLowerCase(),32);if(u)return Object.freeze({platform:u,recipientId:l[0],target:a})}return null}function jr(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=Se(e.platform||t.platform||"unknown",32);return async function(i){let s=Ga(i);try{let a=Number(await t.notifyRecipient(n,s,i)),l=Number.isSafeInteger(a)&&a>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 Hr({watchdog:e,intervalMs:t=3e5,setIntervalFn:n=setInterval,clearIntervalFn:r=clearInterval,onError:o=i=>process.stderr.write(`oracle-gateway: held NFT watchdog failed: ${Se(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,a=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&&(a(),i=n(a,t),typeof i?.unref=="function"&&i.unref())},stop(){i!==null&&r(i),i=null},run:a})}var Je=_(()=>{});var zr={};_e(zr,{A2ABus:()=>hn,normalizeName:()=>Xe});function Xe(e){return String(e||"").trim().toLowerCase().replace(/^@/,"")}var hn,Vr=_(()=>{hn=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=Xe(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(Xe(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=Xe(t),a=Xe(n);if(!s||!this.agents.has(s))return{ok:!1,error:`a2a: unknown sender '${t}'`};if(!a||!this.agents.has(a))return{ok:!1,error:`a2a: unknown recipient '${n}' (roster: ${[...this.agents.keys()].join(", ")||"empty"})`};if(a===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:a,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:a,kind:String(o),text:l,hops:u,ts:new Date().toISOString()};this.record(d);try{let c=await this.agents.get(a).handler(d);return c&&this.record({id:`${d.id}-reply`,from:a,to:s,kind:"reply",text:String(c).slice(0,8e3),hops:u,ts:new Date().toISOString()}),{ok:!0,reply:c||null,id:d.id}}catch(c){return{ok:!1,error:`a2a: '${a}' handler failed: ${c.message}`}}}record(t){this.history.push(t),this.history.length>this.historyCap&&this.history.splice(0,this.history.length-this.historyCap)}recent(t=20){return this.history.slice(-t)}}});import Qe from"node:fs";import Ya from"node:os";import Re from"node:path";import{fileURLToPath as Ja}from"node:url";function yn(){return process.env.ORACLE_FAKE_HOME||Ya.homedir()}function Qa(){return process.env.ORACLE_PUBLIC_DESKTOP==="1"}function ie(){return Qa()?process.env.ORACLE_CONFIG_DIR||Re.join(yn(),".config","oracle"):Re.join(yn(),".config","oracle")}function Za(){return Re.join(ie(),"desk.json")}function ec(){return Re.join(ie(),"env")}function Pe({force:e=!1}={}){if(Pe._done&&!e)return Pe._result||null;Pe._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=ec();if(Qe.existsSync(o))for(let i of Qe.readFileSync(o,"utf8").split(/\r?\n/)){let s=i.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*?)\s*$/);if(!s||s[2].startsWith("#"))continue;let a=s[2];(a.startsWith('"')&&a.endsWith('"')||a.startsWith("'")&&a.endsWith("'"))&&(a=a.slice(1,-1)),n(s[1],a)}}catch{}try{let o=Za();if(Qe.existsSync(o)){let i=JSON.parse(Qe.readFileSync(o,"utf8"));i&&typeof i=="object"&&(n("ORACLE_DESK_URL",i.deskUrl||i.dataUrl||i.url),n("ORACLE_DATA_URL",i.dataUrl||i.deskUrl||i.url),n("ORACLE_API_URL",i.apiUrl||i.dataUrl||i.deskUrl),n("ORACLE_PUBLIC_URL",i.publicUrl||i.deskUrl||i.dataUrl),n("ORACLE_EXEC_URL",i.execUrl),n("MAD_DESK_URL",i.deskUrl||i.dataUrl))}}catch{}let r=process.env.ORACLE_DESK_URL||process.env.ORACLE_DATA_URL||"";return r&&(n("ORACLE_DESK_URL",r),n("ORACLE_DATA_URL",r),n("ORACLE_API_URL",r),n("ORACLE_PUBLIC_URL",r),n("MAD_DESK_URL",r)),Pe._result=Object.keys(t).length?t:null,Pe._result}function vt(e){return Qe.mkdirSync(e,{recursive:!0}),e}var Xa,fm,At=_(()=>{Xa=Re.dirname(Ja(import.meta.url)),fm=Re.resolve(Xa,"../..");try{Pe()}catch{}});function It(e){return String(e||"").trim()||void 0}function nc(e,{required:t=!1}={}){let n=It(e)?.toLowerCase();if(!n){if(t)throw new Error("model provider is required");return}if(!tc.has(n))throw new Error(`unsupported provider: ${n}`);return n}function rc(e,{required:t=!1}={}){let n=It(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 oc(e){let t=It(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 Kr({provider:e,model:t,baseUrl:n}={},{requireModel:r=!1}={}){let o=nc(e),i=rc(t,{required:r});if(o==="custom")return{provider:o,...i?{model:i}:{},baseUrl:oc(n)};if(It(n))throw new Error("baseUrl is only supported for the custom provider");return{...o?{provider:o}:{},...i?{model:i}:{}}}var tc,Wr=_(()=>{tc=new Set(["openrouter","openai","anthropic","xai","deepseek","gemini","kimi","mistral","nous","qwen","glm","local","ollama","custom","anthropic-oauth","openai-codex","xai-oauth"])});import Me from"node:fs";import gn from"node:path";function Gr(){return gn.join(ie(),"model.json")}function Le(e){return String(e||"").trim()||void 0}function Yr(e={}){let t=Le(e.backend)?.toLowerCase()||"auto",n=Kr({provider:e.provider,model:e.model,baseUrl:e.baseUrl},{requireModel:t==="standalone"}),r=Le(e.apiKeyEnv),o=Number.parseInt(String(e.contextLength||""),10),i=Object.fromEntries(Object.entries(e.contextByModel||{}).filter(([,d])=>Number.isSafeInteger(d)&&d>0)),s=Le(e.reasoningEffort),a=Le(e.computeHost||e.remoteHost),l=Le(e.computeUser||e.remoteUser),u=Le(e.computePath||e.remotePath);if(!ic.has(t))throw new Error(`unsupported backend: ${t}`);if(process.env.ORACLE_PUBLIC_DESKTOP==="1"&&["remote","arch"].includes(t))throw new Error("remote compute backends are disabled in the public desktop");if(r&&!/^[A-Z][A-Z0-9_]*$/.test(r))throw new Error("api key env must be an uppercase environment variable name");if(t==="remote"&&!a)throw new Error("remote backend requires computeHost");return{backend:t,...n,...r?{apiKeyEnv:r}:{},...Number.isFinite(o)&&o>0?{contextLength:o}:{},...Object.keys(i).length?{contextByModel:i}:{},...s?{reasoningEffort:s}:{},...a?{computeHost:a}:{},...l?{computeUser:l}:{},...u?{computePath:u}:{}}}function Fe(){let e=Gr();if(!Me.existsSync(e))return null;try{return Yr(JSON.parse(Me.readFileSync(e,"utf8")))}catch{return null}}function wn(e){let t=Yr(e),n=Gr();vt(gn.dirname(n)),process.platform!=="win32"&&Me.chmodSync(gn.dirname(n),448);let r=`${n}.${process.pid}.tmp`;return Me.writeFileSync(r,`${JSON.stringify(t,null,2)}
8
+ `,{mode:384}),Me.renameSync(r,n),process.platform!=="win32"&&Me.chmodSync(n,384),t}var ic,Jr=_(()=>{At();Wr();ic=new Set(["auto","standalone","hermes","remote","arch"])});var Xr=_(()=>{});var Am,Im,_m,Cm,Qr=_(()=>{Xr();pe();Am=Object.freeze({NONE:"none",PREPARE_CHECKSUM:"prepare-checksum",PREPARE_HMAC:"prepare-hmac"}),Im=Object.freeze(["signature","signedTx","signedTransaction","rawTransaction","signedPayload","signedRaw"]),_m=Object.freeze(["txid","txHash","transactionHash","broadcastHash"]),Cm=Object.freeze(["tee-attestation","remote-attestation","hardware-enclave","trusted-execution-environment","execution-authorization","signature","broadcast"])});import{existsSync as sc,readFileSync as ac}from"node:fs";import{request as cc}from"node:http";import lc from"node:path";function dc(e=process.env){let t=String(e.ORACLE_SIGNER_URL||uc).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 pc(e=process.env){if(e.ORACLE_SIGNER_TOKEN)return String(e.ORACLE_SIGNER_TOKEN);let t=lc.join(ie(),"signer","signer-token");return sc(t)?ac(t,"utf8").trim():null}function xe(e,{method:t="GET",body:n=null,env:r=process.env,timeoutMs:o=4e3}={}){let i=dc(r),s=pc(r);return!i||!s?Promise.resolve({ok:!1,error:"local signer is not running"}):new Promise(a=>{let l=new URL(e,i),u=n?Buffer.from(JSON.stringify(n)):null,d=cc({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}:{}}},c=>{let f=[];c.on("data",m=>f.push(m)),c.on("end",()=>{let m=Buffer.concat(f).toString("utf8"),p={};try{p=m?JSON.parse(m):{}}catch{p={error:"signer refused"}}a({httpStatus:c.statusCode,...p})})});d.on("timeout",()=>{d.destroy(),a({ok:!1,error:"local signer timed out"})}),d.on("error",()=>a({ok:!1,error:"local signer is not running"})),u&&d.write(u),d.end()})}var uc,_t=_(()=>{At();Qr();uc="http://127.0.0.1:9462"});function Zr(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}}var Ct=_(()=>{});var eo=_(()=>{an();un()});var Wm,Gm,to=_(()=>{Ct();eo();Wm=Object.freeze([100,50,25]),Gm=Object.freeze([100,50,25,10])});function g(e){return D(e)?String(e).replace(mc,t=>`\\${t}`):O}function D(e){return e==null?!1:typeof e=="number"?Number.isFinite(e):typeof e=="string"?e.trim()!=="":!0}function te(e){if(!D(e))return O;let t=String(e).replace(/`/g,"");return t===""?O:`\`${t}\``}function Ee(e,{decimals:t=2}={}){if(!D(e))return O;let n=Number(e);return Number.isFinite(n)?n.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:t}):O}function j(e,{decimals:t=2}={}){let n=Ee(e,{decimals:t});return n===O?O:`${n} USD`}function bn(e,{decimals:t=2}={}){let n=Ee(e,{decimals:t});return n===O?O:`${n}%`}function Ot(e){let t=Ee(e,{decimals:0});return t===O?O:`${t} bps`}function ke(e,t){if(!D(e))return O;let n=Number(t);if(!Number.isInteger(n)||n<0||n>77)return O;let r;try{r=BigInt(typeof e=="string"?e.trim():e)}catch{return O}let o=r<0n,i=o?-r:r,s=10n**BigInt(n),a=(i/s).toString(),l=(i%s).toString().padStart(n,"0").replace(/0+$/,"");return`${o?"-":""}${a}${l?`.${l}`:""}`}function Sn(e){if(typeof e=="number"&&Number.isFinite(e))return e<0||e>1?O: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 O}function fe(e={}){let t=e.chainId;if(!D(t)||!Number.isFinite(Number(t)))return D(e.chain)?g(e.chain):O;let r=Zt(t)?.name||(D(e.chain)?String(e.chain):O);return`${g(r)} (chainId ${Number(t)})`}function no(e={}){return g(e.venue??e.dex??e.pool?.venue)}function hc(e){return e==null?"NONE (text card only)":typeof e=="string"?e.trim()?te(e):"NONE (text card only)":e.error||e.ok===!1||e.available===!1?`UNAVAILABLE${D(e.error)?` \u2014 ${g(e.error)}`:""} (text card stands)`:D(e.url)?te(e.url):"NONE (text card only)"}function ve(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(D(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 yc(e){let t=ve(e);return t.allowed?`${t.actions.map(n=>g(n)).join(" / ")} (${g(t.reason)})`:`prepare-only \u2014 ${g(t.reason)}`}function se(e,t,n={}){let r=[`*${e}*`];for(let o of t){if(!o)continue;let[i,s]=o;r.push(`${i}: ${s==null||s===""?O:s}`)}return r.push(`Chart: ${hc(n.chart)}`),r.push(`Actions: ${yc(n)}`),Array.isArray(n.warnings)&&n.warnings.length&&r.push(`Warnings: ${n.warnings.map(o=>g(o)).join("; ")}`),(D(n.source)||D(n.fetchedAt))&&r.push(`Source: ${g(n.source)} at ${g(n.fetchedAt)}`),r.join(`
9
+ `)}function ae(e){let t=Sn(e.confidence);return t===O?null:["Confidence",t]}function gc(e){let t=e.quote;if(!t||typeof t!="object")return[];let n=D(t.decimals)?ke(t.amountOutRaw??t.out??t.raw,t.decimals):O;return[["Quote out (raw)",te(t.amountOutRaw??t.out??t.raw)],["Quote out",n===O?O:`${g(n)} ${g(t.symbol??"")}`.trim()]]}function ro(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",O];let n=Ot(t.selectedBps),r=Ot(t.capBps);return["Auto-slippage",n===O&&r===O?O:`${n} selected, cap ${r}`]}function wc(e={}){let t=e||{};return se(`ORACLE TOKEN \u2014 ${g(t.symbol??t.token??t.name)}`,[["Chain",fe(t)],["Venue",no(t)],["Name",g(t.name)],["Address",te(t.address??t.mint??t.contract)],["Price",j(t.priceUsd,{decimals:8})],["Market cap",j(t.marketCapUsd)],["Liquidity",j(t.liquidityUsd)],["Volume 24h",j(t.volume24hUsd)],["Change 24h",bn(t.priceChange24h)],["Fee tier",D(t.feeTier)?`${Ot(Number(t.feeTier)/100)} (${Ee(t.feeTier,{decimals:0})})`:O],["Age",g(t.age)],...gc(t),ro(t),ae(t)],t)}function bc(e={}){let t=e||{};return se(`ORACLE LAUNCH \u2014 ${g(t.symbol??t.token??t.name)}`,[["Chain",fe(t)],["Venue",no(t)],["Address",te(t.address??t.mint??t.contract)],["Pool",te(t.pool?.address??t.poolAddress??t.pool)],["Liquidity",j(t.liquidityUsd)],["Route ready",g(t.routeReady)],["Sellable",g(t.sellable)],["Sell sim",g(t.sellSimulation??t.sellSim)],["Smart wallets",g(t.smartWalletOverlap)],["Risk",g(t.risk??t.riskStatus)],["Prepared ticket",g(t.preparedTicket??t.ticketStatus)],ro(t),ae(t)],t)}function Sc(e={}){let t=e||{};return se(`ORACLE HIP-3 \u2014 ${g(t.market??t.coin??t.name)}`,[["Venue",`Hyperliquid builder-dex ${g(t.dexName?`${t.dexName} (${t.dex})`:t.dex)}`],["Market",g(t.market??t.coin)],["Mark",j(t.markPx,{decimals:6})],["Oracle",j(t.oraclePx,{decimals:6})],["Funding",bn(t.funding,{decimals:6})],["Open interest",j(t.openInterestUsd)],["Depth",g(t.depth)],["Liquidation notes",g(t.liquidationNotes??t.riskNotes)],["Account context",g(t.accountContext)],ae(t)],t)}function xc(e={}){let t=e||{};return se(`ORACLE HIP-4 \u2014 ${g(t.event??t.market??t.name)}`,[["Venue",`Hyperliquid HIP-4 ${g(t.dex??"outcome")}`],["Event",g(t.event)],["Outcome",g(t.outcome)],["Market id",te(t.marketId??t.market)],["Bid",j(t.bid,{decimals:6})],["Ask",j(t.ask,{decimals:6})],["Depth",g(t.depth)],["Edge",bn(t.edge)],["Position",g(t.position)],ae(t)],t)}function Ec(e={}){let t=e||{};return se(`ORACLE POLYMARKET \u2014 ${g(t.event??t.market??t.name)}`,[["Venue","Polymarket CLOB"],["Event",g(t.event)],["Market",g(t.market)],["Market id",te(t.marketId??t.conditionId??t.tokenId)],["Yes",j(t.yesPrice,{decimals:4})],["No",j(t.noPrice,{decimals:4})],["Best bid / ask",`${j(t.bestBid,{decimals:4})} / ${j(t.bestAsk,{decimals:4})}`],["Volume",j(t.volumeUsd)],["Resolution risk",g(t.resolutionRisk)],["Order intent",g(t.orderIntent)],ae(t)],t)}function kc(e={}){let t=e||{},n=D(t.completedSplits)&&D(t.totalSplits)?`${Ee(t.completedSplits,{decimals:0})} / ${Ee(t.totalSplits,{decimals:0})}`:O;return se(`ORACLE TWAP \u2014 ${g(t.pair??t.symbol??t.name)}`,[["Chain",fe(t)],["Side",g(t.side??t.direction)],["Amount",`${g(ke(t.amountTotal??t.amount,t.decimals??18))} ${g(t.symbol??"")}`.trim()],["Splits",`${Ee(t.totalSplits,{decimals:0})} over ${g(t.window)}`],["Progress",n],["Avg price",j(t.averagePrice,{decimals:6})],["Next split",g(t.nextSplitAt)],["Slippage cap",Ot(t.slippageBps)],["Status",g(t.status)],ae(t)],t)}function vc(e={}){let t=e||{},n=t.approval??t.revokeCheck??{},r=n.needsRevoke&&n.spender?`revoke.cash \u2014 ${g(n.spender)}`:n.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return se(`ORACLE BRIDGE \u2014 ${g(t.pair??t.fromSymbol)} \u2192 ${g(t.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",fe({chainId:t.fromChainId,chain:t.fromChain})],["To chain",fe({chainId:t.toChainId,chain:t.toChain})],["Amount",`${g(ke(t.amount,t.fromDecimals??18))} ${g(t.fromSymbol??"")}`.trim()],["Best route",g(t.bestRoute??t.winner)],["Est. received",`${g(ke(t.amountOut,t.toDecimals??18))} ${g(t.toSymbol??"")}`.trim()],["Fee",j(t.feeUsd)],["Est. time",g(t.estimatedTime)],["Revoke check",r],["All providers",g(t.providers?.join(", "))],["Preparable",g(t.preparable)],ae(t)],t)}function Ac(e){let n=(Array.isArray(e)?e:[]).slice(1,4).map(r=>{let o=g(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("; "):O}function Ic(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return D(t)?g(t):O}function _c(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=`${g(t.tokenInSymbol??t.fromSymbol??"IN")} \u2192 ${g(t.tokenOutSymbol??t.toSymbol??"OUT")}`,s=[["Intent",g(t.intent??"swap")],["Chain",fe({chainId:t.chainId??n.chainId,chain:t.chain??n.chain})],["Pair",i],["Amount in",`${g(ke(t.amountIn??n.amountIn,t.decimalsIn??18))} ${g(t.tokenInSymbol??"")}`.trim()],["Best swap",g(o.source??o.venue??n.bestRoute??t.bestRoute)],["Net out",`${g(ke(o.netOut??o.amountOut??n.amountOut,t.decimalsOut??18))} ${g(t.tokenOutSymbol??"")}`.trim()],["Ranked on",Ic(n)],["Gas accounted",g(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",D(n.improvementBps)?`${g(n.improvementBps)} bps`:O],["Runners-up",Ac(n.routes??t.routes)]];if(r){let a=r.best??r.winner??{};s.push(["Best bridge",g(a.source??r.bestRoute??t.bestBridge)],["Bridge out",`${g(ke(a.netOut??a.amountOut??r.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${g(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",fe({chainId:r.toChainId??t.toChainId,chain:r.toChain??t.toChain})],["Est. time",g(r.estimatedTime??a.meta?.durationSeconds)])}else s.push(["Best bridge","same-chain \u2014 use Best swap"]);return s.push(["Preparable",g(t.preparable??o.executionReady)],ae(t)),se(`ORACLE SWAP \u2014 ${i}`,s,t)}function xn(e={}){let t=e||{};return se("ORACLE APPROVE \u2014 local signer",[["Pending id",te(t.id??(typeof t.digest=="string"?t.digest.slice(0,8):null))],["Surface",g(t.surface)],["Action",g(t.action)],["Chain",fe({chainId:t.chain??t.chainId,chain:t.chainName})],["To",te(t.to??t.destination)],["Value",D(t.value)?g(t.value):O],["Signer",g(t.armed===!0?"running + armed":t.armed===!1?"running, disarmed":"not running")],ae({confidence:t.confidence??(t.armed===!0?"high":"low")})],t)}function En({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 O,Zm,mc,eh,Nt=_(()=>{en();to();O="UNKNOWN",Zm=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),mc=/[_*[\]`]/g;eh=Object.freeze({token:wc,launch:bc,hip3:Sc,hip4:xc,polymarket:Ec,twap:kc,bridge:vc,swap:_c,approve:xn})});function kn(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 vn(e,{platform:t,grant:n,armed:r}){if(!e.length)return{text:"No pending local-signer artifacts.",buttons:En({platform:t,hasGrant:!1})};let o=e[0];return{text:e.map(s=>xn({...s,armed:r,grant:n,confidence:r?"high":"medium"})).join(`
11
11
 
12
- `),buttons:Qt({platform:t,id:o.id,digest:o.digest,hasGrant:fe({grant:r}).allowed})}}async function rr({platform:e,text:t,grant:r={local:!0},env:n=process.env,ownerProof:o}={}){let i=er(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 c=await ue("/pending",{env:n});if(c.ok===!1||c.error)return{text:`Local signer: ${c.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let h=Array.isArray(c.items)?c.items:[],p=tr(h,{platform:e,grant:r,armed:c.armed===!0});if(s)return p;if(!h.length)return{text:"No pending local-signer artifacts. /approve is only needed when cards are unavailable.",buttons:null};let f=h.map(w=>`\u2022 ${w.id} ${w.surface}/${w.action} to ${w.to||"n/a"}`);return f.push("Cards are not available here. Reply /approve <id> or /deny <id>."),{text:f.join(`
13
- `),buttons:null}}let a=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(a,{method:"POST",body:{id:i.id,...o?{ownerProof:o}:{}},env:n});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 Cn({platform:e,data:t,senderId:r,chatId:n,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 h=(await ue("/pending",{env:s})).items?.find(p=>p.id===l[2].toLowerCase()||p.digest===l[2].toLowerCase());if(!h)return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};d=o.mint({digest:h.digest,senderId:r,chatId:n,platform:e})}return rr({platform:e,text:`/${u} ${l[2]}`,grant:i,env:s,ownerProof:d})}var nr=T(()=>{ht();Zt();ht()});import{execFile as wa}from"node:child_process";import{existsSync as ba,mkdirSync as Sa,readFileSync as Tn,realpathSync as Ea,writeFileSync as va}from"node:fs";import oe from"node:path";import{promisify as xa}from"node:util";import{fileURLToPath as On}from"node:url";function Ia(e=import.meta.url){try{let t=Ea(On(e)),r=`${oe.sep}node_modules${oe.sep}`,n=t.lastIndexOf(r);if(n>0)return{root:t.slice(0,n),managed:!0}}catch{}return{root:null,managed:!1}}function ir(e=import.meta.url){try{let t=oe.dirname(On(e));for(let r=0;r<8;r+=1){let n=oe.join(t,"package.json");if(ba(n)){let i=JSON.parse(Tn(n,"utf8"));if(i?.name===or&&i.version)return i.version}let o=oe.dirname(t);if(o===t)break;t=o}}catch{return null}return null}function Ca(e,t){let r=i=>String(i).replace(/^v/,"").split("-")[0].split(".").map(s=>Number.parseInt(s,10)||0),n=r(e),o=r(t);for(let i=0;i<Math.max(n.length,o.length);i+=1){let s=n[i]??0,a=o[i]??0;if(s>a)return 1;if(s<a)return-1}return 0}function Nn(e){let t=e?.stateDir||oe.join(process.env.HOME||".",".oracle");return oe.join(t,"update-check.json")}function Ta(e){try{return JSON.parse(Tn(Nn(e),"utf8"))}catch{return null}}function Oa(e,t){try{let r=Nn(e);Sa(oe.dirname(r),{recursive:!0}),va(r,`${JSON.stringify(t,null,2)}
15
- `)}catch{}}async function Na({timeoutMs:e=4e3}={}){try{let t=new AbortController,r=setTimeout(()=>t.abort(),e),n=await fetch(`${ka}/${encodeURIComponent(or)}/latest`,{signal:t.signal});return clearTimeout(r),n.ok&&(await n.json())?.version||null}catch{return null}}async function $n({paths:e,force:t=!1,timeoutMs:r=4e3}={}){let n=ir(),o=t?null:Ta(e),s=o&&Date.now()-(o.checkedAt||0)<_a?o.latest:null;return s||(s=await Na({timeoutMs:r}),s&&Oa(e,{latest:s,checkedAt:Date.now()})),!n||!s?{current:n,latest:s,updateAvailable:!1,checked:!!s}:{current:n,latest:s,updateAvailable:Ca(s,n)>0,checked:!0}}async function Pn({version:e="latest",dryRun:t=!1}={}){let{root:r,managed:n}=Ia();if(!n||!r)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=`${or}@${e}`,i=["install","--prefix",r,"--no-audit","--no-fund",o];if(t)return{ok:!0,dryRun:!0,root:r,command:`npm ${i.join(" ")}`};try{let{stdout:s,stderr:a}=await Aa("npm",i,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:r,stdout:s,stderr:a}}catch(s){return{ok:!1,reason:"npm-failed",root:r,message:s?.stderr||s?.message||"npm install failed"}}}var Aa,or,ka,_a,Rn=T(()=>{Aa=xa(wa),or="@oracle-agent/oracle",ka="https://registry.npmjs.org",_a=1440*60*1e3});import $a from"node:fs";import Pa from"node:os";import Ln from"node:path";function Ie(e){return String(e||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function Ra(){let e=process.env.ORACLE_CONFIG_DIR||Ln.join(Pa.homedir(),".config","oracle");return Ln.join(e,"chains.json")}function La(e){if(!e||typeof e!="object")return null;let t=String(e.key??"").trim();if(!t||/[/\\.]/.test(t))return null;let r=Ie(t);if(!Fn.test(r))return null;let n=typeof e.chainId=="string"?e.chainId.trim():Number(e.chainId);if(n===""||n===null||n===void 0||typeof n=="number"&&!Number.isFinite(n))return null;let o=typeof e.agent=="string"&&Fn.test(e.agent.trim())?e.agent.trim():"oracle";return{key:r,aliases:Array.isArray(e.aliases)?e.aliases.map(Ie).filter(Boolean).slice(0,8):[],chainId:n,name:String(e.name||r).slice(0,60),kind:["evm","svm","utxo","venue","daml"].includes(e.kind)?e.kind:"evm",family:Ie(e.family)||r,agent:o,note:String(e.note||"user-defined").slice(0,80),build:e.build!==!1,source:"user"}}function Ua(e=$a.readFileSync){try{let t=JSON.parse(e(Ra(),"utf8")),r=Array.isArray(t?.chains)?t.chains:[],n=[],o=new Set;for(let i of r){let s=La(i);!s||o.has(s.key)||(o.add(s.key),n.push(s))}return n}catch{return[]}}function Mn(){let e=Ua();if(e.length===0)return Un;let t=new Map(Un.map(r=>[r.key,r]));for(let r of e)t.set(r.key,r);return[...t.values()]}function Fa({buildOnly:e=!1}={}){return Mn().filter(t=>e?t.build:!0)}function He(e){let t=Ie(e);if(!t)return null;for(let r of Mn())if(r.key===t||String(r.chainId).toLowerCase()===t||(r.aliases||[]).map(Ie).includes(t)||Ie(r.name)===t)return r;return null}function Bn({selectedKey:e=null,buildOnly:t=!1}={}){let r=Fa({buildOnly:t}),n=["oracle chains","","pick a build/trade surface:",""];for(let o of r){let i=e&&e===o.key?"*":" ",s=String(o.chainId).padEnd(6),a=o.key.padEnd(12);n.push(`${i} ${a} ${s} ${o.note}`)}return n.push(""),n.push("usage:"),n.push(" /chain list"),n.push(" /chain hyperliquid select"),n.push(" /chain show current"),n.push(" /chain clear unset"),n.push(" oracle chain use base same from shell"),e&&n.push("",`active: ${e}`),n.join(`
12
+ `),buttons:En({platform:t,id:o.id,digest:o.digest,hasGrant:ve({grant:n}).allowed})}}async function An({platform:e,text:t,grant:n={local:!0},env:r=process.env,ownerProof:o}={}){let i=kn(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 c=await xe("/pending",{env:r});if(c.ok===!1||c.error)return{text:`Local signer: ${c.error||"not running"}. Start \`oracle signer\` on this machine first.`,buttons:null};let f=Array.isArray(c.items)?c.items:[],m=vn(f,{platform:e,grant:n,armed:c.armed===!0});if(s)return m;if(!f.length)return{text:"No pending local-signer artifacts. /approve is only needed when cards are unavailable.",buttons:null};let p=f.map(y=>`\u2022 ${y.id} ${y.surface}/${y.action} to ${y.to||"n/a"}`);return p.push("Cards are not available here. Reply /approve <id> or /deny <id>."),{text:p.join(`
13
+ `),buttons:null}}let a=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 xe(a,{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 oo({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 f=(await xe("/pending",{env:s})).items?.find(m=>m.id===l[2].toLowerCase()||m.digest===l[2].toLowerCase());if(!f)return{text:"Nothing pending with that id. It may have expired or already been decided.",buttons:null};d=o.mint({digest:f.digest,senderId:n,chatId:r,platform:e})}return An({platform:e,text:`/${u} ${l[2]}`,grant:i,env:s,ownerProof:d})}var In=_(()=>{_t();Nt();_t()});import{execFile as Cc}from"node:child_process";import{existsSync as Oc,mkdirSync as Nc,readFileSync as io,realpathSync as Tc,writeFileSync as $c}from"node:fs";import me from"node:path";import{promisify as Pc}from"node:util";import{fileURLToPath as so}from"node:url";function Fc(e=import.meta.url){try{let t=Tc(so(e)),n=`${me.sep}node_modules${me.sep}`,r=t.lastIndexOf(n);if(r>0)return{root:t.slice(0,r),managed:!0}}catch{}return{root:null,managed:!1}}function Cn(e=import.meta.url){try{let t=me.dirname(so(e));for(let n=0;n<8;n+=1){let r=me.join(t,"package.json");if(Oc(r)){let i=JSON.parse(io(r,"utf8"));if(i?.name===_n&&i.version)return i.version}let o=me.dirname(t);if(o===t)break;t=o}}catch{return null}return null}function Uc(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,a=o[i]??0;if(s>a)return 1;if(s<a)return-1}return 0}function ao(e){let t=e?.stateDir||me.join(process.env.HOME||".",".oracle");return me.join(t,"update-check.json")}function Bc(e){try{return JSON.parse(io(ao(e),"utf8"))}catch{return null}}function Dc(e,t){try{let n=ao(e);Nc(me.dirname(n),{recursive:!0}),$c(n,`${JSON.stringify(t,null,2)}
15
+ `)}catch{}}async function qc({timeoutMs:e=4e3}={}){try{let t=new AbortController,n=setTimeout(()=>t.abort(),e),r=await fetch(`${Lc}/${encodeURIComponent(_n)}/latest`,{signal:t.signal});return clearTimeout(n),r.ok&&(await r.json())?.version||null}catch{return null}}async function co({paths:e,force:t=!1,timeoutMs:n=4e3}={}){let r=Cn(),o=t?null:Bc(e),s=o&&Date.now()-(o.checkedAt||0)<Mc?o.latest:null;return s||(s=await qc({timeoutMs:n}),s&&Dc(e,{latest:s,checkedAt:Date.now()})),!r||!s?{current:r,latest:s,updateAvailable:!1,checked:!!s}:{current:r,latest:s,updateAvailable:Uc(s,r)>0,checked:!0}}async function lo({version:e="latest",dryRun:t=!1}={}){let{root:n,managed:r}=Fc();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=`${_n}@${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:a}=await Rc("npm",i,{timeout:3e5,maxBuffer:16777216});return{ok:!0,root:n,stdout:s,stderr:a}}catch(s){return{ok:!1,reason:"npm-failed",root:n,message:s?.stderr||s?.message||"npm install failed"}}}var Rc,_n,Lc,Mc,uo=_(()=>{Rc=Pc(Cc),_n="@oracle-agent/oracle",Lc="https://registry.npmjs.org",Mc=1440*60*1e3});import jc from"node:fs";import Hc from"node:os";import po from"node:path";function Ue(e){return String(e||"").trim().toLowerCase().replace(/^\/+/,"").replace(/\s+/g,"-")}function zc(){let e=process.env.ORACLE_CONFIG_DIR||po.join(Hc.homedir(),".config","oracle");return po.join(e,"chains.json")}function Vc(e){if(!e||typeof e!="object")return null;let t=String(e.key??"").trim();if(!t||/[/\\.]/.test(t))return null;let n=Ue(t);if(!mo.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"&&mo.test(e.agent.trim())?e.agent.trim():"oracle";return{key:n,aliases:Array.isArray(e.aliases)?e.aliases.map(Ue).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:Ue(e.family)||n,agent:o,note:String(e.note||"user-defined").slice(0,80),build:e.build!==!1,source:"user"}}function Kc(e=jc.readFileSync){try{let t=JSON.parse(e(zc(),"utf8")),n=Array.isArray(t?.chains)?t.chains:[],r=[],o=new Set;for(let i of n){let s=Vc(i);!s||o.has(s.key)||(o.add(s.key),r.push(s))}return r}catch{return[]}}function ho(){let e=Kc();if(e.length===0)return fo;let t=new Map(fo.map(n=>[n.key,n]));for(let n of e)t.set(n.key,n);return[...t.values()]}function Wc({buildOnly:e=!1}={}){return ho().filter(t=>e?t.build:!0)}function Ze(e){let t=Ue(e);if(!t)return null;for(let n of ho())if(n.key===t||String(n.chainId).toLowerCase()===t||(n.aliases||[]).map(Ue).includes(t)||Ue(n.name)===t)return n;return null}function yo({selectedKey:e=null,buildOnly:t=!1}={}){let n=Wc({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),a=o.key.padEnd(12);r.push(`${i} ${a} ${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 Un,Fn,sr=T(()=>{Un=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}]);Fn=/^[a-z0-9][a-z0-9-]*$/});import ar from"node:fs";import Ma from"node:path";function Dn(){return Ma.join(X(),"active-chain.json")}function cr(){let e=Dn();if(!ar.existsSync(e))return null;try{let t=JSON.parse(ar.readFileSync(e,"utf8"));if(!t||typeof t!="object"||!t.key)return null;let r=He(t.key);return r?{key:r.key,chainId:r.chainId,name:r.name,agent:r.agent,selectedAt:t.selectedAt||null}:null}catch{return null}}function qn(e){let t=He(e);if(!t){let n=new Error(`unknown chain '${e}'`);throw n.code="UNKNOWN_CHAIN",n}pt(X());let r={key:t.key,chainId:t.chainId,name:t.name,agent:t.agent,selectedAt:new Date().toISOString()};return ar.writeFileSync(Dn(),JSON.stringify(r,null,2)+`
19
- `,{mode:384}),r}var jn=T(()=>{sr();ft()});import{createHash as Ba,randomBytes as Nf}from"node:crypto";import{mkdirSync as Da,readFileSync as qa,writeFileSync as ja}from"node:fs";import{homedir as Ha}from"node:os";import{dirname as Va,join as Hn}from"node:path";function ze(e=process.env){return Hn(e.ORACLE_CONFIG_DIR||Hn(Ha(),".config","oracle"),"telegram-cards.json")}function We(){return{links:{},artifacts:{},threads:{}}}function gt(){return Ve}function Vn(e,{readFile:t=qa}={}){try{let r=JSON.parse(String(t(e)));Ve={links:r.links&&typeof r.links=="object"?r.links:{},artifacts:r.artifacts&&typeof r.artifacts=="object"?r.artifacts:{},threads:r.threads&&typeof r.threads=="object"?r.threads:{}}}catch{Ve=We()}return Ve}function wt(e,t=Ve,{writeFile:r=ja,mkdir:n=Da}={}){n(Va(e),{recursive:!0,mode:448}),r(e,JSON.stringify(t),{mode:384})}function ie(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function Ya(e){return Ba("sha256").update(String(e)).digest("hex")}function lr(e){if(Array.isArray(e))return e.map(lr);if(!e||typeof e!="object")return e;let t={};for(let[r,n]of Object.entries(e))/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(r)||(t[r]=lr(n));return t}function Ja(e){let r=String(e||"").trim().match(/^oracle:card:(deepen|refresh|prepare|ta|fa|long|short|allow|deny):([a-z0-9-]{4,40})$/i);return r?{action:r[1].toLowerCase(),artifactId:r[2].toLowerCase()}:null}function zn({platform:e="telegram",artifactId:t,openUrl:r,hasGrant:n=!1}={}){let o=String(t||"").trim().toLowerCase();if(!ur.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}`}],a=c=>An(r,{side:c}),l=a("long"),u=a("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(r)?(i.push([{text:"Open",url:String(r)},s[0]]),i.push(d),i.push(n?[s[1],{text:"Prep",callback_data:`oracle:card:prepare:${o}`}]:[s[1]])):(i.push(s),i.push(d),n&&i.push([{text:"Prep",callback_data:`oracle:card:prepare:${o}`}])),String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:i.filter(c=>c.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function Wn(e={}){let r=[`*${ie(e.title)?g(e.title):"Oracle artifact"}*`,`Kind: ${ie(e.kind)?g(e.kind):C}`,`Id: ${ie(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:C}`,`Summary: ${ie(e.summary)?g(e.summary):C}`],n=Jt(e.confidence);n!==C&&r.push(`Confidence: ${n}`),(ie(e.source)||ie(e.fetchedAt))&&r.push(`Source: ${g(e.source)} at ${g(e.fetchedAt)}`),Array.isArray(e.warnings)&&e.warnings.length&&r.push(`Warnings: ${e.warnings.map(i=>g(i)).join("; ")}`);let o=fe(e);return r.push(o.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${g(o.reason)}`),r.join(`
20
- `)}function Xa(e,t={},{now:r=Date.now()}={}){let n=e||We(),o=String(t.id||"").trim().toLowerCase();if(!ur.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(r).toISOString(),warnings:Array.isArray(t.warnings)?t.warnings.map(String):[],payload:lr(t.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=i,i}function dr(e,{chatId:t,artifactId:r,now:n=Date.now()}={}){let o=e||We(),i=String(t||"").trim(),s=String(r||"").trim().toLowerCase();if(!i)throw new TypeError("chat id required");if(!ur.test(s))throw new TypeError("artifact id required");return o.threads[i]={artifactId:s,updatedAt:n},o.threads[i]}function Gn(e,{chatId:t,text:r}={}){let n=String(t||"").trim(),o=String(r||"").trim();if(!n||!o||/^\//.test(o))return null;let i=e?.threads?.[n];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 Kn(e,{token:t,telegramUserId:r,now:n=Date.now()}={}){let o=e||We(),i=String(t||"").trim(),s=String(r||"").trim();if(!Ga.test(i))return{ok:!1,error:"invalid start token"};if(!Ka.test(s))return{ok:!1,error:"invalid telegram user"};let a=Ya(i),l=o.links[a];return l?(delete o.links[a],Number(l.expiresAt)<=n?{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 Yn(e,{data:t,chatId:r,grant:n=null,now:o=Date.now()}={}){let i=Ja(t);if(!i)return null;if(!Wa.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};r&&dr(e,{chatId:r,artifactId:s.id,now:o});let a=fe({grant:n},{now:o}),l=zn({artifactId:s.id,openUrl:s.openUrl,hasGrant:a.allowed});return i.action==="refresh"?{text:Wn(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.`}:a.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 ${a.reason}. Deepen and Refresh still work.`,buttons:l,prompt:null}}function Jn(e={},{grant:t=null,now:r=Date.now(),state:n}={}){let o=n||gt(),i=String(e.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),s=Xa(o,{...e,id:i},{now:r}),a=fe({grant:t},{now:r});return{text:Wn({...s,grant:t}),replyMarkup:zn({artifactId:s.id,openUrl:s.openUrl,hasGrant:a.allowed}).replyMarkup,artifact:s,state:o}}var za,Wa,ur,Ga,Ka,Ve,pr=T(()=>{Kt();Zt();za=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),Wa=new Set(za),ur=/^[a-z0-9-]{4,40}$/i,Ga=/^[0-9a-f]{32}$/,Ka=/^\d+$/;Ve=We()});var So={};ye(So,{NON_OWNER_REPLY:()=>Te,buildPersona:()=>Oe,handleSelfUpdate:()=>no,isForwarded:()=>oo,isOwnerSender:()=>Ce,ownerIdsFor:()=>to,parseGatewayChainCommand:()=>mo,parseGatewayCompactCommand:()=>fo,parseGatewayEffortCommand:()=>co,parseGatewayGoalCommand:()=>po,parseGatewayHelpCommand:()=>lo,parseGatewayModelCommand:()=>ao,parseGatewaySetupModelCommand:()=>lc,parseGatewayStatusCommand:()=>uo,parsePeerAsk:()=>yo,parseSelfUpdate:()=>ro,resolveBackendArgv:()=>go,resolveGatewayModel:()=>io,resolveOracleBin:()=>eo,routePeerConsult:()=>Ge,routeToAgent:()=>ee});import{spawn as Zn}from"node:child_process";import{dirname as Qa,join as mr}from"node:path";import{homedir as Za}from"node:os";import{mkdirSync as ec,readFileSync as tc,writeFileSync as rc,unlinkSync as nc}from"node:fs";import{fileURLToPath as oc}from"node:url";function eo({env:e=process.env,moduleUrl:t=import.meta.url}={}){return e.ORACLE_CLI_ENTRY||mr(Qa(oc(t)),"oracle.mjs")}function to(e,t=process.env){let r=String(t[`ORACLE_OWNER_${String(e).toUpperCase()}`]||""),n=String(t.ORACLE_OWNER_IDS||"");return new Set(`${r},${n}`.split(",").map(o=>o.trim()).filter(Boolean))}function Ce({platform:e,senderId:t,extraOwners:r},n=process.env){let o=String(t||"").trim();return o?to(e,n).has(o)?!0:Array.isArray(r)?r.map(i=>String(i).trim()).filter(Boolean).includes(o):!1:!1}function ro(e){let t=String(e||"").trim();if(!t)return null;let r=t.replace(/^\/update(?:@[\w_]+)?\b/i,"update");return/^(?:oracle\s+)?update\s+--check\s*$/i.test(r)?{checkOnly:!0}:/^(?:oracle\s+)?update\s*$/i.test(r)?{checkOnly:!1}:null}async function no(e,{check:t=$n,update:r=Pn,versionOf:n=ir}={}){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 r({version:i==="latest"?"latest":i});if(!s.ok)return`oracle update failed: ${s.message}`;let a=n();return[`oracle ${o.current||"?"} \u2192 ${a||i}`,"Restart the gateway to load it: oracle gateway"].join(`
21
- `)}function oo(e={}){return!!(e.forwarded||e.forward_from||e.forward_from_chat||e.forward_origin||e.forward_sender_name||e.forward_date)}function io({readConfig:e=_e}={}){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 ao(e){let r=String(e||"").trim().match(/^\/model(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();if(!n)return{action:"list"};if(n.toLowerCase()==="show"||n==="?")return{action:"show"};if(n.toLowerCase()==="list")return{action:"list"};let o=n.split(/\s+/),i=so[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,a]=o[0].split(":");if(s&&a)return{action:"set",provider:s,model:a}}return{action:"usage"}}function co(e){let r=String(e||"").trim().match(/^\/(?:effort|reasoning)(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim().toLowerCase();return!n||n==="show"||n==="?"?{action:"show"}:sc.includes(n)?{action:"set",reasoningEffort:n}:{action:"usage"}}function ac({provider:e,model:t}){let r=_e()||{},n=Gt({...r,backend:r.backend&&r.backend!=="auto"?r.backend:"standalone",provider:e,model:t});return`model ${n.provider} / ${n.model}
22
- Oracle persona unchanged. Native harness only \u2014 Hermes Telegram uses its own /model.`}function cc(e){let t=_e();if(!t)throw new Error("no model configured \u2014 run /model first");return`effort ${Gt({...t,reasoningEffort:e}).reasoningEffort||e}
23
- Native harness only.`}function Xn(){let e=_e(),t=["Oracle native models (tap /model <id> to switch):"];for(let[r,n]of Object.entries(so)){let o=e?.provider===n.provider&&e?.model===n.model?" \u2190 current":"";t.push(`/model ${r} ${n.provider} / ${n.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 fr(){let e=_e();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 fo,mo,On=_(()=>{fo=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}]);mo=/^[a-z0-9][a-z0-9-]*$/});import Nn from"node:fs";import Gc from"node:path";function go(){return Gc.join(ie(),"active-chain.json")}function Tn(){let e=go();if(!Nn.existsSync(e))return null;try{let t=JSON.parse(Nn.readFileSync(e,"utf8"));if(!t||typeof t!="object"||!t.key)return null;let n=Ze(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 wo(e){let t=Ze(e);if(!t){let r=new Error(`unknown chain '${e}'`);throw r.code="UNKNOWN_CHAIN",r}vt(ie());let n={key:t.key,chainId:t.chainId,name:t.name,agent:t.agent,selectedAt:new Date().toISOString()};return Nn.writeFileSync(go(),JSON.stringify(n,null,2)+`
19
+ `,{mode:384}),n}var bo=_(()=>{On();At()});var So=_(()=>{});function xo(e,{coin:t,side:n,sizeUsd:r,leverage:o,venue:i,confirm:s,user:a}={}){let l=Zr(e);if(!l)return null;if(t&&Yc.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()),a&&/^0x[0-9a-fA-F]{40}$/.test(String(a))&&l.searchParams.set("user",String(a).toLowerCase()),l.toString()}var Yc,Eo=_(()=>{So();Ct();Ct();Yc=/^[A-Z0-9][A-Z0-9._-]{0,11}$/});var ko=_(()=>{});var vo=_(()=>{});var Ao=_(()=>{ko();vo()});import{AbiCoder as Jc,Interface as $n,getAddress as qh,isAddress as jh,keccak256 as Hh}from"ethers";var Gh,Io,Yh,Jh,Xh,Qh,Zh,_o=_(()=>{Ce();wt();Ao();pe();Gh=Jc.defaultAbiCoder(),Io={1:{name:"ethereum",poolManager:"0x000000000004444c5dc75cB358380D2e3dE08A90",quoter:"0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203",stateView:"0x7ffe42c4a5deea5b0fec41c94c136cf115597227",universalRouter:"0x66a9893cc07d91d95644aedd05d03f95e1dba8af",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},10:{name:"optimism",poolManager:"0x9a13f98cb987694c9f086b1f5eb990eea8264ec3",quoter:"0x1f3131a13296fb91c90870043742c3cdbff1a8d7",stateView:"0xc18a3169788f4f75a170290584eca6395c75ecdb",universalRouter:"0x851116d9223fabed8e56c0e6b8ad0c31d98b3507",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",poolManager:"0x28e2ea090877bf75740558f6bfb36a5ffee9e9df",quoter:"0x9f75dd27d6664c475b90e105573e550ff69437b0",stateView:"0xd13dd3d6e93f276fafc9db9e6bb47c1180aee0c4",universalRouter:"0x1906c1d672b88cd1b9ac7593301ca990f94eae07",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",poolManager:"0x67366782805870060151383f4bbff9dab53e5cd6",quoter:"0xb3d5c3dfc3a7aebff71895a7191796bffc2c81b9",stateView:"0x5ea1bd7974c8a611cbab0bdcafcb1d9cc9b3ba5a",universalRouter:"0x1095692a6237d83c6a72f3f5efedb9a670c49223",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},8453:{name:"base",poolManager:"0x498581fF718922c3f8e6A244956aF099B2652b2b",quoter:"0x0d5e0f971ed27fbff6c2837bf31316121532048d",stateView:"0xa3c0c9b65bad0b08107aa264b0f3db444b867a71",universalRouter:"0x6ff5693b99212da76ad316178a184ab56d299b43",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",poolManager:"0x360e68faccca8ca495c1b759fd9eee466db9fb32",quoter:"0x3972c00f7ed4885e145823eb7c655375d275a1c5",stateView:"0x76fd297e2d437cd7f76d50f01afe6160f86e9990",universalRouter:"0xa51afafe0263b40edaef0df8781ea9aa03e381a3",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},43114:{name:"avalanche",poolManager:"0x06380c0e0912312b5150364b9dc4542ba0dbbc85",quoter:"0xbe40675bb704506a3c2ccfb762dcfd1e979845c2",stateView:"0xc3c9e198c735a4b97e3e683f391ccbdd60b69286",universalRouter:"0x94b75331ae8d42c1b61065089b7d48fe14aa73b7",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"},4663:{name:"robinhood",poolManager:"0x8366a39cc670b4001a1121b8f6a443a643e40951",quoter:"0x8dc178efb8111bb0973dd9d722ebeff267c98f94",stateView:"0xf3334192d15450cdd385c8b70e03f9a6bd9e673b",universalRouter:"0x8876789976dEcBfCbBbe364623C63652db8C0904",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"}},Yh=new $n(["function quoteExactInputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountOut, uint256 gasEstimate)","function quoteExactOutputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountIn, uint256 gasEstimate)"]),Jh=new $n(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]),Xh=new $n(["function getSlot0(bytes32 poolId) view returns (uint160 sqrtPriceX96,int24 tick,uint24 protocolFee,uint24 lpFee)","function getLiquidity(bytes32 poolId) view returns (uint128 liquidity)"]),Qh=Object.freeze([[13,"beforeInitialize"],[12,"afterInitialize"],[11,"beforeAddLiquidity"],[10,"afterAddLiquidity"],[9,"beforeRemoveLiquidity"],[8,"afterRemoveLiquidity"],[7,"beforeSwap"],[6,"afterSwap"],[5,"beforeDonate"],[4,"afterDonate"],[3,"beforeSwapReturnsDelta"],[2,"afterSwapReturnsDelta"],[1,"afterAddLiquidityReturnsDelta"],[0,"afterRemoveLiquidityReturnsDelta"]]),Zh=(1n<<14n)-1n});import{AbiCoder as Xc,Interface as Qc,getAddress as Ro,isAddress as Zc}from"ethers";function R(e){throw new Error(`uniswap-v4-lp: ${e}`)}function ee(e,t){(e==null||e==="")&&R(`${t} address required`);let n=String(e);return Zc(n)||R(`${t} is not a valid address: ${n}`),Ro(n)}function H(e,t,{max:n=el,min:r=0n}={}){(e==null||e==="")&&R(`${t} required`);let o;try{o=typeof e=="bigint"?e:BigInt(String(e))}catch{R(`${t} must be an integer, got ${String(e)}`)}return o<r&&R(`${t} must be >= ${r}`),o>n&&R(`${t} exceeds ${t==="fee"?"uint24":n===Q?"uint128":"uint256"}`),o}function Po(e,t){let n=Number(e);return Number.isInteger(n)||R(`${t} must be an integer tick`),(n<Oo||n>No)&&R(`${t} ${n} outside [${Oo}, ${No}]`),n}function Tt(e){return e==null||e===""||String(e).toLowerCase()!=="0x"&&R("opaque hookData is inspect-only until a hook-specific adapter exists"),"0x"}function Fo(e={}){(!e||typeof e!="object")&&R("poolKey required");let t=e.currency0==null||e.currency0===""?he:ee(e.currency0,"poolKey.currency0"),n=ee(e.currency1,"poolKey.currency1");BigInt(t)>=BigInt(n)&&R("poolKey.currency0 must sort below currency1 (V4 PoolKey invariant); reordering would target a different pool");let r=Number(H(e.fee,"fee",{max:tl})),o=Number(e.tickSpacing);(!Number.isInteger(o)||o<=0||o>32767)&&R(`poolKey.tickSpacing must be a positive int16, got ${e.tickSpacing}`);let i=e.hooks==null||e.hooks===""?he:ee(e.hooks,"poolKey.hooks");return{currency0:t,currency1:n,fee:r,tickSpacing:o,hooks:i}}function Uo(e,t,n){let r=Po(e,"tickLower"),o=Po(t,"tickUpper");return r>=o&&R(`tickLower ${r} must be below tickUpper ${o}`),(r%n!==0||o%n!==0)&&R(`ticks must be multiples of tickSpacing ${n} (got ${r}, ${o})`),{tickLower:r,tickUpper:o}}function al(e){let t=Number(e);return(!Number.isSafeInteger(t)||t<=0)&&R("deadline (unix seconds) required"),t}function Bo(e){return`0x${e.map(t=>t.toString(16).padStart(2,"0")).join("")}`}function Z(e,t){return Lo.encode(sl[e],t)}function cl(e,t){return(!Array.isArray(e)||!Array.isArray(t)||e.length!==t.length||e.length===0)&&R("actions and params must be equal-length non-empty arrays"),Lo.encode(["bytes","bytes[]"],[Bo(e),t])}function $t({chainId:e,positionManager:t,actions:n,params:r,deadline:o,value:i,summary:s,extra:a={}}){let l=cl(n,r),u=Mo.encodeFunctionData("modifyLiquidities",[l,BigInt(o)]);return Object.freeze({chainId:Number(e),to:t,data:u,value:i.toString(),deadline:o,actions:n.map(d=>nl[d]),actionsHex:Bo(n),summary:s,...a})}function Pt(e){let t=Number(e.chainId);(!Number.isInteger(t)||t<=0)&&R("chainId required");let n=ee(e.positionManager,"positionManager");return{chainId:t,positionManager:n,deadline:al(e.deadline)}}function ll(e={}){let{chainId:t,positionManager:n,deadline:r}=Pt(e),o=Fo(e.poolKey),{tickLower:i,tickUpper:s}=Uo(e.tickLower,e.tickUpper,o.tickSpacing),a=H(e.liquidity,"liquidity");a===0n&&R("liquidity must be > 0 for mint");let l=H(e.amount0Max,"amount0Max",{max:Q}),u=H(e.amount1Max,"amount1Max",{max:Q}),d=ee(e.owner,"owner"),c=Tt(e.hookData),f=o.currency0===he,m=[J.MINT_POSITION,J.SETTLE_PAIR],p=[Z("MINT_POSITION",[o,i,s,a,l,u,d,c]),Z("SETTLE_PAIR",[o.currency0,o.currency1])];f&&(m.push(J.SWEEP),p.push(Z("SWEEP",[he,d])));let y=f?l:0n,S=`mint v4 LP ${o.currency0}/${o.currency1} fee ${o.fee} ticks [${i}, ${s}] liquidity ${a} (max ${l} / ${u}) to ${d}${f?" paying native value":""}${o.hooks!==he?` hooked ${o.hooks}`:""}`;return $t({chainId:t,positionManager:n,actions:m,params:p,deadline:r,value:y,summary:S,extra:{poolKey:o,tickLower:i,tickUpper:s,owner:d,requiresApproval:jo(o,{amount0Max:l,amount1Max:u})}})}function Do(e={}){let{chainId:t,positionManager:n,deadline:r}=Pt(e),o=H(e.tokenId,"tokenId"),i=H(e.liquidity,"liquidity"),s=H(e.amount0Min,"amount0Min",{max:Q}),a=H(e.amount1Min,"amount1Min",{max:Q}),{currency0:l,currency1:u}=qo(e),d=ee(e.recipient??e.owner,"recipient"),c=Tt(e.hookData),f=[J.DECREASE_LIQUIDITY,J.TAKE_PAIR],m=[Z("DECREASE_LIQUIDITY",[o,i,s,a,c]),Z("TAKE_PAIR",[l,u,d])],p=i===0n?`collect fees on v4 LP #${o} to ${d}`:`decrease v4 LP #${o} by ${i} liquidity (min ${s} / ${a}) to ${d}`;return $t({chainId:t,positionManager:n,actions:f,params:m,deadline:r,value:0n,summary:p,extra:{tokenId:o.toString(),recipient:d,currency0:l,currency1:u}})}function ul(e={}){return Do({...e,liquidity:0n,amount0Min:0n,amount1Min:0n})}function dl(e={}){let{chainId:t,positionManager:n,deadline:r}=Pt(e),o=H(e.tokenId,"tokenId"),i=H(e.amount0Min,"amount0Min",{max:Q}),s=H(e.amount1Min,"amount1Min",{max:Q}),{currency0:a,currency1:l}=qo(e),u=ee(e.recipient??e.owner,"recipient"),d=Tt(e.hookData),c=[J.BURN_POSITION,J.TAKE_PAIR],f=[Z("BURN_POSITION",[o,i,s,d]),Z("TAKE_PAIR",[a,l,u])];return $t({chainId:t,positionManager:n,actions:c,params:f,deadline:r,value:0n,summary:`burn v4 LP #${o} (min ${i} / ${s}) to ${u}`,extra:{tokenId:o.toString(),recipient:u,currency0:a,currency1:l}})}function pl(e={}){let{chainId:t,positionManager:n,deadline:r}=Pt(e),o=e.burn||{},i=e.mint||{},s=H(o.tokenId,"burn.tokenId"),a=H(o.amount0Min??0n,"burn.amount0Min",{max:Q}),l=H(o.amount1Min??0n,"burn.amount1Min",{max:Q}),u=Fo(i.poolKey);u.currency0===he&&R("rebalance refuses native currency pools: shortfall msg.value cannot be sized offline");let{tickLower:d,tickUpper:c}=Uo(i.tickLower,i.tickUpper,u.tickSpacing),f=H(i.liquidity,"mint.liquidity");f===0n&&R("mint.liquidity must be > 0 for rebalance");let m=H(i.amount0Max,"mint.amount0Max",{max:Q}),p=H(i.amount1Max,"mint.amount1Max",{max:Q}),y=ee(i.owner??e.owner,"owner"),S=Tt(i.hookData??o.hookData),v=[J.BURN_POSITION,J.MINT_POSITION,J.CLOSE_CURRENCY,J.CLOSE_CURRENCY],N=[Z("BURN_POSITION",[s,a,l,S]),Z("MINT_POSITION",[u,d,c,f,m,p,y,S]),Z("CLOSE_CURRENCY",[u.currency0]),Z("CLOSE_CURRENCY",[u.currency1])];return $t({chainId:t,positionManager:n,actions:v,params:N,deadline:r,value:0n,summary:`rebalance v4 LP: burn #${s} then mint ${u.currency0}/${u.currency1} fee ${u.fee} ticks [${d}, ${c}] liquidity ${f} (max ${m} / ${p}) to ${y}, one unlock`,extra:{burnTokenId:s.toString(),poolKey:u,tickLower:d,tickUpper:c,owner:y,requiresApproval:jo(u,{amount0Max:m,amount1Max:p})}})}function qo(e){let t=e.poolKey&&typeof e.poolKey=="object"?e.poolKey:e,n=t.currency0==null||t.currency0===""?he:ee(t.currency0,"currency0"),r=ee(t.currency1,"currency1");return BigInt(n)>=BigInt(r)&&R("currency0 must sort below currency1"),{currency0:n,currency1:r}}function jo(e,{amount0Max:t,amount1Max:n}){let r=[];return e.currency0!==he&&r.push({token:e.currency0,spender:Co,amount:t.toString()}),r.push({token:e.currency1,spender:Co,amount:n.toString()}),{note:"PositionManager settles ERC-20 debt via Permit2; token\u2192Permit2 approval and a Permit2 allowance for PositionManager are both required",approvals:r}}function Ho(e={},t={}){let n=t.chains||Io,r=Number(e.chainId);(!Number.isInteger(r)||r<=0)&&R("chainId required");let o=n[r];o||R(`unsupported chainId ${r} (supported: ${Object.keys(n).join(", ")})`),o.positionManager||R(`no v4 PositionManager registered for chain ${r} (${o.name||"unnamed"})`);let i=String(e.kind||"").toLowerCase(),s=fl[i];s||R(`unknown kind ${e.kind} (expected ${rl.join("|")})`);let a=Number(e.deadlineSec);(!Number.isInteger(a)||a<To||a>$o)&&R(`deadlineSec must be an integer from ${To} through ${$o}`);let u=Number(t.nowSeconds??Math.floor(Date.now()/1e3))+a,d=e.params&&typeof e.params=="object"?e.params:{},c=s({...d,chainId:r,positionManager:Ro(o.positionManager),deadline:u}),f=e.from??d.owner??d.recipient??null,m=f?ee(f,"from"):null,p={...c},{to:y,data:S,value:v,summary:N,actions:E,actionsHex:h,requiresApproval:x=null}=c;for(let b of["to","data","value","summary","actions","actionsHex","requiresApproval","chainId","deadline"])delete p[b];return be({provider:"uniswap-v4-lp",kind:`univ4-lp-${i}`,lpKind:i,prepareReady:!0,calldataReady:!0,executionReady:!1,executionAllowed:!1,requiresUserSignature:!0,requiresWalletSignature:!0,backendSigner:!1,unsigned:!0,houseSigned:!1,signingReady:!1,broadcastReady:!1,simulate:null,chainId:r,chainName:o.name||null,deadline:u,summary:N,plan:{actions:E,actionsHex:h,selector:ol},detail:p,requiresApproval:x,transaction:{chainId:r,from:m,to:y,data:S,value:v},notes:["prepare-only: user wallet must sign","one modifyLiquidities unlock; Telegram never sends","action bytes verified against v4-periphery Actions.sol; simulate before signing"]},{provider:"uniswap-v4-lp",kind:`univ4-lp-${i}`,env:t.env,nowMs:t.nowMs})}var Lo,he,Co,Oo,No,Q,el,tl,To,$o,J,nl,rl,Mo,ol,il,sl,fl,zo=_(()=>{_o();pe();Lo=Xc.defaultAbiCoder(),he="0x0000000000000000000000000000000000000000",Co="0x000000000022D473030F116dDEE9F6B43aC78BA3",Oo=-887272,No=887272,Q=(1n<<128n)-1n,el=(1n<<256n)-1n,tl=(1n<<24n)-1n,To=30,$o=600,J=Object.freeze({INCREASE_LIQUIDITY:0,DECREASE_LIQUIDITY:1,MINT_POSITION:2,BURN_POSITION:3,SETTLE_PAIR:13,TAKE_PAIR:17,CLOSE_CURRENCY:18,SWEEP:20}),nl=Object.freeze(Object.fromEntries(Object.entries(J).map(([e,t])=>[t,e]))),rl=Object.freeze(["mint","decrease","collect","burn","rebalance"]),Mo=new Qc(["function modifyLiquidities(bytes unlockData, uint256 deadline) payable"]),ol=Mo.getFunction("modifyLiquidities").selector,il="tuple(address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks)",sl=Object.freeze({MINT_POSITION:Object.freeze([il,"int24","int24","uint256","uint128","uint128","address","bytes"]),INCREASE_LIQUIDITY:Object.freeze(["uint256","uint256","uint128","uint128","bytes"]),DECREASE_LIQUIDITY:Object.freeze(["uint256","uint256","uint128","uint128","bytes"]),BURN_POSITION:Object.freeze(["uint256","uint128","uint128","bytes"]),SETTLE_PAIR:Object.freeze(["address","address"]),TAKE_PAIR:Object.freeze(["address","address","address"]),CLOSE_CURRENCY:Object.freeze(["address"]),SWEEP:Object.freeze(["address","address"])});fl=Object.freeze({mint:ll,decrease:Do,collect:ul,burn:dl,rebalance:pl})});function Y(e){return e==null?!1:typeof e=="number"?Number.isFinite(e):typeof e=="string"?e.trim()!==""&&e.trim().toLowerCase()!==G:!0}function et(e,{estimate:t=!0,signed:n=!1}={}){if(!Y(e))return G;let r=Number(e);if(!Number.isFinite(r))return G;let o=Math.abs(r),i=o>=1e3?o.toLocaleString("en-US",{maximumFractionDigits:0}):o.toFixed(2),s=r<0?"-":n&&r>0?"+":"";return`${t?"~":""}${s}$${i}`}function Pn(e){if(!Y(e))return G;let t=Number(e);return Number.isFinite(t)?t===0?"0":t>=1e3?t.toLocaleString("en-US",{maximumFractionDigits:2}):t>=1?t.toFixed(4):t.toPrecision(4):G}function hl(e){if(!Y(e))return G;let t=Number(e);return Number.isFinite(t)?`${(t/1e4).toFixed(t%100===0?2:3)}%`:g(e)}function yl(e){let t={1:"Ethereum",10:"Optimism",56:"BSC",137:"Polygon",8453:"Base",42161:"Arbitrum",43114:"Avalanche",4663:"Robinhood"},n=Number(e);return Number.isInteger(n)?t[n]?`${t[n]} (${n})`:`chain ${n}`:G}function gl(e){if(!e||typeof e!="object")return`Decision: ${G}`;let t=Y(e.action)?String(e.action).toUpperCase():G,n=Y(e.mode)?String(e.mode):"alert_only",r=Y(e.reason)?g(e.reason):G;return`Decision: ${g(t)} (${g(n)}) \u2014 ${r}`}function Ko(e={}){let n=[`*LP ${Y(e.pair)?g(e.pair):G} \xB7 ${g(yl(e.chainId))}*`,`Net: ${et(e.netUsd,{signed:!0})}`,`Fees ${et(e.feesUsd)} \xB7 IL ${et(e.ilUsd)} \xB7 Gas ${et(e.gasUsd)} \xB7 Slip ${et(e.slippageUsd)}`,`Range: ${Pn(e.rangeLower)} \u2013 ${Pn(e.rangeUpper)} \xB7 now ${Pn(e.priceNow)} \xB7 ${typeof e.inRange=="boolean"?e.inRange?"IN range":"OUT of range":`range ${G}`}`,`Fee tier: ${hl(e.feeTier)}`,gl(e.decision)];(Y(e.source)||Y(e.observedAt))&&n.push(`Source: ${Y(e.source)?g(e.source):G} at ${Y(e.observedAt)?g(e.observedAt):G}`),n.push("Buttons open the graph or queue an unsigned prepare. Telegram never sends.");let r=n.join(`
20
+ `);return r.length>Vo&&(r=`${r.slice(0,Vo-1)}\u2026`),r}function Wo({platform:e="telegram",artifactId:t,hasGrant:n=!1,openUrl:r,collectUrl:o}={}){let i=String(t||"").trim().toLowerCase();if(!ml.test(i))return{kind:"text_menu",text:"no LP artifact to continue",cancelHint:""};let s=[];Y(r)&&s.push({text:"Open",url:String(r)}),s.push({text:"Refresh",callback_data:`oracle:card:refresh:${i}`});let a=[Y(o)?{text:"Collect",url:String(o)}:{text:"Collect",callback_data:`oracle:card:collect:${i}`}];n&&a.push({text:"Rebalance",callback_data:`oracle:card:rebalance:${i}`}),a.push({text:"Exit",callback_data:`oracle:card:exit:${i}`});let l=[s,a].filter(c=>c.length>0),u=n?"Collect/Rebalance/Exit queue unsigned prepares. Sign in your wallet. Telegram never sends.":"Collect/Exit queue unsigned prepares. Rebalance needs a local grant. Telegram never sends.";return String(e)==="telegram"?{kind:"inline_keyboard",replyMarkup:{inline_keyboard:l},cancelHint:u}:{kind:"text_menu",text:l.flat().map(c=>c.text).join(" / "),cancelHint:u}}var Vo,G,ml,Go=_(()=>{Nt();Vo=1e3,G="unknown",ml=/^[a-z0-9-]{4,40}$/i});import{createHash as wl,randomBytes as cy}from"node:crypto";import{mkdirSync as bl,readFileSync as Sl,writeFileSync as xl}from"node:fs";import{homedir as El}from"node:os";import{dirname as kl,join as Yo}from"node:path";function nt(e=process.env){return Yo(e.ORACLE_CONFIG_DIR||Yo(El(),".config","oracle"),"telegram-cards.json")}function rt(){return{links:{},artifacts:{},threads:{}}}function Lt(){return tt}function Qo(e,{readFile:t=Sl}={}){try{let n=JSON.parse(String(t(e)));tt={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{tt=rt()}return tt}function Mt(e,t=tt,{writeFile:n=xl,mkdir:r=bl}={}){r(kl(e),{recursive:!0,mode:448}),n(e,JSON.stringify(t),{mode:384})}function ce(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function Cl(e){return wl("sha256").update(String(e)).digest("hex")}function Rn(e){if(Array.isArray(e))return e.map(Rn);if(!e||typeof e!="object")return e;let t={};for(let[n,r]of Object.entries(e))!Ol.has(n)&&/(secret|token|key|seed|private|password|mnemonic|auth)/i.test(n)||(t[n]=Rn(r));return t}function Zo(e){return String(e?.kind||"").toLowerCase()==="lp"}function Nl(e){let n=String(e||"").trim().match(_l);return n?{action:n[1].toLowerCase(),artifactId:n[2].toLowerCase()}:null}function Tl({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}`}],a=c=>xo(n,{side:c}),l=a("long"),u=a("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 ce(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(c=>c.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function ei(e,t){return Zo(e)?Wo({artifactId:e.id,openUrl:e.openUrl,collectUrl:e.payload?.lp?.collectUrl,hasGrant:t}):Tl({artifactId:e.id,openUrl:e.openUrl,hasGrant:t})}function ti(e={}){if(Zo(e)&&e.payload?.lp?.card&&typeof e.payload.lp.card=="object")return Ko(e.payload.lp.card);let n=[`*${ce(e.title)?g(e.title):"Oracle artifact"}*`,`Kind: ${ce(e.kind)?g(e.kind):O}`,`Id: ${ce(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:O}`,`Summary: ${ce(e.summary)?g(e.summary):O}`],r=Sn(e.confidence);r!==O&&n.push(`Confidence: ${r}`),(ce(e.source)||ce(e.fetchedAt))&&n.push(`Source: ${g(e.source)} at ${g(e.fetchedAt)}`),Array.isArray(e.warnings)&&e.warnings.length&&n.push(`Warnings: ${e.warnings.map(i=>g(i)).join("; ")}`);let o=ve(e);return n.push(o.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${g(o.reason)}`),n.join(`
21
+ `)}function $l(e,t={},{now:n=Date.now()}={}){let r=e||rt(),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:ce(t.openUrl)?String(t.openUrl):null,confidence:t.confidence,source:t.source||"oracle",fetchedAt:t.fetchedAt||new Date(n).toISOString(),warnings:Array.isArray(t.warnings)?t.warnings.map(String):[],payload:Rn(t.payload||{}),wallet:/^0x[0-9a-f]{40}$/i.test(String(t.wallet||""))?String(t.wallet).toLowerCase():null,walletLabel:ce(t.walletLabel)?String(t.walletLabel).slice(0,64):null,chainId:Number.isInteger(Number(t.chainId))&&Number(t.chainId)>0?Number(t.chainId):null,createdAt:new Date(n).toISOString()};return r.artifacts[o]=i,i}function Mn(e,{chatId:t,artifactId:n,now:r=Date.now()}={}){let o=e||rt(),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 ni(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 ri(e,{token:t,telegramUserId:n,now:r=Date.now()}={}){let o=e||rt(),i=String(t||"").trim(),s=String(n||"").trim();if(!Al.test(i))return{ok:!1,error:"invalid start token"};if(!Il.test(s))return{ok:!1,error:"invalid telegram user"};let a=Cl(i),l=o.links[a];return l?(delete o.links[a],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 Pl(e,t,{now:n,prepareLp:r=Ho}={}){let o=Xo[t],i=e.payload?.lp&&typeof e.payload.lp=="object"?e.payload.lp:{},s=i[o]&&typeof i[o]=="object"?i[o]:null,a={artifactId:e.id,action:t,lpKind:o,unsigned:!0,broadcast:!1};if(!s||i.chainId==null)return{...a,envelope:null,reason:`artifact carries no ${o} params; desk must gather them`};try{let l=r({chainId:i.chainId,kind:o,params:s,deadlineSec:i.deadlineSec??300,from:i.owner??s.owner??s.recipient},{nowSeconds:Math.floor(Number(n)/1e3),nowMs:n});return{...a,envelope:l,reason:null}}catch(l){return{...a,envelope:null,reason:String(l?.message||l)}}}function Rt(e){let t=String(e||"");return t.length>=12?`${t.slice(0,6)}\u2026${t.slice(-4)}`:t}function oi(e,{data:t,chatId:n,grant:r=null,now:o=Date.now(),prepareLp:i,guest:s=!1,followStore:a=null,bagReader:l=null}={}){let u=Nl(t);if(!u)return null;if(!vl.has(u.action))return{text:"That card action is not available.",buttons:null};let d=e?.artifacts?.[u.artifactId];if(!d)return{text:"That artifact is gone. Ask again and I will issue a new card.",buttons:null};if(n&&Mn(e,{chatId:n,artifactId:d.id,now:o}),u.action==="follow"||u.action==="bag"){if(s)return{text:"Owner only.",buttons:null,prompt:null};let p=String(d.wallet||"").toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(p))return{text:"No wallet on this card.",buttons:null,prompt:null};if(u.action==="follow"){if(!a||typeof a.add!="function")return{text:"Follow list is not available here.",buttons:null,prompt:null};let y=a.add({address:p,chainId:d.chainId??null,label:d.walletLabel??null,source:"tap"});return y.added?{text:`Following ${Rt(p)}. Alerts on its buys and sells from now.`,buttons:null,prompt:null,follow:y}:y.reason==="already-following"?{text:`Already following ${Rt(p)}.`,buttons:null,prompt:null,follow:y}:{text:`Not following ${Rt(p)}: ${y.reason}.`,buttons:null,prompt:null,follow:y}}return typeof l!="function"?{text:"Bag is not available here.",buttons:null,prompt:null}:{text:`Reading bag for ${Rt(p)}\u2026`,buttons:null,prompt:null,bag:l({chainId:d.chainId??null,address:p})}}let c=ve({grant:r},{now:o}),f=ei(d,c.allowed);if(u.action==="refresh")return{text:ti(d),buttons:f,prompt:null};if(u.action==="deepen")return{text:null,buttons:null,prompt:`Deepen artifact ${d.id} (${d.kind}). Prior: ${d.summary||d.title}. Be terse. Do not sign or broadcast.`};if(u.action==="ta")return{text:null,buttons:null,prompt:`TA artifact ${d.id}. Prior: ${d.summary||d.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.`};if(u.action==="fa")return{text:null,buttons:null,prompt:`FA artifact ${d.id}. Prior: ${d.summary||d.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.`};if(u.action==="allow")return{text:"Allow is the graph. Open the ticket there and CONFIRM. Telegram did not send.",buttons:null,prompt:null};if(u.action==="deny")return{text:`Denied ${d.id}. Ticket cancelled. Nothing signed.`,buttons:null,prompt:null};if(u.action==="long"||u.action==="short")return{text:null,buttons:null,prompt:`Open the live graph ticket for a ${u.action} on artifact ${d.id}. Prior: ${d.summary||d.title}. Size from the connected HL account. Execute only on CONFIRM on the graph. Never sign from Telegram.`};let m=u.action==="prepare"?"Prepare":u.action[0].toUpperCase()+u.action.slice(1);if(!c.allowed)return{text:`${m} blocked \u2014 ${c.reason}. Deepen and Refresh still work.`,buttons:f,prompt:null};if(u.action in Xo){let p=Pl(d,u.action,{now:o,prepareLp:i});return{text:p.envelope?`Queued unsigned ${p.lpKind} for LP ${d.id} (${p.envelope.plan.actions.join("+")}, one modifyLiquidities). Nothing signed. Sign in your wallet.`:`${m} for ${d.id} needs inputs \u2014 ${p.reason}. Nothing signed.`,buttons:f,prompt:null,prepare:p}}return{text:`Queued unsigned prepare for ${d.id}. Nothing signed. Allow/Deny still required.`,buttons:f,prompt:null,prepare:{artifactId:d.id,unsigned:!0,broadcast:!1}}}function ii(e={},{grant:t=null,now:n=Date.now(),state:r}={}){let o=r||Lt(),i=String(e.id||`art-${Math.abs(Number(n)).toString(36)}`).toLowerCase().slice(0,40),s=$l(o,{...e,id:i},{now:n}),a=ve({grant:t},{now:n});return{text:ti({...s,grant:t}),replyMarkup:ei(s,a.allowed).replyMarkup,artifact:s,state:o}}var Jo,Xo,vl,Ln,Al,Il,_l,tt,Ol,Fn=_(()=>{Eo();Nt();zo();Go();Jo=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny","bag","follow","rebalance","exit","collect"]),Xo=Object.freeze({rebalance:"rebalance",exit:"burn",collect:"collect"}),vl=new Set(Jo),Ln=/^[a-z0-9-]{4,40}$/i,Al=/^[0-9a-f]{32}$/,Il=/^\d+$/,_l=new RegExp(`^oracle:card:(${Jo.join("|")}):([a-z0-9-]{4,40})$`,"i");tt=rt();Ol=new Set(["tokenId","poolKey","burnTokenId"])});var Ci={};_e(Ci,{NON_OWNER_REPLY:()=>De,buildPersona:()=>qe,handleSelfUpdate:()=>pi,isForwarded:()=>fi,isOwnerSender:()=>Be,ownerIdsFor:()=>ui,parseGatewayChainCommand:()=>Ei,parseGatewayCompactCommand:()=>xi,parseGatewayEffortCommand:()=>gi,parseGatewayGoalCommand:()=>Si,parseGatewayHelpCommand:()=>wi,parseGatewayModelCommand:()=>yi,parseGatewaySetupModelCommand:()=>Vl,parseGatewayStatusCommand:()=>bi,parsePeerAsk:()=>vi,parseSelfUpdate:()=>di,resolveBackendArgv:()=>Ai,resolveGatewayModel:()=>mi,resolveOracleBin:()=>li,routePeerConsult:()=>ot,routeToAgent:()=>le});import{spawn as ci}from"node:child_process";import{dirname as Rl,join as Bn}from"node:path";import{homedir as Ll}from"node:os";import{mkdirSync as Ml,readFileSync as Fl,writeFileSync as Ul,unlinkSync as Bl}from"node:fs";import{fileURLToPath as Dl}from"node:url";function li({env:e=process.env,moduleUrl:t=import.meta.url}={}){return e.ORACLE_CLI_ENTRY||Bn(Rl(Dl(t)),"oracle.mjs")}function ui(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 Be({platform:e,senderId:t,extraOwners:n},r=process.env){let o=String(t||"").trim();return o?ui(e,r).has(o)?!0:Array.isArray(n)?n.map(i=>String(i).trim()).filter(Boolean).includes(o):!1:!1}function di(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 pi(e,{check:t=co,update:n=lo,versionOf:r=Cn}={}){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 a=r();return[`oracle ${o.current||"?"} \u2192 ${a||i}`,"Restart the gateway to load it: oracle gateway"].join(`
22
+ `)}function fi(e={}){return!!(e.forwarded||e.forward_from||e.forward_from_chat||e.forward_origin||e.forward_sender_name||e.forward_date)}function mi({readConfig:e=Fe}={}){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 yi(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=hi[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,a]=o[0].split(":");if(s&&a)return{action:"set",provider:s,model:a}}return{action:"usage"}}function gi(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"}:jl.includes(r)?{action:"set",reasoningEffort:r}:{action:"usage"}}function Hl({provider:e,model:t}){let n=Fe()||{},r=wn({...n,backend:n.backend&&n.backend!=="auto"?n.backend:"standalone",provider:e,model:t});return`model ${r.provider} / ${r.model}
23
+ Oracle persona unchanged. Native harness only \u2014 Hermes Telegram uses its own /model.`}function zl(e){let t=Fe();if(!t)throw new Error("no model configured \u2014 run /model first");return`effort ${wn({...t,reasoningEffort:e}).reasoningEffort||e}
24
+ Native harness only.`}function si(){let e=Fe(),t=["Oracle native models (tap /model <id> to switch):"];for(let[n,r]of Object.entries(hi)){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(`
25
+ `)}function Un(){let e=Fe();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
26
  `):["No standalone model configured.","Use /model openrouter","or /model qwen","or /model glm","or /model nous","or /model <provider> <model-id>"].join(`
26
- `)}function lc(e){let r=String(e||"").trim().match(/^\/setup(?:\s+model(?:\s+(.+))?)?$/i);if(!r)return null;let n=String(r[1]||"").trim();return n?{action:"hint",provider:n.split(/\s+/)[0]}:{action:"menu"}}function lo(e){let t=String(e||"").trim();return/^\/(?:help|commands|\?)$/i.test(t)?{action:"help"}:null}function uo(e){let t=String(e||"").trim();return/^\/(?:status|usage)$/i.test(t)?{action:"status"}:null}function po(e){let r=String(e||"").trim().match(/^\/goal(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();return!n||n.toLowerCase()==="show"?{action:"show"}:/^(clear|done|complete)$/i.test(n)?{action:"clear"}:{action:"set",goal:n}}function fo(e){let r=String(e||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return r?{action:"compact",focus:String(r[1]||"").trim()}:null}function mo(e){let r=String(e||"").trim().match(/^\/chain(?:\s+(.+))?$/i);if(!r)return null;let n=String(r[1]||"").trim();return!n||n.toLowerCase()==="list"?{action:"list"}:{action:"set",chain:n}}function yr(){return mr(hr,"gateway-goal.json")}function ho(){try{let e=JSON.parse(tc(yr(),"utf8"));return e&&typeof e.goal=="string"?e:null}catch{return null}}function uc(e){ec(hr,{recursive:!0,mode:448});let t={schemaVersion:1,goal:String(e),updatedAt:new Date().toISOString()};return rc(yr(),`${JSON.stringify(t,null,2)}
27
- `,{mode:384}),t}function dc(){try{nc(yr())}catch{}}function pc(){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 fc(){let e=fr(),t=cr(),r=ho();return[e,`chain ${t?.key||t?.name||"default"}`,`goal ${r?.goal||"unset"}`].join(`
29
- `)}function yo(e){let t=String(e||"").trim();if(!t)return null;let r=t.match(/^\/ask(?:@[\w_]+)?\s+([\w-]+)\s+([\s\S]+)$/i);return r||(r=t.match(/^@([\w-]+)\s+([\s\S]+)$/)),r?{peer:r[1].toLowerCase(),text:r[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 go(e,t,{profile:r}={}){let n=String(e||"oracle").toLowerCase(),o=String(t||"");if(n==="oracle")return{ok:!0,bin:null,args:["chat","-q",o]};if(n==="grok")return{ok:!0,bin:"grok",args:["-p",o]};if(n==="hermes"){let i=[];return r&&i.push("-p",String(r)),i.push("-z",o),{ok:!0,bin:"hermes",args:i}}return n==="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:r="",backend:n,profile:o}={}){let i=[`[a2a consult from agent '${e}' \u2014 answer with information only; do not prepare, arm, or execute anything]`,r?`[your role: ${r}]`:"",String(t||"").trim()].filter(Boolean).join(`
30
- `);return bo({text:i,backend:n,profile:o,unconfiguredPrefix:"unconfigured: "})}async function ee({platform:e,chatId:t,senderId:r,text:n,userName:o,meta:i={},updater:s,extraOwners:a,bus:l,agentName:u,persona:d,backend:c,profile:h}={}){if(!Ce({platform:e,senderId:r,extraOwners:a}))return process.stderr.write(`gateway: denied non-owner sender ${e}:${String(r||"unknown")}
31
- `),Te;if(oo(i))return process.stderr.write(`gateway: dropped forwarded message on ${e}
32
- `),null;let p=ro(n);if(p)return no(p,s);let f=ao(n);if(f)try{return f.action==="list"?Xn():f.action==="show"?fr():f.action==="usage"?Xn():ac(f)}catch(b){return`model not saved: ${b.message}`}let w=co(n);if(w)try{return w.action==="show"?fr():w.action==="usage"?"usage: /effort low|medium|high":cc(w.reasoningEffort)}catch(b){return`effort not saved: ${b.message}`}if(lo(n))return pc();if(uo(n))return fc();let S=po(n);if(S){if(S.action==="show"){let b=ho();return b?.goal?`goal ${b.goal}`:"goal unset \u2014 /goal <objective>"}return S.action==="clear"?(dc(),"goal cleared"):(uc(S.goal),`goal pinned: ${S.goal}`)}let A=fo(n);if(A){let b=A.focus?` Focus: ${A.focus}.`:"";return Qn({platform:e,chatId:t,senderId:r,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:c,profile:h})}let O=mo(n);if(O){if(O.action==="list")return Bn({selectedKey:cr()?.key||null});let b=He(O.chain);return b?(qn(b.key),`chain ${b.key}`):`unknown chain '${O.chain}' \u2014 /chain list`}if(er(n)){let b=await rr({platform:e,text:n,grant:{local:!0}});return b?b.buttons?.kind==="inline_keyboard"?{text:b.text,replyMarkup:b.buttons.replyMarkup}:b.text:null}if(l){let b=yo(n);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(n||"").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 m=n.toLowerCase().trim();return/\b(buy|sell|swap|bridge|send|transfer|balance|portfolio|watch|quote|price)\b/.test(m)?hc({platform:e,chatId:t,senderId:r,text:n,userName:o}):Qn({platform:e,chatId:t,senderId:r,text:n,userName:o,persona:d,backend:c,profile:h})}function wo(e,{timeout:t=12e4}={}){return new Promise(r=>{let n=Zn(process.execPath,[ic,...e],{stdio:["ignore","pipe","pipe"],timeout:t,env:{...process.env,ORACLE_CONFIG_DIR:hr,ORACLE_TOOL_SURFACE:"research-x-telegram"}}),o="",i="";n.stdout.on("data",s=>o+=s.toString()),n.stderr.on("data",s=>i+=s.toString()),n.on("close",s=>r({code:s,out:o.trim(),err:i.trim()}))})}function mc(e,t,{timeout:r=18e4}={}){return new Promise(n=>{let o=Zn(e,t,{stdio:["ignore","pipe","pipe"],timeout:r,env:{...process.env}}),i="",s="";o.on("error",a=>n({code:127,out:"",err:String(a.message)})),o.stdout.on("data",a=>i+=a.toString()),o.stderr.on("data",a=>s+=a.toString()),o.on("close",a=>n({code:a,out:i.trim(),err:s.trim()}))})}async function hc({text:e,chatId:t}){let r=await wo(["route","swap","--text",e],{timeout:3e4});if(r.code===0&&r.out)try{return yc(JSON.parse(r.out),{chatId:t})}catch{return r.out}return`Trade routing failed. Try: \`${e}\` again.`}async function Qn({text:e,persona:t,backend:r,profile:n}){let o=t?`[your role: ${t}]
35
- ${e}`:e;return bo({text:o,backend:r,profile:n,unconfiguredPrefix:"Oracle is not configured yet: "})}async function bo({text:e,backend:t,profile:r,unconfiguredPrefix:n}){let o=go(t,e,{profile:r});if(!o.ok)return`${n}${o.error}`;if(!o.bin){let s=io();if(!s.ok)return`${n}${s.error}`;let a=await wo(o.args);return a.code===0&&a.out?a.out:a.err||"Oracle could not answer that. Try again."}let i=await mc(o.bin,o.args);return i.code===0&&i.out?i.out:/ENOENT/.test(i.err)?`${n}backend '${o.bin}' is not installed on this machine`:i.err||`${o.bin} could not answer that. Try again.`}function yc(e,{chatId:t}={}){if(e.error)return`\u274C ${e.error}`;let r=e.quote||e.portfolio||(e.tx?"Unsigned trade prepared. Sign from your own wallet.":"");if(!r&&!e.tx)return JSON.stringify(e,null,2);let n=Jn({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:r,payload:e},{grant:{local:!0}});return t&&dr(n.state,{chatId:t,artifactId:n.artifact.id}),wt(ze(),n.state),{text:n.text,replyMarkup:n.replyMarkup}}var hr,ic,Te,so,sc,Ne=T(()=>{En();nr();Rn();sr();jn();pr();hr=process.env.ORACLE_CONFIG_DIR||mr(Za(),".config","oracle");ic=eo();Te="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";so=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"}}),sc=Object.freeze(["low","medium","high"])});function wc(e,t){let r=new Set,n=[];for(let o of Array.isArray(e)?e:[]){let i=typeof o?.digest=="string"?o.digest:null;i&&(r.add(i),t.has(i)||n.push(o))}t.clear();for(let o of r)t.add(o);return n}function Eo({onNew:e,intervalMs:t=gc,env:r=process.env,signerCall:n=ue,setIntervalFn:o=setInterval,clearIntervalFn:i=clearInterval}={}){if(typeof e!="function")throw new Error("pending-watch: onNew callback required");let s=new Set,a=!1,l=!1;async function u(){if(!l){l=!0;try{let c=await n("/pending",{env:r});if(!c||c.ok===!1||c.error||!Array.isArray(c.items))return;let h=wc(c.items,s);if(!a){a=!0;return}if(h.length===0)return;try{await e(h,{armed:c.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 gc,vo=T(()=>{ht();gc=4e3});import me from"node:fs";function bc(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 xo(e){let t;try{t=me.openSync(e,me.constants.O_RDONLY|me.constants.O_NOFOLLOW)}catch(r){throw r.code==="ELOOP"?new Error("local-vault: refusing symlink"):r}try{let r=me.fstatSync(t);if(bc(r),r.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let n=me.lstatSync(e);if(n.isSymbolicLink()||n.dev!==r.dev||n.ino!==r.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 Zf,em,tm,Ao=T(()=>{Zf=Object.freeze({N:1<<17,r:8,p:1}),em=256*1024*1024,tm=16*1024});import{createHash as Sc,createHmac as ko,randomBytes as Ec,timingSafeEqual as vc}from"node:crypto";function Co({keyFile:e,approvedTelegramOwners:t,nowMs:r=Date.now}={}){if(!e)throw new Error("cex owner proof: signer policy key required");let n=new Set((t||[]).map($e).filter(Boolean));if(!n.size)throw new Error("cex owner proof: approved owner context required");let o=new Set,i=a=>{let l=Buffer.from(xo(e));try{return a(l)}finally{l.fill(0)}},s=i(a=>Sc("sha256").update("cex-owner-instance\0").update(a).digest("hex"));return Object.freeze({mint({digest:a,senderId:l,chatId:u,platform:d,ttlMs:c=15e3}={}){let h=$e(l),p=$e(u),f=r();if(d!=="telegram"||!h||p!==h||!n.has(h))throw new Error("cex owner proof: exact Telegram owner DM required");if(!/^[0-9a-f]{64}$/.test(String(a||""))||!Number.isSafeInteger(c)||c<1||c>3e4)throw new Error("cex owner proof: binding refused");let w={version:1,decision:"Allow",digest:a,ownerSenderId:h,telegramChatId:p,audience:_o,instance:s,nonce:Ec(16).toString("hex"),issuedAtMs:f,expiresAtMs:f+c},S=i(A=>ko("sha256",A).update(Io(w)).digest("hex"));return{claims:w,mac:S}},verify(a,{digest:l}={}){let u=a?.claims,d=r();if(!u||u.version!==1||u.decision!=="Allow"||u.digest!==l||u.audience!==_o||u.instance!==s||!/^[0-9a-f]{32}$/.test(u.nonce||"")||$e(u.ownerSenderId)!==$e(u.telegramChatId)||!n.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 c=i(h=>ko("sha256",h).update(Io(u)).digest("hex"));return xc(a.mac,c)?(o.add(u.nonce),!0):!1}})}var _o,$e,Io,xc,To=T(()=>{Ao();_o="oracle-local-signer-cex-owner-allow-v1",$e=e=>/^(?:0|[1-9]\d{0,19})$/.test(String(e||""))?String(e):null,Io=e=>JSON.stringify(e),xc=(e,t)=>{let r=Buffer.from(String(e)),n=Buffer.from(String(t));return r.length===n.length&&vc(r,n)}});var $o={};ye($o,{buildPersona:()=>Oe,telegram:()=>_c,telegramPendingRecipients:()=>kc});import{join as Oo}from"node:path";import{homedir as Ac}from"node:os";function bt(e=process.env){return Vn(ze(e)),gt()}function No(e=process.env){wt(ze(e),gt())}function kc({extraOwners:e,env:t=process.env}={}){let r=String(t.ORACLE_OWNER_TELEGRAM||"").split(",").map(o=>o.trim()).filter(Boolean),n=Array.isArray(e)?e.map(o=>String(o).trim()):[];return[...new Set([...r,...n])].filter(o=>/^\d+$/.test(o))}function gr(e,t){if(!t)return;if(typeof t=="string")return e.reply(t,{parse_mode:"Markdown"});let r=t.replyMarkup?{reply_markup:t.replyMarkup}:{};return e.reply(t.text,{parse_mode:"Markdown",...r})}async function _c(e){let{Bot:t}=await import("grammy");bt();let r=new t(e.token),n=String(e.name||"oracle").toLowerCase(),o=Oe(e),i=Array.isArray(e.owners)?e.owners:void 0,s=e.bus;s&&s.register(n,{role:e.role||"",chains:e.chains||[],handler:c=>Ge({from:c.from,text:c.text,persona:o,backend:e.backend,profile:e.hermesProfile})}),r.command("start",c=>{let h=String(c.from?.id||c.chat.id);if(!Ce({platform:"telegram",senderId:h,extraOwners:i}))return c.reply(Te);let p=String(c.match||"").trim();if(p){let f=bt(),w=Kn(f,{token:p,telegramUserId:h});return No(),w.ok?c.reply("Telegram linked to Oracle. Agent artifacts will land as interactive cards. Deepen stays in this thread."):c.reply(`Link failed: ${w.error}`)}return c.reply(`${n} 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.":""}`)}),r.command("update",async c=>{let h=String(c.from?.id||c.chat.id),p=String(c.chat.id);if(!Ce({platform:"telegram",senderId:h,extraOwners:i}))return c.reply(Te);if(c.message.forward_origin||c.message.forward_from||c.message.forward_date)return;c.replyWithChatAction("typing").catch(()=>{});let f=await ee({platform:"telegram",chatId:p,senderId:h,text:c.match?`update ${c.match}`.trim():"update",userName:c.from?.username||c.from?.first_name||"user"});if(f)return gr(c,f)}),r.on("message:text",async c=>{let h=String(c.chat.id),p=String(c.from?.id||h),f=c.message.text;try{c.replyWithChatAction("typing").catch(()=>{});let w=bt(),S=Gn(w,{chatId:h,text:f}),A=await ee({platform:"telegram",chatId:h,senderId:p,text:S||f,userName:c.from?.username||c.from?.first_name||"user",extraOwners:i,bus:s,agentName:n,persona:o,backend:e.backend,profile:e.hermesProfile,meta:{forward_origin:c.message.forward_origin,forward_from:c.message.forward_from,forward_from_chat:c.message.forward_from_chat,forward_sender_name:c.message.forward_sender_name,forward_date:c.message.forward_date}});A&&await gr(c,A)}catch(w){process.stderr.write(`telegram-gateway[${n}]: ${w.message}
36
- `),await c.reply("Something went wrong. Try again.").catch(()=>{})}}),r.on("callback_query:data",async c=>{let h=String(c.from?.id||"");if(!Ce({platform:"telegram",senderId:h,extraOwners:i})){await c.answerCallbackQuery({text:Te.slice(0,180),show_alert:!0}).catch(()=>{});return}let p=String(c.callbackQuery?.data||""),f=String(process.env.ORACLE_OWNER_TELEGRAM||"").split(",").map(O=>O.trim()).filter(Boolean),w=process.env.ORACLE_CONFIG_DIR||Oo(Ac(),".config","oracle"),S;try{S=Co({keyFile:Oo(w,"signer","policy-integrity-key"),approvedTelegramOwners:f})}catch{}let A=await Cn({platform:"telegram",data:p,senderId:h,chatId:String(c.chat?.id||""),ownerProofAuthority:S,grant:{local:!0}});if(!A){let O=bt(),x=Yn(O,{data:p,chatId:String(c.chat?.id||""),grant:{local:!0}});if(No(),!x){await c.answerCallbackQuery().catch(()=>{});return}if(await c.answerCallbackQuery({text:"ok"}).catch(()=>{}),x.prompt){let m=await ee({platform:"telegram",chatId:String(c.chat?.id||""),senderId:h,text:x.prompt,extraOwners:i,bus:s,agentName:n,persona:o,backend:e.backend,profile:e.hermesProfile});m&&await gr(c,m);return}if(x.text){let m=x.buttons?.replyMarkup?{reply_markup:x.buttons.replyMarkup}:{};await c.reply(x.text,{parse_mode:"Markdown",...m}).catch(()=>{})}return}await c.answerCallbackQuery({text:"ok"}).catch(()=>{}),A.text&&await c.reply(A.text,{parse_mode:"Markdown"}).catch(()=>{})}),await r.init(),r.start().catch(c=>{process.stderr.write(`telegram-gateway[${n}]: polling stopped: ${String(c?.message||c).slice(0,160)}
37
- `)});let a=Ee("telegram",{owners:i}).filter(c=>/^\d+$/.test(c)),l=null;return a.length>0&&e.pendingWatch!==!1&&(l=Eo({intervalMs:e.pendingWatchIntervalMs,onNew:async(c,{armed:h})=>{let p=tr(c,{platform:"telegram",grant:{local:!0},armed:h}),f=p.buttons?.replyMarkup?{reply_markup:p.buttons.replyMarkup}:{};for(let w of a)await r.api.sendMessage(w,p.text,{parse_mode:"Markdown",...f}).catch(()=>{})}})),{platform:"telegram",name:n,bot:r,ownerIds:a,notifyRecipient:async(c,h)=>{let p=String(c||"");return a.includes(p)?(await r.api.sendMessage(p,String(h)),1):0},stop:async()=>{l?.stop(),await Promise.resolve(r.stop()).catch(()=>{})},stopPendingWatch:()=>l?.stop()}}var Po=T(()=>{Ne();nr();vo();To();pr();De()});var Ro={};ye(Ro,{discord:()=>Ic});async function Ic(e){let{Client:t,GatewayIntentBits:r}=await import("discord.js"),n=new t({intents:[r.Guilds,r.GuildMessages,r.MessageContent,r.DirectMessages]}),o=String(e.name||"oracle").toLowerCase(),i=Oe(e),s=Array.isArray(e.owners)?e.owners:void 0,a=e.bus;a&&a.register(o,{role:e.role||"",chains:e.chains||[],handler:c=>Ge({from:c.from,text:c.text,persona:i,backend:e.backend,profile:e.hermesProfile})}),n.on("messageCreate",async c=>{if(c.author.bot)return;let h=c.channel.id,p=c.author.id,f=c.content;try{let w=!c.guild,S=c.mentions.has(n.user.id);if(!w&&!S)return;c.channel.sendTyping().catch(()=>{});let A=await ee({platform:"discord",chatId:h,senderId:p,text:f.replace(`<@${n.user.id}>`,"").trim(),userName:c.author.username,extraOwners:s,bus:a,agentName:o,persona:i,backend:e.backend,profile:e.hermesProfile,meta:{forwarded:c.reference?.type===1||Array.isArray(c.messageSnapshots)&&c.messageSnapshots.length>0}});A&&await c.reply(typeof A=="string"?A:A.text).catch(()=>{})}catch(w){process.stderr.write(`discord-gateway[${o}]: ${w.message}
38
- `)}}),await n.login(e.token);let l=Ee("discord",e);return{platform:"discord",name:o,client:n,ownerIds:l,notifyRecipient:async(c,h)=>{let p=String(c||"");return l.includes(p)?(await(await n.users.fetch(p)).send(String(h).slice(0,2e3)),1):0},stop:async()=>{await Promise.resolve(n.destroy())}}}var Lo=T(()=>{Ne();De()});var Fo={};ye(Fo,{whatsapp:()=>Oc});import{join as Uo}from"node:path";import{homedir as Cc}from"node:os";async function Oc(e){let[{Client:t,LocalAuth:r},{generate:n}]=await Promise.all([import("whatsapp-web.js"),import("qrcode-terminal")]),o=new t({authStrategy:new r({dataPath:Uo(Tc,".wwebjs_auth")}),puppeteer:{headless:!0,args:["--no-sandbox"]}});o.on("qr",l=>{process.stderr.write(`
27
+ `)}function Vl(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 wi(e){let t=String(e||"").trim();return/^\/(?:help|commands|\?)$/i.test(t)?{action:"help"}:null}function bi(e){let t=String(e||"").trim();return/^\/(?:status|usage)$/i.test(t)?{action:"status"}:null}function Si(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 xi(e){let n=String(e||"").trim().match(/^\/(?:compact|compress)(?:\s+(.+))?$/i);return n?{action:"compact",focus:String(n[1]||"").trim()}:null}function Ei(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 qn(){return Bn(Dn,"gateway-goal.json")}function ki(){try{let e=JSON.parse(Fl(qn(),"utf8"));return e&&typeof e.goal=="string"?e:null}catch{return null}}function Kl(e){Ml(Dn,{recursive:!0,mode:448});let t={schemaVersion:1,goal:String(e),updatedAt:new Date().toISOString()};return Ul(qn(),`${JSON.stringify(t,null,2)}
28
+ `,{mode:384}),t}function Wl(){try{Bl(qn())}catch{}}function Gl(){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(`
29
+ `)}function Yl(){let e=Un(),t=Tn(),n=ki();return[e,`chain ${t?.key||t?.name||"default"}`,`goal ${n?.goal||"unset"}`].join(`
30
+ `)}function vi(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 qe(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 Ai(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 ot({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(`
31
+ `);return _i({text:i,backend:r,profile:o,unconfiguredPrefix:"unconfigured: "})}async function le({platform:e,chatId:t,senderId:n,text:r,userName:o,meta:i={},updater:s,extraOwners:a,bus:l,agentName:u,persona:d,backend:c,profile:f}={}){if(!Be({platform:e,senderId:n,extraOwners:a}))return process.stderr.write(`gateway: denied non-owner sender ${e}:${String(n||"unknown")}
32
+ `),De;if(fi(i))return process.stderr.write(`gateway: dropped forwarded message on ${e}
33
+ `),null;let m=di(r);if(m)return pi(m,s);let p=yi(r);if(p)try{return p.action==="list"?si():p.action==="show"?Un():p.action==="usage"?si():Hl(p)}catch(b){return`model not saved: ${b.message}`}let y=gi(r);if(y)try{return y.action==="show"?Un():y.action==="usage"?"usage: /effort low|medium|high":zl(y.reasoningEffort)}catch(b){return`effort not saved: ${b.message}`}if(wi(r))return Gl();if(bi(r))return Yl();let S=Si(r);if(S){if(S.action==="show"){let b=ki();return b?.goal?`goal ${b.goal}`:"goal unset \u2014 /goal <objective>"}return S.action==="clear"?(Wl(),"goal cleared"):(Kl(S.goal),`goal pinned: ${S.goal}`)}let v=xi(r);if(v){let b=v.focus?` Focus: ${v.focus}.`:"";return ai({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:c,profile:f})}let N=Ei(r);if(N){if(N.action==="list")return yo({selectedKey:Tn()?.key||null});let b=Ze(N.chain);return b?(wo(b.key),`chain ${b.key}`):`unknown chain '${N.chain}' \u2014 /chain list`}if(kn(r)){let b=await An({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=vi(r);if(b){let k=await l.send({from:u||"oracle",to:b.peer,text:b.text,kind:"consult"});return k.ok?k.reply?`[${b.peer}] ${k.reply}`:`[${b.peer}] (no reply)`:k.error}if(/^\/(agents|roster)\b/i.test(String(r||"").trim())){let k=l.roster().map(C=>`\u2022 ${C.name}${C.role?` \u2014 ${C.role}`:""}${C.chains.length?` (${C.chains.join(", ")})`:""}`);return k.length?`Agents on the bus:
34
+ ${k.join(`
35
+ `)}`:"No peer agents registered."}}let h=r.toLowerCase().trim();return/\b(buy|sell|swap|bridge|send|transfer|balance|portfolio|watch|quote|price)\b/.test(h)?Xl({platform:e,chatId:t,senderId:n,text:r,userName:o}):ai({platform:e,chatId:t,senderId:n,text:r,userName:o,persona:d,backend:c,profile:f})}function Ii(e,{timeout:t=12e4}={}){return new Promise(n=>{let r=ci(process.execPath,[ql,...e],{stdio:["ignore","pipe","pipe"],timeout:t,env:{...process.env,ORACLE_CONFIG_DIR:Dn,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 Jl(e,t,{timeout:n=18e4}={}){return new Promise(r=>{let o=ci(e,t,{stdio:["ignore","pipe","pipe"],timeout:n,env:{...process.env}}),i="",s="";o.on("error",a=>r({code:127,out:"",err:String(a.message)})),o.stdout.on("data",a=>i+=a.toString()),o.stderr.on("data",a=>s+=a.toString()),o.on("close",a=>r({code:a,out:i.trim(),err:s.trim()}))})}async function Xl({text:e,chatId:t}){let n=await Ii(["route","swap","--text",e],{timeout:3e4});if(n.code===0&&n.out)try{return Ql(JSON.parse(n.out),{chatId:t})}catch{return n.out}return`Trade routing failed. Try: \`${e}\` again.`}async function ai({text:e,persona:t,backend:n,profile:r}){let o=t?`[your role: ${t}]
36
+ ${e}`:e;return _i({text:o,backend:n,profile:r,unconfiguredPrefix:"Oracle is not configured yet: "})}async function _i({text:e,backend:t,profile:n,unconfiguredPrefix:r}){let o=Ai(t,e,{profile:n});if(!o.ok)return`${r}${o.error}`;if(!o.bin){let s=mi();if(!s.ok)return`${r}${s.error}`;let a=await Ii(o.args);return a.code===0&&a.out?a.out:a.err||"Oracle could not answer that. Try again."}let i=await Jl(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 Ql(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=ii({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&&Mn(r.state,{chatId:t,artifactId:r.artifact.id}),Mt(nt(),r.state),{text:r.text,replyMarkup:r.replyMarkup}}var Dn,ql,De,hi,jl,je=_(()=>{Jr();In();uo();On();bo();Fn();Dn=process.env.ORACLE_CONFIG_DIR||Bn(Ll(),".config","oracle");ql=li();De="Oracle is self-hostable. Install your own instance: npm install -g @oracle-agent/oracle";hi=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"}}),jl=Object.freeze(["low","medium","high"])});function eu(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 Oi({onNew:e,intervalMs:t=Zl,env:n=process.env,signerCall:r=xe,setIntervalFn:o=setInterval,clearIntervalFn:i=clearInterval}={}){if(typeof e!="function")throw new Error("pending-watch: onNew callback required");let s=new Set,a=!1,l=!1;async function u(){if(!l){l=!0;try{let c=await r("/pending",{env:n});if(!c||c.ok===!1||c.error||!Array.isArray(c.items))return;let f=eu(c.items,s);if(!a){a=!0;return}if(f.length===0)return;try{await e(f,{armed:c.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 Zl,Ni=_(()=>{_t();Zl=4e3});import Ae from"node:fs";function tu(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 Ti(e){let t;try{t=Ae.openSync(e,Ae.constants.O_RDONLY|Ae.constants.O_NOFOLLOW)}catch(n){throw n.code==="ELOOP"?new Error("local-vault: refusing symlink"):n}try{let n=Ae.fstatSync(t);if(tu(n),n.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");let r=Ae.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 Ae.readFileSync(t,"utf8").replace(/[\r\n]+$/,"")}finally{Ae.closeSync(t)}}var $y,Py,Ry,$i=_(()=>{$y=Object.freeze({N:1<<17,r:8,p:1}),Py=256*1024*1024,Ry=16*1024});import{createHash as nu,createHmac as Pi,randomBytes as ru,timingSafeEqual as ou}from"node:crypto";function Mi({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(He).filter(Boolean));if(!r.size)throw new Error("cex owner proof: approved owner context required");let o=new Set,i=a=>{let l=Buffer.from(Ti(e));try{return a(l)}finally{l.fill(0)}},s=i(a=>nu("sha256").update("cex-owner-instance\0").update(a).digest("hex"));return Object.freeze({mint({digest:a,senderId:l,chatId:u,platform:d,ttlMs:c=15e3}={}){let f=He(l),m=He(u),p=n();if(d!=="telegram"||!f||m!==f||!r.has(f))throw new Error("cex owner proof: exact Telegram owner DM required");if(!/^[0-9a-f]{64}$/.test(String(a||""))||!Number.isSafeInteger(c)||c<1||c>3e4)throw new Error("cex owner proof: binding refused");let y={version:1,decision:"Allow",digest:a,ownerSenderId:f,telegramChatId:m,audience:Ri,instance:s,nonce:ru(16).toString("hex"),issuedAtMs:p,expiresAtMs:p+c},S=i(v=>Pi("sha256",v).update(Li(y)).digest("hex"));return{claims:y,mac:S}},verify(a,{digest:l}={}){let u=a?.claims,d=n();if(!u||u.version!==1||u.decision!=="Allow"||u.digest!==l||u.audience!==Ri||u.instance!==s||!/^[0-9a-f]{32}$/.test(u.nonce||"")||He(u.ownerSenderId)!==He(u.telegramChatId)||!r.has(He(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 c=i(f=>Pi("sha256",f).update(Li(u)).digest("hex"));return iu(a.mac,c)?(o.add(u.nonce),!0):!1}})}var Ri,He,Li,iu,Fi=_(()=>{$i();Ri="oracle-local-signer-cex-owner-allow-v1",He=e=>/^(?:0|[1-9]\d{0,19})$/.test(String(e||""))?String(e):null,Li=e=>JSON.stringify(e),iu=(e,t)=>{let n=Buffer.from(String(e)),r=Buffer.from(String(t));return n.length===r.length&&ou(n,r)}});var Di={};_e(Di,{buildPersona:()=>qe,telegram:()=>cu,telegramPendingRecipients:()=>au});import{join as Ui}from"node:path";import{homedir as su}from"node:os";function Ft(e=process.env){return Qo(nt(e)),Lt()}function Bi(e=process.env){Mt(nt(e),Lt())}function au({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 jn(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 cu(e){let{Bot:t}=await import("grammy");Ft();let n=new t(e.token),r=String(e.name||"oracle").toLowerCase(),o=qe(e),i=Array.isArray(e.owners)?e.owners:void 0,s=e.bus;s&&s.register(r,{role:e.role||"",chains:e.chains||[],handler:c=>ot({from:c.from,text:c.text,persona:o,backend:e.backend,profile:e.hermesProfile})}),n.command("start",c=>{let f=String(c.from?.id||c.chat.id);if(!Be({platform:"telegram",senderId:f,extraOwners:i}))return c.reply(De);let m=String(c.match||"").trim();if(m){let p=Ft(),y=ri(p,{token:m,telegramUserId:f});return Bi(),y.ok?c.reply("Telegram linked to Oracle. Agent artifacts will land as interactive cards. Deepen stays in this thread."):c.reply(`Link failed: ${y.error}`)}return c.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 c=>{let f=String(c.from?.id||c.chat.id),m=String(c.chat.id);if(!Be({platform:"telegram",senderId:f,extraOwners:i}))return c.reply(De);if(c.message.forward_origin||c.message.forward_from||c.message.forward_date)return;c.replyWithChatAction("typing").catch(()=>{});let p=await le({platform:"telegram",chatId:m,senderId:f,text:c.match?`update ${c.match}`.trim():"update",userName:c.from?.username||c.from?.first_name||"user"});if(p)return jn(c,p)}),n.on("message:text",async c=>{let f=String(c.chat.id),m=String(c.from?.id||f),p=c.message.text;try{c.replyWithChatAction("typing").catch(()=>{});let y=Ft(),S=ni(y,{chatId:f,text:p}),v=await le({platform:"telegram",chatId:f,senderId:m,text:S||p,userName:c.from?.username||c.from?.first_name||"user",extraOwners:i,bus:s,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile,meta:{forward_origin:c.message.forward_origin,forward_from:c.message.forward_from,forward_from_chat:c.message.forward_from_chat,forward_sender_name:c.message.forward_sender_name,forward_date:c.message.forward_date}});v&&await jn(c,v)}catch(y){process.stderr.write(`telegram-gateway[${r}]: ${y.message}
37
+ `),await c.reply("Something went wrong. Try again.").catch(()=>{})}}),n.on("callback_query:data",async c=>{let f=String(c.from?.id||"");if(!Be({platform:"telegram",senderId:f,extraOwners:i})){await c.answerCallbackQuery({text:De.slice(0,180),show_alert:!0}).catch(()=>{});return}let m=String(c.callbackQuery?.data||""),p=String(process.env.ORACLE_OWNER_TELEGRAM||"").split(",").map(N=>N.trim()).filter(Boolean),y=process.env.ORACLE_CONFIG_DIR||Ui(su(),".config","oracle"),S;try{S=Mi({keyFile:Ui(y,"signer","policy-integrity-key"),approvedTelegramOwners:p})}catch{}let v=await oo({platform:"telegram",data:m,senderId:f,chatId:String(c.chat?.id||""),ownerProofAuthority:S,grant:{local:!0}});if(!v){let N=Ft(),E=oi(N,{data:m,chatId:String(c.chat?.id||""),grant:{local:!0}});if(Bi(),!E){await c.answerCallbackQuery().catch(()=>{});return}if(await c.answerCallbackQuery({text:"ok"}).catch(()=>{}),E.prompt){let h=await le({platform:"telegram",chatId:String(c.chat?.id||""),senderId:f,text:E.prompt,extraOwners:i,bus:s,agentName:r,persona:o,backend:e.backend,profile:e.hermesProfile});h&&await jn(c,h);return}if(E.text){let h=E.buttons?.replyMarkup?{reply_markup:E.buttons.replyMarkup}:{};await c.reply(E.text,{parse_mode:"Markdown",...h}).catch(()=>{})}return}await c.answerCallbackQuery({text:"ok"}).catch(()=>{}),v.text&&await c.reply(v.text,{parse_mode:"Markdown"}).catch(()=>{})}),await n.init(),n.start().catch(c=>{process.stderr.write(`telegram-gateway[${r}]: polling stopped: ${String(c?.message||c).slice(0,160)}
38
+ `)});let a=$e("telegram",{owners:i}).filter(c=>/^\d+$/.test(c)),l=null;return a.length>0&&e.pendingWatch!==!1&&(l=Oi({intervalMs:e.pendingWatchIntervalMs,onNew:async(c,{armed:f})=>{let m=vn(c,{platform:"telegram",grant:{local:!0},armed:f}),p=m.buttons?.replyMarkup?{reply_markup:m.buttons.replyMarkup}:{};for(let y of a)await n.api.sendMessage(y,m.text,{parse_mode:"Markdown",...p}).catch(()=>{})}})),{platform:"telegram",name:r,bot:n,ownerIds:a,notifyRecipient:async(c,f)=>{let m=String(c||"");return a.includes(m)?(await n.api.sendMessage(m,String(f)),1):0},stop:async()=>{l?.stop(),await Promise.resolve(n.stop()).catch(()=>{})},stopPendingWatch:()=>l?.stop()}}var qi=_(()=>{je();In();Ni();Fi();Fn();Je()});var ji={};_e(ji,{discord:()=>lu});async function lu(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=qe(e),s=Array.isArray(e.owners)?e.owners:void 0,a=e.bus;a&&a.register(o,{role:e.role||"",chains:e.chains||[],handler:c=>ot({from:c.from,text:c.text,persona:i,backend:e.backend,profile:e.hermesProfile})}),r.on("messageCreate",async c=>{if(c.author.bot)return;let f=c.channel.id,m=c.author.id,p=c.content;try{let y=!c.guild,S=c.mentions.has(r.user.id);if(!y&&!S)return;c.channel.sendTyping().catch(()=>{});let v=await le({platform:"discord",chatId:f,senderId:m,text:p.replace(`<@${r.user.id}>`,"").trim(),userName:c.author.username,extraOwners:s,bus:a,agentName:o,persona:i,backend:e.backend,profile:e.hermesProfile,meta:{forwarded:c.reference?.type===1||Array.isArray(c.messageSnapshots)&&c.messageSnapshots.length>0}});v&&await c.reply(typeof v=="string"?v:v.text).catch(()=>{})}catch(y){process.stderr.write(`discord-gateway[${o}]: ${y.message}
39
+ `)}}),await r.login(e.token);let l=$e("discord",e);return{platform:"discord",name:o,client:r,ownerIds:l,notifyRecipient:async(c,f)=>{let m=String(c||"");return l.includes(m)?(await(await r.users.fetch(m)).send(String(f).slice(0,2e3)),1):0},stop:async()=>{await Promise.resolve(r.destroy())}}}var Hi=_(()=>{je();Je()});var Vi={};_e(Vi,{whatsapp:()=>pu});import{join as zi}from"node:path";import{homedir as uu}from"node:os";async function pu(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:zi(du,".wwebjs_auth")}),puppeteer:{headless:!0,args:["--no-sandbox"]}});o.on("qr",l=>{process.stderr.write(`
39
40
  WhatsApp: scan this QR code in WhatsApp \u2192 Linked Devices:
40
41
 
41
- `),n(l,{small:!0}),process.stderr.write(`
42
+ `),r(l,{small:!0}),process.stderr.write(`
42
43
  `)}),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,c=l.body;try{let h=await ee({platform:"whatsapp",chatId:u,senderId:d,text:c,userName:l._data?.notifyName||"user",meta:{forwarded:l.isForwarded||l._data?.isForwarded,forward_date:l._data?.forwardingScore?!0:void 0}});if(h){let f=(typeof h=="string"?h:h.text).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");await l.reply(f)}}catch(h){process.stderr.write(`whatsapp-gateway: ${h.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 c=String(u).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");return await o.sendMessage(d,c),1},stop:async()=>{await Promise.resolve(o.destroy()).catch(()=>{})}}}var Tc,Mo=T(()=>{Ne();De();Tc=process.env.ORACLE_CONFIG_DIR||Uo(Cc(),".config","oracle")});var Bo={};ye(Bo,{signal_:()=>Nc});async function Nc(e){return process.stderr.write(`signal-gateway: requires signal-cli binary
44
+ `)}),o.on("message",async l=>{if(l.fromMe)return;let u=l.from,d=l.author||l.from,c=l.body;try{let f=await le({platform:"whatsapp",chatId:u,senderId:d,text:c,userName:l._data?.notifyName||"user",meta:{forwarded:l.isForwarded||l._data?.isForwarded,forward_date:l._data?.forwardingScore?!0:void 0}});if(f){let p=(typeof f=="string"?f:f.text).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");await l.reply(p)}}catch(f){process.stderr.write(`whatsapp-gateway: ${f.message}
45
+ `)}}),await o.initialize();let i=$e("whatsapp",e);return{platform:"whatsapp",client:o,ownerIds:i,notifyRecipient:async(l,u)=>{let d=String(l||"");if(!i.includes(d))return 0;let c=String(u).replace(/\*\*/g,"*").replace(/```[\s\S]*?```/g,"[code]").replace(/`/g,"");return await o.sendMessage(d,c),1},stop:async()=>{await Promise.resolve(o.destroy()).catch(()=>{})}}}var du,Ki=_(()=>{je();Je();du=process.env.ORACLE_CONFIG_DIR||zi(uu(),".config","oracle")});var Wi={};_e(Wi,{signal_:()=>fu});async function fu(e){return process.stderr.write(`signal-gateway: requires signal-cli binary
45
46
  `),process.stderr.write(`signal-gateway: not built yet \u2014 use Telegram or Discord for now
46
- `),{platform:"signal",status:"stub"}}var Do=T(()=>{Ne()});import{createServer as $c}from"node:http";import{env as Pe}from"node:process";import{join as Ke}from"node:path";import{homedir as Pc}from"node:os";import{readFileSync as Sr,existsSync as Rc,mkdirSync as Lc,writeFileSync as Uc}from"node:fs";import{createHash as Fc,randomBytes as Mc}from"node:crypto";import dt from"node:path";import{homedir as cn}from"node:os";import{readFileSync as xs}from"node:fs";import{createHash as As}from"node:crypto";import P from"node:fs";import Xe from"node:path";import{createHash as Ko,randomUUID as Ar}from"node:crypto";var xt=1,W=class extends Error{constructor(t,r="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=r}};function et(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(et).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${et(e[r])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function kr(e){return Ko("sha256").update(et(e)).digest("hex")}function Qe(e){let t=e(),r=t instanceof Date?t.getTime():typeof t=="string"?Date.parse(t):Number(t);if(!Number.isFinite(r))throw new TypeError("clock must return epoch milliseconds, an ISO string, or a Date");return Math.trunc(r)}function Ze(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function _r(e){P.mkdirSync(e,{recursive:!0,mode:448});try{P.chmodSync(e,448)}catch{}}function At(e){try{let t=P.statSync(e);return{...JSON.parse(P.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function Ir({filePath:e,kind:t,initialData:r,validateData:n,clock:o=()=>Date.now(),maxBytes:i=4*1024*1024,lockStaleMs:s=3e4,lockWaitMs:a=2e3,lockIdFactory:l=()=>Ar()}={}){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 r!="function"||typeof n!="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(a)||a<0||a>3e4)throw new TypeError("lockWaitMs must be between 0 and 30000");let u=`${e}.lock`;function d(){let x=r();return n(x),{schemaVersion:xt,kind:t,generation:0,data:x}}function c(x){let m;try{m=JSON.parse(x)}catch(v){throw new W(`corrupt ${t} snapshot: invalid JSON (${v.message})`,"STORE_CORRUPT")}if(!m||typeof m!="object"||Array.isArray(m))throw new W(`corrupt ${t} snapshot: root must be an object`,"STORE_CORRUPT");if(m.schemaVersion!==xt)throw new W(`unsupported ${t} schemaVersion ${String(m.schemaVersion)}`,"STORE_SCHEMA");if(m.kind!==t||!Number.isSafeInteger(m.generation)||m.generation<0)throw new W(`corrupt ${t} snapshot metadata`,"STORE_CORRUPT");let{integrity:E,...b}=m;if(typeof E!="string"||!/^[a-f0-9]{64}$/.test(E)||kr(b)!==E)throw new W(`corrupt ${t} snapshot: checksum mismatch`,"STORE_CORRUPT");try{n(m.data)}catch(v){throw new W(`corrupt ${t} snapshot: ${v.message}`,"STORE_CORRUPT")}return b}function h(){if(!P.existsSync(e))return d();let x=P.statSync(e);if(!x.isFile()||x.size>i)throw new W(`${t} snapshot is not a bounded regular file`,"STORE_BOUNDS");try{P.chmodSync(e,384)}catch{}return c(P.readFileSync(e,"utf8"))}function p(){_r(Xe.dirname(e));let x=Qe(o),m=String(l()),E=`${JSON.stringify({schemaVersion:1,lockId:m,pid:process.pid,acquiredAt:x})}
47
- `,b=()=>{let R;try{return R=P.openSync(u,"wx",384),P.writeFileSync(R,E,"utf8"),P.fsyncSync(R),P.closeSync(R),{lockId:m}}catch(y){let _=R!==void 0;if(_)try{P.closeSync(R)}catch{}if(_)try{P.unlinkSync(u)}catch{}if(y?.code!=="EEXIST")throw y;return null}},I=Qe(o)+a,N=new Int32Array(new SharedArrayBuffer(4));for(;;){let R=b();if(R)return R;let y=Qe(o),_=At(u),M=!1;if(_){let D=y-Number(_.acquiredAt??_.mtimeMs);M=Number.isFinite(D)&&D>=s}else try{M=y-P.statSync(u).mtimeMs>=s}catch{M=!1}if(M){let D=At(u);if(_?D?.lockId===_.lockId:D===null){try{P.unlinkSync(u)}catch(z){if(z?.code!=="ENOENT")throw z}continue}}let L=I-y;if(L<=0)throw new W(`${t} store is busy`,"STORE_BUSY");Atomics.wait(N,0,0,Math.min(10,L))}}function f(x){if(At(u)?.lockId===x.lockId)try{P.unlinkSync(u)}catch(E){if(E?.code!=="ENOENT")throw E}}function w(x){n(x.data);let m={...x,integrity:kr(x)},E=`${et(m)}
48
- `;if(Buffer.byteLength(E)>i)throw new W(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let b=Xe.dirname(e);_r(b);let v=Xe.join(b,`.${Xe.basename(e)}.${process.pid}.${Ar()}.tmp`),I;try{I=P.openSync(v,"wx",384),P.writeFileSync(I,E,"utf8"),P.fsyncSync(I),P.closeSync(I),I=void 0,P.renameSync(v,e);try{P.chmodSync(e,384)}catch{}try{let N=P.openSync(b,"r");try{P.fsyncSync(N)}finally{P.closeSync(N)}}catch{}}finally{if(I!==void 0)try{P.closeSync(I)}catch{}try{P.unlinkSync(v)}catch(N){if(N?.code!=="ENOENT")throw N}}}function S(){return Ze(h().data)}function A(){let x=h();return{schemaVersion:x.schemaVersion,kind:x.kind,generation:x.generation,data:Ze(x.data)}}function O(x){if(typeof x!="function")throw new TypeError("mutator must be a function");let m=p();try{let E=h(),b=Ze(E.data),v=x(b,{generation:E.generation,now:Qe(o)});return n(b),w({schemaVersion:xt,kind:t,generation:E.generation+1,data:b}),Ze(v)}finally{f(m)}}return Object.freeze({filePath:e,read:S,inspect:A,mutate:O})}H();H();import{getAddress as Ni}from"ethers";import{types as Br}from"node:util";function Pt(e){if(!e||typeof e!="object"||Br.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function re(e,t="provider response",r=0){if(r>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(Br.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]=re(s.value,t,r+1)}return o}if(!Pt(e))throw new Error(`${t} contains a non-JSON value`);let n=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`);n[o]=re(i.value,t,r+1)}return n}var Ci=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,Ti=/[<>&`*_~[\]()|\\]/g,Oi=/[\u0000-\u001F\u007F]/g;function st(e,{max:t=32,fallback:r=""}={}){return e==null?r:String(e).normalize("NFKC").replace(Ci,"").replace(Oi,"").replace(Ti,"").replace(/\s+/g," ").trim().slice(0,t).trim()||r}var Dr=Object.freeze({1:"https://eth.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com"}),qr=e=>!!Dr[e];function $i(e){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("invalid NFT cursor");let t=new URLSearchParams;for(let[r,n]of Object.entries(e)){if(!(r==="token_contract_address_hash"?/^0x[\da-f]{40}$/i.test(String(n)):r==="token_type"?["ERC-721","ERC-1155","ERC-404"].includes(n):["token_id","items_count"].includes(r)&&/^\d{1,100}$/.test(String(n))))throw new Error("invalid NFT cursor");t.set(r,String(n))}if(!t.size)throw new Error("empty NFT cursor");return t.toString()}async function jr(e={},t={}){let r=Ni(e.address),n=Dr[e.chainId];if(!n)throw new Error("Blockscout NFT chain not verified");let o=Math.min(3,Math.max(1,Math.trunc(Number(e.maxPages)||3))),i=[],s=[],a=new Set,l=null,u="",d=0,c=!1;for(;d<o;)try{let h=re(await j(`${n}/api/v2/addresses/${r}/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(h?.items))throw new Error("invalid NFT inventory response");d++;for(let f of h.items.slice(0,50)){let w=f.token;if(!/^0x[\da-f]{40}$/i.test(w?.address_hash||"")||!/^\d+$/.test(String(f.id??"")))throw new Error("invalid NFT identity");if(!["ERC-721","ERC-1155","ERC-404"].includes(w.type))throw new Error("invalid NFT standard");if(f.owner?.hash&&f.owner.hash.toLowerCase()!==r.toLowerCase())throw new Error("NFT owner mismatch");i.push({chain:e.chain,chainId:e.chainId,family:"evm",owner:r,contract:w.address_hash,tokenId:String(f.id),tokenStandard:w.type,collection:st(w.name,{max:160,fallback:w.address_hash}),name:st(f.metadata?.name||w.name,{max:160,fallback:`NFT ${f.id}`}),imageUrl:f.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(h.items.length>50)throw new Error("NFT provider page exceeds 50 item bound");let p=h.next_page_params??null;if(!p){l=null,c=!0;break}if(l=null,u=$i(p),l=Object.fromEntries(new URLSearchParams(u)),a.has(u))throw new Error("repeated NFT cursor");a.add(u)}catch(h){if(s.push(`blockscout: ${h.message}`.slice(0,300)),!d)throw h;break}return{nfts:i,complete:c,next:l,pages:d,truncated:!c,errors:s}}import{getAddress as Vi}from"ethers";Me();H();var Rl=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"});H();var Ul=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),Ut=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Ft=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});Me();Me();var Fi=Object.freeze([{key:"ethereum",chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://etherscan.io",dexscreenerSlug:"ethereum",venueKind:"uniswap-v3",wrappedNative:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",stableQuoteAssets:["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48","0xdAC17F958D2ee523a2206206994597C13D831ec7"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.71 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:1}}]},{key:"optimism",chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://optimistic.etherscan.io",dexscreenerSlug:"optimism",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85","0x94b008aA00579c1307B0EF2c499aD98a8ce58e58"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1905.23 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:10}}]},{key:"bsc",chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],nativeCurrency:{symbol:"BNB",decimals:18},explorer:"https://bscscan.com",dexscreenerSlug:"bsc",venueKind:"uniswap-v3",wrappedNative:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",stableQuoteAssets:["0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d","0x55d398326f99059fF775485246999027B3197955"],venues:[{kind:"quoter",address:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WBNB->USDC fee 500 quoted 413.86 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}},{kind:"router",address:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:56}}]},{key:"polygon",chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],nativeCurrency:{symbol:"POL",decimals:18},explorer:"https://polygonscan.com",dexscreenerSlug:"polygon",venueKind:"uniswap-v3",wrappedNative:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",stableQuoteAssets:["0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359","0xc2132D05D31c914a87C6611C10748AEb04B58e8F"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WMATIC->USDC fee 500 quoted 0.0720 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:137}}]},{key:"stable",chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],nativeCurrency:{symbol:"USDT0",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x5d442b349590a6048Eb2dC0eC346cAA5F47A9ab5",venues:[{kind:"quoter",address:"0xb070179E7032CdA868b53e6C1742F80c9e940d1A",label:"Uniswap V3 QuoterV2 (canonical)",verified:{method:"Stable is on the OFFICIAL Uniswap v3 Deployments List (governance-recognised 2026-05-12, UAC process completed 2026-04, deployed by Protofire), so this is a canonical deployment rather than a fork. eth_getCode returned 8273 bytes, the same size as the canonical quoter on the seven already-verified chains. Functional probe on a live pool (TOAST -> USDT0, fee 10000): 100 in -> 0.000003, 1000 -> 0.000031, 10000 -> 0.000319 USDT0. Output scales monotonically with input, which is a working quoter answering, not a revert. Two of three sampled pools carry non-zero liquidity. NOTE: the pools discovered so far are thin, so real routing size is limited -- the venue is proved, deep liquidity is not.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:988}},{kind:"router",address:"0x32eaf9B5d5F2CD7361c5012890C943D7de84C22a",label:"Uniswap SwapRouter02 (canonical)",verified:{method:"eth_getCode returned 24497 bytes. Cross-checked on-chain rather than trusted from docs: router.factory() returns 0x88f0a512ef09175d456bc9547f914f48c013e4aa, the same v3 core factory that created the pools quoted above, and router.WETH9() returns the wrappedNative recorded on this chain entry. Address published in the Stable docs DEX reference and the Uniswap deployments list.",source:"docs.stable.xyz/en/reference/dexes + on-chain factory()/WETH9() round-trip",date:"2026-08-05",chainId:988}}]},{key:"hyperevm",chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],nativeCurrency:{symbol:"HYPE",decimals:18},dexscreenerSlug:"hyperevm",venueKind:"uniswap-v3",wrappedNative:"0x5555555555555555555555555555555555555555",venues:[{kind:"quoter",address:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",label:"HyperSwap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle(1 WHYPE -> USDT0) returned live output on all four fee tiers (100: 57.3385, 500: 57.4187, 3000: 57.3237, 10000: 56.1963 USDT0). Decimals read on-chain: WHYPE 18, USDT0 6. Best tier checked against an INDEPENDENT control the same minute -- Hyperliquid allMids put HYPE at 57.3205, so the pool is 0.171% from the perp mid, which is the right shape for fee plus impact rather than a wrong contract or a decimals bug.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}},{kind:"router",address:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D",label:"HyperSwap V3 SwapRouter",verified:{method:"eth_getCode returned 12070 bytes, and it is the router paired with the quoter proved above -- the same pair already shipped in UNI_V3_VENUES[999].hyperswap, which is the map the quote/prepare path actually routes through.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:999}}]},{key:"abstract",chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},venueKind:"uniswap-v3",wrappedNative:"0x3439153EB7AF838Ad19d56E1571FBD09333C2809",venues:[{kind:"quoter",address:"0x728BD3eC25D5EDBafebB84F3d67367Cd9EBC7693",label:"Uniswap V3 QuoterV2 (Abstract deployment)",verified:{method:"Abstract is a ZK-stack chain, so CREATE2 addresses differ and the canonical Uniswap addresses are NOT valid here -- probing them returns codesize 0, which is what previously made this chain look like it had no V3 at all. Found the real deployment from live traffic instead: scanned recent Swap(...) logs, took the busiest pool, read pool.factory() = 0xa1160e73b63f322ae88cc2d8e700833e71d0b2a1, then enumerated that factory's deployer (0xf3d63166F0Ca56C3c1A3508FcE03Ff0Cf3Fb691e) and probed each of its 56 contracts with a real quoteExactInputSingle call. Exactly one answered: 1 WETH -> 1846.475731 USDC.e at fee 500. Independent sanity check: the pool's own slot0() spot price is 1873.11 USDC.e per WETH, so the quoter sits ~1.4% below spot, the right shape for fee plus price impact on this size.",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-08-05",chainId:2741}},{kind:"router",address:"0x7712FA47387542819d4E35A23f8116C90C18767C",label:"Uniswap SwapRouter02 (Abstract deployment)",verified:{method:"eth_getCode returned 167392 bytes and the runtime contains the exactInputSingle selector. router.factory() matches the factory proved above and router.WETH9() matches the wrappedNative on this entry. Chosen over its byte-identical twin (0xfD6257F4...) because this is the address real users actually route through: it appeared as tx.to on live swaps against the WETH/USDC.e pool.",source:"on-chain factory()/WETH9() round-trip + live swap tx.to sampling",date:"2026-08-05",chainId:2741}}]},{key:"robinhood",chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC","ROBINHOOD_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},dexscreenerSlug:"robinhood",venueKind:"uniswap-v3",wrappedNative:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",stableQuoteAssets:["0x5fc5360d0400a0fd4f2af552add042d716f1d168"],venues:[{kind:"quoter",address:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDG fee 100 quoted 1866.58 USDG, and USDG->CASHCAT fee 10000 quoted a live amount). A contract that correctly prices known pairs IS a working V3 quoter",source:"live eth_call against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"router",address:"0xcaf681a66d020601342297493863e78c959e5cb2",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode (24497 bytes) on this chain and the paired quoter at the same deployment passed a live functional quote",source:"live eth_getCode against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}},{kind:"factory",address:"0x1f7d7550b1b028f7571e69a784071f0205fd2efa",label:"Uniswap V3 Factory",verified:{method:"eth_getCode returned real bytecode (24535 bytes) and a PoolCreated log scan over this factory returned 76 pools in ~9000 recent blocks",source:"live eth_getLogs against rpc.mainnet.chain.robinhood.com",date:"2026-07-31",chainId:4663}}]},{key:"base",chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://basescan.org",dexscreenerSlug:"base",venueKind:"uniswap-v3",wrappedNative:"0x4200000000000000000000000000000000000006",stableQuoteAssets:["0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"],venues:[{kind:"quoter",address:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",label:"Uniswap V3 QuoterV2 (Base)",verified:{method:"functional probe: quoteExactInputSingle returned WETH->USDC at fee 500 = 1908.44 USDC, a live sane price. The canonical mainnet quoter address also has bytecode on Base but does NOT price this pair, which is exactly the false positive a codesize-only check accepts",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router",address:"0x2626664c2603336E57B271c5C0b26F421741e481",label:"Uniswap V3 SwapRouter02 (Base)",verified:{method:"eth_getCode returned real bytecode and the paired Base quoter passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:8453}},{kind:"router-v2",address:"0x4752ba5DBc23f44D87826276BF6Fd6b1C372aD24",label:"Uniswap V2 Router02 (Base)",verified:{method:"eth_getCode returned 17891 bytes; live getAmountsOut on WETH->USDC round-tripped to 98.75% (2x0.30% fee + impact)",source:"https://docs.uniswap.org/contracts/v2/reference/smart-contracts/v2-deployments",date:"2026-07-30",chainId:8453}}]},{key:"arbitrum",chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],nativeCurrency:{symbol:"ETH",decimals:18},explorer:"https://arbiscan.io",dexscreenerSlug:"arbitrum",venueKind:"uniswap-v3",wrappedNative:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",stableQuoteAssets:["0xaf88d065e77c8cC2239327C5EDb3A432268e5831","0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"],venues:[{kind:"quoter",address:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WETH->USDC fee 500 quoted 1908.72 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}},{kind:"router",address:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:42161}}]},{key:"avalanche",chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],nativeCurrency:{symbol:"AVAX",decimals:18},explorer:"https://snowtrace.io",dexscreenerSlug:"avalanche",venueKind:"uniswap-v3",wrappedNative:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",stableQuoteAssets:["0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"],venues:[{kind:"quoter",address:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",label:"Uniswap V3 QuoterV2",verified:{method:"functional probe, not a codesize check: quoteExactInputSingle returned a live sane price (WAVAX->USDC fee 500 quoted 6.48 USDC). A contract that correctly prices a known pair IS a working V3 quoter",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}},{kind:"router",address:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",label:"Uniswap V3 SwapRouter02",verified:{method:"eth_getCode returned real bytecode on this chain and the paired quoter at the same deployment passed a live functional quote",source:"scripts/verify-v3-venues.mjs (re-runnable)",date:"2026-07-30",chainId:43114}}]}]);H();Me();H();function Mt(e,t="address"){let r=String(e||"").trim();if(!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(r))throw new Error(`solana-rpc: ${t} must be a base58 public key`);return r}H();function ge(e,t="address"){let r=String(e||"").trim();if(!/^(bc1|tb1|bcrt1)[a-z0-9]{20,90}$/i.test(r)&&!/^[13mn2][a-km-zA-HJ-NP-Z1-9]{25,34}$/.test(r))throw new Error(`bitcoin-esplora: ${t} must look like a Bitcoin address`);return r}var zr="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function we({provider:e,defaultUrl:t,hosts:r=[],url:n,strict:o=!1}){let s=(String(n??"").trim()||String(t)).replace(/\/$/,"");if(s===String(t).replace(/\/$/,""))return{baseUrl:s,trusted:!0,host:Wr(t)};let a;try{a=new URL(s)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(a.protocol!=="http:"&&a.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let l=a.host;if(!l)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Wr(t),...r]).has(l)){let d=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(l);return a.protocol==="http:"&&!d?{baseUrl:s,trusted:!1,host:l,reason:"plaintext http downgrade"}:{baseUrl:s,trusted:!0,host:l}}if(String(process.env[zr]||"")==="1")return{baseUrl:s,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${zr}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:l}}function Wr(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function ce(e,t,r){let n={...e};if(!r)return n;for(let[o,i]of Object.entries(t||{}))i&&(n[o]=i);return n}function Gr(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var Bi=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function Di(e={}){let t=e.apiKey||process.env.UNISAT_API_KEY||process.env.BESTINSLOT_API_KEY||process.env.BTC_META_API_KEY||"",r=!1;try{let n=Gr(e);if(n){let o=new URL(n).host,i=new URL(n).protocol,s=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(o);r=Bi.includes(o)&&(i==="https:"||s)}}catch{r=!1}return ce({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},r)}async function qi(e,t={}){let n=await(t.fetchImpl||fetch)(e,{method:"GET",headers:Di(t),signal:AbortSignal.timeout(t.timeoutMs??12e3)}),o=await n.text(),i;try{i=JSON.parse(o)}catch{i=o}if(!n.ok)throw new Error(`bitcoin-meta GET ${e}: HTTP ${n.status} ${String(o).slice(0,160)}`);return i}async function Bt(e={},t={}){let r=ge(e.address||e.addr,"address"),n=Gr(t);if(!n)return{provider:"bitcoin-meta",address:r,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=[`${n}/v1/indexer/address/${r}/inscription-data?cursor=0&size=${o}`,`${n}/v1/inscriptions/address/${r}?limit=${o}`,`${n}/address/${r}/inscriptions?limit=${o}`],s=null;for(let a of i)try{let l=await qi(a,t),u=ji(l);return{provider:"bitcoin-meta",address:r,ok:!0,count:u.length,inscriptions:u,source:a}}catch(l){s=l}return{provider:"bitcoin-meta",address:r,ok:!1,inscriptions:[],error:String(s?.message||s||"all indexer paths failed")}}function ji(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(n=>({id:n.inscriptionId||n.id||n.inscription_id||null,number:n.inscriptionNumber??n.number??null,sat:n.sat||n.satoshi||null,contentType:n.contentType||n.content_type||null,utxo:n.utxo||n.output||(n.txid!=null?`${n.txid}:${n.vout??n.n}`:null),raw:n}))}H();H();H();var Nu=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 Fu=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"}),Hi=Object.freeze(["block_number","index"]),Mu=new Set([...Hi,"items_count","value","hash","inserted_at","fee"]);var fd=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 at(e,...t){for(let r of t){let n=String(e?.[r]||"").trim();if(n)return n}return null}function Kr(e){if(!e)return null;try{return Vi(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function Yr(e={},t=process.env){let r=e.addresses||{},n=Kr(r.evm||e.evmAddress||at(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=r.solana||e.solanaAddress||at(t,"ORACLE_SOLANA_ADDRESS"),i=r.bitcoin||e.bitcoinAddress||at(t,"ORACLE_BITCOIN_ADDRESS"),s=Kr(r.hyperliquid||e.hyperliquidAddress||at(t,"ORACLE_HYPERLIQUID_ADDRESS")||n);return{evm:n,solana:o?Mt(o,"portfolio Solana address"):null,bitcoin:i?ge(i,"portfolio Bitcoin address"):null,hyperliquid:s}}H();import{readFileSync as Wi,existsSync as Gi}from"node:fs";import{getAddress as Ki,Interface as ct,TypedDataEncoder as Ed,parseUnits as vd}from"ethers";be();var Yi="https://api.opensea.io/api/v2",Ji="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)",Id=new ct([`function ${Ji}`]),Cd=new ct(["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"]),Xi=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"]),Qi=new Set(Xi),Zi=new Set(["solana","flow"]);function es(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!Gi(e))return"";try{for(let t of Wi(e,"utf8").split(`
49
- `)){let r=t.match(/^\s*OPENSEA_API_KEY\s*=\s*(.+)\s*$/);if(r)return r[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||es()}function Xr(e={}){return we({provider:"opensea",defaultUrl:Yi,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function lt(e={}){return Xr(e).baseUrl}function ut(e={}){return ce({accept:"application/json"},{"x-api-key":Be(e)},Xr(e).trusted)}function ts(e){let t=String(e||"ethereum").trim().toLowerCase();if(!Qi.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function Jr(e,t="address"){try{return Ki(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function Qr(e,t=null){let r=String(e||"").trim();if(!r)throw new Error("opensea: account address required");if(t&&!Zi.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(r))return Jr(r,"account address");if(!/^[1-9A-HJ-NP-Za-km-z]{32,64}$/.test(r))throw new Error("opensea: invalid account address");return r}function rs(e={},t,r){return{chain:t,owner:r,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 ns(e,t={}){if(!e)throw new Error("collection slug required");if(!Be(t))throw new Error("OPENSEA_API_KEY required");return j(`${lt(t)}/collections/${encodeURIComponent(e)}`,{headers:ut(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function os(e,t={}){if(!e)throw new Error("collection slug required");if(!Be(t))throw new Error("OPENSEA_API_KEY required");return j(`${lt(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:ut(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Zr(e,t={}){let r=await ns(e,t),n=r.stats||r.total||{},o=r.floor_price??r.floorPrice??n.floor_price??n.floorPrice??null;if(o==null){let c=await os(e,t);n=c?.total||c?.stats||c||{},o=n.floor_price??n.floorPrice??null}let i=(Array.isArray(r.contracts)?r.contracts:[]).map(c=>({chain:String(c?.chain||c?.chain_identifier||r.chain||"").trim().toLowerCase(),address:String(c?.address||c?.contract_address||c?.contract||"").trim()})).filter(c=>c.chain&&c.address),s=String(t.expectedChain||"").trim().toLowerCase(),a=String(t.expectedContract||"").trim(),l=null;if(s&&a){let c=h=>s==="solana"?h:h.toLowerCase();if(l=i.find(h=>h.chain===s&&c(h.address)===c(a))||null,!l)throw new Error("opensea: collection identity does not match held contract")}let u=l?.chain||String(r.chain||"").trim().toLowerCase()||i[0]?.chain||"",d=String(r.floor_price_symbol||r.floorPriceSymbol||n.floor_price_symbol||n.floorPriceSymbol||"").trim().toUpperCase()||null;return{slug:r.collection||e,name:r.name||null,floor:o,chain:u||null,contracts:i,currency:d,totalSupply:r.total_supply??n.total_supply??null,numOwners:r.num_owners??n.num_owners??null,raw:{contracts:i,fees:r.fees,category:r.category}}}async function qt(e={},t={}){if(!Be(t))throw new Error("OPENSEA_API_KEY required");let r=ts(e.chain),n=Qr(e.address||e.owner,r),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=[],a=e.next?String(e.next):null,l=0;do{let u=new URL(`${lt(t)}/chain/${encodeURIComponent(r)}/account/${encodeURIComponent(n)}/nfts`);u.searchParams.set("limit",String(o)),e.collection&&u.searchParams.set("collection",String(e.collection)),a&&u.searchParams.set("next",a);let d=await j(u.toString(),{headers:ut(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let c of Array.isArray(d?.nfts)?d.nfts:[])s.push(rs(c,r,n));a=d?.next?String(d.next):null,l+=1}while(a&&l<i);return{provider:"opensea-nft",source:"opensea-account-inventory",chain:r,owner:n,count:s.length,pages:l,complete:!a,next:a,nfts:s,exec:!1,readOnly:!0}}async function en(e={},t={}){if(!Be(t))throw new Error("OPENSEA_API_KEY required");let r=Qr(e.address||e.owner),n=await j(`${lt(t)}/account/${encodeURIComponent(r)}/pnl`,{headers:ut(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});return{provider:"opensea-nft",source:"opensea-indexed-account-pnl",address:r,scope:"OpenSea-indexed account trading PnL across supported currencies, not per-item NFT cost basis",methodology:"provider-indexed",realizedPnlUsd:n?.realized_pnl_usd??null,unrealizedPnlUsd:n?.unrealized_pnl_usd??null,totalPnlUsd:n?.total_pnl_usd??null,netInvestedUsd:n?.net_invested_usd??null,currentValueUsd:n?.current_value_usd??null,returnPercentage:n?.return_percentage??null,itemLevelPnlAvailable:!1,raw:n,exec:!1,readOnly:!0}}var Td=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 Od=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 Nd=new ct(["function setApprovalForAll(address operator,bool approved)"]),$d=new ct(["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 ss="https://api.satflow.com/v1";function tn(e={}){return we({provider:"satflow",defaultUrl:ss,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function as(e={}){return tn(e).baseUrl}function rn(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function cs(e={}){return ce({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":rn(e)},tn(e).trusted)}async function ls(e,{method:t="GET",body:r,opts:n={}}={}){if(!rn(n))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${as(n)}${e.startsWith("/")?e:`/${e}`}`,a=await(n.fetchImpl||fetch)(i,{method:t,headers:cs(n),body:r!=null?JSON.stringify(r):void 0,signal:AbortSignal.timeout(n.timeoutMs??2e4)}),l=await a.text(),u;try{u=JSON.parse(l)}catch{u=l}if(!a.ok)throw new Error(`satflow ${t} ${e}: HTTP ${a.status} ${String(l).slice(0,200)}`);return u}async function nn(e={},t={}){let r=ge(e.address||e.addr,"address"),n=new URLSearchParams({address:r});e.type&&n.set("type",e.type),e.limit!=null&&n.set("limit",String(e.limit)),e.offset!=null&&n.set("offset",String(e.offset));let o=await ls(`/address/wallet-contents?${n}`,{opts:t});return{provider:"satflow",address:r,contents:o}}H();be();H();var Gd=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 us=[/\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],ds=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,ps=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function fs(e={}){let t=[],r=String(e.name||""),n=String(e.description||""),o=`${r} ${n}`;ds.test(r)&&t.push("url-in-name");let i=us.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),ps.test(r)&&t.push("value-claim-in-name"),/[\u200B-\u200F\u202A-\u202E\uFEFF]/.test(r)&&t.push("invisible-characters"),e.disabled===!0&&t.push("marketplace-disabled");let s=e.estimatedValueUsd==null&&e.estimatedValueSats==null,a=!Array.isArray(e.traits)||e.traits.length===0;s&&a&&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 on(e={}){let t=fs(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}be();var ms=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"}]),hs=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 jt(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 r=await it(t);return r.ok?{ok:!0,data:r.data}:{ok:!1,error:`${e}: ${r.error}`.slice(0,300)}}function ys(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 gs(e={},t){let r=e.inscription_id||e.inscriptionId||e.id||e.inscription||null;return{chain:"bitcoin",family:"bitcoin",owner:t,contract:null,tokenId:r==null?null:String(r),tokenStandard:"ordinal",collection:e.collection_slug||e.collectionSlug||e.collection?.slug||e.collection||null,name:e.name||e.meta?.name||(r?`Inscription ${r}`:"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 ws(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 sn(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function bs(e){let t=new Map;if(Array.isArray(e)){for(let r of e)r?.assetKey&&t.set(String(r.assetKey).toLowerCase(),r);return t}if(e&&typeof e=="object")for(let[r,n]of Object.entries(e))t.set(r.toLowerCase(),n);return t}function Ss(e,t){let r=sn(e),n=t.get(r),o=e.estimatedValueUsd==null?null:Number(e.estimatedValueUsd);if(!n)return{...e,assetKey:r};let i=Number(n.costUsd),s=Number(n.feesUsd??0);if(!Number.isFinite(i)||i<0||!Number.isFinite(s)||s<0)return{...e,assetKey:r,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"invalid user-supplied cost basis"}};let a=Math.round((i+s)*100)/100;return Number.isFinite(o)?{...e,assetKey:r,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,acquiredAt:n.acquiredAt||null,source:n.source||"user-supplied"},itemPnl:{status:"estimated",methodology:"provider estimated current value minus supplied USD acquisition cost and fees",unrealizedUsd:Math.round((o-a)*100)/100,currentValueUsd:o,totalCostUsd:a,realizedUsd:null}}:{...e,assetKey:r,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,acquiredAt:n.acquiredAt||null,source:n.source||"user-supplied"},itemPnl:{status:"unavailable",reason:"current NFT valuation is unavailable"}}}function Es(e){let t=new Map;for(let r of e){let n=sn(r);t.has(n)||t.set(n,r)}return[...t.values()]}function vs(e,t){let r=e.filter(i=>i.itemPnl?.status==="estimated"),n=e.length-r.length,o=Math.round(r.reduce((i,s)=>i+Number(s.itemPnl.unrealizedUsd||0),0)*100)/100;return{nftItemPnl:{status:n===0&&e.length?"estimated-complete-for-held-items":r.length?"partial":"unavailable",methodology:"Only items with explicit acquisition cost and provider estimated current value are included",knownUnrealizedUsd:o,knownItems:r.length,unknownItems:n,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 an(e={},t={}){let r=new Date().toISOString(),n=Yr(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(m=>String(m).toLowerCase())):null,i=ms.filter(m=>!o||o.has(m.chain)),s=[],a=[],l=jt(t,"opensea"),u=n.evm?i.filter(m=>m.family!=="solana"):[],d=await Fe(u,4,async m=>({row:m,result:await Se(`opensea-${m.chain}`,()=>qt({chain:m.chain,address:n.evm,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3)}));for(let{row:m,result:E}of d)if(E.ok){let b=E.data.nfts.map(v=>({...v,family:m.family,chainId:m.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));a.push(...b),s.push({family:m.family,chain:m.chain,chainId:m.chainId,status:E.data.complete?"ok":"partial",count:b.length,complete:E.data.complete,next:E.data.next,source:"opensea"})}else{let b=qr(m.chainId)?await Se(`blockscout-${m.chain}`,()=>jr({chain:m.chain,chainId:m.chainId,address:n.evm,maxPages:e.maxPages},{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})):null;b?.ok?(a.push(...b.data.nfts),s.push({...m,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:[E.error,...b.data.errors]})):s.push({...m,status:"unavailable",count:null,complete:!1,error:E.error,errors:[E.error,...b?[b.error]:[]],source:"opensea"})}if(!n.evm)for(let m of i.filter(E=>E.family!=="solana"))s.push({family:m.family,chain:m.chain,chainId:m.chainId,status:"not-configured",reason:"EVM address missing"});if(n.solana&&(!o||o.has("solana"))){let m=await Se("opensea-solana",()=>qt({chain:"solana",address:n.solana,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3);if(m.ok){let E=m.data.nfts.map(b=>({...b,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));a.push(...E),s.push({family:"solana",chain:"solana",status:m.data.complete?"ok":"partial",count:E.length,complete:m.data.complete,next:m.data.next,source:"opensea"})}else s.push({family:"solana",chain:"solana",status:"unavailable",error:m.error,source:"opensea"})}else(!o||o.has("solana"))&&s.push({family:"solana",chain:"solana",status:"not-configured",reason:"Solana address missing"});if(n.bitcoin&&(!o||o.has("bitcoin"))){let m=await Se("satflow-wallet-contents",()=>nn({address:n.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},jt(t,"satflow")),t.timeoutMs??35e3);if(m.ok){let E=ys(m.data.contents).map(v=>gs(v,n.bitcoin));a.push(...E);let b=E.length<Number(e.bitcoinLimit??100);s.push({family:"bitcoin",chain:"bitcoin",status:b?"ok":"partial",count:E.length,complete:b,source:"satflow"})}else{let E=await Se("bitcoin-meta-inscriptions",()=>Bt({address:n.bitcoin},jt(t,"bitcoinMeta")),t.timeoutMs??35e3),b=E.ok&&E.data?.ok&&Array.isArray(E.data.inscriptions)?E.data.inscriptions:[];a.push(...b.map(v=>ws(v,n.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":m.error})}}else(!o||o.has("bitcoin"))&&s.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let c=[];if(e.includePnl!==!1)for(let m of[...new Set([n.evm,n.solana].filter(Boolean))]){let E=await Se(`opensea-pnl-${m}`,()=>en({address:m},l),t.timeoutMs??35e3);c.push(E.ok?{status:"ok",...E.data}:{status:"unavailable",address:m,source:"opensea-indexed-account-pnl",error:E.error})}let h=bs(e.costBasis),p=Es(a).map(m=>Ss(m,h)).map(m=>on(m)),f=p.filter(m=>!m.spam),w=p.filter(m=>m.spam),S=f.filter(m=>m.estimatedValueUsd!=null&&Number.isFinite(Number(m.estimatedValueUsd))),A=Math.round(S.reduce((m,E)=>m+Number(E.estimatedValueUsd),0)*100)/100,O=f.length-S.length,x=s.filter(m=>m.status!=="ok"||m.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:r,addresses:n,coverage:s,unsupported:hs,inventory:{count:p.length,visibleCount:f.length,flaggedCount:w.length,items:p,visibleItems:f,flaggedItems:w},valuation:{estimatedCurrentValueUsd:A,valuedItems:S.length,unvaluedItems:O,complete:O===0&&x.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:vs(f,c),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 ln=1,ks=/^0x[0-9a-f]{40}$/,_s=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,Is=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function Cs(e=process.env){let t=e.ORACLE_CONFIG_DIR||dt.join(cn(),".config","oracle");return dt.join(t,"held-nft-pump.v1.json")}function Ts(e=process.env){let t=e.ORACLE_CONFIG_DIR||dt.join(cn(),".config","oracle"),r={};try{let o=JSON.parse(xs(dt.join(t,"portfolio.json"),"utf8"));r=o&&typeof o=="object"&&!Array.isArray(o)?o.addresses||o:{}}catch{}let n={evm:e.ORACLE_EVM_ADDRESS||r.evm,solana:e.ORACLE_SOLANA_ADDRESS||r.solana};return Object.fromEntries(Object.entries(n).filter(([,o])=>typeof o=="string"&&o.trim()).map(([o,i])=>[o,i.trim()]))}function Os(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function un(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function Ns(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 r=BigInt(String(t));return r>0n?r:0n}function $s(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function Ps(e){if(!e||e.version!==ln||!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 r=Object.entries(e.collections);if(r.length>1e4||Object.keys(t).length>1e4)throw new TypeError("held NFT pump state exceeds collection bound");for(let[n,o]of r){if(!n||n.length>260||!o||un(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 n of Object.values(t))if(!n||!Number.isSafeInteger(n.count)||n.count<1||!Number.isFinite(n.nextCheckAt)||n.nextCheckAt<0)throw new TypeError("invalid held NFT provider backoff")}function Rs(e={}){let t=e?.inventory?.visibleItems??e?.inventory?.items??[],r=new Map;for(let n of Array.isArray(t)?t:[]){if(n?.spam===!0||n?.disabled===!0)continue;let o=String(n?.chain||"").trim().toLowerCase(),i=String(n?.contract||"").trim(),s=o==="solana"?i:i.toLowerCase(),a=String(n?.collection||"").trim().toLowerCase();if(!o||!a||!(o==="solana"?_s.test(s):ks.test(s)))continue;let l=Ns(n);if(l===0n)continue;let u=`${o}:${s}`,d=r.get(u);d&&d.slug!==a||r.set(u,{key:u,chain:o,contract:s,slug:a,name:d?.name||String(n?.name||a),heldCountRaw:(d?.heldCountRaw||0n)+l})}return[...r.values()].map(({heldCountRaw:n,...o})=>({...o,heldCount:$s(n)})).sort((n,o)=>n.key.localeCompare(o.key))}function Ls(e,t){let r=String(e?.currency||"").trim().toUpperCase();if(!Is.test(r))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 n=Array.isArray(e?.contracts)?e.contracts:Array.isArray(e?.raw?.contracts)?e.raw.contracts:[],o=t.chain==="solana"?t.contract:t.contract.toLowerCase();return n.some(s=>{let a=String(s?.address||s?.contract_address||s?.contract||"").trim(),l=t.chain==="solana"?a:a.toLowerCase(),u=String(s?.chain||s?.chain_identifier||"").trim().toLowerCase();return l===o&&u===t.chain})?{ok:!0,currency:r}:{ok:!1,reason:"floor-identity-mismatch"}}function Us(e,t,r,n,o){let i=Math.round((t/n.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:n.anchorFloor,floor:t,currency:r,changePct:i,observedAt:new Date(o).toISOString(),evidence:Object.freeze({source:"opensea-collection-floor",status:"provider-estimate",chain:e.chain,contract:e.contract,currency:r,observedAt:new Date(o).toISOString(),warning:"Floor is a provider estimate, not an executable bid or guaranteed liquidation value."}),custody:"none",executionAllowed:!1})}function dn({filePath:e,env:t=process.env,clock:r=()=>Date.now(),inventoryFn:n=an,floorFn:o=Zr,notifyFn:i=async()=>({delivered:0}),thresholdPct:s=Number(t.ORACLE_NFT_PUMP_THRESHOLD_PCT??15),cooldownMs:a=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 n!="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(a)||a<6e4||a>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 c=Ir({filePath:e||Cs(t),kind:"oracle-held-nft-pump",clock:r,maxBytes:4*1024*1024,initialData:()=>({version:ln,cursor:0,collections:{},failures:{}}),validateData:Ps}),h=!1;function p(w,S){c.mutate(A=>{A.failures||={};let O=Math.min(20,Number(A.failures[w]?.count||0)+1);A.failures[w]={count:O,nextCheckAt:S+Math.min(6*36e5,3e5*2**Math.min(6,O-1))}})}async function f(){if(h)return{skipped:!0,reason:"tick-in-progress",alerts:[],unavailable:[]};h=!0;try{let w=Number(r());if(!Number.isFinite(w))throw new TypeError("held NFT watchdog clock is invalid");let S=Ts(t),A=Os(t),O=As("sha256").update(JSON.stringify(Object.entries(S).sort())).digest("hex");c.mutate(y=>{let _=!!(y.walletFingerprint&&y.walletFingerprint!==O);_&&(y.collections={},y.failures={},y.cursor=0),y.walletFingerprint=O,y.walletChanged=_});let x=await n({addresses:S,includePnl:!1,pageSize:u,maxPages:d},{env:A}),m=Rs(x),E=new Set(m.map(y=>y.key)),b=new Set((Array.isArray(x?.coverage)?x.coverage:[]).filter(y=>y?.status==="ok"&&y?.complete===!0).map(y=>String(y.chain||"").toLowerCase()).filter(Boolean));b.size&&c.mutate(y=>{for(let _ of Object.keys(y.collections)){let M=_.slice(0,_.indexOf(":"));b.has(M)&&!E.has(_)&&delete y.collections[_]}for(let _ of Object.keys(y.failures||{})){let M=_.slice(0,_.indexOf(":"));b.has(M)&&!E.has(_)&&delete y.failures[_]}});let v=c.mutate(y=>{let _=m.length?(y.cursor||0)%m.length:0;return y.cursor=m.length?(_+Math.min(l,m.length))%m.length:0,_}),I=[];for(let y=0;y<Math.min(l,m.length);y+=1)I.push(m[(v+y)%m.length]);let N=[],R=[];for(let y of I){let _=c.inspect().data.failures?.[y.key];if(_&&_.nextCheckAt>w){R.push({key:y.key,reason:"floor-provider-backoff"});continue}let M;try{M=await o(y.slug,{env:A,expectedChain:y.chain,expectedContract:y.contract})}catch{p(y.key,w),R.push({key:y.key,reason:"floor-provider-unavailable"});continue}let L=Ls(M,y);if(!L.ok){p(y.key,w),R.push({key:y.key,reason:L.reason});continue}let D=un(M?.floor);if(D===null){p(y.key,w),R.push({key:y.key,reason:"floor-unavailable"});continue}let V=c.mutate(U=>{U.failures||={},delete U.failures[y.key];let k=U.collections[y.key];if(!k)return U.collections[y.key]={anchorFloor:D,lastAlertAt:null,updatedAt:w,currency:L.currency},null;if(k.updatedAt=w,k.currency!==L.currency)return k.anchorFloor=D,k.currency=L.currency,k.lastAlertAt=null,null;if(D<k.anchorFloor)return k.anchorFloor=D,k.currency=L.currency,null;if((D/k.anchorFloor-1)*100+1e-9<s)return null;if(k.lastAlertAt!==null&&w-k.lastAlertAt<a)return k.anchorFloor=D,k.currency=L.currency,null;let Ye=Us({...y,name:M?.name||y.name},D,L.currency,k,w);return k.anchorFloor=D,k.lastAlertAt=w,k.updatedAt=w,k.currency=L.currency,Ye});if(!V)continue;let z;try{z=await i(V)}catch{z=null}if(!z||Number(z.delivered||0)!==1){R.push({key:y.key,reason:"notification-delivery-failed"});continue}N.push(V)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:m.length,checkedCollections:I.length,alerts:N,unavailable:R,coverage:x?.coverage??[]}}finally{h=!1}}return Object.freeze({filePath:c.filePath,tick:f,inspect:c.inspect})}De();var Et=Pe.ORACLE_CONFIG_DIR||Ke(Pc(),".config","oracle"),qo=Ke(Et,"gateway.json");function Bc(){return Rc(qo)?JSON.parse(Sr(qo,"utf8")):{platforms:{}}}function Dc(e={},t=Pe){let r=e?.notifications?.heldNftPumps;return r===!1?!1:r===!0?!0:String(t.ORACLE_NFT_PUMP_ENABLED||"")==="1"}function qc({configDir:e=Et,environment:t=Pe}={}){let r=String(t.ORACLE_MESSAGING_PLATFORM||"").trim().toLowerCase();if(r)return r;try{let n=JSON.parse(Sr(Ke(e,"messaging.json"),"utf8"));return String(n?.platform||"").trim().toLowerCase()}catch{return""}}function jc(e,t=Et){let r=String(e?.platform||""),n=String(e?.recipientId||"");if(!r||!n)throw new TypeError("recipient-bound held NFT subscription is required");let o=Fc("sha256").update(`${r}\0${n}`).digest("hex").slice(0,24);return Ke(t,`held-nft-pump.${o}.v1.json`)}function Hc({heldNftPumpLoop:e,platforms:t=[],server:r,exitFn:n=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{}r?.close&&await new Promise(s=>r.close(()=>s())),n(0)})(),o)}}function wr(e){return e?Array.isArray(e)?e.filter(Boolean):[e]:[]}var Vc=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function St(e,t,r,n){try{n.push(await t(r))}catch(o){let i=Vc[e];if(i&&/Cannot find (module|package)|ERR_MODULE_NOT_FOUND/.test(String(o.message))){process.stderr.write(`oracle-gateway: ${e} needs an optional dependency. Install it first:
47
+ `),{platform:"signal",status:"stub"}}var Gi=_(()=>{je()});import{createServer as mu}from"node:http";import{env as ze}from"node:process";import{join as it}from"node:path";import{homedir as hu}from"node:os";import{readFileSync as Vn,existsSync as yu,mkdirSync as gu,writeFileSync as wu}from"node:fs";import{createHash as bu,randomBytes as Su}from"node:crypto";import kt from"node:path";import{homedir as Fr}from"node:os";import{readFileSync as Ra}from"node:fs";import{createHash as La}from"node:crypto";import P from"node:fs";import ct from"node:path";import{createHash as ns,randomUUID as Yn}from"node:crypto";var qt=1,X=class extends Error{constructor(t,n="DURABLE_STORE_ERROR"){super(t),this.name="DurableStoreError",this.code=n}};function dt(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(dt).join(",")}]`;if(e&&typeof e=="object")return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${dt(e[n])}`).join(",")}}`;throw new TypeError(`durable store values must be JSON-safe, got ${typeof e}`)}function Jn(e){return ns("sha256").update(dt(e)).digest("hex")}function lt(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 ut(e){return e===void 0?void 0:JSON.parse(JSON.stringify(e))}function Xn(e){P.mkdirSync(e,{recursive:!0,mode:448});try{P.chmodSync(e,448)}catch{}}function jt(e){try{let t=P.statSync(e);return{...JSON.parse(P.readFileSync(e,"utf8")),mtimeMs:t.mtimeMs}}catch{return null}}function Qn({filePath:e,kind:t,initialData:n,validateData:r,clock:o=()=>Date.now(),maxBytes:i=4*1024*1024,lockStaleMs:s=3e4,lockWaitMs:a=2e3,lockIdFactory:l=()=>Yn()}={}){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(a)||a<0||a>3e4)throw new TypeError("lockWaitMs must be between 0 and 30000");let u=`${e}.lock`;function d(){let E=n();return r(E),{schemaVersion:qt,kind:t,generation:0,data:E}}function c(E){let h;try{h=JSON.parse(E)}catch(k){throw new X(`corrupt ${t} snapshot: invalid JSON (${k.message})`,"STORE_CORRUPT")}if(!h||typeof h!="object"||Array.isArray(h))throw new X(`corrupt ${t} snapshot: root must be an object`,"STORE_CORRUPT");if(h.schemaVersion!==qt)throw new X(`unsupported ${t} schemaVersion ${String(h.schemaVersion)}`,"STORE_SCHEMA");if(h.kind!==t||!Number.isSafeInteger(h.generation)||h.generation<0)throw new X(`corrupt ${t} snapshot metadata`,"STORE_CORRUPT");let{integrity:x,...b}=h;if(typeof x!="string"||!/^[a-f0-9]{64}$/.test(x)||Jn(b)!==x)throw new X(`corrupt ${t} snapshot: checksum mismatch`,"STORE_CORRUPT");try{r(h.data)}catch(k){throw new X(`corrupt ${t} snapshot: ${k.message}`,"STORE_CORRUPT")}return b}function f(){if(!P.existsSync(e))return d();let E=P.statSync(e);if(!E.isFile()||E.size>i)throw new X(`${t} snapshot is not a bounded regular file`,"STORE_BOUNDS");try{P.chmodSync(e,384)}catch{}return c(P.readFileSync(e,"utf8"))}function m(){Xn(ct.dirname(e));let E=lt(o),h=String(l()),x=`${JSON.stringify({schemaVersion:1,lockId:h,pid:process.pid,acquiredAt:E})}
48
+ `,b=()=>{let L;try{return L=P.openSync(u,"wx",384),P.writeFileSync(L,x,"utf8"),P.fsyncSync(L),P.closeSync(L),{lockId:h}}catch(w){let I=L!==void 0;if(I)try{P.closeSync(L)}catch{}if(I)try{P.unlinkSync(u)}catch{}if(w?.code!=="EEXIST")throw w;return null}},C=lt(o)+a,T=new Int32Array(new SharedArrayBuffer(4));for(;;){let L=b();if(L)return L;let w=lt(o),I=jt(u),B=!1;if(I){let q=w-Number(I.acquiredAt??I.mtimeMs);B=Number.isFinite(q)&&q>=s}else try{B=w-P.statSync(u).mtimeMs>=s}catch{B=!1}if(B){let q=jt(u);if(I?q?.lockId===I.lockId:q===null){try{P.unlinkSync(u)}catch(W){if(W?.code!=="ENOENT")throw W}continue}}let M=C-w;if(M<=0)throw new X(`${t} store is busy`,"STORE_BUSY");Atomics.wait(T,0,0,Math.min(10,M))}}function p(E){if(jt(u)?.lockId===E.lockId)try{P.unlinkSync(u)}catch(x){if(x?.code!=="ENOENT")throw x}}function y(E){r(E.data);let h={...E,integrity:Jn(E)},x=`${dt(h)}
49
+ `;if(Buffer.byteLength(x)>i)throw new X(`${t} snapshot exceeds ${i} bytes`,"STORE_BOUNDS");let b=ct.dirname(e);Xn(b);let k=ct.join(b,`.${ct.basename(e)}.${process.pid}.${Yn()}.tmp`),C;try{C=P.openSync(k,"wx",384),P.writeFileSync(C,x,"utf8"),P.fsyncSync(C),P.closeSync(C),C=void 0,P.renameSync(k,e);try{P.chmodSync(e,384)}catch{}try{let T=P.openSync(b,"r");try{P.fsyncSync(T)}finally{P.closeSync(T)}}catch{}}finally{if(C!==void 0)try{P.closeSync(C)}catch{}try{P.unlinkSync(k)}catch(T){if(T?.code!=="ENOENT")throw T}}}function S(){return ut(f().data)}function v(){let E=f();return{schemaVersion:E.schemaVersion,kind:E.kind,generation:E.generation,data:ut(E.data)}}function N(E){if(typeof E!="function")throw new TypeError("mutator must be a function");let h=m();try{let x=f(),b=ut(x.data),k=E(b,{generation:x.generation,now:lt(o)});return r(b),y({schemaVersion:qt,kind:t,generation:x.generation+1,data:b}),ut(k)}finally{p(h)}}return Object.freeze({filePath:e,read:S,inspect:v,mutate:N})}V();V();import{getAddress as Bs}from"ethers";import{types as ur}from"node:util";function Xt(e){if(!e||typeof e!="object"||ur.isProxy(e)||Array.isArray(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function de(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(ur.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]=de(s.value,t,n+1)}return o}if(!Xt(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]=de(i.value,t,n+1)}return r}var Ms=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,Fs=/[<>&`*_~[\]()|\\]/g,Us=/[\u0000-\u001F\u007F]/g;function gt(e,{max:t=32,fallback:n=""}={}){return e==null?n:String(e).normalize("NFKC").replace(Ms,"").replace(Us,"").replace(Fs,"").replace(/\s+/g," ").trim().slice(0,t).trim()||n}var dr=Object.freeze({1:"https://eth.blockscout.com",8453:"https://base.blockscout.com",42161:"https://arbitrum.blockscout.com"}),pr=e=>!!dr[e];function Ds(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 fr(e={},t={}){let n=Bs(e.address),r=dr[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=[],a=new Set,l=null,u="",d=0,c=!1;for(;d<o;)try{let f=de(await z(`${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(f?.items))throw new Error("invalid NFT inventory response");d++;for(let p of f.items.slice(0,50)){let y=p.token;if(!/^0x[\da-f]{40}$/i.test(y?.address_hash||"")||!/^\d+$/.test(String(p.id??"")))throw new Error("invalid NFT identity");if(!["ERC-721","ERC-1155","ERC-404"].includes(y.type))throw new Error("invalid NFT standard");if(p.owner?.hash&&p.owner.hash.toLowerCase()!==n.toLowerCase())throw new Error("NFT owner mismatch");i.push({chain:e.chain,chainId:e.chainId,family:"evm",owner:n,contract:y.address_hash,tokenId:String(p.id),tokenStandard:y.type,collection:gt(y.name,{max:160,fallback:y.address_hash}),name:gt(p.metadata?.name||y.name,{max:160,fallback:`NFT ${p.id}`}),imageUrl:p.image_url||null,estimatedValueUsd:null,spam:["scam","spam"].includes(y.reputation)||y.is_spam===!0,source:"blockscout-owner-inventory",listingAdapter:null,acquisitionCost:null,itemPnl:{status:"unavailable",reason:"owner indexer provides no acquisition cost"}})}if(f.items.length>50)throw new Error("NFT provider page exceeds 50 item bound");let m=f.next_page_params??null;if(!m){l=null,c=!0;break}if(l=null,u=Ds(m),l=Object.fromEntries(new URLSearchParams(u)),a.has(u))throw new Error("repeated NFT cursor");a.add(u)}catch(f){if(s.push(`blockscout: ${f.message}`.slice(0,300)),!d)throw f;break}return{nfts:i,complete:c,next:l,pages:d,truncated:!c,errors:s}}import{getAddress as Xs}from"ethers";Ce();wt();V();var Sd=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),nn=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),rn=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});Ce();Ce();tn();an();V();Ce();V();function cn(e,t="address"){let n=String(e||"").trim();if(!/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(n))throw new Error(`solana-rpc: ${t} must be a base58 public key`);return n}V();function Oe(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 hr="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function Ne({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:yr(t)};let a;try{a=new URL(s)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(a.protocol!=="http:"&&a.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let l=a.host;if(!l)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([yr(t),...n]).has(l)){let d=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(l);return a.protocol==="http:"&&!d?{baseUrl:s,trusted:!1,host:l,reason:"plaintext http downgrade"}:{baseUrl:s,trusted:!0,host:l}}if(String(process.env[hr]||"")==="1")return{baseUrl:s,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${hr}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:l}}function yr(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function we(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 gr(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}var Ks=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"];function Ws(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=gr(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=Ks.includes(o)&&(i==="https:"||s)}}catch{n=!1}return we({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},n)}async function Gs(e,t={}){let r=await(t.fetchImpl||fetch)(e,{method:"GET",headers:Ws(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 ln(e={},t={}){let n=Oe(e.address||e.addr,"address"),r=gr(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 a of i)try{let l=await Gs(a,t),u=Ys(l);return{provider:"bitcoin-meta",address:n,ok:!0,count:u.length,inscriptions:u,source:a}}catch(l){s=l}return{provider:"bitcoin-meta",address:n,ok:!1,inscriptions:[],error:String(s?.message||s||"all indexer paths failed")}}function Ys(e){let t=e?.data?.inscription||e?.data?.detail||e?.data?.list||e?.data||e?.inscriptions||e?.results||(Array.isArray(e)?e:[]);return(Array.isArray(t)?t:[]).map(r=>({id:r.inscriptionId||r.id||r.inscription_id||null,number:r.inscriptionNumber??r.number??null,sat:r.sat||r.satoshi||null,contentType:r.contentType||r.content_type||null,utxo:r.utxo||r.output||(r.txid!=null?`${r.txid}:${r.vout??r.n}`:null),raw:r}))}V();V();V();wt();var gp=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood",2741:"abstract",solana:"solana"});V();un();var Js=Object.freeze(["block_number","index"]),Ap=new Set([...Js,"items_count","value","hash","inserted_at","fee"]);var ef=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 bt(e,...t){for(let n of t){let r=String(e?.[n]||"").trim();if(r)return r}return null}function br(e){if(!e)return null;try{return Xs(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function Sr(e={},t=process.env){let n=e.addresses||{},r=br(n.evm||e.evmAddress||bt(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=n.solana||e.solanaAddress||bt(t,"ORACLE_SOLANA_ADDRESS"),i=n.bitcoin||e.bitcoinAddress||bt(t,"ORACLE_BITCOIN_ADDRESS"),s=br(n.hyperliquid||e.hyperliquidAddress||bt(t,"ORACLE_HYPERLIQUID_ADDRESS")||r);return{evm:r,solana:o?cn(o,"portfolio Solana address"):null,bitcoin:i?Oe(i,"portfolio Bitcoin address"):null,hyperliquid:s}}V();import{readFileSync as ra,existsSync as oa}from"node:fs";import{getAddress as ia,Interface as St,TypedDataEncoder as uf,parseUnits as df}from"ethers";pe();var sa="https://api.opensea.io/api/v2",aa="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)",yf=new St([`function ${aa}`]),gf=new St(["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"]),ca=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"]),la=new Set(ca),ua=new Set(["solana","flow"]);function da(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!oa(e))return"";try{for(let t of ra(e,"utf8").split(`
50
+ `)){let n=t.match(/^\s*OPENSEA_API_KEY\s*=\s*(.+)\s*$/);if(n)return n[1].replace(/^["']|["']$/g,"").trim()}}catch{}return""}function Ye(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||da()}function _r(e={}){return Ne({provider:"opensea",defaultUrl:sa,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function xt(e={}){return _r(e).baseUrl}function Et(e={}){return we({accept:"application/json"},{"x-api-key":Ye(e)},_r(e).trusted)}function pa(e){let t=String(e||"ethereum").trim().toLowerCase();if(!la.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function Ir(e,t="address"){try{return ia(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function Cr(e,t=null){let n=String(e||"").trim();if(!n)throw new Error("opensea: account address required");if(t&&!ua.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(n))return Ir(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 fa(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 ma(e,t={}){if(!e)throw new Error("collection slug required");if(!Ye(t))throw new Error("OPENSEA_API_KEY required");return z(`${xt(t)}/collections/${encodeURIComponent(e)}`,{headers:Et(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function ha(e,t={}){if(!e)throw new Error("collection slug required");if(!Ye(t))throw new Error("OPENSEA_API_KEY required");return z(`${xt(t)}/collections/${encodeURIComponent(e)}/stats`,{headers:Et(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function Or(e,t={}){let n=await ma(e,t),r=n.stats||n.total||{},o=n.floor_price??n.floorPrice??r.floor_price??r.floorPrice??null;if(o==null){let c=await ha(e,t);r=c?.total||c?.stats||c||{},o=r.floor_price??r.floorPrice??null}let i=(Array.isArray(n.contracts)?n.contracts:[]).map(c=>({chain:String(c?.chain||c?.chain_identifier||n.chain||"").trim().toLowerCase(),address:String(c?.address||c?.contract_address||c?.contract||"").trim()})).filter(c=>c.chain&&c.address),s=String(t.expectedChain||"").trim().toLowerCase(),a=String(t.expectedContract||"").trim(),l=null;if(s&&a){let c=f=>s==="solana"?f:f.toLowerCase();if(l=i.find(f=>f.chain===s&&c(f.address)===c(a))||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 pn(e={},t={}){if(!Ye(t))throw new Error("OPENSEA_API_KEY required");let n=pa(e.chain),r=Cr(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=[],a=e.next?String(e.next):null,l=0;do{let u=new URL(`${xt(t)}/chain/${encodeURIComponent(n)}/account/${encodeURIComponent(r)}/nfts`);u.searchParams.set("limit",String(o)),e.collection&&u.searchParams.set("collection",String(e.collection)),a&&u.searchParams.set("next",a);let d=await z(u.toString(),{headers:Et(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let c of Array.isArray(d?.nfts)?d.nfts:[])s.push(fa(c,n,r));a=d?.next?String(d.next):null,l+=1}while(a&&l<i);return{provider:"opensea-nft",source:"opensea-account-inventory",chain:n,owner:r,count:s.length,pages:l,complete:!a,next:a,nfts:s,exec:!1,readOnly:!0}}async function Nr(e={},t={}){if(!Ye(t))throw new Error("OPENSEA_API_KEY required");let n=Cr(e.address||e.owner),r=await z(`${xt(t)}/account/${encodeURIComponent(n)}/pnl`,{headers:Et(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 wf=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 bf=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 Sf=new St(["function setApprovalForAll(address operator,bool approved)"]),xf=new St(["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)"]);pe();var ga="https://api.satflow.com/v1";function Tr(e={}){return Ne({provider:"satflow",defaultUrl:ga,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function wa(e={}){return Tr(e).baseUrl}function $r(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function ba(e={}){return we({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":$r(e)},Tr(e).trusted)}async function Sa(e,{method:t="GET",body:n,opts:r={}}={}){if(!$r(r))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${wa(r)}${e.startsWith("/")?e:`/${e}`}`,a=await(r.fetchImpl||fetch)(i,{method:t,headers:ba(r),body:n!=null?JSON.stringify(n):void 0,signal:AbortSignal.timeout(r.timeoutMs??2e4)}),l=await a.text(),u;try{u=JSON.parse(l)}catch{u=l}if(!a.ok)throw new Error(`satflow ${t} ${e}: HTTP ${a.status} ${String(l).slice(0,200)}`);return u}async function Pr(e={},t={}){let n=Oe(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 Sa(`/address/wallet-contents?${r}`,{opts:t});return{provider:"satflow",address:n,contents:o}}V();pe();V();var Mf=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 xa=[/\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],Ea=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,ka=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i;function va(e={}){let t=[],n=String(e.name||""),r=String(e.description||""),o=`${n} ${r}`;Ea.test(n)&&t.push("url-in-name");let i=xa.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),ka.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,a=!Array.isArray(e.traits)||e.traits.length===0;s&&a&&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 Rr(e={}){let t=va(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}pe();var Aa=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"}]),Ia=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 fn(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function Te(e,t){let n=await yt(t);return n.ok?{ok:!0,data:n.data}:{ok:!1,error:`${e}: ${n.error}`.slice(0,300)}}function _a(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 Ca(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 Oa(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 Lr(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function Na(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 Ta(e,t){let n=Lr(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 a=Math.round((i+s)*100)/100;return Number.isFinite(o)?{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,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-a)*100)/100,currentValueUsd:o,totalCostUsd:a,realizedUsd:null}}:{...e,assetKey:n,acquisitionCost:{costUsd:i,feesUsd:s,totalCostUsd:a,acquiredAt:r.acquiredAt||null,source:r.source||"user-supplied"},itemPnl:{status:"unavailable",reason:"current NFT valuation is unavailable"}}}function $a(e){let t=new Map;for(let n of e){let r=Lr(n);t.has(r)||t.set(r,n)}return[...t.values()]}function Pa(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 Mr(e={},t={}){let n=new Date().toISOString(),r=Sr(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(h=>String(h).toLowerCase())):null,i=Aa.filter(h=>!o||o.has(h.chain)),s=[],a=[],l=fn(t,"opensea"),u=r.evm?i.filter(h=>h.family!=="solana"):[],d=await Ge(u,4,async h=>({row:h,result:await Te(`opensea-${h.chain}`,()=>pn({chain:h.chain,address:r.evm,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3)}));for(let{row:h,result:x}of d)if(x.ok){let b=x.data.nfts.map(k=>({...k,family:h.family,chainId:h.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));a.push(...b),s.push({family:h.family,chain:h.chain,chainId:h.chainId,status:x.data.complete?"ok":"partial",count:b.length,complete:x.data.complete,next:x.data.next,source:"opensea"})}else{let b=pr(h.chainId)?await Te(`blockscout-${h.chain}`,()=>fr({chain:h.chain,chainId:h.chainId,address:r.evm,maxPages:e.maxPages},{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})):null;b?.ok?(a.push(...b.data.nfts),s.push({...h,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:[x.error,...b.data.errors]})):s.push({...h,status:"unavailable",count:null,complete:!1,error:x.error,errors:[x.error,...b?[b.error]:[]],source:"opensea"})}if(!r.evm)for(let h of i.filter(x=>x.family!=="solana"))s.push({family:h.family,chain:h.chain,chainId:h.chainId,status:"not-configured",reason:"EVM address missing"});if(r.solana&&(!o||o.has("solana"))){let h=await Te("opensea-solana",()=>pn({chain:"solana",address:r.solana,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3);if(h.ok){let x=h.data.nfts.map(b=>({...b,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));a.push(...x),s.push({family:"solana",chain:"solana",status:h.data.complete?"ok":"partial",count:x.length,complete:h.data.complete,next:h.data.next,source:"opensea"})}else s.push({family:"solana",chain:"solana",status:"unavailable",error:h.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 h=await Te("satflow-wallet-contents",()=>Pr({address:r.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},fn(t,"satflow")),t.timeoutMs??35e3);if(h.ok){let x=_a(h.data.contents).map(k=>Ca(k,r.bitcoin));a.push(...x);let b=x.length<Number(e.bitcoinLimit??100);s.push({family:"bitcoin",chain:"bitcoin",status:b?"ok":"partial",count:x.length,complete:b,source:"satflow"})}else{let x=await Te("bitcoin-meta-inscriptions",()=>ln({address:r.bitcoin},fn(t,"bitcoinMeta")),t.timeoutMs??35e3),b=x.ok&&x.data?.ok&&Array.isArray(x.data.inscriptions)?x.data.inscriptions:[];a.push(...b.map(k=>Oa(k,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":h.error})}}else(!o||o.has("bitcoin"))&&s.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let c=[];if(e.includePnl!==!1)for(let h of[...new Set([r.evm,r.solana].filter(Boolean))]){let x=await Te(`opensea-pnl-${h}`,()=>Nr({address:h},l),t.timeoutMs??35e3);c.push(x.ok?{status:"ok",...x.data}:{status:"unavailable",address:h,source:"opensea-indexed-account-pnl",error:x.error})}let f=Na(e.costBasis),m=$a(a).map(h=>Ta(h,f)).map(h=>Rr(h)),p=m.filter(h=>!h.spam),y=m.filter(h=>h.spam),S=p.filter(h=>h.estimatedValueUsd!=null&&Number.isFinite(Number(h.estimatedValueUsd))),v=Math.round(S.reduce((h,x)=>h+Number(x.estimatedValueUsd),0)*100)/100,N=p.length-S.length,E=s.filter(h=>h.status!=="ok"||h.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:n,addresses:r,coverage:s,unsupported:Ia,inventory:{count:m.length,visibleCount:p.length,flaggedCount:y.length,items:m,visibleItems:p,flaggedItems:y},valuation:{estimatedCurrentValueUsd:v,valuedItems:S.length,unvaluedItems:N,complete:N===0&&E.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:Pa(p,c),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 Ur=1,Ma=/^0x[0-9a-f]{40}$/,Fa=/^[1-9A-HJ-NP-Za-km-z]{32,64}$/,Ua=/^[A-Z0-9][A-Z0-9._-]{1,15}$/;function Ba(e=process.env){let t=e.ORACLE_CONFIG_DIR||kt.join(Fr(),".config","oracle");return kt.join(t,"held-nft-pump.v1.json")}function Da(e=process.env){let t=e.ORACLE_CONFIG_DIR||kt.join(Fr(),".config","oracle"),n={};try{let o=JSON.parse(Ra(kt.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 qa(e){return{...e,ORACLE_DEFAULT_ADDRESS:"",MAD_OPERATOR_ADDRESS:""}}function Br(e){let t=Number(e);return Number.isFinite(t)&&t>0?t:null}function ja(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 Ha(e){return e<=BigInt(Number.MAX_SAFE_INTEGER)?Number(e):e.toString()}function za(e){if(!e||e.version!==Ur||!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||Br(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(),s=o==="solana"?i:i.toLowerCase(),a=String(r?.collection||"").trim().toLowerCase();if(!o||!a||!(o==="solana"?Fa.test(s):Ma.test(s)))continue;let l=ja(r);if(l===0n)continue;let u=`${o}:${s}`,d=n.get(u);d&&d.slug!==a||n.set(u,{key:u,chain:o,contract:s,slug:a,name:d?.name||String(r?.name||a),heldCountRaw:(d?.heldCountRaw||0n)+l})}return[...n.values()].map(({heldCountRaw:r,...o})=>({...o,heldCount:Ha(r)})).sort((r,o)=>r.key.localeCompare(o.key))}function Ka(e,t){let n=String(e?.currency||"").trim().toUpperCase();if(!Ua.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 a=String(s?.address||s?.contract_address||s?.contract||"").trim(),l=t.chain==="solana"?a:a.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 Wa(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 Dr({filePath:e,env:t=process.env,clock:n=()=>Date.now(),inventoryFn:r=Mr,floorFn:o=Or,notifyFn:i=async()=>({delivered:0}),thresholdPct:s=Number(t.ORACLE_NFT_PUMP_THRESHOLD_PCT??15),cooldownMs:a=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(a)||a<6e4||a>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 c=Qn({filePath:e||Ba(t),kind:"oracle-held-nft-pump",clock:n,maxBytes:4*1024*1024,initialData:()=>({version:Ur,cursor:0,collections:{},failures:{}}),validateData:za}),f=!1;function m(y,S){c.mutate(v=>{v.failures||={};let N=Math.min(20,Number(v.failures[y]?.count||0)+1);v.failures[y]={count:N,nextCheckAt:S+Math.min(6*36e5,3e5*2**Math.min(6,N-1))}})}async function p(){if(f)return{skipped:!0,reason:"tick-in-progress",alerts:[],unavailable:[]};f=!0;try{let y=Number(n());if(!Number.isFinite(y))throw new TypeError("held NFT watchdog clock is invalid");let S=Da(t),v=qa(t),N=La("sha256").update(JSON.stringify(Object.entries(S).sort())).digest("hex");c.mutate(w=>{let I=!!(w.walletFingerprint&&w.walletFingerprint!==N);I&&(w.collections={},w.failures={},w.cursor=0),w.walletFingerprint=N,w.walletChanged=I});let E=await r({addresses:S,includePnl:!1,pageSize:u,maxPages:d},{env:v}),h=Va(E),x=new Set(h.map(w=>w.key)),b=new Set((Array.isArray(E?.coverage)?E.coverage:[]).filter(w=>w?.status==="ok"&&w?.complete===!0).map(w=>String(w.chain||"").toLowerCase()).filter(Boolean));b.size&&c.mutate(w=>{for(let I of Object.keys(w.collections)){let B=I.slice(0,I.indexOf(":"));b.has(B)&&!x.has(I)&&delete w.collections[I]}for(let I of Object.keys(w.failures||{})){let B=I.slice(0,I.indexOf(":"));b.has(B)&&!x.has(I)&&delete w.failures[I]}});let k=c.mutate(w=>{let I=h.length?(w.cursor||0)%h.length:0;return w.cursor=h.length?(I+Math.min(l,h.length))%h.length:0,I}),C=[];for(let w=0;w<Math.min(l,h.length);w+=1)C.push(h[(k+w)%h.length]);let T=[],L=[];for(let w of C){let I=c.inspect().data.failures?.[w.key];if(I&&I.nextCheckAt>y){L.push({key:w.key,reason:"floor-provider-backoff"});continue}let B;try{B=await o(w.slug,{env:v,expectedChain:w.chain,expectedContract:w.contract})}catch{m(w.key,y),L.push({key:w.key,reason:"floor-provider-unavailable"});continue}let M=Ka(B,w);if(!M.ok){m(w.key,y),L.push({key:w.key,reason:M.reason});continue}let q=Br(B?.floor);if(q===null){m(w.key,y),L.push({key:w.key,reason:"floor-unavailable"});continue}let K=c.mutate(F=>{F.failures||={},delete F.failures[w.key];let A=F.collections[w.key];if(!A)return F.collections[w.key]={anchorFloor:q,lastAlertAt:null,updatedAt:y,currency:M.currency},null;if(A.updatedAt=y,A.currency!==M.currency)return A.anchorFloor=q,A.currency=M.currency,A.lastAlertAt=null,null;if(q<A.anchorFloor)return A.anchorFloor=q,A.currency=M.currency,null;if((q/A.anchorFloor-1)*100+1e-9<s)return null;if(A.lastAlertAt!==null&&y-A.lastAlertAt<a)return A.anchorFloor=q,A.currency=M.currency,null;let st=Wa({...w,name:B?.name||w.name},q,M.currency,A,y);return A.anchorFloor=q,A.lastAlertAt=y,A.updatedAt=y,A.currency=M.currency,st});if(!K)continue;let W;try{W=await i(K)}catch{W=null}if(!W||Number(W.delivered||0)!==1){L.push({key:w.key,reason:"notification-delivery-failed"});continue}T.push(K)}return{provider:"held-nft-pump",readOnly:!0,custody:"none",executionAllowed:!1,heldCollections:h.length,checkedCollections:C.length,alerts:T,unavailable:L,coverage:E?.coverage??[]}}finally{f=!1}}return Object.freeze({filePath:c.filePath,tick:p,inspect:c.inspect})}Je();var Bt=ze.ORACLE_CONFIG_DIR||it(hu(),".config","oracle"),Yi=it(Bt,"gateway.json");function xu(){return yu(Yi)?JSON.parse(Vn(Yi,"utf8")):{platforms:{}}}function Eu(e={},t=ze){let n=e?.notifications?.heldNftPumps;return n===!1?!1:n===!0?!0:String(t.ORACLE_NFT_PUMP_ENABLED||"")==="1"}function ku({configDir:e=Bt,environment:t=ze}={}){let n=String(t.ORACLE_MESSAGING_PLATFORM||"").trim().toLowerCase();if(n)return n;try{let r=JSON.parse(Vn(it(e,"messaging.json"),"utf8"));return String(r?.platform||"").trim().toLowerCase()}catch{return""}}function vu(e,t=Bt){let n=String(e?.platform||""),r=String(e?.recipientId||"");if(!n||!r)throw new TypeError("recipient-bound held NFT subscription is required");let o=bu("sha256").update(`${n}\0${r}`).digest("hex").slice(0,24);return it(t,`held-nft-pump.${o}.v1.json`)}function Au({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 Hn(e){return e?Array.isArray(e)?e.filter(Boolean):[e]:[]}var Iu=Object.freeze({telegram:"grammy",discord:"discord.js",whatsapp:"whatsapp-web.js"});async function Ut(e,t,n,r){try{r.push(await t(n))}catch(o){let i=Iu[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
51
  npm install -g ${i}
51
52
  `);return}process.stderr.write(`oracle-gateway: ${e} failed to start: ${o.message}
52
- `)}}async function zc(){let e=Bc(),t=[],r=wr(e.platforms?.telegram),n=wr(e.platforms?.discord),o=wr(e.agents),s=r.length+n.length+o.length>1?new(await Promise.resolve().then(()=>(yn(),hn))).A2ABus:null;if(s&&o.length){let{routePeerConsult:c,buildPersona:h}=await Promise.resolve().then(()=>(Ne(),So));for(let p of o)try{let f=h(p);s.register(p.name,{role:p.role||"",chains:p.chains||[],handler:w=>c({from:w.from,text:w.text,persona:f,backend:p.backend,profile:p.hermesProfile})}),process.stderr.write(`oracle-gateway: headless agent '${p.name}' on bus (backend: ${p.backend||"oracle"})
53
- `)}catch(f){process.stderr.write(`oracle-gateway: headless agent '${p.name||"?"}' skipped: ${f.message}
54
- `)}}for(let c of r)await St("telegram",async()=>(await Promise.resolve().then(()=>(Po(),$o))).telegram({...c,bus:s}),e,t);for(let c of n)await St("discord",async()=>(await Promise.resolve().then(()=>(Lo(),Ro))).discord({...c,bus:s}),e,t);e.platforms?.whatsapp&&await St("whatsapp",async c=>(await Promise.resolve().then(()=>(Mo(),Fo))).whatsapp(c.platforms.whatsapp),e,t),e.platforms?.signal&&await St("signal",async c=>(await Promise.resolve().then(()=>(Do(),Bo))).signal_(c.platforms.signal),e,t),t.length===0&&process.stderr.write(`oracle-gateway: no platforms configured. Run 'oracle setup telegram' first.
53
+ `)}}async function _u(){let e=xu(),t=[],n=Hn(e.platforms?.telegram),r=Hn(e.platforms?.discord),o=Hn(e.agents),s=n.length+r.length+o.length>1?new(await Promise.resolve().then(()=>(Vr(),zr))).A2ABus:null;if(s&&o.length){let{routePeerConsult:c,buildPersona:f}=await Promise.resolve().then(()=>(je(),Ci));for(let m of o)try{let p=f(m);s.register(m.name,{role:m.role||"",chains:m.chains||[],handler:y=>c({from:y.from,text:y.text,persona:p,backend:m.backend,profile:m.hermesProfile})}),process.stderr.write(`oracle-gateway: headless agent '${m.name}' on bus (backend: ${m.backend||"oracle"})
54
+ `)}catch(p){process.stderr.write(`oracle-gateway: headless agent '${m.name||"?"}' skipped: ${p.message}
55
+ `)}}for(let c of n)await Ut("telegram",async()=>(await Promise.resolve().then(()=>(qi(),Di))).telegram({...c,bus:s}),e,t);for(let c of r)await Ut("discord",async()=>(await Promise.resolve().then(()=>(Hi(),ji))).discord({...c,bus:s}),e,t);e.platforms?.whatsapp&&await Ut("whatsapp",async c=>(await Promise.resolve().then(()=>(Ki(),Vi))).whatsapp(c.platforms.whatsapp),e,t),e.platforms?.signal&&await Ut("signal",async c=>(await Promise.resolve().then(()=>(Gi(),Wi))).signal_(c.platforms.signal),e,t),t.length===0&&process.stderr.write(`oracle-gateway: no platforms configured. Run 'oracle setup telegram' first.
55
56
  `),process.stderr.write(`oracle-gateway: ${t.length} platform(s) connected
56
- `);let a=null;if(Dc(e,Pe)){let c=pn(t,qc());if(c){let h=dn({env:Pe,filePath:jc(c),notifyFn:fn(c)});a=mn({watchdog:h}),a.start(),process.stderr.write(`oracle-gateway: held NFT pump watch active via ${c.platform}
57
+ `);let a=null;if(Eu(e,ze)){let c=qr(t,ku());if(c){let f=Dr({env:ze,filePath:vu(c),notifyFn:jr(c)});a=Hr({watchdog:f}),a.start(),process.stderr.write(`oracle-gateway: held NFT pump watch active via ${c.platform}
57
58
  `)}else process.stderr.write(`oracle-gateway: held NFT pump disabled \u2014 selected messenger must have exactly one owner
58
- `)}let l=s?Yc():null,u=$c((c,h)=>Gc(c,h,{config:e,bus:s,a2aToken:l}));u.listen(Pe.ORACLE_GATEWAY_PORT||9270,"127.0.0.1");let d=Hc({heldNftPumpLoop:a,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 Wc=16384;async function Gc(e,t,{config:r,bus:n,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(r.platforms||{}),a2a:!!n});if(!i.pathname.startsWith("/a2a"))return s(404,{error:"not found"});if(!n)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 a=String(e.headers.authorization||"");if(!o||a!==`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:n.roster()});if(e.method==="POST"&&i.pathname==="/a2a/ask"){let l="";e.on("data",u=>{l+=u,l.length>Wc&&e.destroy()}),e.on("end",async()=>{try{let u=JSON.parse(l||"{}"),d=Kc(u.from);n.agents.has(d)||n.register(d,{role:"loopback client",handler:async()=>null});let c=await n.send({from:d,to:u.to,text:u.text,kind:"consult"});return s(c.ok?200:400,c)}catch(u){return s(400,{ok:!1,error:`bad request: ${u.message}`})}});return}return s(404,{error:"not found"})}function Kc(e){return String(e||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function Yc(e=Et){let t=Ke(e,"a2a-token");try{let n=Sr(t,"utf8").trim();if(n)return n}catch{}let r=Mc(24).toString("hex");return Lc(e,{recursive:!0}),Uc(t,`${r}
60
- `,{mode:384}),r}var{pathToFileURL:Jc}=await import("node:url"),{realpathSync:Xc}=await import("node:fs"),jo=process.argv[1],br=!1;if(jo)try{br=import.meta.url===Jc(Xc(jo)).href}catch{br=!1}br&&zc().catch(e=>{process.stderr.write(`oracle-gateway: ${e.message}
61
- `),process.exit(1)});export{Hc as createGatewayShutdown,Yc as ensureA2AToken,Dc as heldNftPumpEnabled,jc as heldNftSubscriptionStatePath,qc as preferredMessagingPlatform,Gc as serveHttp,wr as toEntries};
59
+ `)}let l=s?Tu():null,u=mu((c,f)=>Ou(c,f,{config:e,bus:s,a2aToken:l}));u.listen(ze.ORACLE_GATEWAY_PORT||9270,"127.0.0.1");let d=Au({heldNftPumpLoop:a,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)
60
+ `)}var Cu=16384;async function Ou(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 a=String(e.headers.authorization||"");if(!o||a!==`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>Cu&&e.destroy()}),e.on("end",async()=>{try{let u=JSON.parse(l||"{}"),d=Nu(u.from);r.agents.has(d)||r.register(d,{role:"loopback client",handler:async()=>null});let c=await r.send({from:d,to:u.to,text:u.text,kind:"consult"});return s(c.ok?200:400,c)}catch(u){return s(400,{ok:!1,error:`bad request: ${u.message}`})}});return}return s(404,{error:"not found"})}function Nu(e){return String(e||"local").trim().toLowerCase().replace(/[^a-z0-9_-]/g,"").slice(0,32)||"local"}function Tu(e=Bt){let t=it(e,"a2a-token");try{let r=Vn(t,"utf8").trim();if(r)return r}catch{}let n=Su(24).toString("hex");return gu(e,{recursive:!0}),wu(t,`${n}
61
+ `,{mode:384}),n}var{pathToFileURL:$u}=await import("node:url"),{realpathSync:Pu}=await import("node:fs"),Ji=process.argv[1],zn=!1;if(Ji)try{zn=import.meta.url===$u(Pu(Ji)).href}catch{zn=!1}zn&&_u().catch(e=>{process.stderr.write(`oracle-gateway: ${e.message}
62
+ `),process.exit(1)});export{Au as createGatewayShutdown,Tu as ensureA2AToken,Eu as heldNftPumpEnabled,vu as heldNftSubscriptionStatePath,ku as preferredMessagingPlatform,Ou as serveHttp,Hn as toEntries};