@oracle-agent/oracle 0.35.4 → 0.35.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  3. package/dist/bin/desk-server.mjs +25 -23
  4. package/dist/bin/oracle-data-mcp.mjs +13 -11
  5. package/dist/bin/oracle-gateway.mjs +35 -35
  6. package/dist/bin/oracle-mev-arb-shadow.mjs +7 -5
  7. package/dist/bin/oracle-mev-shadow.mjs +7 -5
  8. package/dist/bin/oracle-public-server.mjs +6 -4
  9. package/dist/bin/oracle-route.mjs +22 -20
  10. package/dist/bin/oracle-scan.mjs +14 -12
  11. package/dist/bin/oracle-telegram-mcp.mjs +10 -10
  12. package/dist/bin/oracle.mjs +7 -5
  13. package/dist/cli/commands/chat.mjs +166 -164
  14. package/dist/cli/commands/doctor.mjs +3 -3
  15. package/dist/cli/commands/eval.mjs +113 -113
  16. package/dist/cli/commands/farm.mjs +14 -14
  17. package/dist/cli/commands/follow.mjs +16 -14
  18. package/dist/cli/commands/model.mjs +170 -168
  19. package/dist/cli/commands/project.mjs +17 -0
  20. package/dist/cli/commands/resolve.mjs +8 -6
  21. package/dist/cli/commands/shadow.mjs +21 -0
  22. package/dist/cli/commands/signer.mjs +10 -10
  23. package/dist/cli/commands/snipe.mjs +10 -8
  24. package/dist/cli/commands/strategy.mjs +5 -5
  25. package/dist/cli/commands/swap.mjs +27 -25
  26. package/dist/cli/commands/telegram.mjs +10 -10
  27. package/dist/cli/commands/venues.mjs +2 -2
  28. package/dist/data/desk-data.mjs +23 -21
  29. package/dist/data/names.mjs +4 -2
  30. package/dist/data/providers/farming.mjs +2 -2
  31. package/dist/index.mjs +37 -35
  32. package/dist/local-signer/index.mjs +3 -3
  33. package/dist/local-signer/runtime.mjs +9 -9
  34. package/dist/nft/universal-mint-router.mjs +5 -3
  35. package/dist/router/index.mjs +4 -2
  36. package/dist/router/prepare-bridge.mjs +2 -2
  37. package/dist/scanner/index.mjs +5 -3
  38. package/dist/strategy/index.mjs +3 -3
  39. package/package.json +1 -1
  40. package/public/oracle-splash/index.html +2 -2
