@oracle-agent/oracle 0.35.19 → 0.35.20

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.
@@ -4,7 +4,7 @@ var L0=Object.defineProperty;var L=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(
4
4
  `)),now:t.now,pkce:t.pkce};return r==="anthropic-oauth"?oS(n):r==="openai-codex"?iS(n):sS(n)}async function qa(e,t,r={}){let n=ft(e),o=vr[n],i=Sr(t);if(!i.refreshToken)throw new Error(`${n} OAuth credential cannot refresh; run oracle auth login`);let s=i.discovery,a,l=r.fetchFn||globalThis.fetch;if(n==="xai-oauth"){if(!s?.token_endpoint){let f=await l(o.discoveryUrl),c=await Ct(f,"xAI OAuth discovery");s={...c.authorization_endpoint?{authorization_endpoint:Er(c.authorization_endpoint)}:{},token_endpoint:Er(c.token_endpoint)}}a=Er(s.token_endpoint)}else a=o.tokenUrl;let u=await l(a,{method:"POST",headers:{"content-type":"application/x-www-form-urlencoded",accept:"application/json",...n==="anthropic-oauth"?{"user-agent":"axios/1.7.9"}:{}},body:Ti({grant_type:"refresh_token",refresh_token:i.refreshToken,client_id:o.clientId})}),d=await Ct(u,`${n} OAuth refresh`);return Ci(d,{...r,refreshToken:i.refreshToken,discovery:s})}async function Hf(e,t={}){let r=ft(e),n=t.store||De(),o=n.get(r);if(!o)throw new Error(`${r} OAuth is not logged in; run oracle auth login ${e}`);let i=Ua(t);if(o.source==="external-access-only"&&o.expiresAt&&o.expiresAt<=i+Oi)throw new Error(`${r} external OAuth access source is expired or near expiry; refresh the source authority`);if(!o.expiresAt||o.expiresAt>i+Oi)return o;let s=async()=>{let a=n.get(r);if(!a)throw new Error(`${r} OAuth is not logged in; run oracle auth login ${e}`);let l=Ua(t);if(!a.expiresAt||a.expiresAt>l+Oi)return a;let u=await qa(r,a,t);return n.set(r,u),u};return typeof n.withLock=="function"?n.withLock(s):s()}function zf(e,t={}){try{return!!(t.store||De()).get(e)?.accessToken}catch{return!1}}function Wf(e){let t=pt(e);return{kind:"standalone",provider:t.id,model:t.model,baseUrl:t.baseUrl,authType:"oauth",protocol:t.protocol}}var vr,Oi,jf,aS,kr=L(()=>{kt();vr=Object.freeze({"anthropic-oauth":{aliases:["anthropic-oauth","anthropic","claude","claude-oauth"],clientId:"9d1c250a-e61b-44d9-88ed-5944d1962f5e",authorizeUrl:"https://claude.ai/oauth/authorize",tokenUrl:"https://platform.claude.com/v1/oauth/token",redirectUri:"https://console.anthropic.com/oauth/code/callback",scope:"org:create_api_key user:profile user:inference",baseUrl:"https://api.anthropic.com/v1",model:"claude-sonnet-4-6",protocol:"anthropic-messages"},"openai-codex":{aliases:["openai-codex","openai-oauth","codex","codex-oauth"],clientId:"app_EMoamEEZ73f0CkXaXp7hrann",issuer:"https://auth.openai.com",tokenUrl:"https://auth.openai.com/oauth/token",baseUrl:"https://chatgpt.com/backend-api/codex",model:"gpt-5.6-sol",protocol:"responses"},"xai-oauth":{aliases:["xai-oauth","xai","grok","grok-oauth"],clientId:"b1a00492-073a-47ea-816f-4c329264a828",issuer:"https://auth.x.ai",discoveryUrl:"https://auth.x.ai/.well-known/openid-configuration",deviceUrl:"https://auth.x.ai/oauth2/device/code",scope:"openid profile email offline_access grok-cli:access api:access",baseUrl:"https://api.x.ai/v1",model:"grok-4.6",protocol:"responses"}}),Oi=12e4;aS={createOAuthStore:ja,getOAuthStore:De,hasOAuthCredentials:zf,loginOAuth:$i,oauthProviderConfig:pt,oauthProviderId:ft,oauthRuntimeConfig:Wf,refreshOAuthCredentials:qa,resolveOAuthCredentials:Hf}});function Li(e){return wS.get(Number(e))||null}function ep(e,t=process.env){let r=Li(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}var Ni,wS,Ri=L(()=>{Ni={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}},wS=new Map(Object.values(Ni).map(e=>[e.chainId,e]))});import Tr from"node:net";import BS from"node:dns";function Fi(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=d=>{if(!d)return[];let f=d.split(":"),c=f.at(-1);if(c?.includes(".")){let p=c.split(".").map(Number);if(p.length!==4||p.some(m=>!Number.isInteger(m)||m<0||m>255))return null;f.splice(f.length-1,1,(p[0]<<8|p[1]).toString(16),(p[2]<<8|p[3]).toString(16))}return f.some(p=>!/^[0-9a-f]{1,4}$/.test(p))?null:f.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 Xa(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 Za(e){if(Tr.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(Tr.isIPv6(e)){let t=Fi(e);if(!t)return!1;let r=Fi("::ffff:0:0");return Xa(t,r,96)?Za([...t.slice(12)].join(".")):Xa(t,Fi("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>Xa(t,Fi(o),i)):!1}return!1}function jS(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(US.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=Tr.isIP(r);return n!==0&&!Za(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function xn(e,{lookupFn:t=BS.promises.lookup}={}){let r=jS(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:Tr.isIPv6(r.host)?6:4}]};let n;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=>!Za(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function fo({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let f=await t();r=f.Agent,n=f.fetch}catch(f){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${f?.message||f}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=f=>String(f).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=f=>(Array.isArray(f)?f:[f]).map(c=>typeof c=="string"?{address:c}:c).filter(c=>c&&c.address).map(c=>({address:c.address,family:c.family||(Tr.isIPv6(c.address)?6:4)})),a=(f,c,p)=>{i.set(o(f),s(typeof c=="string"?[{address:c,family:p}]:c))},l=f=>{let c=o(f);if(Tr.isIP(c))return[{address:c,family:Tr.isIPv6(c)?6:4}];let p=i.get(c);if(!p||!p.length)throw new Error(`refused: unpinned host ${f} during pinned fetch`);return p},u=new r({connect:{lookup(f,c,p){let m;try{m=l(f)}catch(h){return p(h)}return c?.all?p(null,m):p(null,m[0].address,m[0].family)}}}),d=qS((f,c={})=>n(f,{...c,dispatcher:u}),a);return{dispatcher:u,fetch:d,pin:a,resolve:l,async close(){try{await u.destroy()}catch{}}}}function qS(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[Qa]=Object.freeze({pin:t}),e}function ec(e){return typeof e=="function"&&typeof e[Qa]?.pin=="function"}function sp(e,t,r){if(!ec(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Qa].pin(t,r)}var US,Qa,tc=L(()=>{US=new Set(["localhost","metadata.google.internal","metadata.goog"]);Qa=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as ap}from"node:crypto";function VS(e){let t=String(e||"").toLowerCase();return mp.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function GS(e){let t={};for(let[r,n]of Object.entries(e||{}))VS(r)||(t[r]=n);return t}function YS(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 JS(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function dp(e){let t=String(e?.method||"");return t?!XS.test(t):!1}function QS(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}return Array.isArray(r)?r.length>0&&r.every(dp):!r||typeof r!="object"?!1:r.jsonrpc&&r.method?dp(r):typeof r.type=="string"&&ZS.has(r.type)&&r.action==null&&r.signature==null&&r.nonce==null}function eE(e,t,r,n={},o=null){let i={};for(let[c,p]of Object.entries(r||{}))i[c.toLowerCase()]=p;let s=Object.keys(i).filter(c=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(c)),l=[...new Set([...mp,...s])].sort().map(c=>`${c}=${i[c]??""}`).join(`
5
5
  `),u=ap("sha256").update(l).digest("hex").slice(0,32),d=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`,f=o==null?"-":ap("sha256").update(String(o)).digest("hex").slice(0,32);return`${e} ${t} ${d} ${u} ${f}`}function tE(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,lp):Math.min(250*2**e,lp)+Math.floor(Math.random()*100)}function po(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function nc(e,t,r){return po(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function mo(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function nE(e){return e?e.byteLength??e.length??0:0}async function fp(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&&(mo(e),!n))throw nc(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let f=await e.text(),c=Buffer.byteLength(f,"utf8");if(c>t){if(!n)throw nc(r,`body ${c} bytes`,t);return Buffer.from(f,"utf8").subarray(0,t).toString("utf8")}return f}let a=[],l=0,u=!1;try{for(;;){let{value:f,done:c}=await s.read();if(c)break;if(f&&(a.push(Buffer.from(f)),l+=nE(f),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 nc(r,`streamed ${l} bytes`,t);let d=Buffer.concat(a);return(u?d.subarray(0,t):d).toString("utf8")}function pp(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function oE(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:l=!1,maxResponseBytes:u=null,importUndici:d,validateResponse:f,signal:c}){let p=new AbortController,m=setTimeout(()=>p.abort(),i),h=c?typeof AbortSignal.any=="function"?AbortSignal.any([c,p.signal]):c:p.signal,S=null,E=t,_=s?{lookupFn:s}:{};if(l&&!a&&!ec(E))throw po(`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 b=async(g,{status:k=null}={})=>{let A=await xn(g,_);if(!A.ok)throw po(k==null?`HTTP refused ${g}: ${A.error}`:`HTTP redirect to ${g} ${A.error}`,k==null?{}:{status:k});let O=new URL(g).hostname;if(a){if(S&&(await S.close(),S=null),!S)try{S=await fo({requireUndici:!0,...d?{importUndici:d}:{}})}catch(N){throw po(k==null?`HTTP refused ${g}: ${N?.message||N}`:`HTTP redirect to ${g} refused: ${N?.message||N}`,k==null?{}:{status:k})}S.pin(O,A.addresses),E=S.fetch}else sp(E,O,A.addresses);return A};try{let g=String(e),k={...n||{}};l&&await b(g);for(let A=0;A<=up;A+=1){let O=await E(g,{method:r,headers:k,body:o,signal:h,redirect:"manual"});if(WS.has(O.status)){if(r!=="GET"&&r!=="HEAD"){let G=await fp(O,u??KS,{url:g,truncate:!0}),Y=new Error(`HTTP ${O.status} ${r} ${g} redirected non-idempotent request`);throw Y.status=O.status,Y.body=pp(G)??G.slice(0,300),Y}if(A===up)throw mo(O),new Error(`HTTP redirect loop for ${e}`);let C=O.headers?.get?.("location"),M;try{M=YS(C,g)}catch(G){throw mo(O),G}let z=!JS(M,g);if(mo(O),z&&(k=GS(k)),l)await b(M,{status:O.status});else if(z){let G=await xn(M,_);if(!G.ok){let Y=new Error(`HTTP redirect from ${g} ${G.error}`);throw Y.status=O.status,Y.retryable=!1,Y}a&&G.addresses?.length&&(S||(S=await fo(d?{importUndici:d}:{})),S&&(S.pin(new URL(M).hostname,G.addresses),E=S.fetch))}g=M;continue}if(typeof f=="function")try{await f(O,{url:g})}catch(C){throw mo(O),po(C?.message||String(C))}let N=await fp(O,u,{url:g,onOversize:()=>p.abort()}),w=pp(N);if(!O.ok){let C=new Error(`HTTP ${O.status} ${r} ${g}`);throw C.status=O.status,C.retryAfter=O.headers?.get?.("retry-after")??null,C.body=w??N.slice(0,300),C}return w??N}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(m),S&&await S.close()}}async function Ce(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,o=(t.method||"GET").toUpperCase(),i={Accept:"application/json",...t.headers||{}},s=t.body;s!=null&&typeof s!="string"&&(i["Content-Type"]=i["Content-Type"]||"application/json",s=JSON.stringify(s));let a=Number.isInteger(t.retries)?Math.max(t.retries,0):zS,l=t.lookupFn,u=!t.fetchImpl,d=t.untrustedUrl===!0,f=t.importUndici,c=t.validateResponse,p=t.signal,m=Number(t.maxResponseBytes),h=Number.isFinite(m)&&m>0?Math.floor(m):null,S=async()=>{let k;for(let A=0;A<=a;A++){p?.throwIfAborted?.();try{return await oE(e,{fetchImpl:r,method:o,headers:i,body:s,timeoutMs:n,lookupFn:l,realFetch:u,untrustedUrl:d,maxResponseBytes:h,importUndici:f,validateResponse:c,signal:p})}catch(O){k=O;let N=O?.status,w=O?.name==="AbortError"||O?.name==="TimeoutError"||p?.aborted,C=new Set([408,425,429]),M=O?.retryable===!1?!1:N!=null?C.has(N)||HS.has(N)&&cp.has(o):!w&&cp.has(o);if(A===a||!M)throw O;let z=tE(A,O?.retryAfter);p?await new Promise((G,Y)=>{let ae=setTimeout(G,z);p.addEventListener("abort",()=>{clearTimeout(ae),Y(p.reason||new DOMException("Aborted","AbortError"))},{once:!0})}):await rE(z)}}throw k};if(!(t.dedupe!==!1&&!p&&QS(o,s)))return S();let _=eE(o,e,i,{untrustedUrl:d,maxResponseBytes:h},s),b=rc.get(_);if(b)return b;let g=S().finally(()=>rc.delete(_));return rc.set(_,g),g}async function $e(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 Sn(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 HS,cp,zS,lp,mp,WS,up,KS,rc,XS,ZS,rE,Be=L(()=>{tc();HS=new Set([408,425,429,500,502,503,504]),cp=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),zS=2,lp=4e3,mp=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],WS=new Set([301,302,303,307,308]),up=3,KS=64*1024;rc=new Map,XS=/(?:^|_)(send|submit|broadcast|sign|requestAirdrop)(?=[A-Z_]|$)/i,ZS=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);rE=e=>new Promise(t=>setTimeout(t,e))});import{Interface as iE,getAddress as sE}from"ethers";function oc(e,t){try{return sE(e).toLowerCase()}catch{throw new Error(`${t} must be a valid EVM address`)}}function aE(e){let t=String(e||"").trim();if(!/^0x[0-9a-fA-F]{64}$/.test(t))throw new Error("txHash must be a 32-byte hex transaction hash");return t.toLowerCase()}function ic(e){return e==null?null:Number.parseInt(String(e),16)}function lE(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=ep(e,r);return n||cE[Number(e)]||null}function dE(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!uE.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}function fE(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function pE(e){if(e?.error)throw fE(e.error);return e?.result}function mE(e,t,r){return`${e}
6
6
  ${t}
7
- ${JSON.stringify(r??[])}`}async function hE(e,t,r){return Ce(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function Cr(e,t,r=[],n={}){let o=String(t||""),i=dE(o),s=lE(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);if(i==="eth_chainid"&&n.cacheChainId!==!1){let d=hp.get(s);if(d!=null)return d}let l=n.dedupe!==!1&&!n.signal?mE(s,o,r):null;if(l&&ho.has(l))return ho.get(l);let u=(async()=>{let d=await hE(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),f=pE(d);return i==="eth_chainid"&&typeof f=="string"&&hp.set(s,f),f})();return l&&(ho.set(l,u),u.finally(()=>{ho.get(l)===u&&ho.delete(l)}).catch(()=>{})),u}async function sc(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await Cr(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function gp(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=aE(e.txHash||e.hash||e.transactionHash),o=await Cr(r,"eth_getTransactionReceipt",[n],t);if(!o)return{ok:!1,chainId:r,txHash:n,status:"pending",receipt:null,reason:"receipt pending"};let i=ic(o.status),s=i===1,a=i===1?"success":i===0?"reverted":"unknown",l=s?null:a==="reverted"?"transaction reverted":"unknown receipt status",u=e.expectedTo?oc(e.expectedTo,"expectedTo"):null,d=o.to?oc(o.to,"receipt.to"):null;return u&&d!==u&&(s=!1,l=`to mismatch: expected ${u}, got ${d||"null"}`),{ok:s,chainId:r,txHash:n,status:a,reason:l,statusCode:i,to:d,from:o.from?oc(o.from,"receipt.from"):null,blockNumber:ic(o.blockNumber),transactionIndex:ic(o.transactionIndex),logs:Array.isArray(o.logs)?o.logs:[],receipt:o}}var DL,cE,uE,ho,hp,En=L(()=>{Be();Ri();DL=new iE(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);cE={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};uE=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;ho=new Map,hp=new Map});var ac=L(()=>{});var HL,wp=L(()=>{Be();ac();HL=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"})});var WL,cc,lc,go=L(()=>{WL=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),cc=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),lc=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"})});var yp=L(()=>{En();go()});var bp=L(()=>{En();go()});var xp=L(()=>{En();wp();Be();go();yp();bp();ac()});var Sp,Ep=L(()=>{xp();go();Sp=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}}]}])});function yE(e={}){return String(e.rpcUrl||process.env.SOLANA_RPC_URL||wE).trim()}function $r(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}function bE(e,t){return t?[...e,{commitment:t}]:e}async function kp(e,t=[],r={}){let n=String(e||"");if(n==="sendTransaction"||n==="sendRawTransaction"||n==="requestAirdrop"||n==="requestAirDrop"||/airdrop/i.test(n)||/^send/i.test(n))throw new Error(`solana-rpc: ${n} refused \u2014 @oracle-agent/oracle is prepare-only (no broadcast/airdrop)`);let o=await Ce(yE(r),{method:"POST",body:{jsonrpc:"2.0",id:r.id||1,method:e,params:t},fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3});if(o?.error)throw new Error(`solana-rpc ${e}: ${o.error.message||JSON.stringify(o.error)}`);return o?.result}async function Ap(e={},t={}){let r=$r(e.address||e.owner,"address"),n=await kp("getBalance",bE([r],e.commitment),t);return{provider:"solana-rpc",cluster:vp,address:r,lamports:String(n?.value??0),slot:n?.context?.slot??null,raw:n}}function xE(e={}){let t=e.account?.data?.parsed?.info||{},r=t.tokenAmount||{};return{pubkey:e.pubkey,mint:t.mint||null,owner:t.owner||null,amount:String(r.amount??"0"),decimals:r.decimals??null,uiAmount:r.uiAmount??null,uiAmountString:r.uiAmountString??null,raw:e}}async function dc(e={},t={}){let r=$r(e.owner||e.address,"owner"),n=e.mint?{mint:$r(e.mint,"mint")}:{programId:$r(e.programId||uc,"token program")},o={encoding:"jsonParsed"};e.commitment&&(o.commitment=e.commitment);let i=await kp("getTokenAccountsByOwner",[r,n,o],t),s=Array.isArray(i?.value)?i.value.map(xE):[];return{provider:"solana-rpc",cluster:vp,owner:r,filter:n,slot:i?.context?.slot??null,accounts:s,raw:i}}var vp,wE,uc,fc=L(()=>{Be();vp="mainnet-beta",wE="https://api.mainnet-beta.solana.com",uc="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"});function _p(e={}){return String(e.network||process.env.BTC_NETWORK||SE).trim().toLowerCase()==="testnet"?"testnet":"mainnet"}function kE(e={}){return e.baseUrl?String(e.baseUrl).replace(/\/$/,""):process.env.BTC_ESPLORA_URL?String(process.env.BTC_ESPLORA_URL).replace(/\/$/,""):_p(e)==="testnet"?vE:EE}function Qt(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}async function AE(e,t={}){let r=`${kE(t)}${e.startsWith("/")?e:`/${e}`}`,o=await(t.fetchImpl||fetch)(r,{method:"GET",headers:{accept:"application/json,text/plain;q=0.9,*/*;q=0.8"},signal:AbortSignal.timeout(t.timeoutMs??12e3)}),i=await o.text();if(!o.ok)throw new Error(`bitcoin-esplora GET ${e}: HTTP ${o.status} ${i.slice(0,160)}`);return i}async function _E(e,t={}){let r=await AE(e,t);try{return JSON.parse(r)}catch{return r}}async function Ip(e={},t={}){let r=Qt(e.address||e.addr,"address"),n=await _E(`/address/${r}`,t),o=n.chain_stats||{},i=n.mempool_stats||{},s=Number(o.funded_txo_sum||0)+Number(i.funded_txo_sum||0),a=Number(o.spent_txo_sum||0)+Number(i.spent_txo_sum||0);return{provider:"bitcoin-esplora",network:_p(t),address:r,balanceSats:String(s-a),chainStats:o,mempoolStats:i,raw:n}}var SE,EE,vE,Di=L(()=>{Be();SE="mainnet",EE="https://mempool.space/api",vE="https://mempool.space/testnet/api"});function vn({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:Tp(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([Tp(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[Op]||"")==="1")return{baseUrl:s,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${Op}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:l}}function Tp(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function Nr(e,t,r){let n={...e};if(!r)return n;for(let[o,i]of Object.entries(t||{}))i&&(n[o]=i);return n}var Op,wo=L(()=>{Op="ORACLE_ALLOW_CUSTOM_PROVIDER_URL"});function pc(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}function OE(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=pc(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=IE.includes(o)&&(i==="https:"||s)}}catch{r=!1}return Nr({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},r)}async function Cp(e,t={}){let n=await(t.fetchImpl||fetch)(e,{method:"GET",headers:OE(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 $p(e={},t={}){let r=Qt(e.address||e.addr,"address"),n=pc(t);if(!n)return{provider:"bitcoin-meta",address:r,ok:!1,balances:[],error:"no indexer configured (set BTC_META_API_URL or vendor API key env)"};let o=[`${n}/v1/indexer/address/${r}/runes/balance-list?start=0&limit=100`,`${n}/v1/runes/address/${r}`,`${n}/runes/balance/${r}`,`${n}/address/${r}/runes`],i=null;for(let s of o)try{let a=await Cp(s,t),l=TE(a);return{provider:"bitcoin-meta",address:r,ok:!0,count:l.length,balances:l,source:s}}catch(a){i=a}return{provider:"bitcoin-meta",address:r,ok:!1,balances:[],error:String(i?.message||i||"all indexer paths failed")}}function TE(e){let t=e?.data?.detail||e?.data?.list||e?.data||e?.balances||e?.results||e?.runes||(Array.isArray(e)?e:[]);return(Array.isArray(t)?t:[]).map(n=>({rune:n.rune||n.runeid||n.runeId||n.spacedRune||n.name||n.ticker||null,runeId:n.runeid||n.runeId||n.id||null,amount:String(n.amount??n.balance??n.total??n.qty??"0"),symbol:n.symbol||null,divisibility:n.divisibility??n.div??null,raw:n}))}async function Bi(e={},t={}){let r=Qt(e.address||e.addr,"address"),n=pc(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 Cp(a,t),u=CE(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 CE(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}))}var IE,mc=L(()=>{Di();wo();IE=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"]});function LE({testnet:e,baseUrl:t}={}){if(t)return t.replace(/\/$/,"").endsWith("/info")?t:`${t.replace(/\/$/,"")}/info`;if(process.env.HL_INFO_URL)return process.env.HL_INFO_URL;if(process.env.HL_API_URL){let r=process.env.HL_API_URL.replace(/\/$/,"");return r.endsWith("/info")?r:`${r}/info`}return e||process.env.HL_TESTNET==="1"?NE:$E}async function Ui(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=LE(t);return Ce(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Np(e={}){return Ui({type:"allMids"},e)}async function Lp(e,t={}){if(!e)throw new Error("hlClearinghouse requires user address");return Ui({type:"spotClearinghouseState",user:e},t)}async function Rp(e,t={}){if(!e)throw new Error("hlUserState requires user");return Ui({type:"clearinghouseState",user:e},t)}var $E,NE,hc=L(()=>{Be();$E="https://api.hyperliquid.xyz/info",NE="https://api.hyperliquid-testnet.xyz/info"});function PE(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||RE).replace(/\/$/,"")}async function gc(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return Ce(`${PE(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}var RE,Pp=L(()=>{Be();RE="https://coins.llama.fi"});function wc(e,{max:t=32,fallback:r=""}={}){return e==null?r:String(e).normalize("NFKC").replace(Mp,"").replace(FE,"").replace(ME,"").replace(/\s+/g," ").trim().slice(0,t).trim()||r}function yc(e){if(e==null)return!1;let t=String(e);return Mp.test(t)?!0:/[\u0400-\u04FF\u0370-\u03FF]/.test(t)&&/[A-Za-z]/.test(t)}var Mp,ME,FE,Fp=L(()=>{Mp=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,ME=/[<>&`*_~[\]()|\\]/g,FE=/[\u0000-\u001F\u007F]/g});function DE(e,t={}){let r=Number(e),n=t.baseUrl||Dp[r];if(!n)throw new Error(`Blockscout not configured for chainId ${r}`);return n.replace(/\/$/,"")}function Bp(e){return!!Dp[Number(e)]}async function Up(e={},t={}){if(!e.address)throw new Error("address required");let r=Number(e.chainId||1),n=`${DE(r,t)}/api/v2/addresses/${encodeURIComponent(e.address)}/token-balances`,o=await Ce(n,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??18e3,headers:{accept:"application/json","user-agent":"OraclePortfolio/1.0"}});return Array.isArray(o)?o:[]}function jp(e=[],{fungibleOnly:t=!0}={}){let r=[];for(let n of e){if(!n||typeof n!="object")continue;let o=n.token&&typeof n.token=="object"?n.token:{},i=String(o.type||n.token_type||"").toUpperCase();if(t&&i&&!i.includes("ERC-20")&&i!=="ERC20")continue;let s=o.address_hash||o.address||n.token_address||n.tokenAddress||null;if(!s||typeof s!="string")continue;let a=String(n.value??n.balance??"0").replace(/^0x/i,"");if(!/^\d+$/.test(a)||a==="0")continue;let l=o.decimals??n.decimals;typeof l=="string"&&/^\d+$/.test(l)&&(l=Number(l)),(typeof l!="number"||!Number.isInteger(l)||l<0||l>36)&&(l=18);let u=wc(o.symbol||o.name,{max:32,fallback:"TOKEN"}),d=wc(o.name,{max:80,fallback:""})||null;r.push({address:s.toLowerCase().startsWith("0x")?s:`0x${s}`,symbol:u,name:d,decimals:l,amountRaw:a,tokenType:i||"ERC-20",source:"blockscout",verification:"indexer-reported",displaySuspicious:yc(o.symbol)||yc(o.name)||void 0})}return r}var Dp,qp=L(()=>{Be();Fp();Dp=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{getAddress as BE}from"ethers";function er(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,...e[t]||{}}}function ji(e,...t){for(let r of t){let n=String(e?.[r]||"").trim();if(n)return n}return null}function Hp(e){if(!e)return null;try{return BE(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function An(e={},t=process.env){let r=e.addresses||{},n=Hp(r.evm||e.evmAddress||ji(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=r.solana||e.solanaAddress||ji(t,"ORACLE_SOLANA_ADDRESS"),i=r.bitcoin||e.bitcoinAddress||ji(t,"ORACLE_BITCOIN_ADDRESS"),s=Hp(r.hyperliquid||e.hyperliquidAddress||ji(t,"ORACLE_HYPERLIQUID_ADDRESS")||n);return{evm:n,solana:o?$r(o,"portfolio Solana address"):null,bitcoin:i?Qt(i,"portfolio Bitcoin address"):null,hyperliquid:s}}function yo(e,t){let r=BigInt(String(e||"0")),n=Number(t);if(!Number.isInteger(n)||n<0||n>36)throw new Error("portfolio: decimals must be an integer from 0 to 36");if(n===0)return r.toString();let o=r<0n,i=o?-r:r,s=10n**BigInt(n),a=i/s,l=String(i%s).padStart(n,"0").replace(/0+$/,"");return`${o?"-":""}${a}${l?`.${l}`:""}`}function kn(e){let t=Number(e);return Number.isFinite(t)?t:null}function qi(e){return Number.isFinite(e)?Number(e.toFixed(2)):null}function tr(e){let t=Number(e);return Number.isFinite(t)&&t!==0}function Wp(e,t){let r=zp[t],n=r?e?.coins?.[r]:null,o=Number(n?.price);return{key:r||null,priceUsd:Number.isFinite(o)?o:null,timestamp:n?.timestamp??null,confidence:n?.confidence??null}}function jE(e){let t=new Map;for(let r of e)if(r?.ok)for(let n of r.data?.accounts||[]){let o=BigInt(String(n.amount||"0"));if(o===0n||!n.mint)continue;let i=`${n.mint}:${n.decimals??"unknown"}`,s=t.get(i)||{mint:n.mint,amountRaw:0n,decimals:n.decimals??null,programs:new Set,accounts:0};s.amountRaw+=o,s.accounts+=1,r.program&&s.programs.add(r.program),t.set(i,s)}return[...t.values()].map(r=>{let n=r.amountRaw.toString(),o=r.decimals==null?null:yo(n,r.decimals),i=r.decimals===0&&r.amountRaw===1n;return{mint:r.mint,amountRaw:n,amount:o,decimals:r.decimals,tokenPrograms:[...r.programs],accountCount:r.accounts,verification:"unverified",classification:i?"collectible-candidate":"fungible-or-unclassified",priceUsd:null,usdValue:null}})}function bc(e,t){return{family:e,status:"unsupported",reason:t}}function xc(e,t){if(!e||e.status!=="ok")return e;let r=Wp(t,e.symbol),n=kn(e.amount),o=n!=null&&r.priceUsd!=null?qi(n*r.priceUsd):null;return{...e,price:r,usdValue:o}}async function Kp(e={},t={}){let r=new Date().toISOString(),n=An(e,t.env||process.env),o=e.includePrices!==!1,i=e.includeTokens!==!1,s=e.includeCollectibles!==!1,a=new Map(Sp.map(B=>[B.chainId,B])),l=Array.isArray(e.evmChainIds)&&e.evmChainIds.length?[...new Set(e.evmChainIds.map(Number))]:[...a.keys()],u=[...new Set(Object.values(zp))],d=o?$e(()=>gc(u,er(t,"prices"))):Promise.resolve({ok:!1,ms:0,error:"price lookup disabled"}),f=Sn(l,e.concurrency||5,async B=>{let H=a.get(B);if(!H)return{family:"evm",chainId:B,name:null,address:n.evm,status:"unsupported",error:"chainId is not in Oracle's configured EVM registry"};if(!n.evm)return{family:"evm",chainId:B,name:H.name,address:null,status:"not-configured",error:"set ORACLE_EVM_ADDRESS or pass addresses.evm"};let Z={...er(t,"evm"),rpcUrl:e.rpcUrls?.[B]||t.evm?.rpcUrls?.[B]},fe=await $e(()=>sc(B,n.evm,Z));if(!fe.ok)return{family:"evm",chainId:B,name:H.name,address:n.evm,status:"unavailable",latencyMs:fe.ms,error:fe.error};let we=H.nativeCurrency?.decimals??18,j=H.nativeCurrency?.symbol||"NATIVE",F=fe.data.balanceWei,q={status:i?"unavailable":"not-requested",assets:[],reason:i?"EVM JSON-RPC cannot enumerate wallet tokens without an address indexer":"token discovery disabled"};if(i&&Bp(B)){let X=await $e(()=>Up({chainId:B,address:n.evm},{...er(t,"blockscout"),timeoutMs:t.timeoutMs??18e3}));X.ok?q={status:"ok",assets:jp(X.data,{fungibleOnly:!0}).map(ce=>{let Se=yo(ce.amountRaw,ce.decimals);return{...ce,amount:Se,priceUsd:null,usdValue:null}}),reason:null,source:"blockscout",latencyMs:X.ms}:q={status:"unavailable",assets:[],reason:X.error||"blockscout token-balances failed",source:"blockscout",latencyMs:X.ms}}return{family:"evm",chainId:B,name:H.name,address:n.evm,status:"ok",latencyMs:fe.ms,native:{status:"ok",symbol:j,amountRaw:F,decimals:we,amount:yo(F,we)},fungibleTokens:q,collectibles:{status:s?"unavailable":"not-requested",assets:[],reason:s?"EVM JSON-RPC cannot enumerate wallet NFTs without an address indexer":"collectible discovery disabled"},source:q.source==="blockscout"?"evm-rpc+blockscout":"evm-rpc"}}),c=(async()=>{if(!n.solana)return{family:"solana",name:"Solana Mainnet",address:null,status:"not-configured",error:"set ORACLE_SOLANA_ADDRESS or pass addresses.solana"};let B=er(t,"solana"),H=await $e(()=>Ap({address:n.solana},B)),Z=i||s?await Promise.all([$e(()=>dc({owner:n.solana,programId:uc},B)).then(q=>({...q,program:"spl-token"})),$e(()=>dc({owner:n.solana,programId:UE},B)).then(q=>({...q,program:"token-2022"}))]):[],fe=jE(Z),we=fe.filter(q=>q.classification==="collectible-candidate"),j=fe.filter(q=>q.classification!=="collectible-candidate"),F=Z.filter(q=>!q.ok).map(q=>q.error);return{family:"solana",name:"Solana Mainnet",address:n.solana,status:H.ok||Z.some(q=>q.ok)?"ok":"unavailable",native:H.ok?{status:"ok",symbol:"SOL",amountRaw:H.data.lamports,decimals:9,amount:yo(H.data.lamports,9),slot:H.data.slot}:{status:"unavailable",symbol:"SOL",error:H.error},fungibleTokens:{status:i?F.length===Z.length?"unavailable":F.length?"partial":"ok":"not-requested",assets:i?j:[],errors:F,note:"SPL accounts are unverified until a metadata/indexer source confirms symbol and spam status"},collectibles:{status:s?F.length===Z.length?"unavailable":"partial":"not-requested",assets:s?we:[],errors:F,note:"decimals=0 and amount=1 is only a collectible candidate, not verified NFT metadata"},source:"solana-rpc"}})(),p=(async()=>{if(!n.bitcoin)return{family:"bitcoin",name:"Bitcoin Mainnet",address:null,status:"not-configured",error:"set ORACLE_BITCOIN_ADDRESS or pass addresses.bitcoin"};let B=er(t,"bitcoin"),H=er(t,"bitcoinMeta"),[Z,fe,we]=await Promise.all([$e(()=>Ip({address:n.bitcoin},B)),i?$e(()=>$p({address:n.bitcoin},H)):Promise.resolve({ok:!1,ms:0,error:"token discovery disabled"}),s?$e(()=>Bi({address:n.bitcoin},H)):Promise.resolve({ok:!1,ms:0,error:"collectible discovery disabled"})]),j=fe.ok?fe.data:null,F=we.ok?we.data:null;return{family:"bitcoin",name:"Bitcoin Mainnet",address:n.bitcoin,status:Z.ok||j?.ok||F?.ok?"ok":"unavailable",native:Z.ok?{status:"ok",symbol:"BTC",amountRaw:Z.data.balanceSats,decimals:8,amount:yo(Z.data.balanceSats,8)}:{status:"unavailable",symbol:"BTC",error:Z.error},fungibleTokens:{status:i?j?.ok?"ok":"unavailable":"not-requested",assets:j?.balances||[],error:j?.ok?null:j?.error||fe.error,verification:"indexer-reported"},collectibles:{status:s?F?.ok?"ok":"unavailable":"not-requested",assets:F?.inscriptions||[],error:F?.ok?null:F?.error||we.error,unknownNotEmpty:!!F?.unknownNotEmpty,verification:"indexer-reported"},source:"bitcoin-esplora+bitcoin-meta"}})(),m=(async()=>{if(!n.hyperliquid)return{family:"hyperliquid",name:"Hyperliquid HyperCore",address:null,status:"not-configured",error:"set ORACLE_HYPERLIQUID_ADDRESS or pass addresses.hyperliquid"};let B=er(t,"hyperliquid"),[H,Z,fe]=await Promise.all([$e(()=>Lp(n.hyperliquid,B)),$e(()=>Rp(n.hyperliquid,B)),$e(()=>Np(B))]),we=(H.ok&&Array.isArray(H.data?.balances)?H.data.balances:[]).filter(F=>tr(F.total)||tr(F.hold)).map(F=>({coin:F.coin||null,total:String(F.total??"0"),hold:String(F.hold??"0"),priceUsd:null,usdValue:null})),j=(Z.ok&&Array.isArray(Z.data?.assetPositions)?Z.data.assetPositions:[]).map(F=>F.position||F).filter(F=>tr(F.szi)).map(F=>({coin:F.coin||null,size:String(F.szi??"0"),entryPrice:F.entryPx??null,positionValueUsd:F.positionValue??null,unrealizedPnlUsd:F.unrealizedPnl??null,liquidationPrice:F.liquidationPx??null}));return{family:"hyperliquid",name:"Hyperliquid HyperCore",address:n.hyperliquid,status:H.ok||Z.ok?"ok":"unavailable",spot:{status:H.ok?"ok":"unavailable",balances:we,error:H.ok?null:H.error},perps:{status:Z.ok?"ok":"unavailable",accountValueUsd:Z.data?.marginSummary?.accountValue??null,withdrawableUsd:Z.data?.withdrawable??null,positions:j,error:Z.ok?null:Z.error},mids:fe.ok?fe.data:{},source:"hyperliquid-info"}})(),[h,S,E,_,b]=await Promise.all([f,c,p,m,d]),g=b.ok?b.data:null,k=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax",81457:"blast",534352:"scroll",59144:"linea",324:"era"}),A=[];for(let B of h){if(B.family!=="evm"||B.fungibleTokens?.status!=="ok")continue;let H=k[B.chainId];if(H)for(let Z of B.fungibleTokens.assets||[])Z.address&&A.push(`${H}:${String(Z.address).toLowerCase()}`)}let O=null;if(o&&A.length){let B=[...new Set(A)],H=await $e(()=>gc(B,er(t,"prices")));H.ok&&(O=H.data)}let N=h.map(B=>{let H=B.native?{...B,native:xc(B.native,g)}:B;if(H.fungibleTokens?.status==="ok"&&Array.isArray(H.fungibleTokens.assets)){let Z=k[H.chainId],fe=H.fungibleTokens.assets.map(we=>{let j=String(we.symbol||"").toUpperCase(),F=null;if(["USDC","USDT","USDT0","DAI","USDBC","USDE","USDCE"].includes(j)&&(F=1),F==null&&Z&&we.address&&O?.coins){let te=`${Z}:${String(we.address).toLowerCase()}`,ce=O.coins[te],Se=Number(ce?.price);Number.isFinite(Se)&&Se>0&&(F=Se)}let q=kn(we.amount),X=q!=null&&F!=null?qi(q*F):null;return{...we,priceUsd:F,usdValue:X}});H={...H,fungibleTokens:{...H.fungibleTokens,assets:fe}}}return H});S.native&&(S.native=xc(S.native,g)),E.native&&(E.native=xc(E.native,g));let w=0,C=0,M=0;for(let B of[...N,S,E]){B.native?.status==="ok"&&tr(B.native.amount)&&(B.native.usdValue!=null?(w+=B.native.usdValue,C+=1):M+=1);for(let H of B.fungibleTokens?.assets||[])!tr(H.amount)&&!tr(H.amountRaw)||(H.usdValue!=null?(w+=H.usdValue,C+=1):M+=1)}let z=Wp(g,"HYPE");for(let B of _.spot?.balances||[]){let H=String(B.coin||"").toUpperCase(),Z=H==="USDC"||H==="USDT"||H==="USDT0"?1:H==="HYPE"?z.priceUsd||kn(_.mids?.HYPE):kn(_.mids?.[B.coin]),fe=kn(B.total);B.priceUsd=Z,B.usdValue=fe!=null&&Z!=null?qi(fe*Z):null,tr(B.total)&&(B.usdValue!=null?(w+=B.usdValue,C+=1):M+=1)}let G=kn(_.perps?.accountValueUsd);G!=null&&G!==0&&(w+=G,C+=1);let Y=[...S.fungibleTokens?.assets||[],...S.collectibles?.assets||[]].filter(B=>tr(B.amount)).length,ae=(E.fungibleTokens?.assets||[]).length+(E.collectibles?.assets||[]).length;M+=Y+ae;let ge=[...N,S,E,_],xe=B=>ge.filter(H=>H.status===B).length,W=[],U=N.filter(B=>B.fungibleTokens?.status==="unavailable"),K=N.filter(B=>B.fungibleTokens?.status==="ok");U.length&&!K.length?W.push("EVM token discovery is unavailable without a working address indexer; native balances are still live."):U.length&&W.push(`EVM token discovery partial: Blockscout covered ${K.length} chain(s); ${U.length} chain(s) still native-only.`),(S.fungibleTokens?.assets?.length||S.collectibles?.assets?.length)&&W.push("Solana token accounts are unverified and may include spam; collectible candidates are not confirmed NFTs."),E.collectibles?.unknownNotEmpty&&W.push("Bitcoin inscription holdings are unknown, not zero, because no address indexer is configured."),b.ok||W.push(`Price provider unavailable: ${b.error}`);let ee=[bc("cosmos","requires a chain-specific bech32 address and LCD/RPC adapter"),bc("sui","Sui balance adapter is not installed"),bc("aptos","Aptos balance adapter is not installed")],Je=ge.some(B=>["unavailable","partial","not-configured"].includes(B.fungibleTokens?.status)||["unavailable","partial","not-configured"].includes(B.collectibles?.status));return{provider:"portfolio",operation:"balances",readOnly:!0,queriedAt:r,addresses:n,coverage:{requestedSurfaces:ge.length,ok:xe("ok"),unavailable:xe("unavailable"),notConfigured:xe("not-configured"),unsupported:xe("unsupported")+ee.length,evmChainsRequested:l.length,evmChainsOk:N.filter(B=>B.status==="ok").length},valuation:{knownUsd:qi(w),label:"known priced value, not a complete portfolio total",pricedItems:C,unpricedNonzeroItems:M,complete:M===0&&!Je&&xe("unavailable")===0&&xe("not-configured")===0&&ee.length===0,priceSource:o?"DefiLlama":null,priceStatus:b.ok?"ok":"unavailable",priceQueriedAt:r},chains:[...N,S,E,_],unsupportedFamilies:ee,warnings:W}}var UE,zp,Sc=L(()=>{Ep();Be();En();fc();Di();mc();hc();Pp();qp();UE="TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",zp=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"})});var qE,WR,rr=L(()=>{qE=300*1e3,WR=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var Vp=L(()=>{});import{readFileSync as HE,existsSync as zE}from"node:fs";import{getAddress as WE,Interface as Hi,TypedDataEncoder as XR,parseUnits as ZR}from"ethers";function XE(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!zE(e))return"";try{for(let t of HE(e,"utf8").split(`
7
+ ${JSON.stringify(r??[])}`}async function hE(e,t,r){return Ce(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function Cr(e,t,r=[],n={}){let o=String(t||""),i=dE(o),s=lE(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);if(i==="eth_chainid"&&n.cacheChainId!==!1){let d=hp.get(s);if(d!=null)return d}let l=n.dedupe!==!1&&!n.signal?mE(s,o,r):null;if(l&&ho.has(l))return ho.get(l);let u=(async()=>{let d=await hE(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),f=pE(d);return i==="eth_chainid"&&typeof f=="string"&&hp.set(s,f),f})();return l&&(ho.set(l,u),u.finally(()=>{ho.get(l)===u&&ho.delete(l)}).catch(()=>{})),u}async function sc(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await Cr(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function gp(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=aE(e.txHash||e.hash||e.transactionHash),o=await Cr(r,"eth_getTransactionReceipt",[n],t);if(!o)return{ok:!1,chainId:r,txHash:n,status:"pending",receipt:null,reason:"receipt pending"};let i=ic(o.status),s=i===1,a=i===1?"success":i===0?"reverted":"unknown",l=s?null:a==="reverted"?"transaction reverted":"unknown receipt status",u=e.expectedTo?oc(e.expectedTo,"expectedTo"):null,d=o.to?oc(o.to,"receipt.to"):null;return u&&d!==u&&(s=!1,l=`to mismatch: expected ${u}, got ${d||"null"}`),{ok:s,chainId:r,txHash:n,status:a,reason:l,statusCode:i,to:d,from:o.from?oc(o.from,"receipt.from"):null,blockNumber:ic(o.blockNumber),transactionIndex:ic(o.transactionIndex),logs:Array.isArray(o.logs)?o.logs:[],receipt:o}}var DL,cE,uE,ho,hp,En=L(()=>{Be();Ri();DL=new iE(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);cE={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};uE=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;ho=new Map,hp=new Map});var ac=L(()=>{});var HL,wp=L(()=>{Be();ac();HL=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"})});var WL,cc,lc,go=L(()=>{WL=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),cc=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),lc=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"})});var yp=L(()=>{En();go()});var bp=L(()=>{En();go()});var xp=L(()=>{En();wp();Be();go();yp();bp();ac()});var Sp,Ep=L(()=>{xp();go();Sp=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}}]}])});function yE(e={}){return String(e.rpcUrl||process.env.SOLANA_RPC_URL||wE).trim()}function $r(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}function bE(e,t){return t?[...e,{commitment:t}]:e}async function kp(e,t=[],r={}){let n=String(e||"");if(n==="sendTransaction"||n==="sendRawTransaction"||n==="requestAirdrop"||n==="requestAirDrop"||/airdrop/i.test(n)||/^send/i.test(n))throw new Error(`solana-rpc: ${n} refused \u2014 @oracle-agent/oracle is prepare-only (no broadcast/airdrop)`);let o=await Ce(yE(r),{method:"POST",body:{jsonrpc:"2.0",id:r.id||1,method:e,params:t},fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3});if(o?.error)throw new Error(`solana-rpc ${e}: ${o.error.message||JSON.stringify(o.error)}`);return o?.result}async function Ap(e={},t={}){let r=$r(e.address||e.owner,"address"),n=await kp("getBalance",bE([r],e.commitment),t);return{provider:"solana-rpc",cluster:vp,address:r,lamports:String(n?.value??0),slot:n?.context?.slot??null,raw:n}}function xE(e={}){let t=e.account?.data?.parsed?.info||{},r=t.tokenAmount||{};return{pubkey:e.pubkey,mint:t.mint||null,owner:t.owner||null,amount:String(r.amount??"0"),decimals:r.decimals??null,uiAmount:r.uiAmount??null,uiAmountString:r.uiAmountString??null,raw:e}}async function dc(e={},t={}){let r=$r(e.owner||e.address,"owner"),n=e.mint?{mint:$r(e.mint,"mint")}:{programId:$r(e.programId||uc,"token program")},o={encoding:"jsonParsed"};e.commitment&&(o.commitment=e.commitment);let i=await kp("getTokenAccountsByOwner",[r,n,o],t),s=Array.isArray(i?.value)?i.value.map(xE):[];return{provider:"solana-rpc",cluster:vp,owner:r,filter:n,slot:i?.context?.slot??null,accounts:s,raw:i}}var vp,wE,uc,fc=L(()=>{Be();vp="mainnet-beta",wE="https://api.mainnet-beta.solana.com",uc="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"});function _p(e={}){return String(e.network||process.env.BTC_NETWORK||SE).trim().toLowerCase()==="testnet"?"testnet":"mainnet"}function kE(e={}){return e.baseUrl?String(e.baseUrl).replace(/\/$/,""):process.env.BTC_ESPLORA_URL?String(process.env.BTC_ESPLORA_URL).replace(/\/$/,""):_p(e)==="testnet"?vE:EE}function Qt(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}async function AE(e,t={}){let r=`${kE(t)}${e.startsWith("/")?e:`/${e}`}`,o=await(t.fetchImpl||fetch)(r,{method:"GET",headers:{accept:"application/json,text/plain;q=0.9,*/*;q=0.8"},signal:AbortSignal.timeout(t.timeoutMs??12e3)}),i=await o.text();if(!o.ok)throw new Error(`bitcoin-esplora GET ${e}: HTTP ${o.status} ${i.slice(0,160)}`);return i}async function _E(e,t={}){let r=await AE(e,t);try{return JSON.parse(r)}catch{return r}}async function Ip(e={},t={}){let r=Qt(e.address||e.addr,"address"),n=await _E(`/address/${r}`,t),o=n.chain_stats||{},i=n.mempool_stats||{},s=Number(o.funded_txo_sum||0)+Number(i.funded_txo_sum||0),a=Number(o.spent_txo_sum||0)+Number(i.spent_txo_sum||0);return{provider:"bitcoin-esplora",network:_p(t),address:r,balanceSats:String(s-a),chainStats:o,mempoolStats:i,raw:n}}var SE,EE,vE,Di=L(()=>{Be();SE="mainnet",EE="https://mempool.space/api",vE="https://mempool.space/testnet/api"});function vn({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:Tp(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([Tp(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[Op]||"")==="1")return{baseUrl:s,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${Op}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:l}}function Tp(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function Nr(e,t,r){let n={...e};if(!r)return n;for(let[o,i]of Object.entries(t||{}))i&&(n[o]=i);return n}var Op,wo=L(()=>{Op="ORACLE_ALLOW_CUSTOM_PROVIDER_URL"});function pc(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}function OE(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=pc(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=IE.includes(o)&&(i==="https:"||s)}}catch{r=!1}return Nr({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},r)}async function Cp(e,t={}){let n=await(t.fetchImpl||fetch)(e,{method:"GET",headers:OE(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 $p(e={},t={}){let r=Qt(e.address||e.addr,"address"),n=pc(t);if(!n)return{provider:"bitcoin-meta",address:r,ok:!1,balances:[],error:"no indexer configured (set BTC_META_API_URL or vendor API key env)"};let o=[`${n}/v1/indexer/address/${r}/runes/balance-list?start=0&limit=100`,`${n}/v1/runes/address/${r}`,`${n}/runes/balance/${r}`,`${n}/address/${r}/runes`],i=null;for(let s of o)try{let a=await Cp(s,t),l=TE(a);return{provider:"bitcoin-meta",address:r,ok:!0,count:l.length,balances:l,source:s}}catch(a){i=a}return{provider:"bitcoin-meta",address:r,ok:!1,balances:[],error:String(i?.message||i||"all indexer paths failed")}}function TE(e){let t=e?.data?.detail||e?.data?.list||e?.data||e?.balances||e?.results||e?.runes||(Array.isArray(e)?e:[]);return(Array.isArray(t)?t:[]).map(n=>({rune:n.rune||n.runeid||n.runeId||n.spacedRune||n.name||n.ticker||null,runeId:n.runeid||n.runeId||n.id||null,amount:String(n.amount??n.balance??n.total??n.qty??"0"),symbol:n.symbol||null,divisibility:n.divisibility??n.div??null,raw:n}))}async function Bi(e={},t={}){let r=Qt(e.address||e.addr,"address"),n=pc(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 Cp(a,t),u=CE(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 CE(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}))}var IE,mc=L(()=>{Di();wo();IE=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"]});function LE({testnet:e,baseUrl:t}={}){if(t)return t.replace(/\/$/,"").endsWith("/info")?t:`${t.replace(/\/$/,"")}/info`;if(process.env.HL_INFO_URL)return process.env.HL_INFO_URL;if(process.env.HL_API_URL){let r=process.env.HL_API_URL.replace(/\/$/,"");return r.endsWith("/info")?r:`${r}/info`}return e||process.env.HL_TESTNET==="1"?NE:$E}async function Ui(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=LE(t);return Ce(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Np(e={}){return Ui({type:"allMids"},e)}async function Lp(e,t={}){if(!e)throw new Error("hlClearinghouse requires user address");return Ui({type:"spotClearinghouseState",user:e},t)}async function Rp(e,t={}){if(!e)throw new Error("hlUserState requires user");return Ui({type:"clearinghouseState",user:e},t)}var $E,NE,hc=L(()=>{Be();$E="https://api.hyperliquid.xyz/info",NE="https://api.hyperliquid-testnet.xyz/info"});function PE(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||RE).replace(/\/$/,"")}async function gc(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return Ce(`${PE(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}var RE,Pp=L(()=>{Be();RE="https://coins.llama.fi"});function wc(e,{max:t=32,fallback:r=""}={}){return e==null?r:String(e).normalize("NFKC").replace(Mp,"").replace(FE,"").replace(ME,"").replace(/\s+/g," ").trim().slice(0,t).trim()||r}function yc(e){if(e==null)return!1;let t=String(e);return Mp.test(t)?!0:/[\u0400-\u04FF\u0370-\u03FF]/.test(t)&&/[A-Za-z]/.test(t)}var Mp,ME,FE,Fp=L(()=>{Mp=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,ME=/[<>&`*_~[\]()|\\]/g,FE=/[\u0000-\u001F\u007F]/g});function DE(e,t={}){let r=Number(e),n=t.baseUrl||Dp[r];if(!n)throw new Error(`Blockscout not configured for chainId ${r}`);return n.replace(/\/$/,"")}function Bp(e){return!!Dp[Number(e)]}async function Up(e={},t={}){if(!e.address)throw new Error("address required");let r=Number(e.chainId||1),n=`${DE(r,t)}/api/v2/addresses/${encodeURIComponent(e.address)}/token-balances`,o=await Ce(n,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??18e3,headers:{accept:"application/json","user-agent":"OraclePortfolio/1.0"}});return Array.isArray(o)?o:[]}function jp(e=[],{fungibleOnly:t=!0}={}){let r=[];for(let n of e){if(!n||typeof n!="object")continue;let o=n.token&&typeof n.token=="object"?n.token:{},i=String(o.type||n.token_type||"").toUpperCase();if(t&&i&&!i.includes("ERC-20")&&i!=="ERC20")continue;let s=o.address_hash||o.address||n.token_address||n.tokenAddress||null;if(!s||typeof s!="string")continue;let a=String(n.value??n.balance??"0").replace(/^0x/i,"");if(!/^\d+$/.test(a)||a==="0")continue;let l=o.decimals??n.decimals;typeof l=="string"&&/^\d+$/.test(l)&&(l=Number(l)),(typeof l!="number"||!Number.isInteger(l)||l<0||l>36)&&(l=18);let u=wc(o.symbol||o.name,{max:32,fallback:"TOKEN"}),d=wc(o.name,{max:80,fallback:""})||null;r.push({address:s.toLowerCase().startsWith("0x")?s:`0x${s}`,symbol:u,name:d,decimals:l,amountRaw:a,tokenType:i||"ERC-20",source:"blockscout",verification:"indexer-reported",displaySuspicious:yc(o.symbol)||yc(o.name)||void 0})}return r}var Dp,qp=L(()=>{Be();Fp();Dp=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{getAddress as BE}from"ethers";function er(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,...e[t]||{}}}function ji(e,...t){for(let r of t){let n=String(e?.[r]||"").trim();if(n)return n}return null}function Hp(e){if(!e)return null;try{return BE(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function An(e={},t=process.env){let r=e.addresses||{},n=Hp(r.evm||e.evmAddress||ji(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=r.solana||e.solanaAddress||ji(t,"ORACLE_SOLANA_ADDRESS"),i=r.bitcoin||e.bitcoinAddress||ji(t,"ORACLE_BITCOIN_ADDRESS"),s=Hp(r.hyperliquid||e.hyperliquidAddress||ji(t,"ORACLE_HYPERLIQUID_ADDRESS")||n);return{evm:n,solana:o?$r(o,"portfolio Solana address"):null,bitcoin:i?Qt(i,"portfolio Bitcoin address"):null,hyperliquid:s}}function yo(e,t){let r=BigInt(String(e||"0")),n=Number(t);if(!Number.isInteger(n)||n<0||n>36)throw new Error("portfolio: decimals must be an integer from 0 to 36");if(n===0)return r.toString();let o=r<0n,i=o?-r:r,s=10n**BigInt(n),a=i/s,l=String(i%s).padStart(n,"0").replace(/0+$/,"");return`${o?"-":""}${a}${l?`.${l}`:""}`}function kn(e){let t=Number(e);return Number.isFinite(t)?t:null}function qi(e){return Number.isFinite(e)?Number(e.toFixed(2)):null}function tr(e){let t=Number(e);return Number.isFinite(t)&&t!==0}function Wp(e,t){let r=zp[t],n=r?e?.coins?.[r]:null,o=Number(n?.price);return{key:r||null,priceUsd:Number.isFinite(o)?o:null,timestamp:n?.timestamp??null,confidence:n?.confidence??null}}function jE(e){let t=new Map;for(let r of e)if(r?.ok)for(let n of r.data?.accounts||[]){let o=BigInt(String(n.amount||"0"));if(o===0n||!n.mint)continue;let i=`${n.mint}:${n.decimals??"unknown"}`,s=t.get(i)||{mint:n.mint,amountRaw:0n,decimals:n.decimals??null,programs:new Set,accounts:0};s.amountRaw+=o,s.accounts+=1,r.program&&s.programs.add(r.program),t.set(i,s)}return[...t.values()].map(r=>{let n=r.amountRaw.toString(),o=r.decimals==null?null:yo(n,r.decimals),i=r.decimals===0&&r.amountRaw===1n;return{mint:r.mint,amountRaw:n,amount:o,decimals:r.decimals,tokenPrograms:[...r.programs],accountCount:r.accounts,verification:"unverified",classification:i?"collectible-candidate":"fungible-or-unclassified",priceUsd:null,usdValue:null}})}function bc(e,t){return{family:e,status:"unsupported",reason:t}}function xc(e,t){if(!e||e.status!=="ok")return e;let r=Wp(t,e.symbol),n=kn(e.amount),o=n!=null&&r.priceUsd!=null?qi(n*r.priceUsd):null;return{...e,price:r,usdValue:o}}async function Kp(e={},t={}){let r=new Date().toISOString(),n=An(e,t.env||process.env),o=e.includePrices!==!1,i=e.includeTokens!==!1,s=e.includeCollectibles!==!1,a=new Map(Sp.map(B=>[B.chainId,B])),l=Array.isArray(e.evmChainIds)&&e.evmChainIds.length?[...new Set(e.evmChainIds.map(Number))]:[...a.keys()],u=[...new Set(Object.values(zp))],d=o?$e(()=>gc(u,er(t,"prices"))):Promise.resolve({ok:!1,ms:0,error:"price lookup disabled"}),f=Sn(l,e.concurrency||5,async B=>{let H=a.get(B);if(!H)return{family:"evm",chainId:B,name:null,address:n.evm,status:"unsupported",error:"chainId is not in Oracle's configured EVM registry"};if(!n.evm)return{family:"evm",chainId:B,name:H.name,address:null,status:"not-configured",error:"set ORACLE_EVM_ADDRESS or pass addresses.evm"};let Q={...er(t,"evm"),rpcUrl:e.rpcUrls?.[B]||t.evm?.rpcUrls?.[B]},fe=await $e(()=>sc(B,n.evm,Q));if(!fe.ok)return{family:"evm",chainId:B,name:H.name,address:n.evm,status:"unavailable",latencyMs:fe.ms,error:fe.error};let we=H.nativeCurrency?.decimals??18,j=H.nativeCurrency?.symbol||"NATIVE",F=fe.data.balanceWei,q={status:i?"unavailable":"not-requested",assets:[],reason:i?"EVM JSON-RPC cannot enumerate wallet tokens without an address indexer":"token discovery disabled"};if(i&&Bp(B)){let X=await $e(()=>Up({chainId:B,address:n.evm},{...er(t,"blockscout"),timeoutMs:t.timeoutMs??18e3}));X.ok?q={status:"ok",assets:jp(X.data,{fungibleOnly:!0}).map(ce=>{let Se=yo(ce.amountRaw,ce.decimals);return{...ce,amount:Se,priceUsd:null,usdValue:null}}),reason:null,source:"blockscout",latencyMs:X.ms}:q={status:"unavailable",assets:[],reason:X.error||"blockscout token-balances failed",source:"blockscout",latencyMs:X.ms}}return{family:"evm",chainId:B,name:H.name,address:n.evm,status:"ok",latencyMs:fe.ms,native:{status:"ok",symbol:j,amountRaw:F,decimals:we,amount:yo(F,we)},fungibleTokens:q,collectibles:{status:s?"unavailable":"not-requested",assets:[],reason:s?"EVM JSON-RPC cannot enumerate wallet NFTs without an address indexer":"collectible discovery disabled"},source:q.source==="blockscout"?"evm-rpc+blockscout":"evm-rpc"}}),c=(async()=>{if(!n.solana)return{family:"solana",name:"Solana Mainnet",address:null,status:"not-configured",error:"set ORACLE_SOLANA_ADDRESS or pass addresses.solana"};let B=er(t,"solana"),H=await $e(()=>Ap({address:n.solana},B)),Q=i||s?await Promise.all([$e(()=>dc({owner:n.solana,programId:uc},B)).then(q=>({...q,program:"spl-token"})),$e(()=>dc({owner:n.solana,programId:UE},B)).then(q=>({...q,program:"token-2022"}))]):[],fe=jE(Q),we=fe.filter(q=>q.classification==="collectible-candidate"),j=fe.filter(q=>q.classification!=="collectible-candidate"),F=Q.filter(q=>!q.ok).map(q=>q.error);return{family:"solana",name:"Solana Mainnet",address:n.solana,status:H.ok||Q.some(q=>q.ok)?"ok":"unavailable",native:H.ok?{status:"ok",symbol:"SOL",amountRaw:H.data.lamports,decimals:9,amount:yo(H.data.lamports,9),slot:H.data.slot}:{status:"unavailable",symbol:"SOL",error:H.error},fungibleTokens:{status:i?F.length===Q.length?"unavailable":F.length?"partial":"ok":"not-requested",assets:i?j:[],errors:F,note:"SPL accounts are unverified until a metadata/indexer source confirms symbol and spam status"},collectibles:{status:s?F.length===Q.length?"unavailable":"partial":"not-requested",assets:s?we:[],errors:F,note:"decimals=0 and amount=1 is only a collectible candidate, not verified NFT metadata"},source:"solana-rpc"}})(),p=(async()=>{if(!n.bitcoin)return{family:"bitcoin",name:"Bitcoin Mainnet",address:null,status:"not-configured",error:"set ORACLE_BITCOIN_ADDRESS or pass addresses.bitcoin"};let B=er(t,"bitcoin"),H=er(t,"bitcoinMeta"),[Q,fe,we]=await Promise.all([$e(()=>Ip({address:n.bitcoin},B)),i?$e(()=>$p({address:n.bitcoin},H)):Promise.resolve({ok:!1,ms:0,error:"token discovery disabled"}),s?$e(()=>Bi({address:n.bitcoin},H)):Promise.resolve({ok:!1,ms:0,error:"collectible discovery disabled"})]),j=fe.ok?fe.data:null,F=we.ok?we.data:null;return{family:"bitcoin",name:"Bitcoin Mainnet",address:n.bitcoin,status:Q.ok||j?.ok||F?.ok?"ok":"unavailable",native:Q.ok?{status:"ok",symbol:"BTC",amountRaw:Q.data.balanceSats,decimals:8,amount:yo(Q.data.balanceSats,8)}:{status:"unavailable",symbol:"BTC",error:Q.error},fungibleTokens:{status:i?j?.ok?"ok":"unavailable":"not-requested",assets:j?.balances||[],error:j?.ok?null:j?.error||fe.error,verification:"indexer-reported"},collectibles:{status:s?F?.ok?"ok":"unavailable":"not-requested",assets:F?.inscriptions||[],error:F?.ok?null:F?.error||we.error,unknownNotEmpty:!!F?.unknownNotEmpty,verification:"indexer-reported"},source:"bitcoin-esplora+bitcoin-meta"}})(),m=(async()=>{if(!n.hyperliquid)return{family:"hyperliquid",name:"Hyperliquid HyperCore",address:null,status:"not-configured",error:"set ORACLE_HYPERLIQUID_ADDRESS or pass addresses.hyperliquid"};let B=er(t,"hyperliquid"),[H,Q,fe]=await Promise.all([$e(()=>Lp(n.hyperliquid,B)),$e(()=>Rp(n.hyperliquid,B)),$e(()=>Np(B))]),we=(H.ok&&Array.isArray(H.data?.balances)?H.data.balances:[]).filter(F=>tr(F.total)||tr(F.hold)).map(F=>({coin:F.coin||null,total:String(F.total??"0"),hold:String(F.hold??"0"),priceUsd:null,usdValue:null})),j=(Q.ok&&Array.isArray(Q.data?.assetPositions)?Q.data.assetPositions:[]).map(F=>F.position||F).filter(F=>tr(F.szi)).map(F=>({coin:F.coin||null,size:String(F.szi??"0"),entryPrice:F.entryPx??null,positionValueUsd:F.positionValue??null,unrealizedPnlUsd:F.unrealizedPnl??null,liquidationPrice:F.liquidationPx??null}));return{family:"hyperliquid",name:"Hyperliquid HyperCore",address:n.hyperliquid,status:H.ok||Q.ok?"ok":"unavailable",spot:{status:H.ok?"ok":"unavailable",balances:we,error:H.ok?null:H.error},perps:{status:Q.ok?"ok":"unavailable",accountValueUsd:Q.data?.marginSummary?.accountValue??null,withdrawableUsd:Q.data?.withdrawable??null,positions:j,error:Q.ok?null:Q.error},mids:fe.ok?fe.data:{},source:"hyperliquid-info"}})(),[h,S,E,_,b]=await Promise.all([f,c,p,m,d]),g=b.ok?b.data:null,k=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax",81457:"blast",534352:"scroll",59144:"linea",324:"era"}),A=[];for(let B of h){if(B.family!=="evm"||B.fungibleTokens?.status!=="ok")continue;let H=k[B.chainId];if(H)for(let Q of B.fungibleTokens.assets||[])Q.address&&A.push(`${H}:${String(Q.address).toLowerCase()}`)}let O=null;if(o&&A.length){let B=[...new Set(A)],H=await $e(()=>gc(B,er(t,"prices")));H.ok&&(O=H.data)}let N=h.map(B=>{let H=B.native?{...B,native:xc(B.native,g)}:B;if(H.fungibleTokens?.status==="ok"&&Array.isArray(H.fungibleTokens.assets)){let Q=k[H.chainId],fe=H.fungibleTokens.assets.map(we=>{let j=String(we.symbol||"").toUpperCase(),F=null;if(["USDC","USDT","USDT0","DAI","USDBC","USDE","USDCE"].includes(j)&&(F=1),F==null&&Q&&we.address&&O?.coins){let te=`${Q}:${String(we.address).toLowerCase()}`,ce=O.coins[te],Se=Number(ce?.price);Number.isFinite(Se)&&Se>0&&(F=Se)}let q=kn(we.amount),X=q!=null&&F!=null?qi(q*F):null;return{...we,priceUsd:F,usdValue:X}});H={...H,fungibleTokens:{...H.fungibleTokens,assets:fe}}}return H});S.native&&(S.native=xc(S.native,g)),E.native&&(E.native=xc(E.native,g));let w=0,C=0,M=0;for(let B of[...N,S,E]){B.native?.status==="ok"&&tr(B.native.amount)&&(B.native.usdValue!=null?(w+=B.native.usdValue,C+=1):M+=1);for(let H of B.fungibleTokens?.assets||[])!tr(H.amount)&&!tr(H.amountRaw)||(H.usdValue!=null?(w+=H.usdValue,C+=1):M+=1)}let z=Wp(g,"HYPE");for(let B of _.spot?.balances||[]){let H=String(B.coin||"").toUpperCase(),Q=H==="USDC"||H==="USDT"||H==="USDT0"?1:H==="HYPE"?z.priceUsd||kn(_.mids?.HYPE):kn(_.mids?.[B.coin]),fe=kn(B.total);B.priceUsd=Q,B.usdValue=fe!=null&&Q!=null?qi(fe*Q):null,tr(B.total)&&(B.usdValue!=null?(w+=B.usdValue,C+=1):M+=1)}let G=kn(_.perps?.accountValueUsd);G!=null&&G!==0&&(w+=G,C+=1);let Y=[...S.fungibleTokens?.assets||[],...S.collectibles?.assets||[]].filter(B=>tr(B.amount)).length,ae=(E.fungibleTokens?.assets||[]).length+(E.collectibles?.assets||[]).length;M+=Y+ae;let ge=[...N,S,E,_],xe=B=>ge.filter(H=>H.status===B).length,W=[],U=N.filter(B=>B.fungibleTokens?.status==="unavailable"),K=N.filter(B=>B.fungibleTokens?.status==="ok");U.length&&!K.length?W.push("EVM token discovery is unavailable without a working address indexer; native balances are still live."):U.length&&W.push(`EVM token discovery partial: Blockscout covered ${K.length} chain(s); ${U.length} chain(s) still native-only.`),(S.fungibleTokens?.assets?.length||S.collectibles?.assets?.length)&&W.push("Solana token accounts are unverified and may include spam; collectible candidates are not confirmed NFTs."),E.collectibles?.unknownNotEmpty&&W.push("Bitcoin inscription holdings are unknown, not zero, because no address indexer is configured."),b.ok||W.push(`Price provider unavailable: ${b.error}`);let ee=[bc("cosmos","requires a chain-specific bech32 address and LCD/RPC adapter"),bc("sui","Sui balance adapter is not installed"),bc("aptos","Aptos balance adapter is not installed")],Je=ge.some(B=>["unavailable","partial","not-configured"].includes(B.fungibleTokens?.status)||["unavailable","partial","not-configured"].includes(B.collectibles?.status));return{provider:"portfolio",operation:"balances",readOnly:!0,queriedAt:r,addresses:n,coverage:{requestedSurfaces:ge.length,ok:xe("ok"),unavailable:xe("unavailable"),notConfigured:xe("not-configured"),unsupported:xe("unsupported")+ee.length,evmChainsRequested:l.length,evmChainsOk:N.filter(B=>B.status==="ok").length},valuation:{knownUsd:qi(w),label:"known priced value, not a complete portfolio total",pricedItems:C,unpricedNonzeroItems:M,complete:M===0&&!Je&&xe("unavailable")===0&&xe("not-configured")===0&&ee.length===0,priceSource:o?"DefiLlama":null,priceStatus:b.ok?"ok":"unavailable",priceQueriedAt:r},chains:[...N,S,E,_],unsupportedFamilies:ee,warnings:W}}var UE,zp,Sc=L(()=>{Ep();Be();En();fc();Di();mc();hc();Pp();qp();UE="TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",zp=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"})});var qE,WR,rr=L(()=>{qE=300*1e3,WR=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var Vp=L(()=>{});import{readFileSync as HE,existsSync as zE}from"node:fs";import{getAddress as WE,Interface as Hi,TypedDataEncoder as XR,parseUnits as ZR}from"ethers";function XE(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!zE(e))return"";try{for(let t of HE(e,"utf8").split(`
8
8
  `)){let r=t.match(/^\s*OPENSEA_API_KEY\s*=\s*(.+)\s*$/);if(r)return r[1].replace(/^["']|["']$/g,"").trim()}}catch{}return""}function Ec(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||XE()}function Yp(e={}){return vn({provider:"opensea",defaultUrl:KE,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function Jp(e={}){return Yp(e).baseUrl}function Xp(e={}){return Nr({accept:"application/json"},{"x-api-key":Ec(e)},Yp(e).trusted)}function ZE(e){let t=String(e||"ethereum").trim().toLowerCase();if(!YE.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function Gp(e,t="address"){try{return WE(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function Zp(e,t=null){let r=String(e||"").trim();if(!r)throw new Error("opensea: account address required");if(t&&!JE.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(r))return Gp(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 QE(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,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 vc(e={},t={}){if(!Ec(t))throw new Error("OPENSEA_API_KEY required");let r=ZE(e.chain),n=Zp(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(`${Jp(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 Ce(u.toString(),{headers:Xp(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let f of Array.isArray(d?.nfts)?d.nfts:[])s.push(QE(f,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 Qp(e={},t={}){if(!Ec(t))throw new Error("OPENSEA_API_KEY required");let r=Zp(e.address||e.owner),n=await Ce(`${Jp(t)}/account/${encodeURIComponent(r)}/pnl`,{headers:Xp(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 KE,VE,nP,oP,GE,YE,JE,iP,sP,aP,cP,em=L(()=>{Be();wo();rr();Vp();KE="https://api.opensea.io/api/v2",VE="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)",nP=new Hi([`function ${VE}`]),oP=new Hi(["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"]),GE=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"]),YE=new Set(GE),JE=new Set(["solana","flow"]);iP=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}),sP=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"}]}),aP=new Hi(["function setApprovalForAll(address operator,bool approved)"]),cP=new Hi(["function cancel((address offerer,address zone,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount)[] offer,(uint8 itemType,address token,uint256 identifierOrCriteria,uint256 startAmount,uint256 endAmount,address recipient)[] consideration,uint8 orderType,uint256 startTime,uint256 endTime,bytes32 zoneHash,uint256 salt,bytes32 conduitKey,uint256 counter)[] orders) returns (bool cancelled)"])});var kc=L(()=>{});function tm(e={}){return vn({provider:"satflow",defaultUrl:tv,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function rv(e={}){return tm(e).baseUrl}function rm(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function nv(e={}){return Nr({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":rm(e)},tm(e).trusted)}async function ov(e,{method:t="GET",body:r,opts:n={}}={}){if(!rm(n))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${rv(n)}${e.startsWith("/")?e:`/${e}`}`,a=await(n.fetchImpl||fetch)(i,{method:t,headers:nv(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 nm(e={},t={}){let r=Qt(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 ov(`/address/wallet-contents?${n}`,{opts:t});return{provider:"satflow",address:r,contents:o}}var tv,om=L(()=>{Di();wo();rr();kc();tv="https://api.satflow.com/v1"});var im=L(()=>{Be();fc();wo();rr();kc()});var vP,sm=L(()=>{Be();vP=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"])});function cv(e={}){let t=[],r=String(e.name||""),n=String(e.description||""),o=`${r} ${n}`;sv.test(r)&&t.push("url-in-name");let i=iv.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),av.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 am(e={}){let t=cv(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}var iv,sv,av,cm=L(()=>{iv=[/\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],sv=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,av=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i});function Ac(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function xo(e,t){let r=await $e(t);return r.ok?{ok:!0,data:r.data}:{ok:!1,error:`${e}: ${r.error}`.slice(0,300)}}function dv(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 fv(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 pv(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 lm(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function mv(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 hv(e,t){let r=lm(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 gv(e){let t=new Map;for(let r of e){let n=lm(r);t.has(n)||t.set(n,r)}return[...t.values()]}function wv(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 um(e={},t={}){let r=new Date().toISOString(),n=An(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(g=>String(g).toLowerCase())):null,i=lv.filter(g=>!o||o.has(g.chain)),s=[],a=[],l=Ac(t,"opensea"),u=n.evm?i.filter(g=>g.family!=="solana"):[],d=await Sn(u,4,async g=>({row:g,result:await xo(`opensea-${g.chain}`,()=>vc({chain:g.chain,address:n.evm,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3)}));for(let{row:g,result:k}of d)if(k.ok){let A=k.data.nfts.map(O=>({...O,family:g.family,chainId:g.chainId,listingAdapter:"opensea",source:"opensea-account-inventory"}));a.push(...A),s.push({family:g.family,chain:g.chain,chainId:g.chainId,status:k.data.complete?"ok":"partial",count:A.length,complete:k.data.complete,next:k.data.next,source:"opensea"})}else s.push({family:g.family,chain:g.chain,chainId:g.chainId,status:"unavailable",error:k.error,source:"opensea"});if(!n.evm)for(let g of i.filter(k=>k.family!=="solana"))s.push({family:g.family,chain:g.chain,chainId:g.chainId,status:"not-configured",reason:"EVM address missing"});if(n.solana&&(!o||o.has("solana"))){let g=await xo("opensea-solana",()=>vc({chain:"solana",address:n.solana,pageSize:e.pageSize,maxPages:e.maxPages},l),t.timeoutMs??35e3);if(g.ok){let k=g.data.nfts.map(A=>({...A,family:"solana",chainId:null,listingAdapter:null,source:"opensea-account-inventory"}));a.push(...k),s.push({family:"solana",chain:"solana",status:g.data.complete?"ok":"partial",count:k.length,complete:g.data.complete,next:g.data.next,source:"opensea"})}else s.push({family:"solana",chain:"solana",status:"unavailable",error:g.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 g=await xo("satflow-wallet-contents",()=>nm({address:n.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},Ac(t,"satflow")),t.timeoutMs??35e3);if(g.ok){let k=dv(g.data.contents).map(O=>fv(O,n.bitcoin));a.push(...k);let A=k.length<Number(e.bitcoinLimit??100);s.push({family:"bitcoin",chain:"bitcoin",status:A?"ok":"partial",count:k.length,complete:A,source:"satflow"})}else{let k=await xo("bitcoin-meta-inscriptions",()=>Bi({address:n.bitcoin},Ac(t,"bitcoinMeta")),t.timeoutMs??35e3),A=k.ok&&k.data?.ok&&Array.isArray(k.data.inscriptions)?k.data.inscriptions:[];a.push(...A.map(O=>pv(O,n.bitcoin))),s.push({family:"bitcoin",chain:"bitcoin",status:A.length?"partial":"unavailable",count:A.length,complete:!1,source:A.length?"bitcoin-meta":"satflow",error:A.length?"Satflow unavailable; fallback has IDs only":g.error})}}else(!o||o.has("bitcoin"))&&s.push({family:"bitcoin",chain:"bitcoin",status:"not-configured",reason:"Bitcoin address missing"});let f=[];if(e.includePnl!==!1)for(let g of[...new Set([n.evm,n.solana].filter(Boolean))]){let k=await xo(`opensea-pnl-${g}`,()=>Qp({address:g},l),t.timeoutMs??35e3);f.push(k.ok?{status:"ok",...k.data}:{status:"unavailable",address:g,source:"opensea-indexed-account-pnl",error:k.error})}let c=mv(e.costBasis),p=gv(a).map(g=>hv(g,c)).map(g=>am(g)),m=p.filter(g=>!g.spam),h=p.filter(g=>g.spam),S=m.filter(g=>g.estimatedValueUsd!=null&&Number.isFinite(Number(g.estimatedValueUsd))),E=Math.round(S.reduce((g,k)=>g+Number(k.estimatedValueUsd),0)*100)/100,_=m.length-S.length,b=s.filter(g=>g.status!=="ok"||g.complete===!1);return{provider:"nft-portfolio",operation:"inventory",readOnly:!0,generatedAt:r,addresses:n,coverage:s,unsupported:uv,inventory:{count:p.length,visibleCount:m.length,flaggedCount:h.length,items:p,visibleItems:m,flaggedItems:h},valuation:{estimatedCurrentValueUsd:E,valuedItems:S.length,unvaluedItems:_,complete:_===0&&b.length===0,methodology:"Sum of provider estimated_value_usd for non-flagged items. It is not an executable bid."},pnl:wv(m,f),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 lv,uv,dm=L(()=>{Be();Sc();em();om();mc();im();sm();cm();rr();lv=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"}]),uv=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"}])});var ym={};dr(ym,{portfolioHistory:()=>wm,portfolioIdForAddresses:()=>_c,portfolioSnapshot:()=>$v,portfolioValueGraph:()=>Mv,resolvePortfolioHistoryFile:()=>Ic});import{constants as zi}from"node:fs";import{chmod as yv,mkdir as bv,open as xv,readFile as Sv}from"node:fs/promises";import{createHash as Ev,randomUUID as vv}from"node:crypto";import kv from"node:os";import _n from"node:path";function nr(e){if(e==null||e==="")return null;let t=Number(e);return Number.isFinite(t)?t:null}function In(e){return Number.isFinite(e)?Number(e.toFixed(2)):null}function pm(e,t){if(e==null||e==="")return null;let r=Date.parse(String(e));if(!Number.isFinite(r))throw new Error(`${t} must be an ISO 8601 timestamp`);return new Date(r).toISOString()}function gm(e,t,r,n,o){if(e==null||e==="")return t;let i=Number(e);if(!Number.isInteger(i)||i<r||i>n)throw new Error(`${o} must be an integer from ${r} to ${n}`);return i}function Av(e={}){return["evm","solana","bitcoin","hyperliquid"].map(t=>`${t}:${String(e[t]||"").trim().toLowerCase()}`).join("|")}function _c(e={}){return`portfolio_${Ev("sha256").update(Av(e)).digest("hex").slice(0,20)}`}function Ic(e={}){if(e.historyFile)return _n.resolve(String(e.historyFile));let t=e.env||process.env;if(t.ORACLE_PORTFOLIO_HISTORY_FILE)return _n.resolve(String(t.ORACLE_PORTFOLIO_HISTORY_FILE));let r=String(t.HERMES_HOME||"").trim()||_n.join(kv.homedir(),".hermes");return _n.join(_n.resolve(r),"state","oracle","portfolio-history.jsonl")}function _v(e){let t=nr(e?.valuation?.knownUsd);return t==null?null:Number(e?.valuation?.pricedItems||0)>0||e?.valuation?.complete===!0?In(t):null}function Iv(e){if(!e||e.status==="unavailable"||e.status==="not-requested")return null;let t=nr(e?.valuation?.estimatedCurrentValueUsd);return t==null?null:Number(e?.valuation?.valuedItems||0)>0||e?.valuation?.complete===!0?In(t):null}function Ov(e){let t=[];for(let r of e?.chains||[]){if(r.family==="hyperliquid"){let o=(r.spot?.balances||[]).reduce((a,l)=>{let u=nr(l.usdValue);return u==null?a:a+u},0),i=nr(r.perps?.accountValueUsd),s=In(o+(i??0));(s!==0||i!=null||(r.spot?.balances||[]).some(a=>nr(a.usdValue)!=null))&&t.push({family:"hyperliquid",chainId:null,name:r.name||"Hyperliquid",knownUsd:s});continue}let n=nr(r.native?.usdValue);n!=null&&t.push({family:r.family||"evm",chainId:r.chainId??null,name:r.name||r.native?.symbol||"Unknown",knownUsd:In(n)})}return t}function Tv(e,t,r){let n=Array.isArray(t?.coverage)?t.coverage:[];return{balances:e?.coverage||null,nfts:{requested:r,ok:n.filter(o=>o.status==="ok").length,partial:n.filter(o=>o.status==="partial").length,unavailable:n.filter(o=>o.status==="unavailable").length,notConfigured:n.filter(o=>o.status==="not-configured").length,status:r?t?.status==="unavailable"?"unavailable":t?.valuation?.complete?"ok":"partial":"not-requested"}}}async function Cv(e,t){let r=Ic(t),n=`${JSON.stringify(e)}
9
9
  `;if(Buffer.byteLength(n)>32*1024)throw new Error("portfolio history snapshot exceeds 32 KiB");await bv(_n.dirname(r),{recursive:!0,mode:448});let o=zi.O_APPEND|zi.O_CREAT|zi.O_WRONLY|(zi.O_NOFOLLOW||0),i=await xv(r,o,384);try{await i.writeFile(n,"utf8")}finally{await i.close()}return await yv(r,384),r}async function $v(e={},t={}){let r=e.includeNfts!==!1,n=t.portfolioBalanceImpl||Kp,o=t.nftInventoryImpl||um,i=n(e,t),s=r?o({...e,includePnl:!1},t).catch(k=>({status:"unavailable",error:String(k?.message||k).slice(0,300)})):Promise.resolve({status:"not-requested"}),[a,l]=await Promise.all([i,s]),u=_v(a),d=Iv(l),f=[u,d].filter(k=>k!=null),c=f.length?In(f.reduce((k,A)=>k+A,0)):null,p=!!(a?.valuation?.complete&&(!r||l?.valuation?.complete===!0)),m=typeof t.now=="function"?t.now():new Date,h=new Date(m).toISOString(),S=a?.addresses||An(e,t.env||process.env),E=_c(S),_=[...a?.warnings||[]];r&&l?.status==="unavailable"&&_.push(`NFT inventory unavailable: ${l.error}`),r&&l?.valuation&&l.valuation.complete!==!0&&_.push("NFT estimated value is incomplete and is not an executable bid.");let b={schemaVersion:1,id:`snapshot_${vv()}`,portfolioId:E,recordedAt:h,sourceQueriedAt:{balances:a?.queriedAt||null,nfts:l?.generatedAt||null},configuredFamilies:Object.fromEntries(["evm","solana","bitcoin","hyperliquid"].map(k=>[k,!!S?.[k]])),valuation:{knownUsd:c,liquidKnownUsd:u,nftEstimatedValueUsd:d,complete:p,label:p?"complete known portfolio value":"known priced value, including provider-estimated NFTs when available, not a complete portfolio total",liquidPricedItems:Number(a?.valuation?.pricedItems||0),liquidUnpricedNonzeroItems:Number(a?.valuation?.unpricedNonzeroItems||0),nftValuedItems:Number(l?.valuation?.valuedItems||0),nftUnvaluedItems:Number(l?.valuation?.unvaluedItems||0)},breakdown:{liquid:Ov(a),nfts:{knownUsd:d,visibleItems:Number(l?.inventory?.visibleCount||0),flaggedItems:Number(l?.inventory?.flaggedCount||0)}},coverage:Tv(a,l,r),warnings:[...new Set(_)].slice(0,50)};return{provider:"portfolio",operation:"snapshot",readOnly:!0,localObservationRecorded:!0,historyFile:await Cv(b,t),snapshot:b,balance:a,nfts:l}}async function Nv(e){let t=Ic(e);try{let r=await Sv(t);if(r.byteLength>fm)throw new Error(`portfolio history exceeds ${fm} bytes`);let n=[],o=0;for(let i of r.toString("utf8").split(`
10
10
  `))if(i.trim())try{let s=JSON.parse(i);s?.schemaVersion===1&&s?.portfolioId&&s?.recordedAt?n.push(s):o+=1}catch{o+=1}return{file:t,snapshots:n,corruptLines:o}}catch(r){if(r?.code==="ENOENT")return{file:t,snapshots:[],corruptLines:0};throw r}}function Lv(e,t){if(e.allPortfolios===!0)return null;if(e.portfolioId)return String(e.portfolioId);let r=An(e,t.env||process.env);return Object.values(r).some(Boolean)?_c(r):null}async function wm(e={},t={}){let r=gm(e.limit,100,1,hm,"portfolio history limit"),n=String(e.order||"desc").toLowerCase();if(!new Set(["asc","desc"]).has(n))throw new Error("portfolio history order must be asc or desc");let o=pm(e.since,"portfolio history since"),i=pm(e.until,"portfolio history until"),s=Lv(e,t),a=await Nv(t),l=a.snapshots.filter(f=>!(s&&f.portfolioId!==s||o&&f.recordedAt<o||i&&f.recordedAt>i));l.sort((f,c)=>String(f.recordedAt).localeCompare(String(c.recordedAt)));let u=l.length;l=l.slice(-r),n==="desc"&&l.reverse();let d=l.filter(f=>nr(f?.valuation?.knownUsd)!=null);return{provider:"portfolio",operation:"history",readOnly:!0,historyFile:a.file,portfolioId:s,order:n,totalStored:a.snapshots.length,totalMatching:u,corruptLines:a.corruptLines,snapshots:l,stats:{returned:l.length,valuedSnapshots:d.length,unpricedSnapshots:l.length-d.length,firstRecordedAt:l.length?[...l].sort((f,c)=>String(f.recordedAt).localeCompare(String(c.recordedAt)))[0].recordedAt:null,lastRecordedAt:l.length?[...l].sort((f,c)=>String(f.recordedAt).localeCompare(String(c.recordedAt))).at(-1).recordedAt:null}}}function mm(e){return`$${Number(e).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`}function Wi(e){return String(e).replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}function Rv(e,t){if(e.length<=t)return e;let r=[];for(let n=0;n<t;n+=1)r.push(e[Math.round(n*(e.length-1)/(t-1))]);return r}function Pv(e,t){let l=e.map(b=>b.value),u=Math.min(...l),d=Math.max(...l);if(u===d){let b=Math.max(1,Math.abs(u)*.05);u-=b,d+=b}else{let b=(d-u)*.1;u=Math.max(0,u-b),d+=b}let f=b=>e.length===1?1240/2:100+1040*b/(e.length-1),c=b=>570-(b-u)/(d-u)*470,p=e.map((b,g)=>`${g?"L":"M"}${f(g).toFixed(2)},${c(b.value).toFixed(2)}`).join(" "),m=Array.from({length:5},(b,g)=>{let k=g/4,A=100+k*470,O=d-k*(d-u);return`<line x1="100" y1="${A}" x2="1140" y2="${A}" stroke="#26313c" stroke-width="1"/><text x="86" y="${A+5}" text-anchor="end" fill="#8795a5" font-size="15">${mm(O)}</text>`}).join(""),h=e.map((b,g)=>`<circle cx="${f(g)}" cy="${c(b.value)}" r="5" fill="#b8f0ff"><title>${Wi(b.recordedAt)}: ${mm(b.value)}</title></circle>`).join(""),S=Wi(e[0].recordedAt.slice(0,10)),E=Wi(e.at(-1).recordedAt.slice(0,10));return`<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="675" viewBox="0 0 1200 675"><rect width="1200" height="675" fill="#0b1016"/><text x="60" y="50" fill="#f4f7fa" font-size="28" font-family="Inter,Arial,sans-serif" font-weight="700">Oracle Portfolio Value</text><text x="60" y="78" fill="#8795a5" font-size="15" font-family="Inter,Arial,sans-serif">Known priced value, not a complete total unless every snapshot says complete \xB7 ${Wi(t||"configured portfolio")}</text>${m}<line x1="100" y1="570" x2="1140" y2="570" stroke="#526171" stroke-width="1"/><path d="${p}" fill="none" stroke="#b8f0ff" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>${h}<text x="100" y="610" fill="#8795a5" font-size="15">${S}</text><text x="1140" y="610" text-anchor="end" fill="#8795a5" font-size="15">${E}</text><text x="60" y="650" fill="#526171" font-size="13">NFT values are provider estimates, not executable bids. Unavailable values are omitted, never plotted as zero.</text></svg>`}async function Mv(e={},t={}){if(e.allPortfolios===!0)throw new Error("portfolio value graph requires one portfolioId or configured public-address portfolio");let r=gm(e.maxPoints,200,2,500,"portfolio graph maxPoints"),n=await wm({...e,order:"asc",limit:e.limit??hm},t);if(!n.portfolioId)throw new Error("portfolio value graph requires one portfolioId or configured public-address portfolio");let o=n.snapshots.map(f=>({recordedAt:f.recordedAt,value:nr(f?.valuation?.knownUsd),complete:f?.valuation?.complete===!0})).filter(f=>f.value!=null);if(!o.length)throw new Error("portfolio value graph requires at least one snapshot with known priced value");let i=Rv(o,r),s=i[0].value,a=i.at(-1).value,l=In(a-s),u=s===0?null:Number(((a-s)/s*100).toFixed(2)),d=Pv(i,n.portfolioId);return{provider:"portfolio",operation:"valueGraph",readOnly:!0,portfolioId:n.portfolioId,mimeType:"image/svg+xml",dataBase64:Buffer.from(d).toString("base64"),byteLength:Buffer.byteLength(d),summary:{points:i.length,omittedUnavailablePoints:n.snapshots.length-o.length,startRecordedAt:i[0].recordedAt,endRecordedAt:i.at(-1).recordedAt,startKnownUsd:s,endKnownUsd:a,changeUsd:l,changePct:u,completeSnapshots:i.filter(f=>f.complete).length,label:"known priced value history; incomplete snapshots are not complete portfolio totals"}}}var fm,hm,bm=L(()=>{Sc();dm();fm=10*1024*1024,hm=1e3});function Ki(e){let t=e?.transactionHash||e?.hash||e?.txid||null;return t?{happened:!0,hash:String(t),note:null}:{happened:!1,hash:null,note:"no transaction hash \u2014 the action did not succeed"}}var Oc=L(()=>{});var Em={};dr(Em,{createWatch:()=>Nc,listWatches:()=>$c,removeWatch:()=>Uv});import So from"node:fs";import Tc from"node:path";import{randomUUID as Fv}from"node:crypto";import{homedir as Dv}from"node:os";function Bv(e=process.env){return e.ORACLE_CONFIG_DIR||Tc.join(Dv(),".config","oracle")}function xm(e=process.env){return Tc.join(Bv(e),"watches.json")}function Cc(e=process.env){let t=xm(e);if(!So.existsSync(t))return{watches:[]};try{let r=JSON.parse(So.readFileSync(t,"utf8"));return{watches:Array.isArray(r.watches)?r.watches:[]}}catch{return{watches:[]}}}function Sm(e,t=process.env){let r=xm(t);So.mkdirSync(Tc.dirname(r),{recursive:!0,mode:448});let n=`${r}.${process.pid}.tmp`;So.writeFileSync(n,`${JSON.stringify(e,null,2)}
@@ -62,8 +62,8 @@ No skills installed. Use skill_create to save a successful workflow.
62
62
  `:`restarting gateway\u2026
63
63
  `);let K=Yf(["-p",o,"gateway",U]);u.push(`gateway:${U}:${K.code}`),typeof e.setRawMode=="function"&&e.setRawMode(!0),e.resume(),E={title:K.code===0?U==="install"?"boot service installed":"gateway restarted":`gateway ${U} failed`,subtitle:K.code===0?U==="install"?"bot survives reboots now":"channels should be live":K.error||`exit ${K.code}`},d="notice",A()}},ae=async W=>{if(!W||W.action==="back"){d="menu",A();return}typeof e.setRawMode=="function"&&e.setRawMode(k),e.pause(),bn(t);let U=W.kind==="oauth"?["login",W.id]:["api-key",W.id];t.write(`connecting ${W.label}\u2026
64
64
  `);let K=1;try{K=await s(U)}catch(ee){t.write(`${ee?.message||ee}
65
- `),K=1}u.push(`model:${W.id}:${K}`),typeof e.setRawMode=="function"&&e.setRawMode(!0),e.resume(),z(),d="menu",A()},ge=W=>{for(let U of W){if(U.ctrl&&U.name==="c"){M({completed:!1,actions:u,reason:"cancel"});return}if(d==="token"){if(U.name==="escape"){m="",h="",d="menu",A();continue}if(U.name==="return"){G();continue}if(U.name==="backspace"||U.sequence==="\x7F"||U.sequence==="\b"){m=m.slice(0,-1),h="",A();continue}let ee=U.sequence||"";if(ee&&!U.ctrl&&!U.meta&&ee!=="\x1B"){if(ee.startsWith("\x1B"))continue;m+=ee,h="",A()}continue}if(d==="confirm-gateway"){if(U.name==="up"||U.name==="down"){p=p===0?1:0,A();continue}if(U.name==="escape"){d="menu",A();continue}U.name==="return"&&(p===0?Y({action:"gateway",id:"gateway"}):(d="menu",A()));continue}if(d==="notice"){(U.name==="return"||U.name==="escape")&&(d="menu",A());continue}if(d==="model"){let ee=b.length;if(U.name==="up"){c=ee?(c-1+ee)%ee:0,A();continue}if(U.name==="down"){c=ee?(c+1)%ee:0,A();continue}if(U.name==="escape"){d="menu",A();continue}U.name==="return"&&ae(b[c]);continue}let K=_.length;if(U.name==="up"){f=K?(f-1+K)%K:0,A();continue}if(U.name==="down"){f=K?(f+1)%K:0,A();continue}if(U.name==="escape"){M({completed:!0,actions:u,reason:"esc"});continue}U.name==="return"&&Y(_[f])}},xe=W=>{ge(g.push(W)),w&&(clearTimeout(w),w=null),g.pending>0&&(w=setTimeout(()=>{w=null,ge(g.flush())},30),typeof w.unref=="function"&&w.unref())};e.on("data",xe)})}import ms from"node:fs";import xt from"node:path";import{homedir as Nl}from"node:os";import{spawnSync as Tl}from"node:child_process";var hS=/^[A-Z0-9][A-Z0-9._-]{0,11}$/;function gS(e){let t=String(e||"").trim();if(!t||t.includes("ts.net")||!/^https:\/\//i.test(t))return null;try{return new URL(t)}catch{return null}}function Qf(e,{coin:t,side:r,sizeUsd:n,leverage:o,venue:i,confirm:s,user:a}={}){let l=gS(e);if(!l)return null;if(t&&hS.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()}Ri();var hL=Object.freeze([100,50,25]),gL=Object.freeze([100,50,25,10]);var Q="UNKNOWN",SL=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),yS=/[_*[\]`]/g;function D(e){return ke(e)?String(e).replace(yS,t=>`\\${t}`):Q}function ke(e){return e==null?!1:typeof e=="number"?Number.isFinite(e):typeof e=="string"?e.trim()!=="":!0}function bt(e){if(!ke(e))return Q;let t=String(e).replace(/`/g,"");return t===""?Q:`\`${t}\``}function Ir(e,{decimals:t=2}={}){if(!ke(e))return Q;let r=Number(e);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:t}):Q}function Te(e,{decimals:t=2}={}){let r=Ir(e,{decimals:t});return r===Q?Q:`${r} USD`}function Ga(e,{decimals:t=2}={}){let r=Ir(e,{decimals:t});return r===Q?Q:`${r}%`}function Pi(e){let t=Ir(e,{decimals:0});return t===Q?Q:`${t} bps`}function Or(e,t){if(!ke(e))return Q;let r=Number(t);if(!Number.isInteger(r)||r<0||r>77)return Q;let n;try{n=BigInt(typeof e=="string"?e.trim():e)}catch{return Q}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 Ya(e){if(typeof e=="number"&&Number.isFinite(e))return e<0||e>1?Q: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 Q}function Xt(e={}){let t=e.chainId;if(!ke(t)||!Number.isFinite(Number(t)))return ke(e.chain)?D(e.chain):Q;let n=Li(t)?.name||(ke(e.chain)?String(e.chain):Q);return`${D(n)} (chainId ${Number(t)})`}function tp(e={}){return D(e.venue??e.dex??e.pool?.venue)}function bS(e){return e==null?"NONE (text card only)":typeof e=="string"?e.trim()?bt(e):"NONE (text card only)":e.error||e.ok===!1||e.available===!1?`UNAVAILABLE${ke(e.error)?` \u2014 ${D(e.error)}`:""} (text card stands)`:ke(e.url)?bt(e.url):"NONE (text card only)"}function Mi(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(ke(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 xS(e){let t=Mi(e);return t.allowed?`${t.actions.map(r=>D(r)).join(" / ")} (${D(t.reason)})`:`prepare-only \u2014 ${D(t.reason)}`}function $t(e,t,r={}){let n=[`*${e}*`];for(let[o,i]of t)n.push(`${o}: ${i==null||i===""?Q:i}`);return n.push(`Chart: ${bS(r.chart)}`),n.push(`Actions: ${xS(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>D(o)).join("; ")}`),(ke(r.source)||ke(r.fetchedAt))&&n.push(`Source: ${D(r.source)} at ${D(r.fetchedAt)}`),n.join(`
66
- `)}function Nt(e){return["Confidence",Ya(e.confidence)]}function SS(e){let t=e.quote;if(!t||typeof t!="object")return[];let r=ke(t.decimals)?Or(t.amountOutRaw??t.out??t.raw,t.decimals):Q;return[["Quote out (raw)",bt(t.amountOutRaw??t.out??t.raw)],["Quote out",r===Q?Q:`${D(r)} ${D(t.symbol??"")}`.trim()]]}function rp(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",Q];let r=Pi(t.selectedBps),n=Pi(t.capBps);return["Auto-slippage",r===Q&&n===Q?Q:`${r} selected, cap ${n}`]}function ES(e={}){let t=e||{};return $t(`ORACLE TOKEN \u2014 ${D(t.symbol??t.token??t.name)}`,[["Chain",Xt(t)],["Venue",tp(t)],["Name",D(t.name)],["Address",bt(t.address??t.mint??t.contract)],["Price",Te(t.priceUsd,{decimals:8})],["Market cap",Te(t.marketCapUsd)],["Liquidity",Te(t.liquidityUsd)],["Volume 24h",Te(t.volume24hUsd)],["Change 24h",Ga(t.priceChange24h)],["Fee tier",ke(t.feeTier)?`${Pi(Number(t.feeTier)/100)} (${Ir(t.feeTier,{decimals:0})})`:Q],["Age",D(t.age)],...SS(t),rp(t),Nt(t)],t)}function vS(e={}){let t=e||{};return $t(`ORACLE LAUNCH \u2014 ${D(t.symbol??t.token??t.name)}`,[["Chain",Xt(t)],["Venue",tp(t)],["Address",bt(t.address??t.mint??t.contract)],["Pool",bt(t.pool?.address??t.poolAddress??t.pool)],["Liquidity",Te(t.liquidityUsd)],["Route ready",D(t.routeReady)],["Sellable",D(t.sellable)],["Sell sim",D(t.sellSimulation??t.sellSim)],["Smart wallets",D(t.smartWalletOverlap)],["Risk",D(t.risk??t.riskStatus)],["Prepared ticket",D(t.preparedTicket??t.ticketStatus)],rp(t),Nt(t)],t)}function kS(e={}){let t=e||{};return $t(`ORACLE HIP-3 \u2014 ${D(t.market??t.coin??t.name)}`,[["Venue",`Hyperliquid builder-dex ${D(t.dex)}`],["Market",D(t.market??t.coin)],["Mark",Te(t.markPx,{decimals:6})],["Oracle",Te(t.oraclePx,{decimals:6})],["Funding",Ga(t.funding,{decimals:6})],["Open interest",Te(t.openInterestUsd)],["Depth",D(t.depth)],["Liquidation notes",D(t.liquidationNotes??t.riskNotes)],["Account context",D(t.accountContext)],Nt(t)],t)}function AS(e={}){let t=e||{};return $t(`ORACLE HIP-4 \u2014 ${D(t.event??t.market??t.name)}`,[["Venue",`Hyperliquid HIP-4 ${D(t.dex??"outcome")}`],["Event",D(t.event)],["Outcome",D(t.outcome)],["Market id",bt(t.marketId??t.market)],["Bid",Te(t.bid,{decimals:6})],["Ask",Te(t.ask,{decimals:6})],["Depth",D(t.depth)],["Edge",Ga(t.edge)],["Position",D(t.position)],Nt(t)],t)}function _S(e={}){let t=e||{};return $t(`ORACLE POLYMARKET \u2014 ${D(t.event??t.market??t.name)}`,[["Venue","Polymarket CLOB"],["Event",D(t.event)],["Market",D(t.market)],["Market id",bt(t.marketId??t.conditionId??t.tokenId)],["Yes",Te(t.yesPrice,{decimals:4})],["No",Te(t.noPrice,{decimals:4})],["Best bid / ask",`${Te(t.bestBid,{decimals:4})} / ${Te(t.bestAsk,{decimals:4})}`],["Volume",Te(t.volumeUsd)],["Resolution risk",D(t.resolutionRisk)],["Order intent",D(t.orderIntent)],Nt(t)],t)}function IS(e={}){let t=e||{},r=ke(t.completedSplits)&&ke(t.totalSplits)?`${Ir(t.completedSplits,{decimals:0})} / ${Ir(t.totalSplits,{decimals:0})}`:Q;return $t(`ORACLE TWAP \u2014 ${D(t.pair??t.symbol??t.name)}`,[["Chain",Xt(t)],["Side",D(t.side??t.direction)],["Amount",`${D(Or(t.amountTotal??t.amount,t.decimals??18))} ${D(t.symbol??"")}`.trim()],["Splits",`${Ir(t.totalSplits,{decimals:0})} over ${D(t.window)}`],["Progress",r],["Avg price",Te(t.averagePrice,{decimals:6})],["Next split",D(t.nextSplitAt)],["Slippage cap",Pi(t.slippageBps)],["Status",D(t.status)],Nt(t)],t)}function OS(e={}){let t=e||{},r=t.approval??t.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${D(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return $t(`ORACLE BRIDGE \u2014 ${D(t.pair??t.fromSymbol)} \u2192 ${D(t.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",Xt({chainId:t.fromChainId,chain:t.fromChain})],["To chain",Xt({chainId:t.toChainId,chain:t.toChain})],["Amount",`${D(Or(t.amount,t.fromDecimals??18))} ${D(t.fromSymbol??"")}`.trim()],["Best route",D(t.bestRoute??t.winner)],["Est. received",`${D(Or(t.amountOut,t.toDecimals??18))} ${D(t.toSymbol??"")}`.trim()],["Fee",Te(t.feeUsd)],["Est. time",D(t.estimatedTime)],["Revoke check",n],["All providers",D(t.providers?.join(", "))],["Preparable",D(t.preparable)],Nt(t)],t)}function TS(e){let r=(Array.isArray(e)?e:[]).slice(1,4).map(n=>{let o=D(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("; "):Q}function CS(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return ke(t)?D(t):Q}function $S(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=`${D(t.tokenInSymbol??t.fromSymbol??"IN")} \u2192 ${D(t.tokenOutSymbol??t.toSymbol??"OUT")}`,s=[["Intent",D(t.intent??"swap")],["Chain",Xt({chainId:t.chainId??r.chainId,chain:t.chain??r.chain})],["Pair",i],["Amount in",`${D(Or(t.amountIn??r.amountIn,t.decimalsIn??18))} ${D(t.tokenInSymbol??"")}`.trim()],["Best swap",D(o.source??o.venue??r.bestRoute??t.bestRoute)],["Net out",`${D(Or(o.netOut??o.amountOut??r.amountOut,t.decimalsOut??18))} ${D(t.tokenOutSymbol??"")}`.trim()],["Ranked on",CS(r)],["Gas accounted",D(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",ke(r.improvementBps)?`${D(r.improvementBps)} bps`:Q],["Runners-up",TS(r.routes??t.routes)]];if(n){let a=n.best??n.winner??{};s.push(["Best bridge",D(a.source??n.bestRoute??t.bestBridge)],["Bridge out",`${D(Or(a.netOut??a.amountOut??n.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${D(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",Xt({chainId:n.toChainId??t.toChainId,chain:n.toChain??t.toChain})],["Est. time",D(n.estimatedTime??a.meta?.durationSeconds)])}else s.push(["Best bridge","same-chain \u2014 use Best swap"]);return s.push(["Preparable",D(t.preparable??o.executionReady)],Nt(t)),$t(`ORACLE SWAP \u2014 ${i}`,s,t)}function NS(e={}){let t=e||{};return $t("ORACLE APPROVE \u2014 local signer",[["Pending id",bt(t.id??(typeof t.digest=="string"?t.digest.slice(0,8):null))],["Surface",D(t.surface)],["Action",D(t.action)],["Chain",Xt({chainId:t.chain??t.chainId,chain:t.chainName})],["To",bt(t.to??t.destination)],["Value",ke(t.value)?D(t.value):Q],["Signer",D(t.armed===!0?"running + armed":t.armed===!1?"running, disarmed":"not running")],Nt({confidence:t.confidence??(t.armed===!0?"high":"low")})],t)}var EL=Object.freeze({token:ES,launch:vS,hip3:kS,hip4:AS,polymarket:_S,twap:IS,bridge:OS,swap:$S,approve:NS});var LS=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),_L=new Set(LS),np=/^[a-z0-9-]{4,40}$/i;function op(){return{links:{},artifacts:{},threads:{}}}var RS=op();function PS(){return RS}function Zt(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function Ja(e){if(Array.isArray(e))return e.map(Ja);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]=Ja(n));return t}function MS({platform:e="telegram",artifactId:t,openUrl:r,hasGrant:n=!1}={}){let o=String(t||"").trim().toLowerCase();if(!np.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=f=>Qf(r,{side:f}),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 Zt(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(f=>f.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function FS(e={}){let r=[`*${Zt(e.title)?D(e.title):"Oracle artifact"}*`,`Kind: ${Zt(e.kind)?D(e.kind):Q}`,`Id: ${Zt(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:Q}`,`Summary: ${Zt(e.summary)?D(e.summary):Q}`,`Confidence: ${Ya(e.confidence)}`];(Zt(e.source)||Zt(e.fetchedAt))&&r.push(`Source: ${D(e.source)} at ${D(e.fetchedAt)}`),Array.isArray(e.warnings)&&e.warnings.length&&r.push(`Warnings: ${e.warnings.map(o=>D(o)).join("; ")}`);let n=Mi(e);return r.push(n.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${D(n.reason)}`),r.join(`
65
+ `),K=1}u.push(`model:${W.id}:${K}`),typeof e.setRawMode=="function"&&e.setRawMode(!0),e.resume(),z(),d="menu",A()},ge=W=>{for(let U of W){if(U.ctrl&&U.name==="c"){M({completed:!1,actions:u,reason:"cancel"});return}if(d==="token"){if(U.name==="escape"){m="",h="",d="menu",A();continue}if(U.name==="return"){G();continue}if(U.name==="backspace"||U.sequence==="\x7F"||U.sequence==="\b"){m=m.slice(0,-1),h="",A();continue}let ee=U.sequence||"";if(ee&&!U.ctrl&&!U.meta&&ee!=="\x1B"){if(ee.startsWith("\x1B"))continue;m+=ee,h="",A()}continue}if(d==="confirm-gateway"){if(U.name==="up"||U.name==="down"){p=p===0?1:0,A();continue}if(U.name==="escape"){d="menu",A();continue}U.name==="return"&&(p===0?Y({action:"gateway",id:"gateway"}):(d="menu",A()));continue}if(d==="notice"){(U.name==="return"||U.name==="escape")&&(d="menu",A());continue}if(d==="model"){let ee=b.length;if(U.name==="up"){c=ee?(c-1+ee)%ee:0,A();continue}if(U.name==="down"){c=ee?(c+1)%ee:0,A();continue}if(U.name==="escape"){d="menu",A();continue}U.name==="return"&&ae(b[c]);continue}let K=_.length;if(U.name==="up"){f=K?(f-1+K)%K:0,A();continue}if(U.name==="down"){f=K?(f+1)%K:0,A();continue}if(U.name==="escape"){M({completed:!0,actions:u,reason:"esc"});continue}U.name==="return"&&Y(_[f])}},xe=W=>{ge(g.push(W)),w&&(clearTimeout(w),w=null),g.pending>0&&(w=setTimeout(()=>{w=null,ge(g.flush())},30),typeof w.unref=="function"&&w.unref())};e.on("data",xe)})}import ms from"node:fs";import xt from"node:path";import{homedir as Nl}from"node:os";import{spawnSync as Tl}from"node:child_process";var hS=/^[A-Z0-9][A-Z0-9._-]{0,11}$/;function gS(e){let t=String(e||"").trim();if(!t||t.includes("ts.net")||!/^https:\/\//i.test(t))return null;try{return new URL(t)}catch{return null}}function Qf(e,{coin:t,side:r,sizeUsd:n,leverage:o,venue:i,confirm:s,user:a}={}){let l=gS(e);if(!l)return null;if(t&&hS.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()}Ri();var hL=Object.freeze([100,50,25]),gL=Object.freeze([100,50,25,10]);var Z="UNKNOWN",SL=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),yS=/[_*[\]`]/g;function D(e){return ke(e)?String(e).replace(yS,t=>`\\${t}`):Z}function ke(e){return e==null?!1:typeof e=="number"?Number.isFinite(e):typeof e=="string"?e.trim()!=="":!0}function bt(e){if(!ke(e))return Z;let t=String(e).replace(/`/g,"");return t===""?Z:`\`${t}\``}function Ir(e,{decimals:t=2}={}){if(!ke(e))return Z;let r=Number(e);return Number.isFinite(r)?r.toLocaleString("en-US",{minimumFractionDigits:0,maximumFractionDigits:t}):Z}function Te(e,{decimals:t=2}={}){let r=Ir(e,{decimals:t});return r===Z?Z:`${r} USD`}function Ga(e,{decimals:t=2}={}){let r=Ir(e,{decimals:t});return r===Z?Z:`${r}%`}function Pi(e){let t=Ir(e,{decimals:0});return t===Z?Z:`${t} bps`}function Or(e,t){if(!ke(e))return Z;let r=Number(t);if(!Number.isInteger(r)||r<0||r>77)return Z;let n;try{n=BigInt(typeof e=="string"?e.trim():e)}catch{return Z}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 Ya(e){if(typeof e=="number"&&Number.isFinite(e))return e<0||e>1?Z: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 Z}function Xt(e={}){let t=e.chainId;if(!ke(t)||!Number.isFinite(Number(t)))return ke(e.chain)?D(e.chain):Z;let n=Li(t)?.name||(ke(e.chain)?String(e.chain):Z);return`${D(n)} (chainId ${Number(t)})`}function tp(e={}){return D(e.venue??e.dex??e.pool?.venue)}function bS(e){return e==null?"NONE (text card only)":typeof e=="string"?e.trim()?bt(e):"NONE (text card only)":e.error||e.ok===!1||e.available===!1?`UNAVAILABLE${ke(e.error)?` \u2014 ${D(e.error)}`:""} (text card stands)`:ke(e.url)?bt(e.url):"NONE (text card only)"}function Mi(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(ke(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 xS(e){let t=Mi(e);return t.allowed?`${t.actions.map(r=>D(r)).join(" / ")} (${D(t.reason)})`:`prepare-only \u2014 ${D(t.reason)}`}function $t(e,t,r={}){let n=[`*${e}*`];for(let o of t){if(!o)continue;let[i,s]=o;n.push(`${i}: ${s==null||s===""?Z:s}`)}return n.push(`Chart: ${bS(r.chart)}`),n.push(`Actions: ${xS(r)}`),Array.isArray(r.warnings)&&r.warnings.length&&n.push(`Warnings: ${r.warnings.map(o=>D(o)).join("; ")}`),(ke(r.source)||ke(r.fetchedAt))&&n.push(`Source: ${D(r.source)} at ${D(r.fetchedAt)}`),n.join(`
66
+ `)}function Nt(e){let t=Ya(e.confidence);return t===Z?null:["Confidence",t]}function SS(e){let t=e.quote;if(!t||typeof t!="object")return[];let r=ke(t.decimals)?Or(t.amountOutRaw??t.out??t.raw,t.decimals):Z;return[["Quote out (raw)",bt(t.amountOutRaw??t.out??t.raw)],["Quote out",r===Z?Z:`${D(r)} ${D(t.symbol??"")}`.trim()]]}function rp(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",Z];let r=Pi(t.selectedBps),n=Pi(t.capBps);return["Auto-slippage",r===Z&&n===Z?Z:`${r} selected, cap ${n}`]}function ES(e={}){let t=e||{};return $t(`ORACLE TOKEN \u2014 ${D(t.symbol??t.token??t.name)}`,[["Chain",Xt(t)],["Venue",tp(t)],["Name",D(t.name)],["Address",bt(t.address??t.mint??t.contract)],["Price",Te(t.priceUsd,{decimals:8})],["Market cap",Te(t.marketCapUsd)],["Liquidity",Te(t.liquidityUsd)],["Volume 24h",Te(t.volume24hUsd)],["Change 24h",Ga(t.priceChange24h)],["Fee tier",ke(t.feeTier)?`${Pi(Number(t.feeTier)/100)} (${Ir(t.feeTier,{decimals:0})})`:Z],["Age",D(t.age)],...SS(t),rp(t),Nt(t)],t)}function vS(e={}){let t=e||{};return $t(`ORACLE LAUNCH \u2014 ${D(t.symbol??t.token??t.name)}`,[["Chain",Xt(t)],["Venue",tp(t)],["Address",bt(t.address??t.mint??t.contract)],["Pool",bt(t.pool?.address??t.poolAddress??t.pool)],["Liquidity",Te(t.liquidityUsd)],["Route ready",D(t.routeReady)],["Sellable",D(t.sellable)],["Sell sim",D(t.sellSimulation??t.sellSim)],["Smart wallets",D(t.smartWalletOverlap)],["Risk",D(t.risk??t.riskStatus)],["Prepared ticket",D(t.preparedTicket??t.ticketStatus)],rp(t),Nt(t)],t)}function kS(e={}){let t=e||{};return $t(`ORACLE HIP-3 \u2014 ${D(t.market??t.coin??t.name)}`,[["Venue",`Hyperliquid builder-dex ${D(t.dex)}`],["Market",D(t.market??t.coin)],["Mark",Te(t.markPx,{decimals:6})],["Oracle",Te(t.oraclePx,{decimals:6})],["Funding",Ga(t.funding,{decimals:6})],["Open interest",Te(t.openInterestUsd)],["Depth",D(t.depth)],["Liquidation notes",D(t.liquidationNotes??t.riskNotes)],["Account context",D(t.accountContext)],Nt(t)],t)}function AS(e={}){let t=e||{};return $t(`ORACLE HIP-4 \u2014 ${D(t.event??t.market??t.name)}`,[["Venue",`Hyperliquid HIP-4 ${D(t.dex??"outcome")}`],["Event",D(t.event)],["Outcome",D(t.outcome)],["Market id",bt(t.marketId??t.market)],["Bid",Te(t.bid,{decimals:6})],["Ask",Te(t.ask,{decimals:6})],["Depth",D(t.depth)],["Edge",Ga(t.edge)],["Position",D(t.position)],Nt(t)],t)}function _S(e={}){let t=e||{};return $t(`ORACLE POLYMARKET \u2014 ${D(t.event??t.market??t.name)}`,[["Venue","Polymarket CLOB"],["Event",D(t.event)],["Market",D(t.market)],["Market id",bt(t.marketId??t.conditionId??t.tokenId)],["Yes",Te(t.yesPrice,{decimals:4})],["No",Te(t.noPrice,{decimals:4})],["Best bid / ask",`${Te(t.bestBid,{decimals:4})} / ${Te(t.bestAsk,{decimals:4})}`],["Volume",Te(t.volumeUsd)],["Resolution risk",D(t.resolutionRisk)],["Order intent",D(t.orderIntent)],Nt(t)],t)}function IS(e={}){let t=e||{},r=ke(t.completedSplits)&&ke(t.totalSplits)?`${Ir(t.completedSplits,{decimals:0})} / ${Ir(t.totalSplits,{decimals:0})}`:Z;return $t(`ORACLE TWAP \u2014 ${D(t.pair??t.symbol??t.name)}`,[["Chain",Xt(t)],["Side",D(t.side??t.direction)],["Amount",`${D(Or(t.amountTotal??t.amount,t.decimals??18))} ${D(t.symbol??"")}`.trim()],["Splits",`${Ir(t.totalSplits,{decimals:0})} over ${D(t.window)}`],["Progress",r],["Avg price",Te(t.averagePrice,{decimals:6})],["Next split",D(t.nextSplitAt)],["Slippage cap",Pi(t.slippageBps)],["Status",D(t.status)],Nt(t)],t)}function OS(e={}){let t=e||{},r=t.approval??t.revokeCheck??{},n=r.needsRevoke&&r.spender?`revoke.cash \u2014 ${D(r.spender)}`:r.needsRevoke===!1?"revoke.cash \u2014 clean":"revoke.cash \u2014 unchecked";return $t(`ORACLE BRIDGE \u2014 ${D(t.pair??t.fromSymbol)} \u2192 ${D(t.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",Xt({chainId:t.fromChainId,chain:t.fromChain})],["To chain",Xt({chainId:t.toChainId,chain:t.toChain})],["Amount",`${D(Or(t.amount,t.fromDecimals??18))} ${D(t.fromSymbol??"")}`.trim()],["Best route",D(t.bestRoute??t.winner)],["Est. received",`${D(Or(t.amountOut,t.toDecimals??18))} ${D(t.toSymbol??"")}`.trim()],["Fee",Te(t.feeUsd)],["Est. time",D(t.estimatedTime)],["Revoke check",n],["All providers",D(t.providers?.join(", "))],["Preparable",D(t.preparable)],Nt(t)],t)}function TS(e){let r=(Array.isArray(e)?e:[]).slice(1,4).map(n=>{let o=D(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("; "):Z}function CS(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return ke(t)?D(t):Z}function $S(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=`${D(t.tokenInSymbol??t.fromSymbol??"IN")} \u2192 ${D(t.tokenOutSymbol??t.toSymbol??"OUT")}`,s=[["Intent",D(t.intent??"swap")],["Chain",Xt({chainId:t.chainId??r.chainId,chain:t.chain??r.chain})],["Pair",i],["Amount in",`${D(Or(t.amountIn??r.amountIn,t.decimalsIn??18))} ${D(t.tokenInSymbol??"")}`.trim()],["Best swap",D(o.source??o.venue??r.bestRoute??t.bestRoute)],["Net out",`${D(Or(o.netOut??o.amountOut??r.amountOut,t.decimalsOut??18))} ${D(t.tokenOutSymbol??"")}`.trim()],["Ranked on",CS(r)],["Gas accounted",D(o.costAccounted===!0?"yes":o.costAccounted===!1?"no \u2014 gross ranking may flatter this route":null)],["Spread vs next",ke(r.improvementBps)?`${D(r.improvementBps)} bps`:Z],["Runners-up",TS(r.routes??t.routes)]];if(n){let a=n.best??n.winner??{};s.push(["Best bridge",D(a.source??n.bestRoute??t.bestBridge)],["Bridge out",`${D(Or(a.netOut??a.amountOut??n.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${D(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",Xt({chainId:n.toChainId??t.toChainId,chain:n.toChain??t.toChain})],["Est. time",D(n.estimatedTime??a.meta?.durationSeconds)])}else s.push(["Best bridge","same-chain \u2014 use Best swap"]);return s.push(["Preparable",D(t.preparable??o.executionReady)],Nt(t)),$t(`ORACLE SWAP \u2014 ${i}`,s,t)}function NS(e={}){let t=e||{};return $t("ORACLE APPROVE \u2014 local signer",[["Pending id",bt(t.id??(typeof t.digest=="string"?t.digest.slice(0,8):null))],["Surface",D(t.surface)],["Action",D(t.action)],["Chain",Xt({chainId:t.chain??t.chainId,chain:t.chainName})],["To",bt(t.to??t.destination)],["Value",ke(t.value)?D(t.value):Z],["Signer",D(t.armed===!0?"running + armed":t.armed===!1?"running, disarmed":"not running")],Nt({confidence:t.confidence??(t.armed===!0?"high":"low")})],t)}var EL=Object.freeze({token:ES,launch:vS,hip3:kS,hip4:AS,polymarket:_S,twap:IS,bridge:OS,swap:$S,approve:NS});var LS=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),_L=new Set(LS),np=/^[a-z0-9-]{4,40}$/i;function op(){return{links:{},artifacts:{},threads:{}}}var RS=op();function PS(){return RS}function Zt(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function Ja(e){if(Array.isArray(e))return e.map(Ja);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]=Ja(n));return t}function MS({platform:e="telegram",artifactId:t,openUrl:r,hasGrant:n=!1}={}){let o=String(t||"").trim().toLowerCase();if(!np.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=f=>Qf(r,{side:f}),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 Zt(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(f=>f.length>0)},cancelHint:"LONG/SHORT open the graph. CONFIRM there. Telegram never sends."}:{kind:"text_menu",text:"TA / FA / LONG / SHORT",cancelHint:""}}function FS(e={}){let r=[`*${Zt(e.title)?D(e.title):"Oracle artifact"}*`,`Kind: ${Zt(e.kind)?D(e.kind):Z}`,`Id: ${Zt(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:Z}`,`Summary: ${Zt(e.summary)?D(e.summary):Z}`],n=Ya(e.confidence);n!==Z&&r.push(`Confidence: ${n}`),(Zt(e.source)||Zt(e.fetchedAt))&&r.push(`Source: ${D(e.source)} at ${D(e.fetchedAt)}`),Array.isArray(e.warnings)&&e.warnings.length&&r.push(`Warnings: ${e.warnings.map(i=>D(i)).join("; ")}`);let o=Mi(e);return r.push(o.allowed?"Actions: TA / FA / LONG / SHORT open the graph. Execute on CONFIRM there.":`Actions: TA / FA / LONG / SHORT \u2014 ${D(o.reason)}`),r.join(`
67
67
  `)}function DS(e,t={},{now:r=Date.now()}={}){let n=e||op(),o=String(t.id||"").trim().toLowerCase();if(!np.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:Zt(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:Ja(t.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=i,i}function ip(e={},{grant:t=null,now:r=Date.now(),state:n}={}){let o=n||PS(),i=String(e.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),s=DS(o,{...e,id:i},{now:r}),a=Mi({grant:t},{now:r});return{text:FS({...s,grant:t}),replyMarkup:MS({artifactId:s.id,openUrl:s.openUrl,hasGrant:a.allowed}).replyMarkup,artifact:s,state:o}}var jA=6,Xh=Object.freeze([{id:"oracle",label:"oracle",detail:"native"},{id:"claude",label:"claude",detail:"OAuth",provider:"anthropic-oauth",model:"claude-sonnet-4-20250514"},{id:"codex",label:"codex",detail:"OAuth",provider:"openai-codex",model:"gpt-5.4"},{id:"grok",label:"grok",detail:"OAuth",provider:"xai-oauth",model:"grok-4.6"},{id:"openrouter",label:"openrouter",detail:"API",provider:"openrouter",model:"openrouter/auto"},{id:"nous",label:"nous",detail:"API",provider:"nous",model:"moonshotai/kimi-k3"},{id:"deepseek",label:"deepseek",detail:"API",provider:"deepseek",model:"deepseek-chat"},{id:"qwen",label:"qwen",detail:"API",provider:"qwen",model:"qwen-plus"},{id:"glm",label:"glm",detail:"API",provider:"glm",model:"glm-4.5"},{id:"kimi",label:"kimi",detail:"API",provider:"kimi",model:"kimi-k3"},{id:"mistral",label:"mistral",detail:"API",provider:"mistral",model:"mistral-large-latest"},{id:"local",label:"local",detail:"llama.cpp",provider:"local",model:"Qwen3-8B-Q4_K_M"},{id:"ollama",label:"ollama",detail:"loopback",provider:"ollama",model:"llama3.2"}]),Cl=Object.freeze(new Map([["grok-4.6",5e5],["xai-oauth/grok-4.6",5e5],["grok-4.20-reasoning",1e6],["xai-oauth/grok-4.20-reasoning",1e6],["grok-code-fast-1",256e3],["gpt-5.6-sol",272e3],["openai/gpt-5.6-sol",272e3],["nous-direct/openai/gpt-5.6-sol",272e3],["gpt-5.5",272e3],["openai/gpt-5.5",272e3],["claude-opus-5",2e5],["anthropic/claude-opus-5",2e5],["claude-opus-4-8",2e5],["claude-sonnet-4-6",2e5],["claude-fable-5",2e5],["claude-sonnet-5",2e5],["anthropic/claude-sonnet-5",2e5],["anthropic/claude-fable-5",2e5],["kimi-k3",128e3],["moonshotai/kimi-k3",128e3],["deepseek-v4-pro",128e3],["deepseek/deepseek-v4-pro",128e3],["deepseek-v4-flash",128e3],["deepseek/deepseek-v4-flash",128e3],["qwen-plus",128e3],["qwen-max",128e3],["glm-4.5",128e3],["glm-4.6",128e3]]));function Mo(e=""){return String(e).trim().replace(/^['"]|['"]$/g,"")}function Zh(e,t){let r=String(e||"").trim().toLowerCase(),n=String(t||"").trim().toLowerCase();return n&&(Cl.get(`${r}/${n}`)||Cl.get(n)||Cl.get(n.split("/").pop()))||0}function Qh(e,t,r){let n=Number(e);return Number.isFinite(n)&&n>0?Math.round(n):Zh(t,r)}function qA(e={},t,r){return Qh(e.contextLength??e.context_length??e.contextWindow??e.context_window??e.maxContext??e.max_context??e.maxPromptLength??e.max_prompt_length??e.maxTokens??e.max_tokens??e.context,t,r)}function Rn(e,t,r,n,o={}){let i=Mo(r),s=Mo(n);if(!i||!s)return;let a=`${i}\0${s}`.toLowerCase(),l=qA(o,i,s);if(t.has(a)){let u=e.find(d=>`${d.provider}\0${d.model}`.toLowerCase()===a);u&&l>0&&(u.contextLength=l),u&&o.selected&&(u.selected=!0);return}t.add(a),e.push({provider:i,model:s,contextLength:l,selected:!!o.selected})}function ps(e=[]){let t=[],r=new Set;for(let n of Array.isArray(e)?e:[])Array.isArray(n)?Rn(t,r,n[0],n[1],n[2]||{}):n&&typeof n=="object"&&Rn(t,r,n.provider,n.model,n);return t}function HA({env:e=process.env,profile:t="oracle"}={}){let r=e.HERMES_HOME||xt.join(Nl(),".hermes"),n=e.ORACLE_HERMES_PROFILE_CONFIG||xt.join(r,"profiles",t||"oracle","config.yaml");if(!ms.existsSync(n))return[];let o=[],i=new Set,s=!1,a=!1,l="",u="",d=!1,f=0,c="";for(let p of ms.readFileSync(n,"utf8").split(/\r?\n/)){let m=p.replace(/#.*$/,"");if(/^providers:\s*$/.test(m)){s=!0,d=!1,l="",a=!1,c="";continue}if(/^fallback_providers:\s*$/.test(m)){d=!0,s=!1,l="",a=!1;continue}if(/^[A-Za-z0-9_.-]+:\s*/.test(m)&&!/^\s/.test(m)&&!/^providers:/.test(m)&&!/^fallback_providers:/.test(m)&&(s=!1,d=!1,l="",a=!1,c=""),s){let h=/^ ([A-Za-z0-9_.-]+):\s*(.*)$/.exec(m);if(h){l=Mo(h[1]),a=!1,f=0,c="";continue}if(!l)continue;let S=/^ (?:context_?length|context_?window|max_?context|maxPromptLength|max_?tokens):\s*(\d+)/i.exec(m);S&&(f=Number(S[1])||0);let E=/^ default_model:\s*(\S+)/.exec(m);if(E&&Rn(o,i,l,E[1],{contextLength:f}),/^ models:\s*$/.test(m)){a=!0,c="";continue}if(a){let _=/^ ([^:\s][^:]*):\s*(.*)$/.exec(m);if(_){c=Mo(_[1]),Rn(o,i,l,c,{contextLength:f});continue}let b=/^ (?:context_?length|context_?window|max_?context|maxPromptLength|max_?tokens):\s*(\d+)/i.exec(m);b&&c&&Rn(o,i,l,c,{contextLength:Number(b[1])||0})}}else if(d){let h=/^\s*-\s*provider:\s*(\S+)/.exec(m);if(h){u=Mo(h[1]);continue}let S=/^\s*model:\s*(\S+)/.exec(m);S&&u&&Rn(o,i,u,S[1])}}return o}function zA(e={}){let t=ps(e.availableModels||[]);if(t.length)return t;let r=e.env||process.env;if(r.ORACLE_AVAILABLE_MODELS_JSON)try{let s=JSON.parse(r.ORACLE_AVAILABLE_MODELS_JSON),a=ps(s);if(a.length)return a}catch{}if(r.ORACLE_TEST_ISOLATE_SECRETS==="1")return[];let n=HA({env:r,profile:e.profile||"oracle"}),o=ps([{provider:"anthropic-oauth",model:"claude-sonnet-4-20250514",contextLength:2e5},{provider:"openai-codex",model:"gpt-5.4",contextLength:272e3},{provider:"xai-oauth",model:"grok-4.6",contextLength:5e5},{provider:"openrouter",model:"openrouter/auto",contextLength:2e5},{provider:"nous",model:"moonshotai/kimi-k3",contextLength:256e3},{provider:"deepseek",model:"deepseek-chat",contextLength:128e3},{provider:"kimi",model:"kimi-k3",contextLength:256e3},{provider:"qwen",model:"qwen-plus",contextLength:128e3},{provider:"glm",model:"glm-4.5",contextLength:128e3},{provider:"mistral",model:"mistral-large-latest",contextLength:128e3},{provider:"local",model:"Qwen3-8B-Q4_K_M",contextLength:65536},{provider:"ollama",model:"llama3.2",contextLength:131072}]),i=new Set(n.map(s=>`${s.provider}/${s.model}`.toLowerCase()));for(let s of o){let a=`${s.provider}/${s.model}`.toLowerCase();i.has(a)||(n.push(s),i.add(a))}return n}function hs(e,t,r){let n=String(t||"").trim().toLowerCase(),o=String(r||"").trim().toLowerCase();if(!o)return!1;let i=String(e.provider||"").toLowerCase(),s=String(e.model||"").toLowerCase();return s===o||s.split("/").pop()===o.split("/").pop()||`${i}/${s}`==`${n}/${o}`}function WA(e){return(e.availableModels||[]).find(t=>hs(t,e.provider,e.model))||null}function cs(e){let t=WA(e),r=Number(t?.contextLength||Zh(e.provider,e.model));Number.isFinite(r)&&r>0&&(e.contextLength=r,e.contextTokens>0&&(e.contextPercent=Math.round(e.contextTokens/r*100)))}function Jh(e){let t=String(e||"").trim().toLowerCase().replace(/^\/?@/,"");return Xh.find(r=>r.id===t||r.label===t)||null}var ls=8;function Ll(e=[],{activeId:t=""}={}){let r=[];t&&r.push({id:"__scratch__",scratch:!0,title:"scratch",model:"",chain:"",messages:[],updatedAt:0});for(let n of e)r.push(n);return r}function KA({sessions:e=[],index:t=0,width:r,palette:n,activeId:o="",confirmDeleteId:i=""}){let s=Math.max(20,Math.floor(Number(r)||80)),a=Math.max(2,s-2),l=h=>n.fg($.banner_border,h),u=" sessions ",d=`${u}${"\u2500".repeat(Math.max(0,a-u.length))}`,f=[];f.push(`${l("\u256D")}${l(d)}${l("\u256E")}`);let c=h=>`${l("\u2502")}${de(h,a)}${l("\u2502")}`,p=Ll(e,{activeId:o});if(!p.length)f.push(c(n.fg($.banner_dim," no saved chats yet \u2014 type naturally and Oracle will remember")));else{let h=p.length,S=Math.max(0,Math.min(t,h-1)),E=Math.max(0,S-Math.floor(ls/2));E+ls>h&&(E=Math.max(0,h-ls));let _=p.slice(E,E+ls);E>0&&f.push(c(n.fg($.banner_dim,` \u2191 ${E} more`))),_.forEach((g,k)=>{let O=E+k===S,N=g.id===o,w=!!(i&&g.id===i),C=w?"!":O?"\u203A":" ",M=g.scratch?"scratch":g.model?String(g.model).split("/").pop():"\u2014",z=g.scratch?"leave":g.chain?String(g.chain):"\u2014",G=`${String(g.title||"untitled").replace(/\s+/g," ")}${w?" delete?":""}`,Y=gr(G,Math.max(8,a-42)),ae=g.scratch?"":GA(g.updatedAt),ge=`${M} \xB7 ${z}`,xe=` ${C} ${Y}${N?" \u25CF":""}`,W=Math.max(1,a-ut(xe)-ut(ge)-ut(ae)-3),U=`${xe}${" ".repeat(W)}${ge}${ae?` ${ae}`:""} `;f.push(c(w?n.bg($.selection_bg,n.bold(n.fg($.error,de(U,a)))):O?n.bg($.selection_bg,n.bold(n.fg($.banner_text,de(U,a)))):n.fg(N?$.tab_active:$.banner_dim,U)))});let b=h-(E+_.length);b>0&&f.push(c(n.fg($.banner_dim,` \u2193 ${b} more`)))}let m=i?" d confirm delete esc cancel \u2190/\u2191/\u2192/\u2193 move":" \u2190/\u2191 prev \u2192/\u2193 next \u21B5 continue r rename d delete f fanout ctrl-n new esc close";return f.push(c(n.fg($.banner_dim,m))),f.push(`${l("\u2570")}${l("\u2500".repeat(a))}${l("\u256F")}`),f}var us=10;function eg(e=[],t=""){let r=String(t||"").trim().toLowerCase();return r?e.filter(n=>`${n.provider||""} ${n.model||""}`.toLowerCase().includes(r)):[...e]}function VA({models:e=[],index:t=0,query:r="",width:n,palette:o,provider:i="",model:s=""}){let a=Math.max(20,Math.floor(Number(n)||80)),l=Math.max(2,a-2),u=S=>o.fg($.banner_border,S),d=" models ",f=`${d}${"\u2500".repeat(Math.max(0,l-d.length))}`,c=[];c.push(`${u("\u256D")}${u(f)}${u("\u256E")}`);let p=S=>`${u("\u2502")}${de(S,l)}${u("\u2502")}`,m=eg(e,r),h=r?o.fg($.accent,` / ${r}`):o.fg($.banner_dim," type to filter signed-in providers first");if(c.push(p(h)),!m.length)c.push(p(o.fg($.banner_dim,r?" no models match":" no models \u2014 oracle setup model")));else{let S=m.length,E=Math.max(0,Math.min(t,S-1)),_=Math.max(0,E-Math.floor(us/2));_+us>S&&(_=Math.max(0,S-us));let b=m.slice(_,_+us);_>0&&c.push(p(o.fg($.banner_dim,` \u2191 ${_} more`))),b.forEach((k,A)=>{let N=_+A===E,w=hs(k,i,s),C=N?"\u203A":" ",M=gr(String(k.model||"").split("/").pop(),Math.max(8,l-36)),z=String(k.provider||"\u2014").replace(/-oauth$/,""),G=k.contextLength?wi(k.contextLength):"auto",Y=` ${C} ${M}${w?" \u25CF":""}`,ae=`${z} \xB7 ${G}`,ge=Math.max(1,l-ut(Y)-ut(ae)-2),xe=`${Y}${" ".repeat(ge)}${ae} `;c.push(p(N?o.bg($.selection_bg,o.bold(o.fg($.banner_text,de(xe,l)))):o.fg(w?$.tab_active:$.banner_dim,xe)))});let g=S-(_+b.length);g>0&&c.push(p(o.fg($.banner_dim,` \u2193 ${g} more`)))}return c.push(p(o.fg($.banner_dim," \u2191\u2193 move \u21B5 select type filter esc close"))),c.push(`${u("\u2570")}${u("\u2500".repeat(l))}${u("\u256F")}`),c}function GA(e){let t=Number(e)||0;if(!t)return"";let r=Math.max(0,Math.round((Date.now()-t)/1e3));return r<60?"now":r<3600?`${Math.round(r/60)}m ago`:r<86400?`${Math.round(r/3600)}h ago`:`${Math.round(r/86400)}d ago`}function ds(e){let t=Number(e);return Number.isFinite(t)?`$${t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`:"unknown"}function YA(e){let t=e?.snapshot||{},r=t.valuation||{},n=Array.isArray(t.breakdown?.liquid)?t.breakdown.liquid:[],o=t.breakdown?.nfts||{},i=Array.isArray(t.warnings)?t.warnings:[],s=["portfolio \xB7 read-only",`known ${ds(r.knownUsd)} \xB7 liquid ${ds(r.liquidKnownUsd)} \xB7 NFTs ${ds(r.nftEstimatedValueUsd)}`,String(r.label||"known priced value, not a complete portfolio total")];if(n.length){s.push(""),s.push("balances");for(let a of n.slice(0,8))s.push(`${a.name||a.family||"wallet"} ${ds(a.knownUsd)}`)}if(s.push(""),s.push(`visible NFTs ${Number(o.visibleItems||0)} \xB7 valued ${Number(r.nftValuedItems||0)} \xB7 unvalued ${Number(r.nftUnvaluedItems||0)}${Number(o.flaggedItems||0)?` \xB7 flagged ${Number(o.flaggedItems||0)}`:""}`),i.length){s.push("");for(let a of i.slice(0,4))s.push(`note: ${a}`)}return s}async function JA(e,t){return(await Promise.resolve().then(()=>(bm(),ym))).portfolioSnapshot(e,t)}async function Rl(e){let t=e||(async()=>{let{runCryptoDeskTool:r}=await Promise.resolve().then(()=>(No(),Sl));return r("signer_status")});try{return(await t())?.ok?"LOCAL SIGNER READY":"LOCAL SIGNER OFFLINE"}catch{return"LOCAL SIGNER OFFLINE"}}function XA(e=[]){let t={pass:[],query:null,model:null,provider:null,quiet:!1,cont:!1,resume:null};for(let r=0;r<e.length;r+=1){let n=e[r];if((n==="-q"||n==="--query")&&e[r+1]){t.query=e[++r],t.pass.push("-q",t.query);continue}if((n==="--model"||n==="-m")&&e[r+1]){t.model=e[++r],t.pass.push("--model",t.model);continue}if(n==="--provider"&&e[r+1]){t.provider=e[++r],t.pass.push("--provider",t.provider);continue}if(n==="--quiet"||n==="-Q"){t.quiet=!0,t.pass.push(n);continue}if(n==="--continue"||n==="-c"){t.cont=!0,t.pass.push("--continue");continue}if(n==="--resume"||n==="-r"){t.resume=e[r+1]&&!e[r+1].startsWith("-")?e[++r]:"latest";continue}t.pass.push(n)}return t}function $l(e,t){if(!t||typeof t!="object")return;let r=Number(t.context_used??t.context_tokens??t.input??t.prompt),n=Number(t.context_max??t.context_length);Number.isFinite(r)&&r>0&&(e.contextTokens=r),Number.isFinite(n)&&n>0&&(e.contextLength=n);let o=Number(t.context_percent);Number.isFinite(o)?e.contextPercent=o:e.contextLength>0&&(e.contextPercent=Math.round(e.contextTokens/e.contextLength*100))}function ZA(e){let t=e.width,r=Math.max(1,t-12),n=e.buffer||"",o=Math.max(0,Math.min(e.cursor??n.length,n.length)),i=0;o>r&&(i=o-r);let s=n.slice(i,i+r),a=o-i,l=s.slice(0,a),u=s.slice(a,a+1)||" ",d=s.slice(a+1),f=e.palette;return[`${l}${f.bg($.selection_bg,u)}${d}`]}var QA=Object.freeze([["\u21B5","send prompt"],["ctrl-n","new session"],["ctrl-k / \u2192","sessions / resume"],["ctrl-p","model selector"],["ctrl-g","copy last reply"],["esc","interrupt / clear prompt"],["ctrl-l","clear screen"],["ctrl-c","cancel"],["ctrl-d","exit when empty"],["?","this help"]]);function e_({width:e,palette:t}){let r=Math.max(20,Math.floor(Number(e)||80)),n=Math.max(2,r-2),o=l=>t.fg($.banner_border,l),i=" shortcuts ",s=l=>`${o("\u2502")}${de(l,n)}${o("\u2502")}`,a=[`${o("\u256D")}${o(`${i}${"\u2500".repeat(Math.max(0,n-i.length))}`)}${o("\u256E")}`];for(let[l,u]of QA)a.push(s(` ${t.bold(t.fg($.tab_active,l.padEnd(12)))}${t.fg($.banner_dim,u)}`));return a.push(s(t.fg($.banner_dim," ? or esc closes"))),a.push(`${o("\u2570")}${o("\u2500".repeat(n))}${o("\u256F")}`),a}function t_(e){let t=e.width,r=Math.max(0,Math.floor(Number(e.height)||0)),n=[];if(e.shortcuts&&(n.push(...e_({width:t,palette:e.palette})),n.push("")),e.picker?.kind==="model")n.push(...VA({models:e.availableModels||[],index:e.picker.index||0,query:e.picker.query||"",width:t,palette:e.palette,provider:e.provider,model:e.model})),n.push("");else if(e.picker?.kind==="setup"){let a=e.picker;a.screen==="token"?n.push(...Ka({width:t,palette:e.palette,platformKey:a.platform||"telegram",tokenLength:String(a.token||"").length,error:a.error||""})):a.screen==="confirm"?n.push(...Va({width:t,palette:e.palette,title:a.title||"restart gateway?",subtitle:a.subtitle||"apply bot tokens",index:a.index||0})):a.screen==="model"?n.push(...Ar({width:t,palette:e.palette,title:"sign in",subtitle:"\u2191\u2193 enter \xB7 OAuth or API key",rows:a.rows||_r(),index:a.index||0})):n.push(...Ar({width:t,palette:e.palette,title:"oracle setup",subtitle:"\u2191\u2193 enter \xB7 model + telegram/discord/whatsapp",rows:a.rows||et(),index:a.index||0})),n.push("")}else if(e.picker){let a=typeof e.listSessions=="function"?e.listSessions():[];n.push(...KA({sessions:a,index:e.picker.index||0,activeId:e.archiveId||"",confirmDeleteId:e.picker.confirmDeleteId||"",width:t,palette:e.palette})),n.push("")}e.liveLines.length>0&&(n.push(...e.liveLines.slice(-jA)),n.push(""));let o=Wd({prompt:ZA(e)[0],width:t,palette:e.palette,busy:e.busy,completions:e.completions});if(e.statusbar!==!1){let a=!e.busy&&!e.buffer&&e.liveLines.length===0;o.push(Kd({model:e.model,contextTokens:e.contextTokens,contextLength:e.contextLength,percent:e.contextPercent,effort:e.effort,thinking:e.thinking,chain:e.chain,session:e.sessionTitle,width:t,palette:e.palette,trayHint:a?"\u2190/\u2192 sessions \xB7 /new \xB7 ?":""}))}if(!r)return[...n,...o];let i=Math.max(0,r-o.length);return[...n.length>i?n.slice(-i):n,...o].slice(-r)}function r_(e){let t=e?.params||e||{};return{type:t.type||e?.type||"",sessionId:t.session_id||e?.session_id||"",payload:t.payload||e?.payload||{}}}function fs(e={}){return typeof e.text=="string"?e.text:typeof e.rendered=="string"?e.rendered:typeof e.message=="string"?e.message:""}function n_(e={}){let t=e.stdout||process.stdout,r=e.stdin||process.stdin,n=Math.max(20,Number(t.columns||e.columns||80)),o=Math.max(8,Number(t.rows||e.rows||24)),i=e.palette||jt({color:t.isTTY!==!1}),s=e.renderer||Pd({stdout:t,rows:t.rows,columns:n}),a=e.client||vd({python:e.python,pythonArgs:e.pythonArgs||[],cwd:e.cwd||process.cwd(),env:e.env||process.env,spawnFn:e.spawnFn,startupTimeoutMs:e.startupTimeoutMs,requestTimeoutMs:e.requestTimeoutMs}),l=new UA,u=e.now||(()=>Date.now()),d=!e.python,f=e.sessions===!1?null:e.sessions||tf({env:e.env||process.env,now:u}),c={palette:i,width:n,height:o,promptLabel:"ORACLE \u203A",buffer:"",cursor:0,model:e.model||"model",contextTokens:0,contextLength:0,contextPercent:0,effort:e.effort||"",thinking:"0s",chain:(e.env||process.env).ORACLE_ACTIVE_CHAIN||"default",executionLabel:"LOCAL SIGNER OFFLINE",busy:!1,cancelled:!1,sessionId:null,archiveId:null,agentId:e.agentId||"oracle",provider:e.provider||"",oracleProvider:e.provider||"",oracleModel:e.model||"",sessionTitle:"",goal:"",version:e.version||ya(),assistantBuffer:"",flushedLines:0,liveLines:[],assistantFrameOpen:!1,startedAt:0,queue:[],yolo:!1,fast:!1,busyPolicy:"queue",tipIndex:0,loop:null,heartbeat:null,verbose:"off",timestamps:!1,statusbar:!0,focus:!1,lastReply:"",completions:[],picker:null,shortcuts:!1,availableModels:zA(e),sessionStart:!!e.sessionStart&&!e.resume},p=null,m=null,h={renderer:s,state:c};c.listSessions=()=>f?f.list():[];function S(v=0){return un({width:c.width,palette:i,executionLabel:c.executionLabel,version:c.version,model:c.model,chain:c.chain,frameIndex:v})}async function E(){if(t.isTTY!==!0||process.env.NODE_TEST_CONTEXT)return!1;_();let v=[0,1,2,3,2,0],y=0;for(let I=0;I<v.length;I+=1){let x=S(v[I]),R=x.join(`
68
68
  `);I>0&&y>0&&t.write(`\x1B[${y}A\r\x1B[J`),t.write(`${R}
69
69
  `),y=x.length,await new Promise(T=>setTimeout(T,90))}return t.write("\x1B[2J\x1B[H"),!1}function _(){if(typeof s.getSize=="function"){let v=s.getSize()||{},y=Number(v.columns),I=Number(v.rows);Number.isFinite(y)&&y>=20&&(c.width=Math.trunc(y)),Number.isFinite(I)&&I>=8&&(c.height=Math.trunc(I))}typeof s.setLines=="function"&&s.setLines(null)}function b(){_(),s.render(t_(c))}function g(v){s.writeAbove(`${v}
@@ -78,7 +78,7 @@ try: /chain list`,{error:!0}),!0)}function z({screen:v="menu",platform:y="",star
78
78
  `)),!0}let V=_t(T);return V?(V.required?.length?z({screen:"token",platform:V.key}):(z({screen:"menu"}),w(`${V.key} uses QR/interactive hermes setup \u2014 pick it in the menu or run: oracle setup ${V.key}`)),!0):(w(`oracle setup: unknown '${T}'
79
79
  try: /setup \xB7 /setup status \xB7 /setup telegram|discord|whatsapp`,{error:!0}),!0)}function Y(v=""){if(!(!f||c.archiveId))try{let y=f.create({title:v,model:c.model,chain:c.chain,agentId:c.agentId,provider:c.provider});c.archiveId=y.id,c.sessionTitle=y.title||"",c.goal=""}catch{}}function ae(v,y){if(!(!f||!c.archiveId))try{let I=f.append(c.archiveId,{role:v,content:y});I?.title&&I.title!==c.sessionTitle&&(c.sessionTitle=I.title),f.setMeta(c.archiveId,{agentId:c.agentId,provider:c.provider,model:c.model,chain:c.chain})}catch{}}function ge(){typeof s.clear=="function"&&s.clear(),Array.isArray(s.above)&&(s.above.length=0)}function xe(v){if(v){if(v.provider&&(c.provider=v.provider),v.model&&(c.model=v.model),v.chain){let y=cn(v.chain);N(y||null),y||(c.chain=v.chain)}cs(c)}}function W(v){let y=Ht({width:c.width,palette:c.palette}),I=Array.isArray(v.messages)?v.messages:[];for(let x of I){if(x.role==="user"){let R=ba({width:c.width,palette:c.palette});g(R.top);for(let T of String(x.content).split(`
80
80
  `))for(let P of wr(T,R.textWidth))g(R.row(P));g(R.bottom),g("");continue}g(y.top);for(let R of String(x.content).split(`
81
- `))for(let T of wr(R,y.textWidth))g(y.row(T));g(y.bottom),g("")}}function U(){if(!f){w("sessions are unavailable on this surface",{error:!0});return}let y=Ll(c.listSessions(),{activeId:c.archiveId}).findIndex(I=>I.id===c.archiveId);c.picker={kind:"session",index:y>=0?y:0},b()}async function K(v){if(c.busy)return w("finish or interrupt the current turn first",{error:!0}),!1;if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let y=v==="latest"?f.latest():f.load(v);if(!y)return w(v==="latest"?"No saved chats yet. Start one with /new.":`Chat ${v} wasn't found. Use /sessions to see saved chats.`,{error:!0}),!1;try{await a.request("session.seed",{session_id:c.sessionId,messages:Ea(y),summary:y.summary||null,goal:y.goal||""})}catch{w("Saved context could not be restored. Showing the transcript instead.")}return xe(y),(y.agentId||y.provider||y.model)&&await id(y.agentId||c.agentId||"oracle",{quiet:!0,provider:y.provider||c.provider,model:y.model||c.model}),ge(),c.archiveId=y.id,c.sessionTitle=y.title||"",c.goal=y.goal||"",g(c.palette.fg($.banner_dim,`${y.title||"session"} \xB7 ${y.messages.length} messages`)),g(""),W(y),!0}async function ee(){if(c.busy)return w("finish or interrupt the current turn first",{error:!0}),!1;ge(),c.archiveId=null,c.sessionTitle="",c.goal="";try{await a.request("session.seed",{session_id:c.sessionId,messages:[],goal:""})}catch{}return w("scratch \xB7 saved chats stay in /sessions"),!0}async function Je(v=""){if(c.busy)return w("finish or interrupt the current turn first",{error:!0}),!1;if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let y=f.create({title:v,model:c.model,chain:c.chain,agentId:c.agentId,provider:c.provider});ge(),c.archiveId=y.id,c.sessionTitle=y.title||"",c.goal="";try{await a.request("session.seed",{session_id:c.sessionId,messages:[]})}catch{}return w(`New chat ready${y.title?` \xB7 ${y.title}`:""}`),!0}function B(v){if(!f)return null;let y=String(v||"").trim();if(!y||y==="current")return c.archiveId?f.load(c.archiveId):null;let I=f.load(y);if(I)return I;let x=f.list().filter(R=>String(R.id||"").startsWith(y));return x.length===1?x[0]:null}function H(v){let y=String(v||"");if(c.buffer=y,c.cursor=y.length,p&&typeof p.getState=="function"&&typeof p.setState=="function"){let I=p.getState();p.setState({...I,buffer:y,cursor:y.length})}}async function Z(v,y){if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let I=B(v),x=String(y||"").trim();if(!I||!x)return w("usage: /session rename <session> <title>",{error:!0}),!1;let R=f.setMeta(I.id,{title:x});return c.archiveId===I.id&&(c.sessionTitle=R?.title||x),w(`renamed \xB7 ${R?.title||x}`),!0}async function fe(v){if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let y=B(v);if(!y)return w(`Chat ${v||""} wasn't found. Use /sessions to see saved chats.`,{error:!0}),!1;f.remove(y.id);let I=y.title||"New chat";return c.archiveId===y.id?(await ee(),w(`Deleted \xB7 ${I}`),!0):(w(`Deleted \xB7 ${I}`),!0)}async function we(v,y){let I=B(v),x=String(y||"").trim();return!I||!x?(w("usage: /session fanout <session> <task>",{error:!0}),!1):(c.archiveId!==I.id&&await K(I.id),await Bt(`Fan out read-only subagents for this session: ${x}`),!0)}function j(v){return/unknown method/i.test(String(v?.message||v||""))}async function F(){let v;try{v=await a.request("session.context",{session_id:c.sessionId})}catch(T){if(!j(T))throw T;let P=await a.request("session.context_breakdown",{session_id:c.sessionId}),V=(P.categories||[]).find(ve=>ve.id==="conversation");v={estimatedTokens:Number(P.context_used)||0,contextLength:Number(P.context_max)||0,percent:Number(P.context_percent)||0,messages:Number(V?.tokens)>0?"":0,summary:null};let ye=Number(v.estimatedTokens)||0,Ze=Number(v.contextLength)||0,oe=ve=>ve>=1e3&&ve%1e3===0?`${ve/1e3}K`:ve.toLocaleString();return w([`context ${oe(ye)} / ${oe(Ze)} tokens \xB7 ${v.percent}%`,...(P.categories||[]).map(ve=>` ${String(ve.label||ve.id).padEnd(22)}${oe(Number(ve.tokens)||0)}`)].join(`
81
+ `))for(let T of wr(R,y.textWidth))g(y.row(T));g(y.bottom),g("")}}function U(){if(!f){w("sessions are unavailable on this surface",{error:!0});return}let y=Ll(c.listSessions(),{activeId:c.archiveId}).findIndex(I=>I.id===c.archiveId);c.picker={kind:"session",index:y>=0?y:0},b()}async function K(v){if(c.busy)return w("finish or interrupt the current turn first",{error:!0}),!1;if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let y=v==="latest"?f.latest():f.load(v);if(!y)return w(v==="latest"?"No saved chats yet. Start one with /new.":`Chat ${v} wasn't found. Use /sessions to see saved chats.`,{error:!0}),!1;try{await a.request("session.seed",{session_id:c.sessionId,messages:Ea(y),summary:y.summary||null,goal:y.goal||""})}catch{w("Saved context could not be restored. Showing the transcript instead.")}return xe(y),(y.agentId||y.provider||y.model)&&await id(y.agentId||c.agentId||"oracle",{quiet:!0,provider:y.provider||c.provider,model:y.model||c.model}),ge(),c.archiveId=y.id,c.sessionTitle=y.title||"",c.goal=y.goal||"",g(c.palette.fg($.banner_dim,`${y.title||"session"} \xB7 ${y.messages.length} messages`)),g(""),W(y),!0}async function ee(){if(c.busy)return w("finish or interrupt the current turn first",{error:!0}),!1;ge(),c.archiveId=null,c.sessionTitle="",c.goal="";try{await a.request("session.seed",{session_id:c.sessionId,messages:[],goal:""})}catch{}return w("scratch \xB7 saved chats stay in /sessions"),!0}async function Je(v=""){if(c.busy)return w("finish or interrupt the current turn first",{error:!0}),!1;if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let y=f.create({title:v,model:c.model,chain:c.chain,agentId:c.agentId,provider:c.provider});ge(),c.archiveId=y.id,c.sessionTitle=y.title||"",c.goal="";try{await a.request("session.seed",{session_id:c.sessionId,messages:[]})}catch{}return w(`New chat ready${y.title?` \xB7 ${y.title}`:""}`),!0}function B(v){if(!f)return null;let y=String(v||"").trim();if(!y||y==="current")return c.archiveId?f.load(c.archiveId):null;let I=f.load(y);if(I)return I;let x=f.list().filter(R=>String(R.id||"").startsWith(y));return x.length===1?x[0]:null}function H(v){let y=String(v||"");if(c.buffer=y,c.cursor=y.length,p&&typeof p.getState=="function"&&typeof p.setState=="function"){let I=p.getState();p.setState({...I,buffer:y,cursor:y.length})}}async function Q(v,y){if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let I=B(v),x=String(y||"").trim();if(!I||!x)return w("usage: /session rename <session> <title>",{error:!0}),!1;let R=f.setMeta(I.id,{title:x});return c.archiveId===I.id&&(c.sessionTitle=R?.title||x),w(`renamed \xB7 ${R?.title||x}`),!0}async function fe(v){if(!f)return w("sessions are unavailable on this surface",{error:!0}),!1;let y=B(v);if(!y)return w(`Chat ${v||""} wasn't found. Use /sessions to see saved chats.`,{error:!0}),!1;f.remove(y.id);let I=y.title||"New chat";return c.archiveId===y.id?(await ee(),w(`Deleted \xB7 ${I}`),!0):(w(`Deleted \xB7 ${I}`),!0)}async function we(v,y){let I=B(v),x=String(y||"").trim();return!I||!x?(w("usage: /session fanout <session> <task>",{error:!0}),!1):(c.archiveId!==I.id&&await K(I.id),await Bt(`Fan out read-only subagents for this session: ${x}`),!0)}function j(v){return/unknown method/i.test(String(v?.message||v||""))}async function F(){let v;try{v=await a.request("session.context",{session_id:c.sessionId})}catch(T){if(!j(T))throw T;let P=await a.request("session.context_breakdown",{session_id:c.sessionId}),V=(P.categories||[]).find(ve=>ve.id==="conversation");v={estimatedTokens:Number(P.context_used)||0,contextLength:Number(P.context_max)||0,percent:Number(P.context_percent)||0,messages:Number(V?.tokens)>0?"":0,summary:null};let ye=Number(v.estimatedTokens)||0,Ze=Number(v.contextLength)||0,oe=ve=>ve>=1e3&&ve%1e3===0?`${ve/1e3}K`:ve.toLocaleString();return w([`context ${oe(ye)} / ${oe(Ze)} tokens \xB7 ${v.percent}%`,...(P.categories||[]).map(ve=>` ${String(ve.label||ve.id).padEnd(22)}${oe(Number(ve.tokens)||0)}`)].join(`
82
82
  `)),!0}let y=Number(v.estimatedTokens)||0,I=Number(v.contextLength)||0,x=Number(v.percent)||0,R=T=>T>=1e3&&T%1e3===0?`${T/1e3}K`:T.toLocaleString();return w([`context ${R(y)} / ${R(I)} tokens \xB7 ${x}%`,`${Number(v.messages)||0} messages \xB7 summary ${v.summary?"present":"none"}`].join(`
83
83
  `)),!0}function q(v,y=""){if(!f||!c.archiveId||!v?.summary)return;let I=f.load(c.archiveId);if(!I)return;let x=Math.max(0,Number(v.keptPlainMessages)||0);f.setSummary(c.archiveId,{content:v.summary,focus:y,compactedMessages:Math.max(0,I.messages.length-x),mode:v.mode})}async function X(v=""){if(c.busy)return w("finish or interrupt the current turn first",{error:!0}),!0;let y;try{y=await a.request("session.compact",{session_id:c.sessionId,focus:v})}catch(I){if(!j(I))throw I;let x=await a.request("session.compress",{session_id:c.sessionId,focus_topic:v}),R=String(x.status||""),T=typeof x.summary=="string"?x.summary:typeof x.summary?.text=="string"?x.summary.text:"";if(y={compacted:R==="compressed"&&Number(x.removed)>0,mode:"semantic",summary:T,keptPlainMessages:Number(x.after_messages)||0},R==="aborted")return w("compaction aborted",{error:!0}),!0;if(x.lock_held)return w(String(x.message||"compaction already running"),{error:!0}),!0;let P=Number(x.before_tokens)||0,V=Number(x.after_tokens)||0;return q(y,v),y.compacted?w(`context compacted \xB7 ${P.toLocaleString()} \u2192 ${V.toLocaleString()} tokens \xB7 ${Number(x.removed)||0} messages summarized`):w("context is already compact"),!0}return q(y,v),y.compacted?w(`context compacted \xB7 ${y.mode}${y.summary?" \xB7 summary persisted":" \xB7 deterministic fallback"}`):w("context is already compact"),!0}function te(){let v=We()||{};c.availableModels.length||(c.availableModels=ps([{provider:v.provider||c.provider||"configured",model:v.model||c.model||"unknown",contextLength:c.contextLength}]));let y=c.availableModels.findIndex(I=>hs(I,c.provider,c.model));return c.picker={kind:"model",index:y>=0?y:0,query:""},!0}function ce(){return te()}function Se(v){let y=String(v||c.lastReply||"").trim();if(!y)return w("usage: /card [summary] or produce a reply first",{error:!0}),!0;try{let I=ip({id:`tui-${Date.now().toString(36)}`.slice(0,40),kind:"thesis",title:"Oracle card",summary:y.slice(0,800),source:"oracle-tui"},{grant:{local:!0}});w(`${I.text}
84
84
  Reply: deepen ${I.artifact.id} | refresh ${I.artifact.id}`)}catch(I){w(I?.message||"card wrap failed",{error:!0})}return!0}function Pe(v){let y=We()||{backend:"standalone"},I=y.provider,x=v.join(" "),R=v.length===1?Jh(v[0]):null;if(R?.provider&&R?.model?(I=R.provider,x=R.model):v.length>=2&&!v[0].includes("/")?(I=v[0],x=v.slice(1).join(" ")):v[0]?.includes(":")&&([I,x]=v[0].split(":")),!x)return w("usage: /model <provider> <model-id>",{error:!0}),!0;let T;try{T=At({...y,backend:y.backend&&y.backend!=="auto"?y.backend:"standalone",provider:I,model:x})}catch(P){return w(`model not saved: ${P?.message||P}`,{error:!0}),!0}return c.provider=T.provider||c.provider,c.model=T.model||c.model,c.availableModels.some(P=>hs(P,c.provider,c.model))||c.availableModels.push({provider:c.provider||"configured",model:c.model,contextLength:Qh(T.contextLength,c.provider,c.model)}),cs(c),f&&c.archiveId&&f.setMeta(c.archiveId,{provider:c.provider,model:c.model}),a.request("session.configure",{session_id:c.sessionId,provider:c.provider,model:c.model}).catch(P=>w(`model applied locally \xB7 client: ${P?.message||P}`,{error:!0})),w(`model ${T.provider} / ${T.model}`),!0}async function Ee(){let v=We()||{},y=await a.request("session.context",{session_id:c.sessionId}).catch(()=>({}));return w([`model ${c.model||v.model||"unknown"}`,`provider ${v.provider||"unset"} \xB7 backend ${v.backend||"auto"}`,`chain ${c.chain||"default"}`,`signer ${c.executionLabel||"unknown"}`,`context ${Number(y.estimatedTokens)||0} / ${Number(y.contextLength)||0} \xB7 ${Number(y.percent)||0}%`].join(`
@@ -100,7 +100,7 @@ ${nt(P.content)}
100
100
  `))}catch(R){w(`portfolio unavailable: ${R?.message||R}`,{error:!0})}return!0})():!1}async function O0(v){let y=String(v||"").trim(),I=La(y);if(!I)return y.startsWith("/")?(w(`unknown command '${y}' \u2014 try /help`,{error:!0}),!0):!1;let x=I.args,R=x?x.split(/\s+/):[];switch(I.name){case"help":return w(["/sessions browse saved chats","/new [title] start a fresh chat","/resume resume latest chat","/leave leave session, keep history","/agent [name] switch Oracle agent tab","/portfolio wallet balances, NFTs, known value","/context show current context budget and summary state","/compact [focus] summarize old turns and persist the checkpoint","/compress [focus] alias for /compact","/usage same as /context plus live model","/status model, chain, signer, context","/model [prov id] switch model now","/memory show durable memory","/steer <note> steer this session","/goal <goal> pin the session objective","/update ask Oracle for a progress update","/undo [n] rewind last n user turns","/retry undo last turn and resubmit it","/title [name] rename the current session","/export write redacted transcript under config dir","/reset alias for /new","/session rm|rename|fanout manage saved chats","/chain list or switch chains","/setup messaging + model onboarding menu","/setup telegram telegram bot how-to","/setup discord discord bot how-to","/setup whatsapp whatsapp qr / cloud how-to","/setup status channel ready/unset (no secrets)","/clear repaint the screen","/exit leave oracle","",...Rf(x)].join(`
101
101
  `)),!0;case"setup":return G(`/setup${x?` ${x}`:""}`);case"hotkeys":return w(Pf().join(`
102
102
  `)),!0;case"sessions":return f?(U(),!0):(w("sessions are unavailable on this surface",{error:!0}),!0);case"new":return Je(x).then(()=>!0).catch(T=>(w(T?.message||"new session failed",{error:!0}),!0));case"resume":return K(x||"latest").then(()=>!0).catch(T=>(w(T?.message||"resume failed",{error:!0}),!0));case"leave":return ee().then(()=>!0).catch(T=>(w(T?.message||"leave failed",{error:!0}),!0));case"context":case"usage":return F().catch(T=>(w(T?.message||"context status unavailable",{error:!0}),!0));case"compress":return X(x).catch(T=>(w(T?.message||"context compaction failed",{error:!0}),!0));case"model":return R.length?Pe(R):ce();case"card":return Se(x);case"status":return Ee().catch(T=>(w(T?.message||"status unavailable",{error:!0}),!0));case"memory":return lt();case"undo":return je(R[0]).catch(T=>(w(T?.message||"undo failed",{error:!0}),!0));case"retry":return tt().catch(T=>(w(T?.message||"retry failed",{error:!0}),!0));case"title":return!f||!c.archiveId||!x?(w(c.sessionTitle?`title ${c.sessionTitle}`:"usage: /title <name>",{error:!x}),!0):(f.setMeta(c.archiveId,{title:x}),c.sessionTitle=x,w(`title ${c.sessionTitle}`),!0);case"export":return Oe(R[0]||"");case"copy":return Yr();case"session":{if(!f)return w("sessions are unavailable on this surface",{error:!0}),!0;let T=(R[0]||"list").toLowerCase();return T==="list"||T==="ls"?(w(rf(f.list(),{now:u(),activeId:c.archiveId}).join(`
103
- `)),!0):T==="new"?Je(R.slice(1).join(" ")).then(()=>!0):T==="leave"||T==="scratch"?ee().then(()=>!0):T==="rm"||T==="delete"?fe(R[1]).then(()=>!0):T==="rename"||T==="title"?Z(R[1],R.slice(2).join(" ")).then(()=>!0):T==="fanout"||T==="fan-out"||T==="delegate"?we(R[1],R.slice(2).join(" ")).then(()=>!0):T==="resume"?K(R[1]||"latest").then(()=>!0):(w(`unknown /session verb '${T}' \u2014 try /help`,{error:!0}),!0)}case"branch":return A0(x).then(()=>!0).catch(T=>(w(T?.message||"branch failed",{error:!0}),!0));case"queue":return Et(x,{steer:!1});case"steer":return Et(x,{steer:!0});case"stop":return c.busy?(c.busy=!1,c.cancelled=!0,Xr(),w("interrupted"),a.request("session.interrupt",{session_id:c.sessionId}).catch(T=>l.emit("error",T)),!0):(w("nothing to interrupt"),!0);case"agents":return ni();case"agent":return sd(x?`/agent ${x}`:"/agent");case"goal":return ea(x?`/goal ${x}`:"/goal");case"update":return ea(x?`/update ${x}`:"/update");case"portfolio":return cd("/portfolio");case"reasoning":return rt(x);case"yolo":return yt("yolo","yolo");case"fast":return x==="on"?c.fast=!0:x==="off"?c.fast=!1:c.fast=!c.fast,w(`fast ${c.fast?"on":"off"} \xB7 session only`),!0;case"busy":{let T=String(x||"").trim().toLowerCase();return["queue","steer","interrupt"].includes(T)&&(c.busyPolicy=T),w(`busy-enter ${c.busyPolicy}`),!0}case"config":return w(af(c).join(`
103
+ `)),!0):T==="new"?Je(R.slice(1).join(" ")).then(()=>!0):T==="leave"||T==="scratch"?ee().then(()=>!0):T==="rm"||T==="delete"?fe(R[1]).then(()=>!0):T==="rename"||T==="title"?Q(R[1],R.slice(2).join(" ")).then(()=>!0):T==="fanout"||T==="fan-out"||T==="delegate"?we(R[1],R.slice(2).join(" ")).then(()=>!0):T==="resume"?K(R[1]||"latest").then(()=>!0):(w(`unknown /session verb '${T}' \u2014 try /help`,{error:!0}),!0)}case"branch":return A0(x).then(()=>!0).catch(T=>(w(T?.message||"branch failed",{error:!0}),!0));case"queue":return Et(x,{steer:!1});case"steer":return Et(x,{steer:!0});case"stop":return c.busy?(c.busy=!1,c.cancelled=!0,Xr(),w("interrupted"),a.request("session.interrupt",{session_id:c.sessionId}).catch(T=>l.emit("error",T)),!0):(w("nothing to interrupt"),!0);case"agents":return ni();case"agent":return sd(x?`/agent ${x}`:"/agent");case"goal":return ea(x?`/goal ${x}`:"/goal");case"update":return ea(x?`/update ${x}`:"/update");case"portfolio":return cd("/portfolio");case"reasoning":return rt(x);case"yolo":return yt("yolo","yolo");case"fast":return x==="on"?c.fast=!0:x==="off"?c.fast=!1:c.fast=!c.fast,w(`fast ${c.fast?"on":"off"} \xB7 session only`),!0;case"busy":{let T=String(x||"").trim().toLowerCase();return["queue","steer","interrupt"].includes(T)&&(c.busyPolicy=T),w(`busy-enter ${c.busyPolicy}`),!0}case"config":return w(af(c).join(`
104
104
  `)),!0;case"skin":return w("skin oracle-ice \xB7 wire globe + bold ORACLE"),!0;case"voice":return w("voice type-only in this TUI. TTS stays on the Hermes profile."),!0;case"approvals":return w("approvals: signer never skipped. yolo does not arm."),!0;case"history":return ri(x);case"loop":return Dt("loop",x);case"heartbeat":return Dt("heartbeat",x);case"background":return Et(x,{steer:!1});case"plan":{let T=ti();if(!x||x==="list"){let V=lf(T);return w(V.length?V.join(`
105
105
  `):"no plans yet \xB7 /plan <title>"),!0}let P=uf(T,x,c.lastReply||"");return w(`plan ${P}`),!0}case"tips":return w(sf(c.tipIndex++)),!0;case"diff":return w(cf(e.cwd||process.cwd(),x).join(`
106
106
  `)),!0;case"rlm":return w("rlm vars \xB7 children cannot sign. /rlm is host-owned, depth 1."),!0;case"verbose":return Ft();case"timestamps":return x==="on"?c.timestamps=!0:x==="off"?c.timestamps=!1:c.timestamps=!c.timestamps,w(`timestamps ${c.timestamps?"on":"off"}`),!0;case"statusbar":return x==="on"?c.statusbar=!0:x==="off"?c.statusbar=!1:c.statusbar=!c.statusbar,w(`statusbar ${c.statusbar?"on":"off"}`),!0;case"focus":return yt("focus","focus");case"skills":return ei(x);case"reload":case"reload-skills":{let T=We()||{};return T.model&&(c.model=T.model),T.reasoningEffort&&(c.effort=T.reasoningEffort),w(I.name==="reload-skills"?`skills ${Gt().length}`:"config reloaded"),!0}case"whoami":return _0();case"profile":return I0();case"version":return w(`oracle ${c.version}`),!0;case"signer":return Qs();case"venues":return ur();case"fees":return Xe();case"watch":return Jr();case"clear":case"redraw":s.clear();for(let T of S())g(T);return!0;case"quit":return await ra(),!0;default:return!1}}function T0(){let v=c.assistantBuffer.split(`
@@ -440,7 +440,7 @@ ${X}`}],persona:te,sessionId:`${g}-compact`,credential:ce,fetchFn:p,signal:q,onT
440
440
 
441
441
  ${j}`:j,te=Xs(k,{contextLength:a.contextLength}),ce=te.compacted?await u0(k,{contextLength:a.contextLength,cutAt:te.dropped,summarize:Je,signal:N.signal}):te;ce.compacted&&(k=ce.messages,ce.summary&&(A={content:ce.summary,focus:"",mode:ce.mode}),K("history.compacted",{dropped:ce.dropped,kept:k.length,keptPlainMessages:ce.keptPlainMessages,mode:ce.mode||"deterministic",summary:ce.summary||null}));let Se=n0(O),Pe=[{role:"system",content:Se?`${E}
442
442
 
443
- ${Se}`:E},...k,{role:"user",content:X}],Ee="",je=null,tt=!1,lt=Oe=>{tt||(K("message.start",{}),tt=!0),Ee+=Oe,K("message.delta",{text:Oe})};try{for(let Ft=0;Ft<_;Ft+=1){let yt=a.authType==="oauth"?await S(a.provider):null;if(w||N.signal.aborted)return;let Yr={config:a,messages:Pe,persona:E,sessionId:g,credential:yt,fetchFn:p,signal:N.signal,onText:lt,tools:b},Wn=a.protocol==="anthropic-messages"?await p0(Yr):a.protocol==="responses"?await m0(Yr):await f0(Yr);if(w||N.signal.aborted)return;let ei=Wn.text,ur=Wn.toolCalls;if(je=Wn.usage||je,ur.length===0){Pe.push({role:"assistant",content:ei}),k=Pe.slice(1),tt||K("message.start",{});let Xe=Su(W.loopVerifier,lt);K("message.complete",{text:Ee,usage:d0(je,a.contextLength),...Xe.stop_reason?{truncated:!0,stop_reason:Xe.stop_reason,note:Xe.note}:{}});return}Pe.push({role:"assistant",content:ei||null,tool_calls:ur});let Qs=ur.length,Jr=0;for(let Xe of ur){let rt,Et=null;try{if(w||N.signal.aborted)return;Et=JSON.parse(Xe.function.arguments||"{}"),rt=await hC(Xe.function.name,Et,m,{...W,signal:N.signal}),Gw(Xe.function.name,Et,rt,W.loopVerifier)}catch(Kn){rt={ok:!1,error:`invalid tool arguments: ${Kn.message}`},Jr++}rt.ok||Jr++;let ti=Array.isArray(rt?._attachments)?rt._attachments:[],Dt=rt&&typeof rt=="object"?{...rt}:rt;Dt&&typeof Dt=="object"&&delete Dt._attachments;let ri=dn(Dt);if(c)try{let Kn=dn(Et,{force:!0}),ni=dn(Dt,{force:!0}),Vn=c(Object.freeze({callId:Xe.id||null,name:Xe.function.name,args:Kn,result:ni}));Vn&&typeof Vn.catch=="function"&&Vn.catch(()=>{})}catch{}Pe.push({role:"tool",tool_call_id:Xe.id||`call_${Yu()}`,content:JSON.stringify(ri),...ti.length?{attachments:ti}:{}});try{ge.append({role:"tool",content:`${Xe.function.name}: ${JSON.stringify(ri).slice(0,2e3)}`})}catch{}}Cg({userMessage:j,toolCalls:Qs,errors:Jr,recovered:Jr>0?!!ur.length:!1,durationMs:0})}k=Pe.slice(1),tt||K("message.start",{});let Oe=Su(W.loopVerifier,lt),lr=Oe.note?`${Oe.note}. Stopped after the ${_}-step tool budget.`:`Stopped after the ${_}-step tool budget. Results above are complete; anything not yet reported was not attempted. Raise ORACLE_MAX_AGENT_STEPS to continue further in one turn.`;K("message.complete",{text:Ee,usage:d0(je,a.contextLength),truncated:!0,stop_reason:Oe.stop_reason||"max_steps",note:lr});return}catch(Oe){Oe?.name!=="AbortError"&&ee(Oe)}finally{C=!1,N=null}}function H(j){let F=B(j);return G=F,F.finally(()=>{G===F&&(G=null)}).catch(()=>{}),F}async function Z(){if(w)throw new Error("standalone client is stopped")}async function fe(j,F={}){if(w)throw new Error("standalone client is stopped");if(j==="session.create"){let q=u();return K("session.info",q),{session_id:g,info:q}}if(j==="session.configure"){if(C||M)throw new Error("a turn is already active");let q=d(F);return K("session.info",q),{ok:!0,info:q}}if(j==="session.seed"){if(C||M)throw new Error("a turn is already active");let q=Array.isArray(F.messages)?F.messages:[],X=[];for(let ce of q){let Se=ce?.role==="assistant"?"assistant":ce?.role==="user"?"user":null,Pe=typeof ce?.content=="string"?ce.content:"";!Se||!Pe.trim()||X.push({role:Se,content:Pe})}let te=Xs(X,{contextLength:a.contextLength});return k=te.compacted?te.messages:X,A=F.summary?.content?{content:String(F.summary.content),focus:String(F.summary.focus||""),mode:String(F.summary.mode||"semantic")}:null,Object.prototype.hasOwnProperty.call(F,"goal")?O=Zo(F.goal):q.length===0&&(O=""),{seeded:k.length,summary:!!A,goal:O||null}}if(j==="session.context"){let q=Js(k),X=Number(a.contextLength)||0;return{messages:k.length,estimatedTokens:q,contextLength:X,percent:X>0?Math.round(q/X*100):0,summary:!!A,goal:O||null}}if(j==="session.compact"){if(C||M)throw new Error("a turn is already active");let q=String(F.focus||O||"").trim().slice(0,240),X=await u0(k,{contextLength:a.contextLength,force:!0,focus:q,summarize:Je});k=X.messages,A=X.summary?{content:X.summary,focus:q,mode:X.mode}:null;let te=Js(k);return{compacted:X.compacted,mode:X.mode,summary:X.summary,dropped:X.dropped,keptPlainMessages:X.keptPlainMessages,messages:k.length,estimatedTokens:te,contextLength:Number(a.contextLength)||0}}if(j==="session.goal")return F.clear===!0?O="":typeof F.text=="string"&&F.text.trim()&&(O=Zo(F.text)),{ok:!0,goal:O||null};if(j==="prompt.submit"){if(C||M)throw new Error("a turn is already active");let q=String(F.text||"").trim();if(!q)throw new Error("prompt text is required");return M=!0,z=setImmediate(()=>{z=null,H(q).catch(ee)}),{accepted:!0}}if(j==="session.interrupt"){let q=!!(N&&C||M);return z&&(clearImmediate(z),z=null),M=!1,N?.abort(),{interrupted:q}}if(j==="session.usage")return{calls:0,input:0,output:0,total:0};throw new Error(`unsupported standalone method: ${j}`)}function we(){if(Y)return Y;w=!0,M=!1,z&&(clearImmediate(z),z=null),N?.abort(),U.stop();let j=G,F=Promise.resolve(h(g));return Y=(async()=>{j&&await Promise.allSettled([j]),await F})(),Y}return Object.freeze({start:Z,request:fe,stop:we,on:f.on.bind(f),off:f.off.bind(f)})}async function h0({client:e,text:t,stdout:r=process.stdout,stderr:n=process.stderr}={}){if(!e)throw new Error("standalone client is required");await e.start();let o=await e.request("session.create",{source:"cli"}),i="",s=!1;try{return await new Promise((a,l)=>{let u=d=>{let f=d?.params?.type,c=d?.params?.payload||{};if(f==="message.delta"&&typeof c.text=="string"){i+=c.text,r.write(c.text);return}if(f==="message.complete"){!i&&c.text&&r.write(String(c.text)),r.write(`
443
+ ${Se}`:E},...k,{role:"user",content:X}],Ee="",je=null,tt=!1,lt=Oe=>{tt||(K("message.start",{}),tt=!0),Ee+=Oe,K("message.delta",{text:Oe})};try{for(let Ft=0;Ft<_;Ft+=1){let yt=a.authType==="oauth"?await S(a.provider):null;if(w||N.signal.aborted)return;let Yr={config:a,messages:Pe,persona:E,sessionId:g,credential:yt,fetchFn:p,signal:N.signal,onText:lt,tools:b},Wn=a.protocol==="anthropic-messages"?await p0(Yr):a.protocol==="responses"?await m0(Yr):await f0(Yr);if(w||N.signal.aborted)return;let ei=Wn.text,ur=Wn.toolCalls;if(je=Wn.usage||je,ur.length===0){Pe.push({role:"assistant",content:ei}),k=Pe.slice(1),tt||K("message.start",{});let Xe=Su(W.loopVerifier,lt);K("message.complete",{text:Ee,usage:d0(je,a.contextLength),...Xe.stop_reason?{truncated:!0,stop_reason:Xe.stop_reason,note:Xe.note}:{}});return}Pe.push({role:"assistant",content:ei||null,tool_calls:ur});let Qs=ur.length,Jr=0;for(let Xe of ur){let rt,Et=null;try{if(w||N.signal.aborted)return;Et=JSON.parse(Xe.function.arguments||"{}"),rt=await hC(Xe.function.name,Et,m,{...W,signal:N.signal}),Gw(Xe.function.name,Et,rt,W.loopVerifier)}catch(Kn){rt={ok:!1,error:`invalid tool arguments: ${Kn.message}`},Jr++}rt.ok||Jr++;let ti=Array.isArray(rt?._attachments)?rt._attachments:[],Dt=rt&&typeof rt=="object"?{...rt}:rt;Dt&&typeof Dt=="object"&&delete Dt._attachments;let ri=dn(Dt);if(c)try{let Kn=dn(Et,{force:!0}),ni=dn(Dt,{force:!0}),Vn=c(Object.freeze({callId:Xe.id||null,name:Xe.function.name,args:Kn,result:ni}));Vn&&typeof Vn.catch=="function"&&Vn.catch(()=>{})}catch{}Pe.push({role:"tool",tool_call_id:Xe.id||`call_${Yu()}`,content:JSON.stringify(ri),...ti.length?{attachments:ti}:{}});try{ge.append({role:"tool",content:`${Xe.function.name}: ${JSON.stringify(ri).slice(0,2e3)}`})}catch{}}Cg({userMessage:j,toolCalls:Qs,errors:Jr,recovered:Jr>0?!!ur.length:!1,durationMs:0})}k=Pe.slice(1),tt||K("message.start",{});let Oe=Su(W.loopVerifier,lt),lr=Oe.note?`${Oe.note}. Stopped after the ${_}-step tool budget.`:`Stopped after the ${_}-step tool budget. Results above are complete; anything not yet reported was not attempted. Raise ORACLE_MAX_AGENT_STEPS to continue further in one turn.`;K("message.complete",{text:Ee,usage:d0(je,a.contextLength),truncated:!0,stop_reason:Oe.stop_reason||"max_steps",note:lr});return}catch(Oe){Oe?.name!=="AbortError"&&ee(Oe)}finally{C=!1,N=null}}function H(j){let F=B(j);return G=F,F.finally(()=>{G===F&&(G=null)}).catch(()=>{}),F}async function Q(){if(w)throw new Error("standalone client is stopped")}async function fe(j,F={}){if(w)throw new Error("standalone client is stopped");if(j==="session.create"){let q=u();return K("session.info",q),{session_id:g,info:q}}if(j==="session.configure"){if(C||M)throw new Error("a turn is already active");let q=d(F);return K("session.info",q),{ok:!0,info:q}}if(j==="session.seed"){if(C||M)throw new Error("a turn is already active");let q=Array.isArray(F.messages)?F.messages:[],X=[];for(let ce of q){let Se=ce?.role==="assistant"?"assistant":ce?.role==="user"?"user":null,Pe=typeof ce?.content=="string"?ce.content:"";!Se||!Pe.trim()||X.push({role:Se,content:Pe})}let te=Xs(X,{contextLength:a.contextLength});return k=te.compacted?te.messages:X,A=F.summary?.content?{content:String(F.summary.content),focus:String(F.summary.focus||""),mode:String(F.summary.mode||"semantic")}:null,Object.prototype.hasOwnProperty.call(F,"goal")?O=Zo(F.goal):q.length===0&&(O=""),{seeded:k.length,summary:!!A,goal:O||null}}if(j==="session.context"){let q=Js(k),X=Number(a.contextLength)||0;return{messages:k.length,estimatedTokens:q,contextLength:X,percent:X>0?Math.round(q/X*100):0,summary:!!A,goal:O||null}}if(j==="session.compact"){if(C||M)throw new Error("a turn is already active");let q=String(F.focus||O||"").trim().slice(0,240),X=await u0(k,{contextLength:a.contextLength,force:!0,focus:q,summarize:Je});k=X.messages,A=X.summary?{content:X.summary,focus:q,mode:X.mode}:null;let te=Js(k);return{compacted:X.compacted,mode:X.mode,summary:X.summary,dropped:X.dropped,keptPlainMessages:X.keptPlainMessages,messages:k.length,estimatedTokens:te,contextLength:Number(a.contextLength)||0}}if(j==="session.goal")return F.clear===!0?O="":typeof F.text=="string"&&F.text.trim()&&(O=Zo(F.text)),{ok:!0,goal:O||null};if(j==="prompt.submit"){if(C||M)throw new Error("a turn is already active");let q=String(F.text||"").trim();if(!q)throw new Error("prompt text is required");return M=!0,z=setImmediate(()=>{z=null,H(q).catch(ee)}),{accepted:!0}}if(j==="session.interrupt"){let q=!!(N&&C||M);return z&&(clearImmediate(z),z=null),M=!1,N?.abort(),{interrupted:q}}if(j==="session.usage")return{calls:0,input:0,output:0,total:0};throw new Error(`unsupported standalone method: ${j}`)}function we(){if(Y)return Y;w=!0,M=!1,z&&(clearImmediate(z),z=null),N?.abort(),U.stop();let j=G,F=Promise.resolve(h(g));return Y=(async()=>{j&&await Promise.allSettled([j]),await F})(),Y}return Object.freeze({start:Q,request:fe,stop:we,on:f.on.bind(f),off:f.off.bind(f)})}async function h0({client:e,text:t,stdout:r=process.stdout,stderr:n=process.stderr}={}){if(!e)throw new Error("standalone client is required");await e.start();let o=await e.request("session.create",{source:"cli"}),i="",s=!1;try{return await new Promise((a,l)=>{let u=d=>{let f=d?.params?.type,c=d?.params?.payload||{};if(f==="message.delta"&&typeof c.text=="string"){i+=c.text,r.write(c.text);return}if(f==="message.complete"){!i&&c.text&&r.write(String(c.text)),r.write(`
444
444
  `),s=!0,a(0);return}if(f==="error"){let p=c.message||c.text||"standalone chat failed";n.write(`oracle chat: ${p}
445
445
  `),s=!0,l(new Error(p))}};e.on("event",u),e.request("prompt.submit",{session_id:o.session_id,text:t}).catch(d=>{s||(s=!0,l(d))})})}finally{await e.stop()}}kr();var Ne="oracle",Qo="oracle";function S0(e){if(e==="hermes"){let t=ze();return t.ok?t.bin:null}for(let t of(process.env.PATH||"").split(ne.delimiter)){let r=ne.join(t,e);try{if(ue.existsSync(r))return r}catch{}}return null}function g0(e){try{let t=ue.readFileSync(e,"utf8").split(/\r?\n/,1)[0];if(!t.startsWith("#!"))return null;let r=t.slice(2).trim().split(/\s+/);if(r[0]?.endsWith("/env")&&r[1]?.startsWith("python"))return{command:r[0],prefix:[r[1]]};if(ne.basename(r[0]||"").startsWith("python"))return{command:r[0],prefix:r.slice(1)}}catch{}return null}function E0(e){let t=g0(e);if(t)return t;try{let n=ue.readFileSync(e,"utf8").match(/["']([^"'\r\n]+\/bin\/hermes)["']/);if(n)return g0(n[1])}catch{}return null}function FC(){return ne.join(vt,"src","cli","oracle-harness.py")}function Zs(e,t){let r=FC(),n=process.env.ORACLE_PLAIN_HARNESS==="0"?null:E0(e);return n&&ue.existsSync(r)?{command:n.command,args:[...n.prefix,r,...t]}:{command:e,args:t}}function DC(){return ne.join(vt,"skins","oracle.yaml")}function BC(e=Ne){let t=ne.join(vt,"profiles","oracle","SOUL.md");if(!ue.existsSync(t))return{ok:!1,reason:"oracle persona missing from package"};let r=ne.join(Me(),"profiles",e,"SOUL.md");return ue.existsSync(r)&&!ue.readFileSync(r,"utf8").startsWith("You are Hermes Agent, an intelligent AI assistant created by Nous Research.")?{ok:!0,reused:!0}:(be(ne.dirname(r)),ue.copyFileSync(t,r),{ok:!0,reused:!1})}function UC(e=Ne){let t=DC();if(!ue.existsSync(t))return{ok:!1,reason:"skin missing from package"};let r=ne.join(Me(),"skins"),n=ne.join(Me(),"profiles",e,"skins");be(r),be(n);let o=ue.readFileSync(t,"utf8");return ue.writeFileSync(ne.join(r,`${Qo}.yaml`),o),ue.writeFileSync(ne.join(n,`${Qo}.yaml`),o),{ok:!0,skin:Qo}}function jC(e=Ne){let t=ne.join(Me(),"profiles",e,"config.yaml");if(!ue.existsSync(t))return{ok:!1,reason:"profile config missing"};let r=S0("oracle")||ne.join(vt,"bin","oracle.mjs"),n=ne.join(Me(),"profiles",e,"oracle");be(n);let o={profile:e,skin:Qo,oracleBin:r,commands:{chain:[r,"chain"],setup:[r,"setup"]},updatedAt:new Date().toISOString()};return ue.writeFileSync(ne.join(n,"chat-surface.json"),JSON.stringify(o,null,2)+`
446
446
  `,{mode:384}),{ok:!0,marker:o}}function qC(e=Ne){let t=ne.join(vt,"skills","oracle-chat");if(!ue.existsSync(t))return{ok:!1,reason:"oracle-chat skill missing"};let r=ne.join(Me(),"profiles",e,"skills","oracle-chat");be(r);for(let n of ue.readdirSync(t)){let o=ne.join(t,n),i=ne.join(r,n);ue.statSync(o).isFile()&&ue.copyFileSync(o,i)}for(let n of["chain","setup"]){let o=ne.join(Me(),"profiles",e,"skills",n);be(o);let i=ne.join(t,`${n}.SKILL.md`),s=ne.join(t,"SKILL.md"),a=ue.existsSync(i)?ue.readFileSync(i,"utf8"):ue.readFileSync(s,"utf8");ue.writeFileSync(ne.join(o,"SKILL.md"),a)}return{ok:!0}}function HC(e=Ne){let t=S0("hermes");if(!t)return{ok:!1,reason:"hermes missing"};let r=MC(t,["-p",e,"config","set","display.skin",Qo],{encoding:"utf8",timeout:3e4});return r.status!==0?{ok:!1,reason:(r.stderr||r.stdout||"config set failed").trim()}:{ok:!0}}function w0(e){if(!ue.existsSync(e))return!1;let t=ue.readFileSync(e,"utf8");if(/^model:\s*\S+/m.test(t))return!0;let r=t.match(/^model:\s*\n((?:[ \t]+.*(?:\n|$))*)/m)?.[1]||"";return/^\s+(?:default|provider):\s*\S+/m.test(r)}function zC(e=Ne){let t=Me();if(ue.existsSync(ne.join(t,"auth.json"))||ue.existsSync(ne.join(t,"profiles",e,"auth.json")))return!0;let r=["OPENROUTER_API_KEY","ANTHROPIC_API_KEY","OPENAI_API_KEY","XAI_API_KEY","GOOGLE_API_KEY","GEMINI_API_KEY","DEEPSEEK_API_KEY","HF_TOKEN","GLM_API_KEY","KIMI_API_KEY","MOONSHOT_API_KEY","MISTRAL_API_KEY","NOUS_API_KEY","MINIMAX_API_KEY"];if(r.some(n=>process.env[n]))return!0;for(let n of[ne.join(t,".env"),ne.join(t,"profiles",e,".env")]){if(!ue.existsSync(n))continue;let o=ue.readFileSync(n,"utf8");if(r.some(i=>new RegExp(`^${i}=.+`,"m").test(o)))return!0}return!1}function y0(e=Ne){let t=Me();return w0(ne.join(t,"config.yaml"))||w0(ne.join(t,"profiles",e,"config.yaml"))||zC(e)}function b0(){return["oracle chat, filled lowercase oracle chat",""," oracle chat open interactive oracle chat",' oracle chat -q "..." one-shot query'," oracle chat --continue resume the latest saved session"," oracle chat --resume [n] resume session n from /sessions"," oracle chat --onboard replay the first-run onboarding"," oracle chat --model <m> use a model for this session"," oracle chat --backend hermes use Hermes through Oracle (claude|codex|\u2026)"," oracle chat --print-banner show oracle vX.Y.Z splash only","","inside chat:"," /sessions list saved sessions"," /resume <n> resume a session in place"," /session new [title] start a fresh session"," /chain list/select chains"," /setup messaging setup menu"," /model switch models (still one oracle persona)"," /help command reference","","brand: filled lowercase oracle + orb / classic boxed layout"].join(`