@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.
- package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
- package/dist/bin/oracle-gateway.mjs +3 -3
- package/dist/bin/oracle-telegram-mcp.mjs +5 -5
- package/dist/cli/commands/chat.mjs +6 -6
- package/dist/cli/commands/model.mjs +6 -6
- package/dist/cli/commands/swap.mjs +10 -10
- package/dist/cli/commands/telegram.mjs +6 -6
- package/package.json +1 -1
- package/public/eval-report.json +23 -9
- package/public/oracle-splash/index.html +43 -22
- package/server.json +2 -2
|
@@ -4,7 +4,7 @@ var N0=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"?nS(n):r==="openai-codex"?oS(n):iS(n)}async function Ua(e,t,r={}){let n=dt(e),o=Sr[n],i=br(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 Ot(f,"xAI OAuth discovery");s={...c.authorization_endpoint?{authorization_endpoint:xr(c.authorization_endpoint)}:{},token_endpoint:xr(c.token_endpoint)}}a=xr(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:Oi({grant_type:"refresh_token",refresh_token:i.refreshToken,client_id:o.clientId})}),d=await Ot(u,`${n} OAuth refresh`);return Ti(d,{...r,refreshToken:i.refreshToken,discovery:s})}async function jf(e,t={}){let r=dt(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=Da(t);if(o.source==="external-access-only"&&o.expiresAt&&o.expiresAt<=i+Ii)throw new Error(`${r} external OAuth access source is expired or near expiry; refresh the source authority`);if(!o.expiresAt||o.expiresAt>i+Ii)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=Da(t);if(!a.expiresAt||a.expiresAt>l+Ii)return a;let u=await Ua(r,a,t);return n.set(r,u),u};return typeof n.withLock=="function"?n.withLock(s):s()}function qf(e,t={}){try{return!!(t.store||De()).get(e)?.accessToken}catch{return!1}}function Hf(e){let t=ft(e);return{kind:"standalone",provider:t.id,model:t.model,baseUrl:t.baseUrl,authType:"oauth",protocol:t.protocol}}var Sr,Ii,Bf,sS,Er=L(()=>{vt();Sr=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"}}),Ii=12e4;sS={createOAuthStore:Ba,getOAuthStore:De,hasOAuthCredentials:qf,loginOAuth:Ci,oauthProviderConfig:ft,oauthProviderId:dt,oauthRuntimeConfig:Hf,refreshOAuthCredentials:Ua,resolveOAuthCredentials:jf}});function Ni(e){return gS.get(Number(e))||null}function Zf(e,t=process.env){let r=Ni(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}var $i,gS,Li=L(()=>{$i={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}},gS=new Map(Object.values($i).map(e=>[e.chainId,e]))});import Ir from"node:net";import DS from"node:dns";function Mi(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 Ya(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 Ja(e){if(Ir.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(Ir.isIPv6(e)){let t=Mi(e);if(!t)return!1;let r=Mi("::ffff:0:0");return Ya(t,r,96)?Ja([...t.slice(12)].join(".")):Ya(t,Mi("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>Ya(t,Mi(o),i)):!1}return!1}function US(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(BS.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=Ir.isIP(r);return n!==0&&!Ja(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function yn(e,{lookupFn:t=DS.promises.lookup}={}){let r=US(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:Ir.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=>!Ja(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function lo({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||(Ir.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(Ir.isIP(c))return[{address:c,family:Ir.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=jS((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 jS(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[Xa]=Object.freeze({pin:t}),e}function Za(e){return typeof e=="function"&&typeof e[Xa]?.pin=="function"}function op(e,t,r){if(!Za(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Xa].pin(t,r)}var BS,Xa,Qa=L(()=>{BS=new Set(["localhost","metadata.google.internal","metadata.goog"]);Xa=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as ip}from"node:crypto";function KS(e){let t=String(e||"").toLowerCase();return fp.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function VS(e){let t={};for(let[r,n]of Object.entries(e||{}))KS(r)||(t[r]=n);return t}function GS(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 YS(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function lp(e){let t=String(e?.method||"");return t?!JS.test(t):!1}function ZS(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(lp):!r||typeof r!="object"?!1:r.jsonrpc&&r.method?lp(r):typeof r.type=="string"&&XS.has(r.type)&&r.action==null&&r.signature==null&&r.nonce==null}function QS(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([...fp,...s])].sort().map(c=>`${c}=${i[c]??""}`).join(`
|
|
5
5
|
`),u=ip("sha256").update(l).digest("hex").slice(0,32),d=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`,f=o==null?"-":ip("sha256").update(String(o)).digest("hex").slice(0,32);return`${e} ${t} ${d} ${u} ${f}`}function eE(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ap):Math.min(250*2**e,ap)+Math.floor(Math.random()*100)}function uo(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function tc(e,t,r){return uo(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function fo(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function rE(e){return e?e.byteLength??e.length??0:0}async function up(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&&(fo(e),!n))throw tc(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 tc(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+=rE(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 tc(r,`streamed ${l} bytes`,t);let d=Buffer.concat(a);return(u?d.subarray(0,t):d).toString("utf8")}function dp(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function nE(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&&!Za(E))throw uo(`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 yn(g,_);if(!A.ok)throw uo(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 lo({requireUndici:!0,...d?{importUndici:d}:{}})}catch(N){throw uo(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 op(E,O,A.addresses);return A};try{let g=String(e),k={...n||{}};l&&await b(g);for(let A=0;A<=cp;A+=1){let O=await E(g,{method:r,headers:k,body:o,signal:h,redirect:"manual"});if(zS.has(O.status)){if(r!=="GET"&&r!=="HEAD"){let G=await up(O,u??WS,{url:g,truncate:!0}),Y=new Error(`HTTP ${O.status} ${r} ${g} redirected non-idempotent request`);throw Y.status=O.status,Y.body=dp(G)??G.slice(0,300),Y}if(A===cp)throw fo(O),new Error(`HTTP redirect loop for ${e}`);let C=O.headers?.get?.("location"),M;try{M=GS(C,g)}catch(G){throw fo(O),G}let z=!YS(M,g);if(fo(O),z&&(k=VS(k)),l)await b(M,{status:O.status});else if(z){let G=await yn(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 lo(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 fo(O),uo(C?.message||String(C))}let N=await up(O,u,{url:g,onOversize:()=>p.abort()}),w=dp(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):HS,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 nE(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)||qS.has(N)&&sp.has(o):!w&&sp.has(o);if(A===a||!M)throw O;let z=eE(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 tE(z)}}throw k};if(!(t.dedupe!==!1&&!p&&ZS(o,s)))return S();let _=QS(o,e,i,{untrustedUrl:d,maxResponseBytes:h},s),b=ec.get(_);if(b)return b;let g=S().finally(()=>ec.delete(_));return ec.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 bn(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 qS,sp,HS,ap,fp,zS,cp,WS,ec,JS,XS,tE,Be=L(()=>{Qa();qS=new Set([408,425,429,500,502,503,504]),sp=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),HS=2,ap=4e3,fp=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],zS=new Set([301,302,303,307,308]),cp=3,WS=64*1024;ec=new Map,JS=/(?:^|_)(send|submit|broadcast|sign|requestAirdrop)(?=[A-Z_]|$)/i,XS=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);tE=e=>new Promise(t=>setTimeout(t,e))});import{Interface as oE,getAddress as iE}from"ethers";function rc(e,t){try{return iE(e).toLowerCase()}catch{throw new Error(`${t} must be a valid EVM address`)}}function sE(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 nc(e){return e==null?null:Number.parseInt(String(e),16)}function cE(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=Zf(e,r);return n||aE[Number(e)]||null}function uE(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!lE.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 dE(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function fE(e){if(e?.error)throw dE(e.error);return e?.result}function pE(e,t,r){return`${e}
|
|
6
6
|
${t}
|
|
7
|
-
${JSON.stringify(r??[])}`}async function mE(e,t,r){return Ce(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function Or(e,t,r=[],n={}){let o=String(t||""),i=uE(o),s=cE(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=pp.get(s);if(d!=null)return d}let l=n.dedupe!==!1&&!n.signal?pE(s,o,r):null;if(l&&po.has(l))return po.get(l);let u=(async()=>{let d=await mE(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),f=fE(d);return i==="eth_chainid"&&typeof f=="string"&&pp.set(s,f),f})();return l&&(po.set(l,u),u.finally(()=>{po.get(l)===u&&po.delete(l)}).catch(()=>{})),u}async function oc(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await Or(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function mp(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=sE(e.txHash||e.hash||e.transactionHash),o=await Or(r,"eth_getTransactionReceipt",[n],t);if(!o)return{ok:!1,chainId:r,txHash:n,status:"pending",receipt:null,reason:"receipt pending"};let i=nc(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?rc(e.expectedTo,"expectedTo"):null,d=o.to?rc(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?rc(o.from,"receipt.from"):null,blockNumber:nc(o.blockNumber),transactionIndex:nc(o.transactionIndex),logs:Array.isArray(o.logs)?o.logs:[],receipt:o}}var PL,aE,lE,po,pp,xn=L(()=>{Be();Li();PL=new oE(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);aE={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"};lE=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;po=new Map,pp=new Map});var ic=L(()=>{});var UL,hp=L(()=>{Be();ic();UL=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"})});var qL,sc,ac,mo=L(()=>{qL=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),sc=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),ac=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"})});var gp=L(()=>{xn();mo()});var wp=L(()=>{xn();mo()});var yp=L(()=>{xn();hp();Be();mo();gp();wp();ic()});var bp,xp=L(()=>{yp();mo();bp=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 wE(e={}){return String(e.rpcUrl||process.env.SOLANA_RPC_URL||gE).trim()}function Tr(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 yE(e,t){return t?[...e,{commitment:t}]:e}async function Ep(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(wE(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 vp(e={},t={}){let r=Tr(e.address||e.owner,"address"),n=await Ep("getBalance",yE([r],e.commitment),t);return{provider:"solana-rpc",cluster:Sp,address:r,lamports:String(n?.value??0),slot:n?.context?.slot??null,raw:n}}function bE(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 lc(e={},t={}){let r=Tr(e.owner||e.address,"owner"),n=e.mint?{mint:Tr(e.mint,"mint")}:{programId:Tr(e.programId||cc,"token program")},o={encoding:"jsonParsed"};e.commitment&&(o.commitment=e.commitment);let i=await Ep("getTokenAccountsByOwner",[r,n,o],t),s=Array.isArray(i?.value)?i.value.map(bE):[];return{provider:"solana-rpc",cluster:Sp,owner:r,filter:n,slot:i?.context?.slot??null,accounts:s,raw:i}}var Sp,gE,cc,uc=L(()=>{Be();Sp="mainnet-beta",gE="https://api.mainnet-beta.solana.com",cc="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"});function kp(e={}){return String(e.network||process.env.BTC_NETWORK||xE).trim().toLowerCase()==="testnet"?"testnet":"mainnet"}function vE(e={}){return e.baseUrl?String(e.baseUrl).replace(/\/$/,""):process.env.BTC_ESPLORA_URL?String(process.env.BTC_ESPLORA_URL).replace(/\/$/,""):kp(e)==="testnet"?EE:SE}function Xt(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 kE(e,t={}){let r=`${vE(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 AE(e,t={}){let r=await kE(e,t);try{return JSON.parse(r)}catch{return r}}async function Ap(e={},t={}){let r=Xt(e.address||e.addr,"address"),n=await AE(`/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:kp(t),address:r,balanceSats:String(s-a),chainStats:o,mempoolStats:i,raw:n}}var xE,SE,EE,Fi=L(()=>{Be();xE="mainnet",SE="https://mempool.space/api",EE="https://mempool.space/testnet/api"});function Sn({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:Ip(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([Ip(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[_p]||"")==="1")return{baseUrl:s,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${_p}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:l}}function Ip(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function Cr(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 _p,ho=L(()=>{_p="ORACLE_ALLOW_CUSTOM_PROVIDER_URL"});function dc(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}function IE(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=dc(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=_E.includes(o)&&(i==="https:"||s)}}catch{r=!1}return Cr({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},r)}async function Op(e,t={}){let n=await(t.fetchImpl||fetch)(e,{method:"GET",headers:IE(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 Tp(e={},t={}){let r=Xt(e.address||e.addr,"address"),n=dc(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 Op(s,t),l=OE(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 OE(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 Di(e={},t={}){let r=Xt(e.address||e.addr,"address"),n=dc(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 Op(a,t),u=TE(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 TE(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 _E,fc=L(()=>{Fi();ho();_E=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"]});function NE({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"?$E:CE}async function Bi(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=NE(t);return Ce(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Cp(e={}){return Bi({type:"allMids"},e)}async function $p(e,t={}){if(!e)throw new Error("hlClearinghouse requires user address");return Bi({type:"spotClearinghouseState",user:e},t)}async function Np(e,t={}){if(!e)throw new Error("hlUserState requires user");return Bi({type:"clearinghouseState",user:e},t)}var CE,$E,pc=L(()=>{Be();CE="https://api.hyperliquid.xyz/info",$E="https://api.hyperliquid-testnet.xyz/info"});function RE(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||LE).replace(/\/$/,"")}async function mc(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return Ce(`${RE(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}var LE,Lp=L(()=>{Be();LE="https://coins.llama.fi"});function hc(e,{max:t=32,fallback:r=""}={}){return e==null?r:String(e).normalize("NFKC").replace(Rp,"").replace(ME,"").replace(PE,"").replace(/\s+/g," ").trim().slice(0,t).trim()||r}function gc(e){if(e==null)return!1;let t=String(e);return Rp.test(t)?!0:/[\u0400-\u04FF\u0370-\u03FF]/.test(t)&&/[A-Za-z]/.test(t)}var Rp,PE,ME,Pp=L(()=>{Rp=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,PE=/[<>&`*_~[\]()|\\]/g,ME=/[\u0000-\u001F\u007F]/g});function FE(e,t={}){let r=Number(e),n=t.baseUrl||Mp[r];if(!n)throw new Error(`Blockscout not configured for chainId ${r}`);return n.replace(/\/$/,"")}function Fp(e){return!!Mp[Number(e)]}async function Dp(e={},t={}){if(!e.address)throw new Error("address required");let r=Number(e.chainId||1),n=`${FE(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 Bp(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=hc(o.symbol||o.name,{max:32,fallback:"TOKEN"}),d=hc(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:gc(o.symbol)||gc(o.name)||void 0})}return r}var Mp,Up=L(()=>{Be();Pp();Mp=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 DE}from"ethers";function Zt(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,...e[t]||{}}}function Ui(e,...t){for(let r of t){let n=String(e?.[r]||"").trim();if(n)return n}return null}function jp(e){if(!e)return null;try{return DE(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function vn(e={},t=process.env){let r=e.addresses||{},n=jp(r.evm||e.evmAddress||Ui(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=r.solana||e.solanaAddress||Ui(t,"ORACLE_SOLANA_ADDRESS"),i=r.bitcoin||e.bitcoinAddress||Ui(t,"ORACLE_BITCOIN_ADDRESS"),s=jp(r.hyperliquid||e.hyperliquidAddress||Ui(t,"ORACLE_HYPERLIQUID_ADDRESS")||n);return{evm:n,solana:o?Tr(o,"portfolio Solana address"):null,bitcoin:i?Xt(i,"portfolio Bitcoin address"):null,hyperliquid:s}}function go(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 En(e){let t=Number(e);return Number.isFinite(t)?t:null}function ji(e){return Number.isFinite(e)?Number(e.toFixed(2)):null}function Qt(e){let t=Number(e);return Number.isFinite(t)&&t!==0}function Hp(e,t){let r=qp[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 UE(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:go(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 wc(e,t){return{family:e,status:"unsupported",reason:t}}function yc(e,t){if(!e||e.status!=="ok")return e;let r=Hp(t,e.symbol),n=En(e.amount),o=n!=null&&r.priceUsd!=null?ji(n*r.priceUsd):null;return{...e,price:r,usdValue:o}}async function zp(e={},t={}){let r=new Date().toISOString(),n=vn(e,t.env||process.env),o=e.includePrices!==!1,i=e.includeTokens!==!1,s=e.includeCollectibles!==!1,a=new Map(bp.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(qp))],d=o?$e(()=>mc(u,Zt(t,"prices"))):Promise.resolve({ok:!1,ms:0,error:"price lookup disabled"}),f=bn(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={...Zt(t,"evm"),rpcUrl:e.rpcUrls?.[B]||t.evm?.rpcUrls?.[B]},fe=await $e(()=>oc(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&&Fp(B)){let X=await $e(()=>Dp({chainId:B,address:n.evm},{...Zt(t,"blockscout"),timeoutMs:t.timeoutMs??18e3}));X.ok?q={status:"ok",assets:Bp(X.data,{fungibleOnly:!0}).map(ce=>{let Se=go(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:go(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=Zt(t,"solana"),H=await $e(()=>vp({address:n.solana},B)),Z=i||s?await Promise.all([$e(()=>lc({owner:n.solana,programId:cc},B)).then(q=>({...q,program:"spl-token"})),$e(()=>lc({owner:n.solana,programId:BE},B)).then(q=>({...q,program:"token-2022"}))]):[],fe=UE(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:go(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=Zt(t,"bitcoin"),H=Zt(t,"bitcoinMeta"),[Z,fe,we]=await Promise.all([$e(()=>Ap({address:n.bitcoin},B)),i?$e(()=>Tp({address:n.bitcoin},H)):Promise.resolve({ok:!1,ms:0,error:"token discovery disabled"}),s?$e(()=>Di({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:go(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=Zt(t,"hyperliquid"),[H,Z,fe]=await Promise.all([$e(()=>$p(n.hyperliquid,B)),$e(()=>Np(n.hyperliquid,B)),$e(()=>Cp(B))]),we=(H.ok&&Array.isArray(H.data?.balances)?H.data.balances:[]).filter(F=>Qt(F.total)||Qt(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=>Qt(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(()=>mc(B,Zt(t,"prices")));H.ok&&(O=H.data)}let N=h.map(B=>{let H=B.native?{...B,native:yc(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=En(we.amount),X=q!=null&&F!=null?ji(q*F):null;return{...we,priceUsd:F,usdValue:X}});H={...H,fungibleTokens:{...H.fungibleTokens,assets:fe}}}return H});S.native&&(S.native=yc(S.native,g)),E.native&&(E.native=yc(E.native,g));let w=0,C=0,M=0;for(let B of[...N,S,E]){B.native?.status==="ok"&&Qt(B.native.amount)&&(B.native.usdValue!=null?(w+=B.native.usdValue,C+=1):M+=1);for(let H of B.fungibleTokens?.assets||[])!Qt(H.amount)&&!Qt(H.amountRaw)||(H.usdValue!=null?(w+=H.usdValue,C+=1):M+=1)}let z=Hp(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||En(_.mids?.HYPE):En(_.mids?.[B.coin]),fe=En(B.total);B.priceUsd=Z,B.usdValue=fe!=null&&Z!=null?ji(fe*Z):null,Qt(B.total)&&(B.usdValue!=null?(w+=B.usdValue,C+=1):M+=1)}let G=En(_.perps?.accountValueUsd);G!=null&&G!==0&&(w+=G,C+=1);let Y=[...S.fungibleTokens?.assets||[],...S.collectibles?.assets||[]].filter(B=>Qt(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=[wc("cosmos","requires a chain-specific bech32 address and LCD/RPC adapter"),wc("sui","Sui balance adapter is not installed"),wc("aptos","Aptos balance adapter is not installed")],Ve=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:ji(w),label:"known priced value, not a complete portfolio total",pricedItems:C,unpricedNonzeroItems:M,complete:M===0&&!Ve&&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 BE,qp,bc=L(()=>{xp();Be();xn();uc();Fi();fc();pc();Lp();Up();BE="TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",qp=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 jE,qR,er=L(()=>{jE=300*1e3,qR=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var Wp=L(()=>{});import{readFileSync as qE,existsSync as HE}from"node:fs";import{getAddress as zE,Interface as qi,TypedDataEncoder as GR,parseUnits as YR}from"ethers";function JE(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!HE(e))return"";try{for(let t of qE(e,"utf8").split(`
|
|
7
|
+
${JSON.stringify(r??[])}`}async function mE(e,t,r){return Ce(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function Or(e,t,r=[],n={}){let o=String(t||""),i=uE(o),s=cE(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=pp.get(s);if(d!=null)return d}let l=n.dedupe!==!1&&!n.signal?pE(s,o,r):null;if(l&&po.has(l))return po.get(l);let u=(async()=>{let d=await mE(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),f=fE(d);return i==="eth_chainid"&&typeof f=="string"&&pp.set(s,f),f})();return l&&(po.set(l,u),u.finally(()=>{po.get(l)===u&&po.delete(l)}).catch(()=>{})),u}async function oc(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await Or(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function mp(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=sE(e.txHash||e.hash||e.transactionHash),o=await Or(r,"eth_getTransactionReceipt",[n],t);if(!o)return{ok:!1,chainId:r,txHash:n,status:"pending",receipt:null,reason:"receipt pending"};let i=nc(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?rc(e.expectedTo,"expectedTo"):null,d=o.to?rc(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?rc(o.from,"receipt.from"):null,blockNumber:nc(o.blockNumber),transactionIndex:nc(o.transactionIndex),logs:Array.isArray(o.logs)?o.logs:[],receipt:o}}var PL,aE,lE,po,pp,xn=L(()=>{Be();Li();PL=new oE(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);aE={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"};lE=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;po=new Map,pp=new Map});var ic=L(()=>{});var UL,hp=L(()=>{Be();ic();UL=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"})});var qL,sc,ac,mo=L(()=>{qL=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),sc=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),ac=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"})});var gp=L(()=>{xn();mo()});var wp=L(()=>{xn();mo()});var yp=L(()=>{xn();hp();Be();mo();gp();wp();ic()});var bp,xp=L(()=>{yp();mo();bp=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 wE(e={}){return String(e.rpcUrl||process.env.SOLANA_RPC_URL||gE).trim()}function Tr(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 yE(e,t){return t?[...e,{commitment:t}]:e}async function Ep(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(wE(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 vp(e={},t={}){let r=Tr(e.address||e.owner,"address"),n=await Ep("getBalance",yE([r],e.commitment),t);return{provider:"solana-rpc",cluster:Sp,address:r,lamports:String(n?.value??0),slot:n?.context?.slot??null,raw:n}}function bE(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 lc(e={},t={}){let r=Tr(e.owner||e.address,"owner"),n=e.mint?{mint:Tr(e.mint,"mint")}:{programId:Tr(e.programId||cc,"token program")},o={encoding:"jsonParsed"};e.commitment&&(o.commitment=e.commitment);let i=await Ep("getTokenAccountsByOwner",[r,n,o],t),s=Array.isArray(i?.value)?i.value.map(bE):[];return{provider:"solana-rpc",cluster:Sp,owner:r,filter:n,slot:i?.context?.slot??null,accounts:s,raw:i}}var Sp,gE,cc,uc=L(()=>{Be();Sp="mainnet-beta",gE="https://api.mainnet-beta.solana.com",cc="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"});function kp(e={}){return String(e.network||process.env.BTC_NETWORK||xE).trim().toLowerCase()==="testnet"?"testnet":"mainnet"}function vE(e={}){return e.baseUrl?String(e.baseUrl).replace(/\/$/,""):process.env.BTC_ESPLORA_URL?String(process.env.BTC_ESPLORA_URL).replace(/\/$/,""):kp(e)==="testnet"?EE:SE}function Xt(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 kE(e,t={}){let r=`${vE(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 AE(e,t={}){let r=await kE(e,t);try{return JSON.parse(r)}catch{return r}}async function Ap(e={},t={}){let r=Xt(e.address||e.addr,"address"),n=await AE(`/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:kp(t),address:r,balanceSats:String(s-a),chainStats:o,mempoolStats:i,raw:n}}var xE,SE,EE,Fi=L(()=>{Be();xE="mainnet",SE="https://mempool.space/api",EE="https://mempool.space/testnet/api"});function Sn({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:Ip(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([Ip(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[_p]||"")==="1")return{baseUrl:s,trusted:!1,host:l};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${l} (set ${_p}=1 to permit it)`);return{baseUrl:s,trusted:!1,host:l}}function Ip(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function Cr(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 _p,ho=L(()=>{_p="ORACLE_ALLOW_CUSTOM_PROVIDER_URL"});function dc(e={}){return String(e.baseUrl||process.env.BTC_META_API_URL||process.env.UNISAT_API_URL||"").trim().replace(/\/$/,"")}function IE(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=dc(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=_E.includes(o)&&(i==="https:"||s)}}catch{r=!1}return Cr({accept:"application/json","user-agent":"oracle-btc-meta/0.1"},{authorization:t?`Bearer ${t}`:"","x-api-key":t},r)}async function Op(e,t={}){let n=await(t.fetchImpl||fetch)(e,{method:"GET",headers:IE(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 Tp(e={},t={}){let r=Xt(e.address||e.addr,"address"),n=dc(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 Op(s,t),l=OE(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 OE(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 Di(e={},t={}){let r=Xt(e.address||e.addr,"address"),n=dc(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 Op(a,t),u=TE(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 TE(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 _E,fc=L(()=>{Fi();ho();_E=["open-api.unisat.io","open-api-testnet.unisat.io","api.bestinslot.xyz","api.hiro.so"]});function NE({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"?$E:CE}async function Bi(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=NE(t);return Ce(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function Cp(e={}){return Bi({type:"allMids"},e)}async function $p(e,t={}){if(!e)throw new Error("hlClearinghouse requires user address");return Bi({type:"spotClearinghouseState",user:e},t)}async function Np(e,t={}){if(!e)throw new Error("hlUserState requires user");return Bi({type:"clearinghouseState",user:e},t)}var CE,$E,pc=L(()=>{Be();CE="https://api.hyperliquid.xyz/info",$E="https://api.hyperliquid-testnet.xyz/info"});function RE(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||LE).replace(/\/$/,"")}async function mc(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return Ce(`${RE(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}var LE,Lp=L(()=>{Be();LE="https://coins.llama.fi"});function hc(e,{max:t=32,fallback:r=""}={}){return e==null?r:String(e).normalize("NFKC").replace(Rp,"").replace(ME,"").replace(PE,"").replace(/\s+/g," ").trim().slice(0,t).trim()||r}function gc(e){if(e==null)return!1;let t=String(e);return Rp.test(t)?!0:/[\u0400-\u04FF\u0370-\u03FF]/.test(t)&&/[A-Za-z]/.test(t)}var Rp,PE,ME,Pp=L(()=>{Rp=/[\u200B-\u200F\u202A-\u202E\u2060-\u2064\uFEFF]/g,PE=/[<>&`*_~[\]()|\\]/g,ME=/[\u0000-\u001F\u007F]/g});function FE(e,t={}){let r=Number(e),n=t.baseUrl||Mp[r];if(!n)throw new Error(`Blockscout not configured for chainId ${r}`);return n.replace(/\/$/,"")}function Fp(e){return!!Mp[Number(e)]}async function Dp(e={},t={}){if(!e.address)throw new Error("address required");let r=Number(e.chainId||1),n=`${FE(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 Bp(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=hc(o.symbol||o.name,{max:32,fallback:"TOKEN"}),d=hc(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:gc(o.symbol)||gc(o.name)||void 0})}return r}var Mp,Up=L(()=>{Be();Pp();Mp=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 DE}from"ethers";function Zt(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,...e[t]||{}}}function Ui(e,...t){for(let r of t){let n=String(e?.[r]||"").trim();if(n)return n}return null}function jp(e){if(!e)return null;try{return DE(String(e).trim().toLowerCase())}catch{throw new Error("portfolio: EVM address must be a valid 20-byte address")}}function vn(e={},t=process.env){let r=e.addresses||{},n=jp(r.evm||e.evmAddress||Ui(t,"ORACLE_EVM_ADDRESS","ORACLE_DEFAULT_ADDRESS","MAD_OPERATOR_ADDRESS")),o=r.solana||e.solanaAddress||Ui(t,"ORACLE_SOLANA_ADDRESS"),i=r.bitcoin||e.bitcoinAddress||Ui(t,"ORACLE_BITCOIN_ADDRESS"),s=jp(r.hyperliquid||e.hyperliquidAddress||Ui(t,"ORACLE_HYPERLIQUID_ADDRESS")||n);return{evm:n,solana:o?Tr(o,"portfolio Solana address"):null,bitcoin:i?Xt(i,"portfolio Bitcoin address"):null,hyperliquid:s}}function go(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 En(e){let t=Number(e);return Number.isFinite(t)?t:null}function ji(e){return Number.isFinite(e)?Number(e.toFixed(2)):null}function Qt(e){let t=Number(e);return Number.isFinite(t)&&t!==0}function Hp(e,t){let r=qp[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 UE(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:go(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 wc(e,t){return{family:e,status:"unsupported",reason:t}}function yc(e,t){if(!e||e.status!=="ok")return e;let r=Hp(t,e.symbol),n=En(e.amount),o=n!=null&&r.priceUsd!=null?ji(n*r.priceUsd):null;return{...e,price:r,usdValue:o}}async function zp(e={},t={}){let r=new Date().toISOString(),n=vn(e,t.env||process.env),o=e.includePrices!==!1,i=e.includeTokens!==!1,s=e.includeCollectibles!==!1,a=new Map(bp.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(qp))],d=o?$e(()=>mc(u,Zt(t,"prices"))):Promise.resolve({ok:!1,ms:0,error:"price lookup disabled"}),f=bn(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={...Zt(t,"evm"),rpcUrl:e.rpcUrls?.[B]||t.evm?.rpcUrls?.[B]},fe=await $e(()=>oc(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&&Fp(B)){let X=await $e(()=>Dp({chainId:B,address:n.evm},{...Zt(t,"blockscout"),timeoutMs:t.timeoutMs??18e3}));X.ok?q={status:"ok",assets:Bp(X.data,{fungibleOnly:!0}).map(ce=>{let Se=go(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:go(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=Zt(t,"solana"),H=await $e(()=>vp({address:n.solana},B)),Q=i||s?await Promise.all([$e(()=>lc({owner:n.solana,programId:cc},B)).then(q=>({...q,program:"spl-token"})),$e(()=>lc({owner:n.solana,programId:BE},B)).then(q=>({...q,program:"token-2022"}))]):[],fe=UE(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:go(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=Zt(t,"bitcoin"),H=Zt(t,"bitcoinMeta"),[Q,fe,we]=await Promise.all([$e(()=>Ap({address:n.bitcoin},B)),i?$e(()=>Tp({address:n.bitcoin},H)):Promise.resolve({ok:!1,ms:0,error:"token discovery disabled"}),s?$e(()=>Di({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:go(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=Zt(t,"hyperliquid"),[H,Q,fe]=await Promise.all([$e(()=>$p(n.hyperliquid,B)),$e(()=>Np(n.hyperliquid,B)),$e(()=>Cp(B))]),we=(H.ok&&Array.isArray(H.data?.balances)?H.data.balances:[]).filter(F=>Qt(F.total)||Qt(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=>Qt(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(()=>mc(B,Zt(t,"prices")));H.ok&&(O=H.data)}let N=h.map(B=>{let H=B.native?{...B,native:yc(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=En(we.amount),X=q!=null&&F!=null?ji(q*F):null;return{...we,priceUsd:F,usdValue:X}});H={...H,fungibleTokens:{...H.fungibleTokens,assets:fe}}}return H});S.native&&(S.native=yc(S.native,g)),E.native&&(E.native=yc(E.native,g));let w=0,C=0,M=0;for(let B of[...N,S,E]){B.native?.status==="ok"&&Qt(B.native.amount)&&(B.native.usdValue!=null?(w+=B.native.usdValue,C+=1):M+=1);for(let H of B.fungibleTokens?.assets||[])!Qt(H.amount)&&!Qt(H.amountRaw)||(H.usdValue!=null?(w+=H.usdValue,C+=1):M+=1)}let z=Hp(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||En(_.mids?.HYPE):En(_.mids?.[B.coin]),fe=En(B.total);B.priceUsd=Q,B.usdValue=fe!=null&&Q!=null?ji(fe*Q):null,Qt(B.total)&&(B.usdValue!=null?(w+=B.usdValue,C+=1):M+=1)}let G=En(_.perps?.accountValueUsd);G!=null&&G!==0&&(w+=G,C+=1);let Y=[...S.fungibleTokens?.assets||[],...S.collectibles?.assets||[]].filter(B=>Qt(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=[wc("cosmos","requires a chain-specific bech32 address and LCD/RPC adapter"),wc("sui","Sui balance adapter is not installed"),wc("aptos","Aptos balance adapter is not installed")],Ve=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:ji(w),label:"known priced value, not a complete portfolio total",pricedItems:C,unpricedNonzeroItems:M,complete:M===0&&!Ve&&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 BE,qp,bc=L(()=>{xp();Be();xn();uc();Fi();fc();pc();Lp();Up();BE="TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb",qp=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 jE,qR,er=L(()=>{jE=300*1e3,qR=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var Wp=L(()=>{});import{readFileSync as qE,existsSync as HE}from"node:fs";import{getAddress as zE,Interface as qi,TypedDataEncoder as GR,parseUnits as YR}from"ethers";function JE(){let e=process.env.OPENSEA_ENV_FILE||`${process.env.HOME||""}/.config/locals-only/opensea.env`;if(!HE(e))return"";try{for(let t of qE(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 xc(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||JE()}function Vp(e={}){return Sn({provider:"opensea",defaultUrl:WE,hosts:["api.opensea.io","testnets-api.opensea.io"],url:e.baseUrl||process.env.OPENSEA_API_URL})}function Gp(e={}){return Vp(e).baseUrl}function Yp(e={}){return Cr({accept:"application/json"},{"x-api-key":xc(e)},Vp(e).trusted)}function XE(e){let t=String(e||"ethereum").trim().toLowerCase();if(!GE.has(t))throw new Error(`opensea: unsupported account chain ${t}`);return t}function Kp(e,t="address"){try{return zE(String(e||"").trim().toLowerCase())}catch{throw new Error(`opensea: invalid ${t}`)}}function Jp(e,t=null){let r=String(e||"").trim();if(!r)throw new Error("opensea: account address required");if(t&&!YE.has(t)||!t&&/^0x[0-9a-fA-F]{40}$/.test(r))return Kp(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 ZE(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 Sc(e={},t={}){if(!xc(t))throw new Error("OPENSEA_API_KEY required");let r=XE(e.chain),n=Jp(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(`${Gp(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:Yp(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4});for(let f of Array.isArray(d?.nfts)?d.nfts:[])s.push(ZE(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 Xp(e={},t={}){if(!xc(t))throw new Error("OPENSEA_API_KEY required");let r=Jp(e.address||e.owner),n=await Ce(`${Gp(t)}/account/${encodeURIComponent(r)}/pnl`,{headers:Yp(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 WE,KE,eP,tP,VE,GE,YE,rP,nP,oP,iP,Zp=L(()=>{Be();ho();er();Wp();WE="https://api.opensea.io/api/v2",KE="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)",eP=new qi([`function ${KE}`]),tP=new qi(["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"]),VE=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"]),GE=new Set(VE),YE=new Set(["solana","flow"]);rP=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}),nP=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"}]}),oP=new qi(["function setApprovalForAll(address operator,bool approved)"]),iP=new qi(["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 Ec=L(()=>{});function Qp(e={}){return Sn({provider:"satflow",defaultUrl:ev,hosts:["api.satflow.com"],url:e.baseUrl||process.env.SATFLOW_API_URL})}function tv(e={}){return Qp(e).baseUrl}function em(e={}){return String(e.apiKey||process.env.SATFLOW_API_KEY||process.env.BTC_SATFLOW_API_KEY||"").trim()}function rv(e={}){return Cr({accept:"application/json","content-type":"application/json","user-agent":"oracle-btc-satflow/0.1"},{"x-api-key":em(e)},Qp(e).trusted)}async function nv(e,{method:t="GET",body:r,opts:n={}}={}){if(!em(n))throw new Error("satflow: SATFLOW_API_KEY not set (request key via Satflow docs form)");let i=`${tv(n)}${e.startsWith("/")?e:`/${e}`}`,a=await(n.fetchImpl||fetch)(i,{method:t,headers:rv(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 tm(e={},t={}){let r=Xt(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 nv(`/address/wallet-contents?${n}`,{opts:t});return{provider:"satflow",address:r,contents:o}}var ev,rm=L(()=>{Fi();ho();er();Ec();ev="https://api.satflow.com/v1"});var nm=L(()=>{Be();uc();ho();er();Ec()});var xP,om=L(()=>{Be();xP=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 av(e={}){let t=[],r=String(e.name||""),n=String(e.description||""),o=`${r} ${n}`;iv.test(r)&&t.push("url-in-name");let i=ov.filter(u=>u.test(o)).length;i>0&&t.push(`lure-language:${i}`),sv.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 im(e={}){let t=av(e);return{...e,spam:e.spam===!0||t.spam,riskLevel:t.risk,riskReasons:t.reasons.length?t.reasons:void 0}}var ov,iv,sv,sm=L(()=>{ov=[/\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],iv=/(https?:\/\/|www\.|[a-z0-9-]+\.(?:com|net|io|xyz|org|app|finance|gift|claims?|site|link|live|vip|top|cc))/i,sv=/(\$\s?\d|\d[\d,.]*\s*(?:usd|usdc|usdt|eth|weth|btc|sol)\b)/i});function vc(e={},t){return{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs,env:e.env,allowDiskCredentials:e.allowDiskCredentials,allowAmbientCredentials:e.allowAmbientCredentials,...e[t]||{}}}async function yo(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 uv(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 dv(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 fv(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 am(e={}){return[e.chain||"unknown",e.contract||"native",e.tokenId||"unknown"].join(":").toLowerCase()}function pv(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 mv(e,t){let r=am(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 hv(e){let t=new Map;for(let r of e){let n=am(r);t.has(n)||t.set(n,r)}return[...t.values()]}function gv(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 cm(e={},t={}){let r=new Date().toISOString(),n=vn(e,t.env||process.env),o=Array.isArray(e.chains)&&e.chains.length?new Set(e.chains.map(g=>String(g).toLowerCase())):null,i=cv.filter(g=>!o||o.has(g.chain)),s=[],a=[],l=vc(t,"opensea"),u=n.evm?i.filter(g=>g.family!=="solana"):[],d=await bn(u,4,async g=>({row:g,result:await yo(`opensea-${g.chain}`,()=>Sc({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 yo("opensea-solana",()=>Sc({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 yo("satflow-wallet-contents",()=>tm({address:n.bitcoin,type:"ordinals",limit:e.bitcoinLimit??100,offset:0},vc(t,"satflow")),t.timeoutMs??35e3);if(g.ok){let k=uv(g.data.contents).map(O=>dv(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 yo("bitcoin-meta-inscriptions",()=>Di({address:n.bitcoin},vc(t,"bitcoinMeta")),t.timeoutMs??35e3),A=k.ok&&k.data?.ok&&Array.isArray(k.data.inscriptions)?k.data.inscriptions:[];a.push(...A.map(O=>fv(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 yo(`opensea-pnl-${g}`,()=>Xp({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=pv(e.costBasis),p=hv(a).map(g=>mv(g,c)).map(g=>im(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:lv,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:gv(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 cv,lv,lm=L(()=>{Be();bc();Zp();rm();fc();nm();om();sm();er();cv=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"}]),lv=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 gm={};lr(gm,{portfolioHistory:()=>hm,portfolioIdForAddresses:()=>kc,portfolioSnapshot:()=>Cv,portfolioValueGraph:()=>Pv,resolvePortfolioHistoryFile:()=>Ac});import{constants as Hi}from"node:fs";import{chmod as wv,mkdir as yv,open as bv,readFile as xv}from"node:fs/promises";import{createHash as Sv,randomUUID as Ev}from"node:crypto";import vv from"node:os";import kn from"node:path";function tr(e){if(e==null||e==="")return null;let t=Number(e);return Number.isFinite(t)?t:null}function An(e){return Number.isFinite(e)?Number(e.toFixed(2)):null}function dm(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 mm(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 kv(e={}){return["evm","solana","bitcoin","hyperliquid"].map(t=>`${t}:${String(e[t]||"").trim().toLowerCase()}`).join("|")}function kc(e={}){return`portfolio_${Sv("sha256").update(kv(e)).digest("hex").slice(0,20)}`}function Ac(e={}){if(e.historyFile)return kn.resolve(String(e.historyFile));let t=e.env||process.env;if(t.ORACLE_PORTFOLIO_HISTORY_FILE)return kn.resolve(String(t.ORACLE_PORTFOLIO_HISTORY_FILE));let r=String(t.HERMES_HOME||"").trim()||kn.join(vv.homedir(),".hermes");return kn.join(kn.resolve(r),"state","oracle","portfolio-history.jsonl")}function Av(e){let t=tr(e?.valuation?.knownUsd);return t==null?null:Number(e?.valuation?.pricedItems||0)>0||e?.valuation?.complete===!0?An(t):null}function _v(e){if(!e||e.status==="unavailable"||e.status==="not-requested")return null;let t=tr(e?.valuation?.estimatedCurrentValueUsd);return t==null?null:Number(e?.valuation?.valuedItems||0)>0||e?.valuation?.complete===!0?An(t):null}function Iv(e){let t=[];for(let r of e?.chains||[]){if(r.family==="hyperliquid"){let o=(r.spot?.balances||[]).reduce((a,l)=>{let u=tr(l.usdValue);return u==null?a:a+u},0),i=tr(r.perps?.accountValueUsd),s=An(o+(i??0));(s!==0||i!=null||(r.spot?.balances||[]).some(a=>tr(a.usdValue)!=null))&&t.push({family:"hyperliquid",chainId:null,name:r.name||"Hyperliquid",knownUsd:s});continue}let n=tr(r.native?.usdValue);n!=null&&t.push({family:r.family||"evm",chainId:r.chainId??null,name:r.name||r.native?.symbol||"Unknown",knownUsd:An(n)})}return t}function Ov(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 Tv(e,t){let r=Ac(t),n=`${JSON.stringify(e)}
|
|
9
9
|
`;if(Buffer.byteLength(n)>32*1024)throw new Error("portfolio history snapshot exceeds 32 KiB");await yv(kn.dirname(r),{recursive:!0,mode:448});let o=Hi.O_APPEND|Hi.O_CREAT|Hi.O_WRONLY|(Hi.O_NOFOLLOW||0),i=await bv(r,o,384);try{await i.writeFile(n,"utf8")}finally{await i.close()}return await wv(r,384),r}async function Cv(e={},t={}){let r=e.includeNfts!==!1,n=t.portfolioBalanceImpl||zp,o=t.nftInventoryImpl||cm,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=Av(a),d=_v(l),f=[u,d].filter(k=>k!=null),c=f.length?An(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||vn(e,t.env||process.env),E=kc(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_${Ev()}`,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:Iv(a),nfts:{knownUsd:d,visibleItems:Number(l?.inventory?.visibleCount||0),flaggedItems:Number(l?.inventory?.flaggedCount||0)}},coverage:Ov(a,l,r),warnings:[...new Set(_)].slice(0,50)};return{provider:"portfolio",operation:"snapshot",readOnly:!0,localObservationRecorded:!0,historyFile:await Tv(b,t),snapshot:b,balance:a,nfts:l}}async function $v(e){let t=Ac(e);try{let r=await xv(t);if(r.byteLength>um)throw new Error(`portfolio history exceeds ${um} 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 Nv(e,t){if(e.allPortfolios===!0)return null;if(e.portfolioId)return String(e.portfolioId);let r=vn(e,t.env||process.env);return Object.values(r).some(Boolean)?kc(r):null}async function hm(e={},t={}){let r=mm(e.limit,100,1,pm,"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=dm(e.since,"portfolio history since"),i=dm(e.until,"portfolio history until"),s=Nv(e,t),a=await $v(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=>tr(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 fm(e){return`$${Number(e).toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`}function zi(e){return String(e).replaceAll("&","&").replaceAll("<","<").replaceAll(">",">").replaceAll('"',""").replaceAll("'","'")}function Lv(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 Rv(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">${fm(O)}</text>`}).join(""),h=e.map((b,g)=>`<circle cx="${f(g)}" cy="${c(b.value)}" r="5" fill="#b8f0ff"><title>${zi(b.recordedAt)}: ${fm(b.value)}</title></circle>`).join(""),S=zi(e[0].recordedAt.slice(0,10)),E=zi(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 ${zi(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 Pv(e={},t={}){if(e.allPortfolios===!0)throw new Error("portfolio value graph requires one portfolioId or configured public-address portfolio");let r=mm(e.maxPoints,200,2,500,"portfolio graph maxPoints"),n=await hm({...e,order:"asc",limit:e.limit??pm},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:tr(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=Lv(o,r),s=i[0].value,a=i.at(-1).value,l=An(a-s),u=s===0?null:Number(((a-s)/s*100).toFixed(2)),d=Rv(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 um,pm,wm=L(()=>{bc();lm();um=10*1024*1024,pm=1e3});function Wi(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 _c=L(()=>{});var xm={};lr(xm,{createWatch:()=>Cc,listWatches:()=>Tc,removeWatch:()=>Bv});import bo from"node:fs";import Ic from"node:path";import{randomUUID as Mv}from"node:crypto";import{homedir as Fv}from"node:os";function Dv(e=process.env){return e.ORACLE_CONFIG_DIR||Ic.join(Fv(),".config","oracle")}function ym(e=process.env){return Ic.join(Dv(e),"watches.json")}function Oc(e=process.env){let t=ym(e);if(!bo.existsSync(t))return{watches:[]};try{let r=JSON.parse(bo.readFileSync(t,"utf8"));return{watches:Array.isArray(r.watches)?r.watches:[]}}catch{return{watches:[]}}}function bm(e,t=process.env){let r=ym(t);bo.mkdirSync(Ic.dirname(r),{recursive:!0,mode:448});let n=`${r}.${process.pid}.tmp`;bo.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=Vf(["-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(),wn(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 ps from"node:fs";import bt from"node:path";import{homedir as Cl}from"node:os";import{spawnSync as Il}from"node:child_process";var mS=/^[A-Z0-9][A-Z0-9._-]{0,11}$/;function hS(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 Xf(e,{coin:t,side:r,sizeUsd:n,leverage:o,venue:i,confirm:s,user:a}={}){let l=hS(e);if(!l)return null;if(t&&mS.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()}Li();var fL=Object.freeze([100,50,25]),pL=Object.freeze([100,50,25,10]);var
|
|
66
|
-
`)}function Ct(e){return["Confidence",
|
|
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 ps from"node:fs";import bt from"node:path";import{homedir as Cl}from"node:os";import{spawnSync as Il}from"node:child_process";var mS=/^[A-Z0-9][A-Z0-9._-]{0,11}$/;function hS(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 Xf(e,{coin:t,side:r,sizeUsd:n,leverage:o,venue:i,confirm:s,user:a}={}){let l=hS(e);if(!l)return null;if(t&&mS.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()}Li();var fL=Object.freeze([100,50,25]),pL=Object.freeze([100,50,25,10]);var Z="UNKNOWN",yL=Object.freeze(["token","launch","hip3","hip4","polymarket","twap","bridge","swap","approve"]),wS=/[_*[\]`]/g;function D(e){return ke(e)?String(e).replace(wS,t=>`\\${t}`):Z}function ke(e){return e==null?!1:typeof e=="number"?Number.isFinite(e):typeof e=="string"?e.trim()!=="":!0}function yt(e){if(!ke(e))return Z;let t=String(e).replace(/`/g,"");return t===""?Z:`\`${t}\``}function Ar(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=Ar(e,{decimals:t});return r===Z?Z:`${r} USD`}function Ka(e,{decimals:t=2}={}){let r=Ar(e,{decimals:t});return r===Z?Z:`${r}%`}function Ri(e){let t=Ar(e,{decimals:0});return t===Z?Z:`${t} bps`}function _r(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 Va(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 Yt(e={}){let t=e.chainId;if(!ke(t)||!Number.isFinite(Number(t)))return ke(e.chain)?D(e.chain):Z;let n=Ni(t)?.name||(ke(e.chain)?String(e.chain):Z);return`${D(n)} (chainId ${Number(t)})`}function Qf(e={}){return D(e.venue??e.dex??e.pool?.venue)}function yS(e){return e==null?"NONE (text card only)":typeof e=="string"?e.trim()?yt(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)?yt(e.url):"NONE (text card only)"}function Pi(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 bS(e){let t=Pi(e);return t.allowed?`${t.actions.map(r=>D(r)).join(" / ")} (${D(t.reason)})`:`prepare-only \u2014 ${D(t.reason)}`}function Tt(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: ${yS(r.chart)}`),n.push(`Actions: ${bS(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 Ct(e){let t=Va(e.confidence);return t===Z?null:["Confidence",t]}function xS(e){let t=e.quote;if(!t||typeof t!="object")return[];let r=ke(t.decimals)?_r(t.amountOutRaw??t.out??t.raw,t.decimals):Z;return[["Quote out (raw)",yt(t.amountOutRaw??t.out??t.raw)],["Quote out",r===Z?Z:`${D(r)} ${D(t.symbol??"")}`.trim()]]}function ep(e){let t=e.autoSlippage;if(!t||typeof t!="object")return["Auto-slippage",Z];let r=Ri(t.selectedBps),n=Ri(t.capBps);return["Auto-slippage",r===Z&&n===Z?Z:`${r} selected, cap ${n}`]}function SS(e={}){let t=e||{};return Tt(`ORACLE TOKEN \u2014 ${D(t.symbol??t.token??t.name)}`,[["Chain",Yt(t)],["Venue",Qf(t)],["Name",D(t.name)],["Address",yt(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",Ka(t.priceChange24h)],["Fee tier",ke(t.feeTier)?`${Ri(Number(t.feeTier)/100)} (${Ar(t.feeTier,{decimals:0})})`:Z],["Age",D(t.age)],...xS(t),ep(t),Ct(t)],t)}function ES(e={}){let t=e||{};return Tt(`ORACLE LAUNCH \u2014 ${D(t.symbol??t.token??t.name)}`,[["Chain",Yt(t)],["Venue",Qf(t)],["Address",yt(t.address??t.mint??t.contract)],["Pool",yt(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)],ep(t),Ct(t)],t)}function vS(e={}){let t=e||{};return Tt(`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",Ka(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)],Ct(t)],t)}function kS(e={}){let t=e||{};return Tt(`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",yt(t.marketId??t.market)],["Bid",Te(t.bid,{decimals:6})],["Ask",Te(t.ask,{decimals:6})],["Depth",D(t.depth)],["Edge",Ka(t.edge)],["Position",D(t.position)],Ct(t)],t)}function AS(e={}){let t=e||{};return Tt(`ORACLE POLYMARKET \u2014 ${D(t.event??t.market??t.name)}`,[["Venue","Polymarket CLOB"],["Event",D(t.event)],["Market",D(t.market)],["Market id",yt(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)],Ct(t)],t)}function _S(e={}){let t=e||{},r=ke(t.completedSplits)&&ke(t.totalSplits)?`${Ar(t.completedSplits,{decimals:0})} / ${Ar(t.totalSplits,{decimals:0})}`:Z;return Tt(`ORACLE TWAP \u2014 ${D(t.pair??t.symbol??t.name)}`,[["Chain",Yt(t)],["Side",D(t.side??t.direction)],["Amount",`${D(_r(t.amountTotal??t.amount,t.decimals??18))} ${D(t.symbol??"")}`.trim()],["Splits",`${Ar(t.totalSplits,{decimals:0})} over ${D(t.window)}`],["Progress",r],["Avg price",Te(t.averagePrice,{decimals:6})],["Next split",D(t.nextSplitAt)],["Slippage cap",Ri(t.slippageBps)],["Status",D(t.status)],Ct(t)],t)}function IS(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 Tt(`ORACLE BRIDGE \u2014 ${D(t.pair??t.fromSymbol)} \u2192 ${D(t.toSymbol??"")}`.replace(/→ $/,""),[["Bridging","deBridge \xB7 LI.FI \u2014 best route wins"],["From chain",Yt({chainId:t.fromChainId,chain:t.fromChain})],["To chain",Yt({chainId:t.toChainId,chain:t.toChain})],["Amount",`${D(_r(t.amount,t.fromDecimals??18))} ${D(t.fromSymbol??"")}`.trim()],["Best route",D(t.bestRoute??t.winner)],["Est. received",`${D(_r(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)],Ct(t)],t)}function OS(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 TS(e){let t=e.rankedOn??e.swap?.rankedOn??e.best?.rankedOn;return ke(t)?D(t):Z}function CS(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",Yt({chainId:t.chainId??r.chainId,chain:t.chain??r.chain})],["Pair",i],["Amount in",`${D(_r(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(_r(o.netOut??o.amountOut??r.amountOut,t.decimalsOut??18))} ${D(t.tokenOutSymbol??"")}`.trim()],["Ranked on",TS(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",OS(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(_r(a.netOut??a.amountOut??n.amountOut,t.bridgeDecimalsOut??t.decimalsOut??18))} ${D(t.bridgeOutSymbol??t.tokenOutSymbol??"")}`.trim()],["Bridge to",Yt({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)],Ct(t)),Tt(`ORACLE SWAP \u2014 ${i}`,s,t)}function $S(e={}){let t=e||{};return Tt("ORACLE APPROVE \u2014 local signer",[["Pending id",yt(t.id??(typeof t.digest=="string"?t.digest.slice(0,8):null))],["Surface",D(t.surface)],["Action",D(t.action)],["Chain",Yt({chainId:t.chain??t.chainId,chain:t.chainName})],["To",yt(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")],Ct({confidence:t.confidence??(t.armed===!0?"high":"low")})],t)}var bL=Object.freeze({token:SS,launch:ES,hip3:vS,hip4:kS,polymarket:AS,twap:_S,bridge:IS,swap:CS,approve:$S});var NS=Object.freeze(["deepen","refresh","prepare","ta","fa","long","short","allow","deny"]),vL=new Set(NS),tp=/^[a-z0-9-]{4,40}$/i;function rp(){return{links:{},artifacts:{},threads:{}}}var LS=rp();function RS(){return LS}function Jt(e){return e==null?!1:typeof e=="string"?e.trim()!=="":!0}function Ga(e){if(Array.isArray(e))return e.map(Ga);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]=Ga(n));return t}function PS({platform:e="telegram",artifactId:t,openUrl:r,hasGrant:n=!1}={}){let o=String(t||"").trim().toLowerCase();if(!tp.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=>Xf(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 Jt(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 MS(e={}){let r=[`*${Jt(e.title)?D(e.title):"Oracle artifact"}*`,`Kind: ${Jt(e.kind)?D(e.kind):Z}`,`Id: ${Jt(e.id)?`\`${String(e.id).replace(/`/g,"")}\``:Z}`,`Summary: ${Jt(e.summary)?D(e.summary):Z}`],n=Va(e.confidence);n!==Z&&r.push(`Confidence: ${n}`),(Jt(e.source)||Jt(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=Pi(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 FS(e,t={},{now:r=Date.now()}={}){let n=e||rp(),o=String(t.id||"").trim().toLowerCase();if(!tp.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:Jt(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:Ga(t.payload||{}),createdAt:new Date(r).toISOString()};return n.artifacts[o]=i,i}function np(e={},{grant:t=null,now:r=Date.now(),state:n}={}){let o=n||RS(),i=String(e.id||`art-${Math.abs(Number(r)).toString(36)}`).toLowerCase().slice(0,40),s=FS(o,{...e,id:i},{now:r}),a=Pi({grant:t},{now:r});return{text:MS({...s,grant:t}),replyMarkup:PS({artifactId:s.id,openUrl:s.openUrl,hasGrant:a.allowed}).replyMarkup,artifact:s,state:o}}var UA=6,Yh=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"}]),Ol=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 Ro(e=""){return String(e).trim().replace(/^['"]|['"]$/g,"")}function Jh(e,t){let r=String(e||"").trim().toLowerCase(),n=String(t||"").trim().toLowerCase();return n&&(Ol.get(`${r}/${n}`)||Ol.get(n)||Ol.get(n.split("/").pop()))||0}function Xh(e,t,r){let n=Number(e);return Number.isFinite(n)&&n>0?Math.round(n):Jh(t,r)}function jA(e={},t,r){return Xh(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 Nn(e,t,r,n,o={}){let i=Ro(r),s=Ro(n);if(!i||!s)return;let a=`${i}\0${s}`.toLowerCase(),l=jA(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 fs(e=[]){let t=[],r=new Set;for(let n of Array.isArray(e)?e:[])Array.isArray(n)?Nn(t,r,n[0],n[1],n[2]||{}):n&&typeof n=="object"&&Nn(t,r,n.provider,n.model,n);return t}function qA({env:e=process.env,profile:t="oracle"}={}){let r=e.HERMES_HOME||bt.join(Cl(),".hermes"),n=e.ORACLE_HERMES_PROFILE_CONFIG||bt.join(r,"profiles",t||"oracle","config.yaml");if(!ps.existsSync(n))return[];let o=[],i=new Set,s=!1,a=!1,l="",u="",d=!1,f=0,c="";for(let p of ps.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=Ro(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&&Nn(o,i,l,E[1],{contextLength:f}),/^ models:\s*$/.test(m)){a=!0,c="";continue}if(a){let _=/^ ([^:\s][^:]*):\s*(.*)$/.exec(m);if(_){c=Ro(_[1]),Nn(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&&Nn(o,i,l,c,{contextLength:Number(b[1])||0})}}else if(d){let h=/^\s*-\s*provider:\s*(\S+)/.exec(m);if(h){u=Ro(h[1]);continue}let S=/^\s*model:\s*(\S+)/.exec(m);S&&u&&Nn(o,i,u,S[1])}}return o}function HA(e={}){let t=fs(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=fs(s);if(a.length)return a}catch{}if(r.ORACLE_TEST_ISOLATE_SECRETS==="1")return[];let n=qA({env:r,profile:e.profile||"oracle"}),o=fs([{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 ms(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 zA(e){return(e.availableModels||[]).find(t=>ms(t,e.provider,e.model))||null}function as(e){let t=zA(e),r=Number(t?.contextLength||Jh(e.provider,e.model));Number.isFinite(r)&&r>0&&(e.contextLength=r,e.contextTokens>0&&(e.contextPercent=Math.round(e.contextTokens/r*100)))}function Gh(e){let t=String(e||"").trim().toLowerCase().replace(/^\/?@/,"");return Yh.find(r=>r.id===t||r.label===t)||null}var cs=8;function $l(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 WA({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=$l(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(cs/2));E+cs>h&&(E=Math.max(0,h-cs));let _=p.slice(E,E+cs);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=mr(G,Math.max(8,a-42)),ae=g.scratch?"":VA(g.updatedAt),ge=`${M} \xB7 ${z}`,xe=` ${C} ${Y}${N?" \u25CF":""}`,W=Math.max(1,a-lt(xe)-lt(ge)-lt(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 ls=10;function Zh(e=[],t=""){let r=String(t||"").trim().toLowerCase();return r?e.filter(n=>`${n.provider||""} ${n.model||""}`.toLowerCase().includes(r)):[...e]}function KA({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=Zh(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(ls/2));_+ls>S&&(_=Math.max(0,S-ls));let b=m.slice(_,_+ls);_>0&&c.push(p(o.fg($.banner_dim,` \u2191 ${_} more`))),b.forEach((k,A)=>{let N=_+A===E,w=ms(k,i,s),C=N?"\u203A":" ",M=mr(String(k.model||"").split("/").pop(),Math.max(8,l-36)),z=String(k.provider||"\u2014").replace(/-oauth$/,""),G=k.contextLength?gi(k.contextLength):"auto",Y=` ${C} ${M}${w?" \u25CF":""}`,ae=`${z} \xB7 ${G}`,ge=Math.max(1,l-lt(Y)-lt(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 VA(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 us(e){let t=Number(e);return Number.isFinite(t)?`$${t.toLocaleString("en-US",{minimumFractionDigits:2,maximumFractionDigits:2})}`:"unknown"}function GA(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 ${us(r.knownUsd)} \xB7 liquid ${us(r.liquidKnownUsd)} \xB7 NFTs ${us(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"} ${us(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 YA(e,t){return(await Promise.resolve().then(()=>(wm(),gm))).portfolioSnapshot(e,t)}async function Nl(e){let t=e||(async()=>{let{runCryptoDeskTool:r}=await Promise.resolve().then(()=>(Co(),bl));return r("signer_status")});try{return(await t())?.ok?"LOCAL SIGNER READY":"LOCAL SIGNER OFFLINE"}catch{return"LOCAL SIGNER OFFLINE"}}function JA(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 Tl(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 XA(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 ZA=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 QA({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 ZA)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 e_(e){let t=e.width,r=Math.max(0,Math.floor(Number(e.height)||0)),n=[];if(e.shortcuts&&(n.push(...QA({width:t,palette:e.palette})),n.push("")),e.picker?.kind==="model")n.push(...KA({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(...za({width:t,palette:e.palette,platformKey:a.platform||"telegram",tokenLength:String(a.token||"").length,error:a.error||""})):a.screen==="confirm"?n.push(...Wa({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(...vr({width:t,palette:e.palette,title:"sign in",subtitle:"\u2191\u2193 enter \xB7 OAuth or API key",rows:a.rows||kr(),index:a.index||0})):n.push(...vr({width:t,palette:e.palette,title:"oracle setup",subtitle:"\u2191\u2193 enter \xB7 model + telegram/discord/whatsapp",rows:a.rows||Xe(),index:a.index||0})),n.push("")}else if(e.picker){let a=typeof e.listSessions=="function"?e.listSessions():[];n.push(...WA({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(-UA)),n.push(""));let o=Hd({prompt:XA(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(zd({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 t_(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 ds(e={}){return typeof e.text=="string"?e.text:typeof e.rendered=="string"?e.rendered:typeof e.message=="string"?e.message:""}function r_(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||Bt({color:t.isTTY!==!1}),s=e.renderer||Ld({stdout:t,rows:t.rows,columns:n}),a=e.client||Sd({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 BA,u=e.now||(()=>Date.now()),d=!e.python,f=e.sessions===!1?null:e.sessions||Qd({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||ga(),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:HA(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 cn({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(e_(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=kt(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=Zr(v.chain);N(y||null),y||(c.chain=v.chain)}as(c)}}function W(v){let y=jt({width:c.width,palette:c.palette}),I=Array.isArray(v.messages)?v.messages:[];for(let x of I){if(x.role==="user"){let R=wa({width:c.width,palette:c.palette});g(R.top);for(let T of String(x.content).split(`
|
|
80
80
|
`))for(let P of hr(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 hr(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=$l(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:xa(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 nd(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 Ve(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
|
|
81
|
+
`))for(let T of hr(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=$l(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:xa(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 nd(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 Ve(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 Ft(`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,Ye=Number(v.contextLength)||0,oe=ve=>ve>=1e3&&ve%1e3===0?`${ve/1e3}K`:ve.toLocaleString();return w([`context ${oe(ye)} / ${oe(Ye)} 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=ct()||{};c.availableModels.length||(c.availableModels=fs([{provider:v.provider||c.provider||"configured",model:v.model||c.model||"unknown",contextLength:c.contextLength}]));let y=c.availableModels.findIndex(I=>ms(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=np({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=ct()||{backend:"standalone"},I=y.provider,x=v.join(" "),R=v.length===1?Gh(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=dr({...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=>ms(P,c.provider,c.model))||c.availableModels.push({provider:c.provider||"configured",model:c.model,contextLength:Xh(T.contextLength,c.provider,c.model)}),as(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=ct()||{},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 @@ ${tt(P.content)}
|
|
|
100
100
|
`))}catch(R){w(`portfolio unavailable: ${R?.message||R}`,{error:!0})}return!0})():!1}async function I0(v){let y=String(v||"").trim(),I=$a(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","",...Nf(x)].join(`
|
|
101
101
|
`)),!0;case"setup":return G(`/setup${x?` ${x}`:""}`);case"hotkeys":return w(Lf().join(`
|
|
102
102
|
`)),!0;case"sessions":return f?(U(),!0):(w("sessions are unavailable on this surface",{error:!0}),!0);case"new":return Ve(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 at();case"undo":return je(R[0]).catch(T=>(w(T?.message||"undo failed",{error:!0}),!0));case"retry":return Ze().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 Vr();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(ef(f.list(),{now:u(),activeId:c.archiveId}).join(`
|
|
103
|
-
`)),!0):T==="new"?Ve(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"?
|
|
103
|
+
`)),!0):T==="new"?Ve(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 k0(x).then(()=>!0).catch(T=>(w(T?.message||"branch failed",{error:!0}),!0));case"queue":return St(x,{steer:!1});case"steer":return St(x,{steer:!0});case"stop":return c.busy?(c.busy=!1,c.cancelled=!0,Yr(),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 ti();case"agent":return od(x?`/agent ${x}`:"/agent");case"goal":return Zs(x?`/goal ${x}`:"/goal");case"update":return Zs(x?`/update ${x}`:"/update");case"portfolio":return sd("/portfolio");case"reasoning":return Qe(x);case"yolo":return wt("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(of(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 ei(x);case"loop":return Mt("loop",x);case"heartbeat":return Mt("heartbeat",x);case"background":return St(x,{steer:!1});case"plan":{let T=Qo();if(!x||x==="list"){let V=af(T);return w(V.length?V.join(`
|
|
105
105
|
`):"no plans yet \xB7 /plan <title>"),!0}let P=cf(T,x,c.lastReply||"");return w(`plan ${P}`),!0}case"tips":return w(nf(c.tipIndex++)),!0;case"diff":return w(sf(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 Pt();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 wt("focus","focus");case"skills":return Zo(x);case"reload":case"reload-skills":{let T=ct()||{};return T.model&&(c.model=T.model),T.reasoningEffort&&(c.effort=T.reasoningEffort),w(I.name==="reload-skills"?`skills ${Kt().length}`:"config reloaded"),!0}case"whoami":return A0();case"profile":return _0();case"version":return w(`oracle ${c.version}`),!0;case"signer":return Xs();case"venues":return cr();case"fees":return Ge();case"watch":return Gr();case"clear":case"redraw":s.clear();for(let T of S())g(T);return!0;case"quit":return await ea(),!0;default:return!1}}function O0(){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=Js(k,{contextLength:a.contextLength}),ce=te.compacted?await c0(k,{contextLength:a.contextLength,cutAt:te.dropped,summarize:Ve,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=t0(O),Pe=[{role:"system",content:Se?`${E}
|
|
442
442
|
|
|
443
|
-
${Se}`:E},...k,{role:"user",content:X}],Ee="",je=null,Ze=!1,at=Oe=>{Ze||(K("message.start",{}),Ze=!0),Ee+=Oe,K("message.delta",{text:Oe})};try{for(let Pt=0;Pt<_;Pt+=1){let wt=a.authType==="oauth"?await S(a.provider):null;if(w||N.signal.aborted)return;let Vr={config:a,messages:Pe,persona:E,sessionId:g,credential:wt,fetchFn:p,signal:N.signal,onText:at,tools:b},Hn=a.protocol==="anthropic-messages"?await d0(Vr):a.protocol==="responses"?await f0(Vr):await u0(Vr);if(w||N.signal.aborted)return;let Zo=Hn.text,cr=Hn.toolCalls;if(je=Hn.usage||je,cr.length===0){Pe.push({role:"assistant",content:Zo}),k=Pe.slice(1),Ze||K("message.start",{});let Ge=bu(W.loopVerifier,at);K("message.complete",{text:Ee,usage:l0(je,a.contextLength),...Ge.stop_reason?{truncated:!0,stop_reason:Ge.stop_reason,note:Ge.note}:{}});return}Pe.push({role:"assistant",content:Zo||null,tool_calls:cr});let Xs=cr.length,Gr=0;for(let Ge of cr){let Qe,St=null;try{if(w||N.signal.aborted)return;St=JSON.parse(Ge.function.arguments||"{}"),Qe=await mC(Ge.function.name,St,m,{...W,signal:N.signal}),Kw(Ge.function.name,St,Qe,W.loopVerifier)}catch(zn){Qe={ok:!1,error:`invalid tool arguments: ${zn.message}`},Gr++}Qe.ok||Gr++;let Qo=Array.isArray(Qe?._attachments)?Qe._attachments:[],Mt=Qe&&typeof Qe=="object"?{...Qe}:Qe;Mt&&typeof Mt=="object"&&delete Mt._attachments;let ei=ln(Mt);if(c)try{let zn=ln(St,{force:!0}),ti=ln(Mt,{force:!0}),Wn=c(Object.freeze({callId:Ge.id||null,name:Ge.function.name,args:zn,result:ti}));Wn&&typeof Wn.catch=="function"&&Wn.catch(()=>{})}catch{}Pe.push({role:"tool",tool_call_id:Ge.id||`call_${Vu()}`,content:JSON.stringify(ei),...Qo.length?{attachments:Qo}:{}});try{ge.append({role:"tool",content:`${Ge.function.name}: ${JSON.stringify(ei).slice(0,2e3)}`})}catch{}}Og({userMessage:j,toolCalls:Xs,errors:Gr,recovered:Gr>0?!!cr.length:!1,durationMs:0})}k=Pe.slice(1),Ze||K("message.start",{});let Oe=bu(W.loopVerifier,at),ar=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:l0(je,a.contextLength),truncated:!0,stop_reason:Oe.stop_reason||"max_steps",note:ar});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
|
|
443
|
+
${Se}`:E},...k,{role:"user",content:X}],Ee="",je=null,Ze=!1,at=Oe=>{Ze||(K("message.start",{}),Ze=!0),Ee+=Oe,K("message.delta",{text:Oe})};try{for(let Pt=0;Pt<_;Pt+=1){let wt=a.authType==="oauth"?await S(a.provider):null;if(w||N.signal.aborted)return;let Vr={config:a,messages:Pe,persona:E,sessionId:g,credential:wt,fetchFn:p,signal:N.signal,onText:at,tools:b},Hn=a.protocol==="anthropic-messages"?await d0(Vr):a.protocol==="responses"?await f0(Vr):await u0(Vr);if(w||N.signal.aborted)return;let Zo=Hn.text,cr=Hn.toolCalls;if(je=Hn.usage||je,cr.length===0){Pe.push({role:"assistant",content:Zo}),k=Pe.slice(1),Ze||K("message.start",{});let Ge=bu(W.loopVerifier,at);K("message.complete",{text:Ee,usage:l0(je,a.contextLength),...Ge.stop_reason?{truncated:!0,stop_reason:Ge.stop_reason,note:Ge.note}:{}});return}Pe.push({role:"assistant",content:Zo||null,tool_calls:cr});let Xs=cr.length,Gr=0;for(let Ge of cr){let Qe,St=null;try{if(w||N.signal.aborted)return;St=JSON.parse(Ge.function.arguments||"{}"),Qe=await mC(Ge.function.name,St,m,{...W,signal:N.signal}),Kw(Ge.function.name,St,Qe,W.loopVerifier)}catch(zn){Qe={ok:!1,error:`invalid tool arguments: ${zn.message}`},Gr++}Qe.ok||Gr++;let Qo=Array.isArray(Qe?._attachments)?Qe._attachments:[],Mt=Qe&&typeof Qe=="object"?{...Qe}:Qe;Mt&&typeof Mt=="object"&&delete Mt._attachments;let ei=ln(Mt);if(c)try{let zn=ln(St,{force:!0}),ti=ln(Mt,{force:!0}),Wn=c(Object.freeze({callId:Ge.id||null,name:Ge.function.name,args:zn,result:ti}));Wn&&typeof Wn.catch=="function"&&Wn.catch(()=>{})}catch{}Pe.push({role:"tool",tool_call_id:Ge.id||`call_${Vu()}`,content:JSON.stringify(ei),...Qo.length?{attachments:Qo}:{}});try{ge.append({role:"tool",content:`${Ge.function.name}: ${JSON.stringify(ei).slice(0,2e3)}`})}catch{}}Og({userMessage:j,toolCalls:Xs,errors:Gr,recovered:Gr>0?!!cr.length:!1,durationMs:0})}k=Pe.slice(1),Ze||K("message.start",{});let Oe=bu(W.loopVerifier,at),ar=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:l0(je,a.contextLength),truncated:!0,stop_reason:Oe.stop_reason||"max_steps",note:ar});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=Js(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=Jo(F.goal):q.length===0&&(O=""),{seeded:k.length,summary:!!A,goal:O||null}}if(j==="session.context"){let q=Ys(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 c0(k,{contextLength:a.contextLength,force:!0,focus:q,summarize:Ve});k=X.messages,A=X.summary?{content:X.summary,focus:q,mode:X.mode}:null;let te=Ys(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=Jo(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 p0({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()}}Er();var Ne="oracle",Xo="oracle";function x0(e){if(e==="hermes"){let t=et();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 m0(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 S0(e){let t=m0(e);if(t)return t;try{let n=ue.readFileSync(e,"utf8").match(/["']([^"'\r\n]+\/bin\/hermes)["']/);if(n)return m0(n[1])}catch{}return null}function MC(){return ne.join(Et,"src","cli","oracle-harness.py")}function h0(e,t){let r=MC(),n=process.env.ORACLE_PLAIN_HARNESS==="0"?null:S0(e);return n&&ue.existsSync(r)?{command:n.command,args:[...n.prefix,r,...t]}:{command:e,args:t}}function FC(){return ne.join(Et,"skins","oracle.yaml")}function DC(e=Ne){let t=ne.join(Et,"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 BC(e=Ne){let t=FC();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,`${Xo}.yaml`),o),ue.writeFileSync(ne.join(n,`${Xo}.yaml`),o),{ok:!0,skin:Xo}}function UC(e=Ne){let t=ne.join(Me(),"profiles",e,"config.yaml");if(!ue.existsSync(t))return{ok:!1,reason:"profile config missing"};let r=x0("oracle")||ne.join(Et,"bin","oracle.mjs"),n=ne.join(Me(),"profiles",e,"oracle");be(n);let o={profile:e,skin:Xo,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 jC(e=Ne){let t=ne.join(Et,"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 qC(e=Ne){let t=x0("hermes");if(!t)return{ok:!1,reason:"hermes missing"};let r=PC(t,["-p",e,"config","set","display.skin",Xo],{encoding:"utf8",timeout:3e4});return r.status!==0?{ok:!1,reason:(r.stderr||r.stdout||"config set failed").trim()}:{ok:!0}}function g0(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 HC(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 w0(e=Ne){let t=Me();return g0(ne.join(t,"config.yaml"))||g0(ne.join(t,"profiles",e,"config.yaml"))||HC(e)}function y0(){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(`
|