@@ -0,0 +1,17 @@
1
+ import d from"node:fs";import i from"node:path";import{homedir as L}from"node:os";import m from"node:fs";import w from"node:path";import B from"node:readline/promises";import{homedir as I}from"node:os";var R=40,y=64;function O(e=process.env){return e&&e.ORACLE_CONFIG_DIR||w.join(I(),".config","oracle")}function A(e=process.env){return w.join(O(e),"projects.json")}function f(e,{platform:o=process.platform}={}){let t=String(e||"").trim();if(!t)return"";if(o==="win32"){let n=t.replace(/\//g,"\\");for(;n.length>3&&n.endsWith("\\");)n=n.slice(0,-1);return n}let r=t.replace(/\\/g,"/").replace(/\/{2,}/g,"/");return r.length>1&&r.endsWith("/")&&(r=r.slice(0,-1)),r}function _(e,o,{platform:t=process.platform}={}){let r=f(e,{platform:t}),n=f(o,{platform:t});return!r||!n?!1:t==="win32"?r.toLowerCase()===n.toLowerCase():r===n}function k(e){try{let o=JSON.parse(m.readFileSync(A(e),"utf8"));return!o||typeof o!="object"||!Array.isArray(o.projects)?{version:1,projects:[],lastProjectId:""}:o}catch{return{version:1,projects:[],lastProjectId:""}}}function $(e,o){let t=A(o);m.mkdirSync(w.dirname(t),{recursive:!0,mode:448}),m.writeFileSync(t,`${JSON.stringify(e,null,2)}
2
+ `,{mode:384})}function g(e,o){let t=String(e||"").trim().replace(/\s+/g," ");return t?t.slice(0,y):(w.basename(f(o)||"project")||"project").slice(0,y)}function p({env:e=process.env}={}){return[...k(e).projects].sort((t,r)=>(r.updatedAt||0)-(t.updatedAt||0))}var D=new Set(["none","read","write"]);function v(e,o="none"){return D.has(e)?e:o}function S(e,{env:o=process.env,now:t=Date.now,platform:r=process.platform}={}){let n=f(e?.cwd,{platform:r});if(!n)throw new Error("project cwd is required");let c=typeof t=="function"?t():t,s=k(o),a=s.projects.find(h=>_(h.cwd,n,{platform:r})),u=e?.access!=null?v(e.access):v(a?.access),l=a?{...a,name:g(e.name||a.name,n),cwd:n,access:u,updatedAt:c}:{id:`p${c.toString(36)}`,name:g(e.name,n),cwd:n,access:u,createdAt:c,updatedAt:c};return s.version=1,s.projects=[l,...s.projects.filter(h=>h.id!==l.id)].slice(0,R),s.lastProjectId=l.id,$(s,o),l}var N=new Set(["none","read","write"]),W=new Set(["/","/etc","/dev","/proc","/sys","/root","/var","/usr","/bin","/sbin","/boot","/home","/Users","/private"]);function T(e,o){if(o===e)return!0;let t=i.relative(e,o);return t!==""&&!t.startsWith("..")&&!i.isAbsolute(t)}function x(e){return N.has(e)?e:"none"}function P(e,{home:o=L()}={}){if(typeof e!="string"||!e||!i.isAbsolute(e))return"path must be absolute";let t=o;try{t=d.realpathSync(o)}catch{t=i.resolve(o)}if(e===t)return"home directory";if(T(e,t)&&e!==t)return"parent of the home directory";if(W.has(e))return e;let r=e.split(i.sep).join("/");return/(^|\/)\.ssh(\/|$)/i.test(r)?"SSH directory":/(^|\/)keys(\/|$)/i.test(r)?"key material directory":null}function H(e){let o=String(e||"").trim()||process.cwd(),t=i.resolve(o),r;try{r=d.realpathSync(t)}catch(s){throw new Error(`project allow: path does not exist (${s.code||s.message})`)}if(!d.statSync(r).isDirectory())throw new Error("project allow: path must be a directory");let c=P(r);if(c)throw new Error(`project allow refused: ${c}`);return r}function C(e,{access:o="write",env:t=process.env,platform:r=process.platform}={}){let n=H(e),c=x(o)==="read"?"read":"write";return S({cwd:n,access:c},{env:t,platform:r})}function E(e,{env:o=process.env,platform:t=process.platform}={}){let r=i.resolve(String(e||"").trim()||process.cwd()),n=p({env:o}).find(c=>{try{return d.realpathSync(c.cwd)===d.realpathSync(r)}catch{return i.resolve(c.cwd)===r}});if(!n)throw new Error("project deny: no saved project for that path");return S({...n,cwd:n.cwd,access:"none"},{env:o,platform:t})}function b({env:e=process.env,mode:o="read"}={}){let t=o==="write",r=[];for(let n of p({env:e})){let c=x(n.access);if(c==="none"||t&&c!=="write")continue;let s;try{s=d.realpathSync(n.cwd)}catch{continue}P(s)||r.includes(s)||r.push(s)}return r}var j=`oracle project: folder permissions for chat file tools.
3
+
4
+ Remembering a chat is not permission. You have to allow a folder.
5
+
6
+ oracle project allow [path] let chat read and write this folder
7
+ oracle project allow [path] --read let chat read only
8
+ oracle project deny [path] take the grant away
9
+ oracle project list
10
+
11
+ Home, /, and key folders stay refused. Writes still ask first.
12
+ Default path is the current directory.
13
+ `;function M(e=[]){let o={},t=[];for(let r of e)r==="--read"?o.read=!0:r==="--help"||r==="-h"?o.help=!0:t.push(r);return{flags:o,positional:t}}var ee={name:"project",summary:"allow or deny local folders the chat bot may read and write",group:"read",usage:j,async run(e){let{flags:o,positional:t}=M(e.argv||[]),r=t[0];if(!r||o.help)return process.stdout.write(j),0;if(r==="allow"){let n=C(t[1],{access:o.read?"read":"write"});return process.stdout.write(`allowed ${n.access} ${n.cwd}
14
+ `),0}if(r==="deny"){let n=E(t[1]);return process.stdout.write(`denied ${n.cwd}
15
+ `),0}if(r==="list"){let n=new Set(b({mode:"read"})),c=p().filter(s=>s.access&&s.access!=="none");if(!c.length)return process.stdout.write(`no folder grants. run: oracle project allow .
16
+ `),0;for(let s of c){let a=n.has(s.cwd)||[...n].some(u=>s.cwd.startsWith(`${u}/`));process.stdout.write(`${s.access.padEnd(5)} ${s.cwd}${a?"":" (missing)"}
17
+ `)}return 0}return process.stderr.write(j),1}};export{ee as default};
@@ -1,5 +1,7 @@
1
- import{keccak_256 as Y}from"@noble/hashes/sha3.js";import{createHash as ve}from"node:crypto";import v from"node:net";import Se from"node:dns";var Re=new Set(["localhost","metadata.google.internal","metadata.goog"]);function B(t){let e=String(t).toLowerCase().split("%")[0];if((e.match(/::/g)||[]).length>1)return null;let r=d=>{if(!d)return[];let s=d.split(":"),a=s.at(-1);if(a?.includes(".")){let i=a.split(".").map(Number);if(i.length!==4||i.some(b=>!Number.isInteger(b)||b<0||b>255))return null;s.splice(s.length-1,1,(i[0]<<8|i[1]).toString(16),(i[2]<<8|i[3]).toString(16))}return s.some(i=>!/^[0-9a-f]{1,4}$/.test(i))?null:s.map(i=>Number.parseInt(i,16))},[n,o]=e.split("::"),c=r(n),u=r(o);if(!c||!u)return null;let f=e.includes("::"),p=8-c.length-u.length;if(!f&&p!==0||f&&p<1)return null;let m=[...c,...Array(Math.max(0,p)).fill(0),...u];return m.length!==8?null:Uint8Array.from(m.flatMap(d=>[d>>8,d&255]))}function O(t,e,r){let n=Math.floor(r/8),o=r%8;for(let u=0;u<n;u+=1)if(t[u]!==e[u])return!1;if(!o)return!0;let c=255<<8-o;return(t[n]&c)===(e[n]&c)}function U(t){if(v.isIPv4(t)){let e=t.split(".").map(Number);return!(e[0]===0||e[0]===10||e[0]===127||e[0]>=224||e[0]===100&&e[1]>=64&&e[1]<=127||e[0]===169&&e[1]===254||e[0]===172&&e[1]>=16&&e[1]<=31||e[0]===192&&(e[1]===0||e[1]===2||e[1]===168)||e[0]===192&&e[1]===88&&e[2]===99||e[0]===198&&(e[1]===18||e[1]===19||e[1]===51)||e[0]===203&&e[1]===0&&e[2]===113)}if(v.isIPv6(t)){let e=B(t);if(!e)return!1;let r=B("::ffff:0:0");return O(e,r,96)?U([...e.slice(12)].join(".")):O(e,B("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,c])=>O(e,B(o),c)):!1}return!1}function xe(t){let e;try{e=new URL(String(t))}catch{return{ok:!1,error:`not a valid URL: ${String(t).slice(0,120)}`}}if(e.protocol!=="http:"&&e.protocol!=="https:")return{ok:!1,error:`refused protocol ${e.protocol} (only http/https)`};let r=e.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(Re.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=v.isIP(r);return n!==0&&!U(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:e,host:r,isLiteralIp:n!==0}}async function F(t,{lookupFn:e=Se.promises.lookup}={}){let r=xe(t);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:v.isIPv6(r.host)?6:4}]};let n;try{n=await e(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=>!U(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function D({requireUndici:t=!1,importUndici:e=()=>import("undici")}={}){let r,n;try{let s=await e();r=s.Agent,n=s.fetch}catch(s){if(t)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${s?.message||s}`);return null}if(typeof r!="function"||typeof n!="function"){if(t)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=s=>String(s).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),c=new Map,u=s=>(Array.isArray(s)?s:[s]).map(a=>typeof a=="string"?{address:a}:a).filter(a=>a&&a.address).map(a=>({address:a.address,family:a.family||(v.isIPv6(a.address)?6:4)})),f=(s,a,i)=>{c.set(o(s),u(typeof a=="string"?[{address:a,family:i}]:a))},p=s=>{let a=o(s);if(v.isIP(a))return[{address:a,family:v.isIPv6(a)?6:4}];let i=c.get(a);if(!i||!i.length)throw new Error(`refused: unpinned host ${s} during pinned fetch`);return i},m=new r({connect:{lookup(s,a,i){let b;try{b=p(s)}catch(I){return i(I)}return a?.all?i(null,b):i(null,b[0].address,b[0].family)}}}),d=Ae((s,a={})=>n(s,{...a,dispatcher:m}),f);return{dispatcher:m,fetch:d,pin:f,resolve:p,async close(){try{await m.destroy()}catch{}}}}var j=Symbol.for("oracle.egressGuard.pinCapableFetch");function Ae(t,e){if(typeof t!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof e!="function")throw new Error("markPinCapableFetch: pin must be a function");return t[j]=Object.freeze({pin:e}),t}function z(t){return typeof t=="function"&&typeof t[j]?.pin=="function"}function X(t,e,r){if(!z(t))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");t[j].pin(e,r)}var Te=new Set([408,425,429,500,502,503,504]),Z=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),_e=2,Q=4e3,ne=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ie=new Set([301,302,303,307,308]),ee=3,Ce=64*1024;function Pe(t){let e=String(t||"").toLowerCase();return ne.includes(e)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(e)}function ke(t){let e={};for(let[r,n]of Object.entries(t||{}))Pe(r)||(e[r]=n);return e}function $e(t,e){if(!t)throw new Error(`HTTP redirect from ${e} missing Location`);let r=new URL(String(t),String(e));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${e} used unsupported protocol ${r.protocol}`);return r.toString()}function Ne(t,e){return new URL(String(t)).origin===new URL(String(e)).origin}var V=new Map;function Le(t,e,r,n={}){let o={};for(let[d,s]of Object.entries(r||{}))o[d.toLowerCase()]=s;let c=Object.keys(o).filter(d=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(d)),f=[...new Set([...ne,...c])].sort().map(d=>`${d}=${o[d]??""}`).join(`
2
- `),p=ve("sha256").update(f).digest("hex").slice(0,32),m=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`;return`${t} ${e} ${m} ${p}`}function He(t,e){let r=Number(e);return Number.isFinite(r)&&r>0?Math.min(r*1e3,Q):Math.min(250*2**t,Q)+Math.floor(Math.random()*100)}var Be=t=>new Promise(e=>setTimeout(e,t));function N(t,e={}){let r=new Error(t);return r.retryable=!1,Object.assign(r,e),r}function G(t,e,r){return N(`HTTP response from ${t} exceeded maxResponseBytes ${r} (${e})`,{oversize:!0})}function L(t){try{let e=t?.body?.cancel?.();e&&typeof e.then=="function"&&e.catch(()=>{})}catch{}}function Me(t){return t?t.byteLength??t.length??0:0}async function te(t,e,{url:r,truncate:n=!1,onOversize:o}={}){if(e==null)return await t.text();let c=Number(t.headers?.get?.("content-length"));if(Number.isFinite(c)&&c>e&&(L(t),!n))throw G(r,`content-length ${c}`,e);let u=t.body?.getReader?.();if(!u){let s=await t.text(),a=Buffer.byteLength(s,"utf8");if(a>e){if(!n)throw G(r,`body ${a} bytes`,e);return Buffer.from(s,"utf8").subarray(0,e).toString("utf8")}return s}let f=[],p=0,m=!1;try{for(;;){let{value:s,done:a}=await u.read();if(a)break;if(s&&(f.push(Buffer.from(s)),p+=Me(s),p>e)){m=!0;break}}}finally{if(m)try{await u.cancel()}catch{}try{u.releaseLock?.()}catch{}}if(m&&(typeof o=="function"&&o(),!n))throw G(r,`streamed ${p} bytes`,e);let d=Buffer.concat(f);return(m?d.subarray(0,e):d).toString("utf8")}function re(t){if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function Oe(t,{fetchImpl:e,method:r,headers:n,body:o,timeoutMs:c,lookupFn:u,realFetch:f,untrustedUrl:p=!1,maxResponseBytes:m=null,importUndici:d,validateResponse:s,signal:a}){let i=new AbortController,b=setTimeout(()=>i.abort(),c),I=a?typeof AbortSignal.any=="function"?AbortSignal.any([a,i.signal]):a:i.signal,w=null,C=e,P=u?{lookupFn:u}:{};if(p&&!f&&!z(C))throw N(`HTTP refused ${t}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let k=async(h,{status:g=null}={})=>{let y=await F(h,P);if(!y.ok)throw N(g==null?`HTTP refused ${h}: ${y.error}`:`HTTP redirect to ${h} ${y.error}`,g==null?{}:{status:g});let l=new URL(h).hostname;if(f){if(w&&(await w.close(),w=null),!w)try{w=await D({requireUndici:!0,...d?{importUndici:d}:{}})}catch(E){throw N(g==null?`HTTP refused ${h}: ${E?.message||E}`:`HTTP redirect to ${h} refused: ${E?.message||E}`,g==null?{}:{status:g})}w.pin(l,y.addresses),C=w.fetch}else X(C,l,y.addresses);return y};try{let h=String(t),g={...n||{}};p&&await k(h);for(let y=0;y<=ee;y+=1){let l=await C(h,{method:r,headers:g,body:o,signal:I,redirect:"manual"});if(Ie.has(l.status)){if(r!=="GET"&&r!=="HEAD"){let R=await te(l,m??Ce,{url:h,truncate:!0}),x=new Error(`HTTP ${l.status} ${r} ${h} redirected non-idempotent request`);throw x.status=l.status,x.body=re(R)??R.slice(0,300),x}if(y===ee)throw L(l),new Error(`HTTP redirect loop for ${t}`);let S=l.headers?.get?.("location"),A;try{A=$e(S,h)}catch(R){throw L(l),R}let $=!Ne(A,h);if(L(l),$&&(g=ke(g)),p)await k(A,{status:l.status});else if($){let R=await F(A,P);if(!R.ok){let x=new Error(`HTTP redirect from ${h} ${R.error}`);throw x.status=l.status,x.retryable=!1,x}f&&R.addresses?.length&&(w||(w=await D(d?{importUndici:d}:{})),w&&(w.pin(new URL(A).hostname,R.addresses),C=w.fetch))}h=A;continue}if(typeof s=="function")try{await s(l,{url:h})}catch(S){throw L(l),N(S?.message||String(S))}let E=await te(l,m,{url:h,onOversize:()=>i.abort()}),H=re(E);if(!l.ok){let S=new Error(`HTTP ${l.status} ${r} ${h}`);throw S.status=l.status,S.retryAfter=l.headers?.get?.("retry-after")??null,S.body=H??E.slice(0,300),S}return H??E}throw new Error(`HTTP redirect loop for ${t}`)}finally{clearTimeout(b),w&&await w.close()}}async function oe(t,e={}){let r=e.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=e.timeoutMs??12e3,o=(e.method||"GET").toUpperCase(),c={Accept:"application/json",...e.headers||{}},u=e.body;u!=null&&typeof u!="string"&&(c["Content-Type"]=c["Content-Type"]||"application/json",u=JSON.stringify(u));let f=Number.isInteger(e.retries)?Math.max(e.retries,0):_e,p=e.lookupFn,m=!e.fetchImpl,d=e.untrustedUrl===!0,s=e.importUndici,a=e.validateResponse,i=e.signal,b=Number(e.maxResponseBytes),I=Number.isFinite(b)&&b>0?Math.floor(b):null,w=async()=>{let g;for(let y=0;y<=f;y++){i?.throwIfAborted?.();try{return await Oe(t,{fetchImpl:r,method:o,headers:c,body:u,timeoutMs:n,lookupFn:p,realFetch:m,untrustedUrl:d,maxResponseBytes:I,importUndici:s,validateResponse:a,signal:i})}catch(l){g=l;let E=l?.status,H=l?.name==="AbortError"||l?.name==="TimeoutError"||i?.aborted,S=new Set([408,425,429]),A=l?.retryable===!1?!1:E!=null?S.has(E)||Te.has(E)&&Z.has(o):!H&&Z.has(o);if(y===f||!A)throw l;let $=He(y,l?.retryAfter);i?await new Promise((R,x)=>{let Ee=setTimeout(R,$);i.addEventListener("abort",()=>{clearTimeout(Ee),x(i.reason||new DOMException("Aborted","AbortError"))},{once:!0})}):await Be($)}}throw g};if(!(e.dedupe!==!1&&!i&&o==="GET"&&u==null))return w();let P=Le(o,t,c,{untrustedUrl:d,maxResponseBytes:I}),k=V.get(P);if(k)return k;let h=w().finally(()=>V.delete(P));return V.set(P,h),h}var se={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}},Ue=new Map(Object.values(se).map(t=>[t.chainId,t]));function ae(t){return Ue.get(Number(t))||null}function ce(t,e=process.env){let r=ae(t);if(!r)return null;for(let n of r.rpcEnv){let o=(e[n]||"").trim();if(o)return o}return null}import{Interface as Fe,getAddress as pt}from"ethers";var ht=new Fe(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var De={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"};function je(t,{rpcUrl:e,env:r=process.env}={}){if(e)return e;let n=ce(t,r);return n||De[Number(t)]||null}var ze=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Ve(t){let e=String(t||""),r=e.toLowerCase();if(e!==e.trim()||!/^[a-zA-Z0-9_]+$/.test(e)||!ze.test(r))throw new Error(`evm-rpc: ${e} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}async function ie(t,e,r=[],n={}){let o=String(e||"");Ve(o);let c=je(t,n);if(!c)throw new Error(`No RPC URL for chainId ${t} (set env from chain registry rpcEnv or pass rpcUrl)`);let f=await oe(c,{method:"POST",body:{jsonrpc:"2.0",id:1,method:e,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3,signal:n.signal});if(f?.error){let p=new Error(f.error.message||JSON.stringify(f.error));throw p.code=f.error.code,p}return f.result}var J=999,q=1,Ge=8453,ue="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",Ye="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",le="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",qe="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",Je=".80002105.reverse",W=/^0x[a-fA-F0-9]{40}$/,fe=new TextEncoder,de=t=>"0x"+Buffer.from(t).toString("hex"),T=t=>de(Y(fe.encode(t))).slice(0,10),pe=t=>t.toLowerCase().replace(/^0x/,"").padStart(64,"0");function M(t){let e=new Uint8Array(32);if(t)for(let r of String(t).split(".").reverse()){let n=Y(fe.encode(r)),o=new Uint8Array(64);o.set(e,0),o.set(n,32),e=Y(o)}return de(e)}function K(t){if(!t||t==="0x"||/^0x0*$/.test(t))return"";try{let e=t.slice(2),r=parseInt(e.slice(0,64),16)*2,n=parseInt(e.slice(r,r+64),16);if(!Number.isFinite(n)||n<=0)return"";let o=e.slice(r+64,r+64+n*2);return Buffer.from(o,"hex").toString("utf8")}catch{return""}}async function _(t,e,r){try{return await ie(t,"eth_call",[{to:e,data:r},"latest"])}catch{return null}}async function We(t){let e=await _(J,ue,T("primaryName(address)")+pe(t)),r=K(e);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function Ke(t){let e=await _(J,Ye,T("getName(address)")+pe(t)),r=K(e);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function he(t,e,r){let n=await _(t,r,T("name(bytes32)")+e.slice(2));return K(n)||null}async function Xe(t){let e=M(`${t.slice(2).toLowerCase()}.addr.reverse`),r=await _(q,le,T("resolver(bytes32)")+e.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:he(q,e,n)}async function Ze(t){let e=M(t.slice(2).toLowerCase()+Je);return he(Ge,e,qe)}var me=[{source:"hl",fn:We},{source:"hype",fn:Ke},{source:"ens",fn:Xe},{source:"basename",fn:Ze}];async function we(t){if(!W.test(String(t||"").trim()))return null;let e=String(t).trim();for(let{source:r,fn:n}of me){let o=await n(e);if(o)return{name:o,source:r,address:e}}return null}async function Qe(t){let e=M(t),r=await _(J,ue,T("ownerOf(uint256)")+e.slice(2));if(!r||r.length<66)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:n}async function et(t,e,r){let n=M(e),o=await _(t,r,T("resolver(bytes32)")+n.slice(2));if(!o)return null;let c="0x"+o.slice(-40);if(/^0x0+$/.test(c))return null;let u=await _(t,c,T("addr(bytes32)")+n.slice(2));if(!u)return null;let f="0x"+u.slice(-40);return/^0x0+$/.test(f)?null:f}async function ye(t){let e=String(t||"").trim().toLowerCase();if(!e||!e.includes("."))return null;if(e.endsWith(".hl")){let r=await Qe(e);return r?{address:r,source:"hl",name:e}:null}if(e.endsWith(".eth")){let r=await et(q,e,le);return r?{address:r,source:e.endsWith(".base.eth")?"basename":"ens",name:e}:null}return null}var be=me.map(t=>t.source);var ge=`oracle resolve <name-or-address> [--json]
1
+ import{keccak_256 as G}from"@noble/hashes/sha3.js";import{createHash as Q}from"node:crypto";import v from"node:net";import ve from"node:dns";var _e=new Set(["localhost","metadata.google.internal","metadata.goog"]);function M(t){let e=String(t).toLowerCase().split("%")[0];if((e.match(/::/g)||[]).length>1)return null;let r=d=>{if(!d)return[];let s=d.split(":"),a=s.at(-1);if(a?.includes(".")){let u=a.split(".").map(Number);if(u.length!==4||u.some(g=>!Number.isInteger(g)||g<0||g>255))return null;s.splice(s.length-1,1,(u[0]<<8|u[1]).toString(16),(u[2]<<8|u[3]).toString(16))}return s.some(u=>!/^[0-9a-f]{1,4}$/.test(u))?null:s.map(u=>Number.parseInt(u,16))},[n,o]=e.split("::"),c=r(n),i=r(o);if(!c||!i)return null;let m=e.includes("::"),f=8-c.length-i.length;if(!m&&f!==0||m&&f<1)return null;let p=[...c,...Array(Math.max(0,f)).fill(0),...i];return p.length!==8?null:Uint8Array.from(p.flatMap(d=>[d>>8,d&255]))}function U(t,e,r){let n=Math.floor(r/8),o=r%8;for(let i=0;i<n;i+=1)if(t[i]!==e[i])return!1;if(!o)return!0;let c=255<<8-o;return(t[n]&c)===(e[n]&c)}function F(t){if(v.isIPv4(t)){let e=t.split(".").map(Number);return!(e[0]===0||e[0]===10||e[0]===127||e[0]>=224||e[0]===100&&e[1]>=64&&e[1]<=127||e[0]===169&&e[1]===254||e[0]===172&&e[1]>=16&&e[1]<=31||e[0]===192&&(e[1]===0||e[1]===2||e[1]===168)||e[0]===192&&e[1]===88&&e[2]===99||e[0]===198&&(e[1]===18||e[1]===19||e[1]===51)||e[0]===203&&e[1]===0&&e[2]===113)}if(v.isIPv6(t)){let e=M(t);if(!e)return!1;let r=M("::ffff:0:0");return U(e,r,96)?F([...e.slice(12)].join(".")):U(e,M("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,c])=>U(e,M(o),c)):!1}return!1}function Te(t){let e;try{e=new URL(String(t))}catch{return{ok:!1,error:`not a valid URL: ${String(t).slice(0,120)}`}}if(e.protocol!=="http:"&&e.protocol!=="https:")return{ok:!1,error:`refused protocol ${e.protocol} (only http/https)`};let r=e.hostname.toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,"");if(_e.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=v.isIP(r);return n!==0&&!F(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:e,host:r,isLiteralIp:n!==0}}async function D(t,{lookupFn:e=ve.promises.lookup}={}){let r=Te(t);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:v.isIPv6(r.host)?6:4}]};let n;try{n=await e(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=>!F(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function j({requireUndici:t=!1,importUndici:e=()=>import("undici")}={}){let r,n;try{let s=await e();r=s.Agent,n=s.fetch}catch(s){if(t)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${s?.message||s}`);return null}if(typeof r!="function"||typeof n!="function"){if(t)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=s=>String(s).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),c=new Map,i=s=>(Array.isArray(s)?s:[s]).map(a=>typeof a=="string"?{address:a}:a).filter(a=>a&&a.address).map(a=>({address:a.address,family:a.family||(v.isIPv6(a.address)?6:4)})),m=(s,a,u)=>{c.set(o(s),i(typeof a=="string"?[{address:a,family:u}]:a))},f=s=>{let a=o(s);if(v.isIP(a))return[{address:a,family:v.isIPv6(a)?6:4}];let u=c.get(a);if(!u||!u.length)throw new Error(`refused: unpinned host ${s} during pinned fetch`);return u},p=new r({connect:{lookup(s,a,u){let g;try{g=f(s)}catch(I){return u(I)}return a?.all?u(null,g):u(null,g[0].address,g[0].family)}}}),d=Ie((s,a={})=>n(s,{...a,dispatcher:p}),m);return{dispatcher:p,fetch:d,pin:m,resolve:f,async close(){try{await p.destroy()}catch{}}}}var z=Symbol.for("oracle.egressGuard.pinCapableFetch");function Ie(t,e){if(typeof t!="function")throw new Error("markPinCapableFetch: fetchImpl must be a function");if(typeof e!="function")throw new Error("markPinCapableFetch: pin must be a function");return t[z]=Object.freeze({pin:e}),t}function J(t){return typeof t=="function"&&typeof t[z]?.pin=="function"}function Z(t,e,r){if(!J(t))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");t[z].pin(e,r)}var Ce=new Set([408,425,429,500,502,503,504]),ee=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Pe=2,te=4e3,ae=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],ke=new Set([301,302,303,307,308]),re=3,$e=64*1024;function Ne(t){let e=String(t||"").toLowerCase();return ae.includes(e)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(e)}function Le(t){let e={};for(let[r,n]of Object.entries(t||{}))Ne(r)||(e[r]=n);return e}function He(t,e){if(!t)throw new Error(`HTTP redirect from ${e} missing Location`);let r=new URL(String(t),String(e));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${e} used unsupported protocol ${r.protocol}`);return r.toString()}function Be(t,e){return new URL(String(t)).origin===new URL(String(e)).origin}var V=new Map,Me=/(?:^|_)(send|submit|broadcast|sign|requestAirdrop)(?=[A-Z_]|$)/i,Oe=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);function ne(t){let e=String(t?.method||"");return e?!Me.test(e):!1}function Ue(t,e){if(t==="GET"&&e==null)return!0;if(t!=="POST"||e==null)return!1;let r=e;if(typeof e=="string")try{r=JSON.parse(e)}catch{return!1}return Array.isArray(r)?r.length>0&&r.every(ne):!r||typeof r!="object"?!1:r.jsonrpc&&r.method?ne(r):typeof r.type=="string"&&Oe.has(r.type)&&r.action==null&&r.signature==null&&r.nonce==null}function Fe(t,e,r,n={},o=null){let c={};for(let[a,u]of Object.entries(r||{}))c[a.toLowerCase()]=u;let i=Object.keys(c).filter(a=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(a)),f=[...new Set([...ae,...i])].sort().map(a=>`${a}=${c[a]??""}`).join(`
2
+ `),p=Q("sha256").update(f).digest("hex").slice(0,32),d=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`,s=o==null?"-":Q("sha256").update(String(o)).digest("hex").slice(0,32);return`${t} ${e} ${d} ${p} ${s}`}function De(t,e){let r=Number(e);return Number.isFinite(r)&&r>0?Math.min(r*1e3,te):Math.min(250*2**t,te)+Math.floor(Math.random()*100)}var je=t=>new Promise(e=>setTimeout(e,t));function N(t,e={}){let r=new Error(t);return r.retryable=!1,Object.assign(r,e),r}function Y(t,e,r){return N(`HTTP response from ${t} exceeded maxResponseBytes ${r} (${e})`,{oversize:!0})}function L(t){try{let e=t?.body?.cancel?.();e&&typeof e.then=="function"&&e.catch(()=>{})}catch{}}function ze(t){return t?t.byteLength??t.length??0:0}async function oe(t,e,{url:r,truncate:n=!1,onOversize:o}={}){if(e==null)return await t.text();let c=Number(t.headers?.get?.("content-length"));if(Number.isFinite(c)&&c>e&&(L(t),!n))throw Y(r,`content-length ${c}`,e);let i=t.body?.getReader?.();if(!i){let s=await t.text(),a=Buffer.byteLength(s,"utf8");if(a>e){if(!n)throw Y(r,`body ${a} bytes`,e);return Buffer.from(s,"utf8").subarray(0,e).toString("utf8")}return s}let m=[],f=0,p=!1;try{for(;;){let{value:s,done:a}=await i.read();if(a)break;if(s&&(m.push(Buffer.from(s)),f+=ze(s),f>e)){p=!0;break}}}finally{if(p)try{await i.cancel()}catch{}try{i.releaseLock?.()}catch{}}if(p&&(typeof o=="function"&&o(),!n))throw Y(r,`streamed ${f} bytes`,e);let d=Buffer.concat(m);return(p?d.subarray(0,e):d).toString("utf8")}function se(t){if(!t)return null;try{return JSON.parse(t)}catch{return null}}async function Je(t,{fetchImpl:e,method:r,headers:n,body:o,timeoutMs:c,lookupFn:i,realFetch:m,untrustedUrl:f=!1,maxResponseBytes:p=null,importUndici:d,validateResponse:s,signal:a}){let u=new AbortController,g=setTimeout(()=>u.abort(),c),I=a?typeof AbortSignal.any=="function"?AbortSignal.any([a,u.signal]):a:u.signal,w=null,C=e,P=i?{lookupFn:i}:{};if(f&&!m&&!J(C))throw N(`HTTP refused ${t}: untrustedUrl requires a pin-capable fetchImpl (see markPinCapableFetch in egress-guard.mjs) or no fetchImpl override so Oracle can pin the connection itself`);let k=async(h,{status:b=null}={})=>{let y=await D(h,P);if(!y.ok)throw N(b==null?`HTTP refused ${h}: ${y.error}`:`HTTP redirect to ${h} ${y.error}`,b==null?{}:{status:b});let l=new URL(h).hostname;if(m){if(w&&(await w.close(),w=null),!w)try{w=await j({requireUndici:!0,...d?{importUndici:d}:{}})}catch(E){throw N(b==null?`HTTP refused ${h}: ${E?.message||E}`:`HTTP redirect to ${h} refused: ${E?.message||E}`,b==null?{}:{status:b})}w.pin(l,y.addresses),C=w.fetch}else Z(C,l,y.addresses);return y};try{let h=String(t),b={...n||{}};f&&await k(h);for(let y=0;y<=re;y+=1){let l=await C(h,{method:r,headers:b,body:o,signal:I,redirect:"manual"});if(ke.has(l.status)){if(r!=="GET"&&r!=="HEAD"){let R=await oe(l,p??$e,{url:h,truncate:!0}),A=new Error(`HTTP ${l.status} ${r} ${h} redirected non-idempotent request`);throw A.status=l.status,A.body=se(R)??R.slice(0,300),A}if(y===re)throw L(l),new Error(`HTTP redirect loop for ${t}`);let S=l.headers?.get?.("location"),x;try{x=He(S,h)}catch(R){throw L(l),R}let $=!Be(x,h);if(L(l),$&&(b=Le(b)),f)await k(x,{status:l.status});else if($){let R=await D(x,P);if(!R.ok){let A=new Error(`HTTP redirect from ${h} ${R.error}`);throw A.status=l.status,A.retryable=!1,A}m&&R.addresses?.length&&(w||(w=await j(d?{importUndici:d}:{})),w&&(w.pin(new URL(x).hostname,R.addresses),C=w.fetch))}h=x;continue}if(typeof s=="function")try{await s(l,{url:h})}catch(S){throw L(l),N(S?.message||String(S))}let E=await oe(l,p,{url:h,onOversize:()=>u.abort()}),B=se(E);if(!l.ok){let S=new Error(`HTTP ${l.status} ${r} ${h}`);throw S.status=l.status,S.retryAfter=l.headers?.get?.("retry-after")??null,S.body=B??E.slice(0,300),S}return B??E}throw new Error(`HTTP redirect loop for ${t}`)}finally{clearTimeout(g),w&&await w.close()}}async function ce(t,e={}){let r=e.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=e.timeoutMs??12e3,o=(e.method||"GET").toUpperCase(),c={Accept:"application/json",...e.headers||{}},i=e.body;i!=null&&typeof i!="string"&&(c["Content-Type"]=c["Content-Type"]||"application/json",i=JSON.stringify(i));let m=Number.isInteger(e.retries)?Math.max(e.retries,0):Pe,f=e.lookupFn,p=!e.fetchImpl,d=e.untrustedUrl===!0,s=e.importUndici,a=e.validateResponse,u=e.signal,g=Number(e.maxResponseBytes),I=Number.isFinite(g)&&g>0?Math.floor(g):null,w=async()=>{let b;for(let y=0;y<=m;y++){u?.throwIfAborted?.();try{return await Je(t,{fetchImpl:r,method:o,headers:c,body:i,timeoutMs:n,lookupFn:f,realFetch:p,untrustedUrl:d,maxResponseBytes:I,importUndici:s,validateResponse:a,signal:u})}catch(l){b=l;let E=l?.status,B=l?.name==="AbortError"||l?.name==="TimeoutError"||u?.aborted,S=new Set([408,425,429]),x=l?.retryable===!1?!1:E!=null?S.has(E)||Ce.has(E)&&ee.has(o):!B&&ee.has(o);if(y===m||!x)throw l;let $=De(y,l?.retryAfter);u?await new Promise((R,A)=>{let xe=setTimeout(R,$);u.addEventListener("abort",()=>{clearTimeout(xe),A(u.reason||new DOMException("Aborted","AbortError"))},{once:!0})}):await je($)}}throw b};if(!(e.dedupe!==!1&&!u&&Ue(o,i)))return w();let P=Fe(o,t,c,{untrustedUrl:d,maxResponseBytes:I},i),k=V.get(P);if(k)return k;let h=w().finally(()=>V.delete(P));return V.set(P,h),h}var ie={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}},Ve=new Map(Object.values(ie).map(t=>[t.chainId,t]));function ue(t){return Ve.get(Number(t))||null}function le(t,e=process.env){let r=ue(t);if(!r)return null;for(let n of r.rpcEnv){let o=(e[n]||"").trim();if(o)return o}return null}import{Interface as Ye,getAddress as At}from"ethers";var xt=new Ye(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Ge={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"};function qe(t,{rpcUrl:e,env:r=process.env}={}){if(e)return e;let n=le(t,r);return n||Ge[Number(t)]||null}var We=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Ke(t){let e=String(t||""),r=e.toLowerCase();if(e!==e.trim()||!/^[a-zA-Z0-9_]+$/.test(e)||!We.test(r))throw new Error(`evm-rpc: ${e} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}var H=new Map,fe=new Map;function Xe(t){let e=new Error(t?.message||JSON.stringify(t));return e.code=t?.code,e}function Ze(t){if(t?.error)throw Xe(t.error);return t?.result}function Qe(t,e,r){return`${t}
3
+ ${e}
4
+ ${JSON.stringify(r??[])}`}async function et(t,e,r){return ce(t,{method:"POST",body:e,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function de(t,e,r=[],n={}){let o=String(e||""),c=Ke(o),i=qe(t,n);if(!i)throw new Error(`No RPC URL for chainId ${t} (set env from chain registry rpcEnv or pass rpcUrl)`);if(c==="eth_chainid"&&n.cacheChainId!==!1){let d=fe.get(i);if(d!=null)return d}let f=n.dedupe!==!1&&!n.signal?Qe(i,o,r):null;if(f&&H.has(f))return H.get(f);let p=(async()=>{let d=await et(i,{jsonrpc:"2.0",id:1,method:e,params:r},n),s=Ze(d);return c==="eth_chainid"&&typeof s=="string"&&fe.set(i,s),s})();return f&&(H.set(f,p),p.finally(()=>{H.get(f)===p&&H.delete(f)}).catch(()=>{})),p}var W=999,q=1,tt=8453,pe="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",rt="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",he="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",nt="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",ot=".80002105.reverse",K=/^0x[a-fA-F0-9]{40}$/,me=new TextEncoder,we=t=>"0x"+Buffer.from(t).toString("hex"),_=t=>we(G(me.encode(t))).slice(0,10),ye=t=>t.toLowerCase().replace(/^0x/,"").padStart(64,"0");function O(t){let e=new Uint8Array(32);if(t)for(let r of String(t).split(".").reverse()){let n=G(me.encode(r)),o=new Uint8Array(64);o.set(e,0),o.set(n,32),e=G(o)}return we(e)}function X(t){if(!t||t==="0x"||/^0x0*$/.test(t))return"";try{let e=t.slice(2),r=parseInt(e.slice(0,64),16)*2,n=parseInt(e.slice(r,r+64),16);if(!Number.isFinite(n)||n<=0)return"";let o=e.slice(r+64,r+64+n*2);return Buffer.from(o,"hex").toString("utf8")}catch{return""}}async function T(t,e,r){try{return await de(t,"eth_call",[{to:e,data:r},"latest"])}catch{return null}}async function st(t){let e=await T(W,pe,_("primaryName(address)")+ye(t)),r=X(e);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function at(t){let e=await T(W,rt,_("getName(address)")+ye(t)),r=X(e);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function ge(t,e,r){let n=await T(t,r,_("name(bytes32)")+e.slice(2));return X(n)||null}async function ct(t){let e=O(`${t.slice(2).toLowerCase()}.addr.reverse`),r=await T(q,he,_("resolver(bytes32)")+e.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:ge(q,e,n)}async function it(t){let e=O(t.slice(2).toLowerCase()+ot);return ge(tt,e,nt)}var be=[{source:"hl",fn:st},{source:"hype",fn:at},{source:"ens",fn:ct},{source:"basename",fn:it}];async function Ee(t){if(!K.test(String(t||"").trim()))return null;let e=String(t).trim();return(await Promise.all(be.map(async({source:n,fn:o})=>{try{let c=await o(e);return c?{name:c,source:n,address:e}:null}catch{return null}}))).find(Boolean)||null}async function ut(t){let e=O(t),r=await T(W,pe,_("ownerOf(uint256)")+e.slice(2));if(!r||r.length<66)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:n}async function lt(t,e,r){let n=O(e),o=await T(t,r,_("resolver(bytes32)")+n.slice(2));if(!o)return null;let c="0x"+o.slice(-40);if(/^0x0+$/.test(c))return null;let i=await T(t,c,_("addr(bytes32)")+n.slice(2));if(!i)return null;let m="0x"+i.slice(-40);return/^0x0+$/.test(m)?null:m}async function Se(t){let e=String(t||"").trim().toLowerCase();if(!e||!e.includes("."))return null;if(e.endsWith(".hl")){let r=await ut(e);return r?{address:r,source:"hl",name:e}:null}if(e.endsWith(".eth")){let r=await lt(q,e,he);return r?{address:r,source:e.endsWith(".base.eth")?"basename":"ens",name:e}:null}return null}var Re=be.map(t=>t.source);var Ae=`oracle resolve <name-or-address> [--json]
3
5
 
4
6
  oracle resolve demi.hl
5
7
  oracle resolve vitalik.eth
@@ -8,16 +10,16 @@ import{keccak_256 as Y}from"@noble/hashes/sha3.js";import{createHash as ve}from"
8
10
  Reads on-chain name records. No API key: HL Names publishes a paid REST API,
9
11
  but the contract answers primaryName(address) for free.
10
12
 
11
- Sources, in priority order: ${be.join(", ")}.`;async function tt(t=[]){let e=t.filter(o=>o!=="--json"),r=t.includes("--json"),n=(e[0]||"").trim();if(!n||n==="--help"||n==="-h")return process.stdout.write(ge+`
12
- `),n?0:1;try{if(W.test(n)){let c=await we(n);return r?(process.stdout.write(JSON.stringify({address:n,name:c?.name??null,source:c?.source??null})+`
13
+ Sources, in priority order: ${Re.join(", ")}.`;async function ft(t=[]){let e=t.filter(o=>o!=="--json"),r=t.includes("--json"),n=(e[0]||"").trim();if(!n||n==="--help"||n==="-h")return process.stdout.write(Ae+`
14
+ `),n?0:1;try{if(K.test(n)){let c=await Ee(n);return r?(process.stdout.write(JSON.stringify({address:n,name:c?.name??null,source:c?.source??null})+`
13
15
  `),0):c?(process.stdout.write(`${n}
14
16
  ${c.name} [${c.source}]
15
17
  `),0):(process.stdout.write(`${n}
16
18
  no name record found
17
- `),0)}let o=await ye(n);return r?(process.stdout.write(JSON.stringify({name:n,address:o?.address??null,source:o?.source??null})+`
19
+ `),0)}let o=await Se(n);return r?(process.stdout.write(JSON.stringify({name:n,address:o?.address??null,source:o?.source??null})+`
18
20
  `),0):o?(process.stdout.write(`${n}
19
21
  ${o.address} [${o.source}]
20
22
  `),0):(process.stdout.write(`${n}
21
23
  unresolved (no owner record)
22
24
  `),0)}catch(o){return process.stderr.write(`resolve failed: ${o?.message||o}
23
- `),1}}var Et={name:"resolve",summary:"resolve .hl/.hype/.eth names to addresses and back",usage:ge,async run(t){return tt(t.argv||[])}};export{Et as default};
25
+ `),1}}var Pt={name:"resolve",summary:"resolve .hl/.hype/.eth names to addresses and back",usage:Ae,async run(t){return ft(t.argv||[])}};export{Pt as default};
@@ -0,0 +1,21 @@
1
+ import V from"node:fs";import Z from"node:os";import Q from"node:path";import h from"node:fs";import U from"node:os";import S from"node:path";import{createHash as D,randomUUID as P}from"node:crypto";var E=1,x=Object.freeze([300*1e3,3600*1e3,14400*1e3,1440*60*1e3]),T=new Set(["prepare","no_trade"]),R=new Set(["buy","sell","long","short","hold","none"]),v=Object.freeze(["privatekey","secretkey","seed","mnemonic","passphrase","password","keystore","keymaterial","apikey","authtoken","accesstoken","refreshtoken","credential","bearer","signature","authorization","xprv","xpriv","wif"]);function w(e){return e!=null&&typeof e=="object"&&!Array.isArray(e)}function f(e){return e==null?e:JSON.parse(JSON.stringify(e))}function b(e){return Array.isArray(e)?e.map(b):w(e)?Object.fromEntries(Object.keys(e).sort().map(r=>[r,b(e[r])])):e}function I(e){return JSON.stringify(b(e))}function $(e){return D("sha256").update(I(e),"utf8").digest("hex")}function H(e){return String(e).toLowerCase().replace(/[^a-z0-9]/g,"")}function g(e,r="$"){if(Array.isArray(e)){e.forEach((o,t)=>g(o,`${r}[${t}]`));return}if(w(e))for(let[o,t]of Object.entries(e)){let i=H(o);if(v.some(n=>i.includes(n)))throw new Error(`prepare-shadow-ledger: forbidden secret-like field at ${r}.${o}`);g(t,`${r}.${o}`)}}function p(e,r){if(e==null||e==="")return null;let o=Number(e);if(!Number.isFinite(o))throw new TypeError(`${r} must be finite`);return o}function l(e,r=256){return e==null||e===""?null:String(e).trim().slice(0,r)||null}function O(e,r,o=1){let t=Number(e);if(!Number.isInteger(t)||t<o)throw new TypeError(`${r} must be an integer >= ${o}`);return t}function J(e){let r=Array.isArray(e)&&e.length?e:x,o=[...new Set(r.map(t=>O(t,"horizonMs")))].sort((t,i)=>t-i);if(o.length>12)throw new TypeError("prepare-shadow-ledger: at most 12 horizons are allowed");return o}function F(e){return e==="buy"||e==="long"?1:e==="sell"||e==="short"?-1:0}function L(){return S.join(U.homedir(),".oracle","prepare-shadow-ledger.json")}function B(e){if(typeof e!="string"||!e||!S.isAbsolute(e))throw new Error("prepare-shadow-ledger: path must be absolute")}function k(e){let r;try{r=h.lstatSync(e)}catch(o){if(o?.code==="ENOENT")return;throw o}if(r.isSymbolicLink())throw new Error("prepare-shadow-ledger: store path must not be a symlink");if(!r.isFile())throw new Error("prepare-shadow-ledger: store path must be a regular file");if((r.mode&18)!==0)throw new Error("prepare-shadow-ledger: store file must not be group or world writable")}function q(){return{version:E,decisions:[],outcomes:[]}}function z(e,r){let o;try{o=JSON.parse(e)}catch{throw new Error("prepare-shadow-ledger: malformed JSON")}if(!w(o))throw new Error("prepare-shadow-ledger: malformed JSON root");if(o.version!==E)throw new Error(`prepare-shadow-ledger: unsupported version ${o.version}`);if(!Array.isArray(o.decisions))throw new Error("prepare-shadow-ledger: decisions must be an array");if(!Array.isArray(o.outcomes))throw new Error("prepare-shadow-ledger: outcomes must be an array");return g(o,S.basename(r)),{version:E,decisions:o.decisions.map(t=>f(t)),outcomes:o.outcomes.map(t=>f(t))}}function N(e,r){g(r,"store");let o=S.dirname(e);h.mkdirSync(o,{recursive:!0,mode:448});let t=S.join(o,`.prepare-shadow-ledger.${process.pid}.${Date.now()}.${P()}.tmp`);try{h.writeFileSync(t,`${JSON.stringify(r)}
2
+ `,{mode:384,flag:"wx"}),h.renameSync(t,e);try{h.chmodSync(e,384)}catch{}}catch(i){try{h.unlinkSync(t)}catch{}throw i}}function G(e={},r={}){if(!w(e))throw new TypeError("prepare-shadow-ledger: decision must be a plain object");g(e,"decision");let o=O(r.nowMs??e.createdAt??Date.now(),"createdAt",0),t=String(e.kind||"prepare").trim();if(!T.has(t))throw new TypeError("prepare-shadow-ledger: kind must be prepare or no_trade");let i=l(e.source,96)||"oracle",n=String(e.side||(t==="no_trade"?"none":"hold")).trim().toLowerCase();if(!R.has(n))throw new TypeError("prepare-shadow-ledger: side is invalid");let a={version:1,kind:t,source:i,createdAt:o,chain:l(e.chain,96),venue:l(e.venue,128),instrument:l(e.instrument??e.asset??e.market,160),side:n,intendedNotionalUsd:p(e.intendedNotionalUsd??e.notionalUsd,"intendedNotionalUsd"),decisionPriceUsd:p(e.decisionPriceUsd??e.priceUsd??e.midPriceUsd,"decisionPriceUsd"),score:p(e.score,"score"),confidence:p(e.confidence,"confidence"),signalId:l(e.signalId,128),prepareHash:l(e.prepareHash,128),routeId:l(e.routeId,128),simulation:w(e.simulation)?b(e.simulation):null,features:w(e.features)?b(e.features):null,note:l(e.note,512),horizonsMs:J(e.horizonsMs),executionAllowed:!1,custody:"none"};return a.id=l(e.id,128)||$({...a,id:void 0}),Object.freeze(a)}function K(e,r){let o=p(e?.decisionPriceUsd,"decisionPriceUsd"),t=p(r?.observedPriceUsd,"observedPriceUsd"),i=F(e?.side);return!(o>0)||!(t>0)||i===0?null:(t-o)/o*1e4*i}function W(e,r={},o={}){if(!w(e))throw new TypeError("prepare-shadow-ledger: decision required");if(!w(r))throw new TypeError("prepare-shadow-ledger: outcome must be a plain object");g(r,"outcome");let t=O(r.horizonMs,"horizonMs");if(!Array.isArray(e.horizonsMs)||!e.horizonsMs.includes(t))throw new Error("prepare-shadow-ledger: outcome horizon was not declared on the decision");let i=O(r.observedAt??o.nowMs??Date.now(),"observedAt",0);if(i<e.createdAt)throw new Error("prepare-shadow-ledger: observedAt cannot precede decision time");let n=p(r.quotedOut,"quotedOut"),a=p(r.actualOut,"actualOut"),s=p(r.observedPriceUsd??r.priceUsd,"observedPriceUsd"),d=p(r.gasUsd,"gasUsd"),c=K(e,{observedPriceUsd:s}),u=n>0&&a!=null?(a-n)/n*1e4:null,m=e.kind==="no_trade"?c==null?null:c<=0:c==null?null:c>0,M={id:l(r.id,128)||$({decisionId:e.id,horizonMs:t,observedAt:i,observedPriceUsd:s,quotedOut:n,actualOut:a,gasUsd:d}),decisionId:e.id,horizonMs:t,observedAt:i,observedPriceUsd:s,quotedOut:n,actualOut:a,outputDeltaBps:u,gasUsd:d,forwardReturnBps:c,good:m,txHash:l(r.txHash??r.transactionHash,128),source:l(r.source,96)||"mark",note:l(r.note,512)};return Object.freeze(M)}var _=new Map;function C(e={}){let r=e.path||L();if(B(r),k(r),h.existsSync(r)?z(h.readFileSync(r,"utf8"),r):N(r,q()),_.has(r))return _.get(r);function o(){return k(r),z(h.readFileSync(r,"utf8"),r)}function t(n){N(r,n)}let i=Object.freeze({path:r,record(n,a={}){let s=G(n,a),d=o();if(d.decisions.some(c=>c.id===s.id))throw new Error(`prepare-shadow-ledger: decision id already exists: ${s.id}`);return d.decisions.push(f(s)),t(d),f(s)},mark(n,a,s={}){let d=o(),c=d.decisions.find(m=>m.id===n);if(!c)throw new Error(`prepare-shadow-ledger: decision not found: ${n}`);let u=W(c,a,s);if(d.outcomes.some(m=>m.decisionId===u.decisionId&&m.horizonMs===u.horizonMs))throw new Error("prepare-shadow-ledger: outcome already exists for decision horizon");return d.outcomes.push(f(u)),t(d),f(u)},list({kind:n}={}){return o().decisions.filter(s=>!n||s.kind===n).map(s=>f(s))},get(n){let a=o(),s=a.decisions.find(c=>c.id===n);if(!s)return null;let d=a.outcomes.filter(c=>c.decisionId===n);return{decision:f(s),outcomes:d.map(c=>f(c))}},outcomes(n=null){return o().outcomes.filter(s=>!n||s.decisionId===n).map(s=>f(s))},summary(){let n=o();return Y(n)}});return _.set(r,i),i}function Y(e={}){let r=Array.isArray(e.decisions)?e.decisions:[],o=Array.isArray(e.outcomes)?e.outcomes:[],t={prepare:0,no_trade:0};for(let s of r)s.kind in t&&(t[s.kind]+=1);let i=new Map,n=new Map(r.map(s=>[s.id,s]));for(let s of o){let d=n.get(s.decisionId),c=String(s.horizonMs);i.has(c)||i.set(c,{horizonMs:s.horizonMs,count:0,prepareCount:0,noTradeCount:0,goodCount:0,knownGoodCount:0,avgForwardReturnBps:null,avgOutputDeltaBps:null});let u=i.get(c);u.count+=1,d?.kind==="prepare"&&(u.prepareCount+=1),d?.kind==="no_trade"&&(u.noTradeCount+=1),typeof s.good=="boolean"&&(u.knownGoodCount+=1,s.good&&(u.goodCount+=1)),Number.isFinite(s.forwardReturnBps)&&(u._forwardSum=(u._forwardSum||0)+s.forwardReturnBps,u._forwardCount=(u._forwardCount||0)+1),Number.isFinite(s.outputDeltaBps)&&(u._outputSum=(u._outputSum||0)+s.outputDeltaBps,u._outputCount=(u._outputCount||0)+1)}let a=[...i.values()].sort((s,d)=>s.horizonMs-d.horizonMs).map(s=>{let d={...s};return s._forwardCount&&(d.avgForwardReturnBps=s._forwardSum/s._forwardCount),s._outputCount&&(d.avgOutputDeltaBps=s._outputSum/s._outputCount),d.goodRate=s.knownGoodCount?s.goodCount/s.knownGoodCount:null,delete d._forwardSum,delete d._forwardCount,delete d._outputSum,delete d._outputCount,d});return{version:E,totalDecisions:r.length,totalOutcomes:o.length,byKind:t,horizons:a,verdict:r.length===0?"empty: no prepare or NO_TRADE decisions recorded yet":"shadow ledger active: prepares and NO_TRADE calls can be graded before arming"}}var A=`oracle shadow: paper journal. No keys. No sending money.
3
+
4
+ You in a terminal can write and read.
5
+ The chat bot can write too, but it has to ask you first.
6
+ The chat bot cannot open random files or pick a different save path.
7
+
8
+ oracle shadow record --json '{"kind":"prepare","source":"signal_score","instrument":"HYPE","side":"buy","decisionPriceUsd":44}'
9
+ oracle shadow mark <decision-id> --json '{"horizonMs":300000,"observedPriceUsd":45}'
10
+ oracle shadow list --json
11
+ oracle shadow get <decision-id>
12
+ oracle shadow outcomes <decision-id>
13
+ oracle shadow summary --json
14
+ `;function X(e=[]){let r={},o=[];for(let t=0;t<e.length;t++){let i=e[t];if(!i.startsWith("--")){o.push(i);continue}let n=i.slice(2),a=e[t+1];a!=null&&!a.startsWith("--")?(r[n]=a,t+=1):r[n]=!0}return{flags:r,positional:o}}function ee(){return Q.join(Z.homedir(),".oracle","prepare-shadow-ledger.json")}function j(e,r){let o=e.json??e.file;if(!o)throw new Error(`shadow ${r}: --json or --file required`);let t=e.file?V.readFileSync(String(e.file),"utf8"):String(o);try{return JSON.parse(t)}catch{throw new Error(`shadow ${r}: input must be valid JSON`)}}function y(e){process.stdout.write(`${JSON.stringify(e,null,2)}
15
+ `)}function re(e){if(!e.length){process.stdout.write(`no shadow decisions
16
+ `);return}for(let r of e)process.stdout.write(`${r.id} ${r.kind} ${r.source} ${r.chain||"?"}/${r.instrument||"?"} ${r.side}
17
+ `)}function oe(e,r=process.env){if(e.store&&r.ORACLE_CHAT_TOOL==="1")throw new Error("shadow --store is unavailable from oracle_cli; use the default ledger store");if(e.file&&r.ORACLE_CHAT_TOOL==="1")throw new Error("shadow --file is unavailable from oracle_cli; pass --json");return e.store||ee()}var fe={name:"shadow",summary:"prepare and NO_TRADE shadow ledger with outcome grading",group:"read",usage:A,async run(e){let{flags:r,positional:o}=X(e.argv||[]),t=o[0];if(!t||r.help)return process.stdout.write(A),0;let i=C({path:oe(r)});if(t==="record"){let n=i.record(j(r,"record"));return y({ok:!0,decision:n}),0}if(t==="mark"){let n=o[1];if(!n)throw new Error("shadow mark: decision id required");let a=i.mark(n,j(r,"mark"));return y({ok:!0,outcome:a}),0}if(t==="list"){let n=i.list({kind:r.kind});return r.json?y({decisions:n}):re(n),0}if(t==="get"){let n=o[1];if(!n)throw new Error("shadow get: decision id required");let a=i.get(n);return a?(y(a),0):(process.stderr.write(`shadow decision not found
18
+ `),1)}if(t==="outcomes")return y({outcomes:i.outcomes(o[1]||null)}),0;if(t==="summary"){let n=i.summary();if(r.json)y(n);else{process.stdout.write(`${n.verdict}
19
+ `),process.stdout.write(`decisions ${n.totalDecisions} outcomes ${n.totalOutcomes}
20
+ `);for(let a of n.horizons)process.stdout.write(`horizon ${a.horizonMs}ms count ${a.count} goodRate ${a.goodRate??"unknown"}
21
+ `)}return 0}return process.stderr.write(A),1}};export{fe as default};