@oracle-agent/oracle 0.35.39 → 0.35.41
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/agent-sessions.mjs +11 -11
- package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +28 -28
- package/dist/bin/oracle-data-mcp.mjs +19 -19
- package/dist/bin/oracle-gateway.mjs +43 -43
- package/dist/bin/oracle-investigate.mjs +5 -5
- package/dist/bin/oracle-launch-radar-shadow.mjs +6 -6
- package/dist/bin/oracle-mev-arb-shadow.mjs +6 -6
- package/dist/bin/oracle-mev-shadow.mjs +6 -6
- package/dist/bin/oracle-public-server.mjs +5 -5
- package/dist/bin/oracle-route.mjs +18 -18
- package/dist/bin/oracle-scan.mjs +11 -11
- package/dist/cli/commands/agent-session.mjs +18 -18
- package/dist/cli/commands/airdrop.mjs +8 -8
- package/dist/cli/commands/chat.mjs +207 -207
- package/dist/cli/commands/doctor.mjs +9 -9
- package/dist/cli/commands/eval.mjs +147 -197
- package/dist/cli/commands/farm.mjs +17 -17
- package/dist/cli/commands/follow.mjs +17 -17
- package/dist/cli/commands/mint.mjs +10 -10
- package/dist/cli/commands/model.mjs +211 -211
- package/dist/cli/commands/quickstart.mjs +6 -6
- package/dist/cli/commands/receipt.mjs +12 -12
- package/dist/cli/commands/resolve.mjs +7 -7
- package/dist/cli/commands/sign.mjs +4 -4
- package/dist/cli/commands/signer.mjs +14 -14
- package/dist/cli/commands/snipe.mjs +9 -9
- package/dist/cli/commands/strategy.mjs +4 -4
- package/dist/cli/commands/swap.mjs +14 -14
- package/dist/cli/commands/venues.mjs +2 -2
- package/dist/data/desk-data.mjs +26 -26
- package/dist/data/names.mjs +3 -3
- package/dist/data/providers/farming.mjs +2 -2
- package/dist/data/providers/lp-destination-discovery.mjs +4 -4
- package/dist/index.mjs +44 -44
- package/dist/investigator/index.mjs +2 -2
- package/dist/launch-radar/index.mjs +5 -5
- package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
- package/dist/local-signer/index.mjs +2 -2
- package/dist/local-signer/runtime.mjs +8 -8
- package/dist/nft/universal-mint-router.mjs +4 -4
- package/dist/notifications/index.mjs +7 -7
- package/dist/router/index.mjs +3 -3
- package/dist/router/prepare-bridge.mjs +2 -2
- package/dist/router/prepare-route.mjs +3 -3
- package/dist/scanner/index.mjs +4 -4
- package/dist/strategy/index.mjs +3 -3
- package/dist/teams/index.mjs +6 -6
- package/dist/tui/standalone-client.mjs +82 -82
- package/package.json +4 -4
- package/public/eval-report.json +3 -3
- package/public/oracle-splash/_variants/ice.html +2 -4
- package/public/oracle-splash/_variants/ivory.html +2 -4
- package/public/oracle-splash/assets/fonts/LICENSE-Cormorant-Garamond.txt +93 -0
- package/public/oracle-splash/assets/fonts/LICENSE-IBM-Plex-Mono.txt +93 -0
- package/public/oracle-splash/assets/fonts/LICENSE-Outfit.txt +93 -0
- package/public/oracle-splash/assets/fonts/LICENSE-UnifrakturCook.txt +94 -0
- package/public/oracle-splash/assets/fonts/font-provenance.json +426 -0
- package/public/oracle-splash/assets/fonts/oracle-font-00.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-01.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-02.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-03.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-04.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-05.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-06.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-07.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-08.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-09.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-10.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-11.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-12.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-13.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-14.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-15.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-16.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-17.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-18.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-19.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-20.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-21.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-22.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-23.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-24.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-25.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-26.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-font-27.woff2 +0 -0
- package/public/oracle-splash/assets/fonts/oracle-fonts.css +504 -0
- package/public/oracle-splash/assets/transport-probe-sw.js +2 -0
- package/public/oracle-splash/docs/browser-and-web/index.html +6 -6
- package/public/oracle-splash/docs/connectors/index.html +5 -5
- package/public/oracle-splash/docs/docs.css +4 -4
- package/public/oracle-splash/docs/docs.js +119 -7
- package/public/oracle-splash/docs/getting-started/index.html +5 -5
- package/public/oracle-splash/docs/index.html +6 -6
- package/public/oracle-splash/docs/reference/index.html +5 -5
- package/public/oracle-splash/docs/security/index.html +5 -5
- package/public/oracle-splash/docs/using-oracle/index.html +5 -5
- package/public/oracle-splash/download/index.html +8 -10
- package/public/oracle-splash/downloads/index.html +3 -5
- package/public/oracle-splash/eval/index.html +96 -0
- package/public/oracle-splash/index.html +16 -18
- package/public/oracle-splash/mesh-graph.svg +1 -1
- package/public/oracle-splash/pricing/index.html +6 -8
- package/public/oracle-splash/security/index.html +3 -5
- package/public/oracle-splash/what-it-does/index.html +4 -6
- package/public/oracle-splash/where-it-works/index.html +3 -5
- package/server.json +2 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
var Je="0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",Ae={1:["https://mainnet.gateway.tenderly.co","https://eth.drpc.org","https://rpc.flashbots.net"],8453:["https://base.gateway.tenderly.co","https://mainnet.base.org","https://base.drpc.org"],42161:["https://arbitrum.gateway.tenderly.co","https://arb1.arbitrum.io/rpc","https://arbitrum.drpc.org"]},Lt=1e4,jt=e=>new Promise(t=>setTimeout(t,e)),Ve=e=>"0x"+BigInt(e).toString(16),Ht=e=>"0x"+"0".repeat(24)+e.slice(2).toLowerCase(),Ke=e=>"0x"+e.slice(26).toLowerCase(),vt=/timeout|timed out|too many requests|rate.?limit|429|502|503|504|internal error|temporarily|aborted|fetch failed|ECONNRESET|socket hang up/i,Ft=/too many|exceeds|limited to|not supported on free plan|response too large|range must not exceed|narrow your filter/i,J=class extends Error{constructor(t,{transient:r=!1,tooBig:n=!1,http:o=0}={}){super(t),this.transient=r,this.tooBig=n,this.http=o}};async function Ut(e,t,r,n){let o=new AbortController,i=setTimeout(()=>o.abort(),n),s,l;try{s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:t,params:r}),signal:o.signal}),l=await s.text()}catch(u){throw new J(`${t} network: ${u.message}`,{transient:!0})}finally{clearTimeout(i)}let a;try{a=JSON.parse(l)}catch{throw new J(`${t} non-JSON http=${s.status}: ${l.slice(0,80)}`,{transient:s.status>=500||s.status===429,http:s.status})}if(a.error){let u=a.error.message||"rpc error";throw new J(`${t} rpc: ${u}`,{transient:vt.test(u),tooBig:Ft.test(u),http:s.status})}if(s.status!==200)throw new J(`${t} http=${s.status}: ${l.slice(0,80)}`,{transient:s.status>=500||s.status===429,http:s.status});return a.result}async function Ye(e,t,r,{retries:n,timeoutMs:o,onWarn:i}){let s;for(let l of e){for(let a=0;a<=n;a++)try{return{result:await Ut(l,t,r,o),url:l}}catch(u){if(s=u,u.tooBig)throw u;if(!u.transient||a===n)break;let c=Math.min(2e3*2**a,8e3)+Math.random()*250;i?.(`retry ${l} (${u.message.slice(0,70)}) in ${Math.round(c)}ms`),await jt(c)}i?.(`endpoint exhausted: ${l} -> ${s?.message.slice(0,70)}`)}throw s??new J("no endpoints available")}async function Ee(e,t,r,n,o,i){let s=[{...t,fromBlock:Ve(r),toBlock:Ve(n)}];try{let{result:a}=await Ye(e,"eth_getLogs",s,o);Array.isArray(a)&&i.push(...a);return}catch(a){if(!a.tooBig||n<=r)throw a;o.onWarn?.(`splitting ${r}-${n} (${a.message.slice(0,60)})`)}let l=r+Math.floor((n-r)/2);await Promise.all([Ee(e,t,r,l,o,i),Ee(e,t,l+1,n,o,i)])}async function Te(e,t={}){if(!/^0x[0-9a-fA-F]{40}$/.test(e||""))throw new Error(`invalid address: ${e}`);let{chains:r=[1,8453,42161],lookback:n=1e5,fromBlock:o,toBlock:i,chunkSize:s=Lt,tokens:l,direction:a="both",retries:u=3,timeoutMs:c=2e4,concurrency:p=4,endpoints:f=Ae,onWarn:h}=t,d={retries:u,timeoutMs:c,onWarn:h},y=Ht(e),E=[],O=[],N={},x=new Set;return await Promise.all(r.map(async b=>{let C=f[b];if(!C?.length){O.push({chainId:b,stage:"config",error:"no endpoints configured"});return}try{let L=i;if(L==null){let{result:g}=await Ye(C,"eth_blockNumber",[],d);L=parseInt(g,16)}let w=Math.max(0,o??L-n+1),S=Math.max(w,L);N[b]={fromBlock:w,toBlock:S,blocks:S-w+1};let _=[];for(let g=w;g<=S;g+=s)_.push([g,Math.min(g+s-1,S)]);let I=[],m=l?.length?{address:l}:{};(a==="in"||a==="both")&&I.push({...m,topics:[Je,null,y]}),(a==="out"||a==="both")&&I.push({...m,topics:[Je,y,null]});let k=[];for(let g of I)for(let j of _)k.push([g,j]);let v=[],$=0,W=Array.from({length:Math.min(p,k.length)},async()=>{for(;$<k.length;){let[g,[j,A]]=k[$++];try{await Ee(C,g,j,A,d,v)}catch(T){O.push({chainId:b,stage:"getLogs",range:[j,A],error:T.message})}}});await Promise.all(W);for(let g of v){if(!g?.topics||g.topics.length<3)continue;let j=parseInt(g.logIndex,16),A=`${b}|${g.transactionHash}|${j}`;x.has(A)||(x.add(A),E.push({chainId:b,token:g.address.toLowerCase(),from:Ke(g.topics[1]),to:Ke(g.topics[2]),value:BigInt(g.data==="0x"?"0x0":g.data).toString(),blockNumber:parseInt(g.blockNumber,16),txHash:g.transactionHash,logIndex:j}))}}catch(L){O.push({chainId:b,stage:"range",error:L.message})}})),E.sort((b,C)=>C.blockNumber-b.blockNumber||C.logIndex-b.logIndex),{events:E,errors:O,ranges:N}}import{keccak_256 as Le}from"@noble/hashes/sha3.js";import{createHash as Gt}from"node:crypto";import{types as z}from"node:util";import V from"node:net";import Mt from"node:dns";var Dt=new Set(["localhost","metadata.google.internal","metadata.goog"]);function le(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=c=>{if(!c)return[];let p=c.split(":"),f=p.at(-1);if(f?.includes(".")){let h=f.split(".").map(Number);if(h.length!==4||h.some(d=>!Number.isInteger(d)||d<0||d>255))return null;p.splice(p.length-1,1,(h[0]<<8|h[1]).toString(16),(h[2]<<8|h[3]).toString(16))}return p.some(h=>!/^[0-9a-f]{1,4}$/.test(h))?null:p.map(h=>Number.parseInt(h,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let l=t.includes("::"),a=8-i.length-s.length;if(!l&&a!==0||l&&a<1)return null;let u=[...i,...Array(Math.max(0,a)).fill(0),...s];return u.length!==8?null:Uint8Array.from(u.flatMap(c=>[c>>8,c&255]))}function Oe(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 _e(e){if(V.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(V.isIPv6(e)){let t=le(e);if(!t)return!1;let r=le("::ffff:0:0");return Oe(t,r,96)?_e([...t.slice(12)].join(".")):Oe(t,le("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>Oe(t,le(o),i)):!1}return!1}function Bt(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(Dt.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=V.isIP(r);return n!==0&&!_e(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function ke(e,{lookupFn:t=Mt.promises.lookup}={}){let r=Bt(e);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 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=>!_e(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function $e({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let p=await t();r=p.Agent,n=p.fetch}catch(p){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${p?.message||p}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=p=>String(p).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=p=>(Array.isArray(p)?p:[p]).map(f=>typeof f=="string"?{address:f}:f).filter(f=>f&&f.address).map(f=>({address:f.address,family:f.family||(V.isIPv6(f.address)?6:4)})),l=(p,f,h)=>{i.set(o(p),s(typeof f=="string"?[{address:f,family:h}]:f))},a=p=>{let f=o(p);if(V.isIP(f))return[{address:f,family:V.isIPv6(f)?6:4}];let h=i.get(f);if(!h||!h.length)throw new Error(`refused: unpinned host ${p} during pinned fetch`);return h},u=new r({connect:{lookup(p,f,h){let d;try{d=a(p)}catch(y){return h(y)}return f?.all?h(null,d):h(null,d[0].address,d[0].family)}}}),c=zt((p,f={})=>n(p,{...f,dispatcher:u}),l);return{dispatcher:u,fetch:c,pin:l,resolve:a,async close(){try{await u.destroy()}catch{}}}}var Re=Symbol.for("oracle.egressGuard.pinCapableFetch");function zt(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[Re]=Object.freeze({pin:t}),e}function Ne(e){return typeof e=="function"&&typeof e[Re]?.pin=="function"}function Xe(e,t,r){if(!Ne(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Re].pin(t,r)}var Wt=new Set([408,425,429,500,502,503,504]),Ze=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),qt=2,Qe=4e3,Jt=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Vt=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Kt=AbortSignal.prototype.throwIfAborted,Yt=EventTarget.prototype.addEventListener,et=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,Ce=e=>e?Jt.call(e):!1,Xt=e=>e?Vt.call(e):void 0,Zt=new Set([301,302,303,307,308]),de=3,no=64*1024,B=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});function P(e){return G(`HTTP JSON body refused: ${e}`)}function Qt(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof z[t]=="function"&&z[t](e))}function er(e){let t=[],r=0,n=0,o=0,i=0,s=new WeakSet,l=c=>{if(r+=Buffer.byteLength(c,"utf8"),r>B.bytes)throw P("serialized byte limit exceeded");t.push(c)},a=c=>{if(Buffer.byteLength(c,"utf8")>B.bytes)throw P("serialized byte limit exceeded");return JSON.stringify(c)},u=(c,p)=>{if(n+=1,n>B.nodes)throw P("node limit exceeded");if(p>B.depth)throw P("depth limit exceeded");if(c===null){l("null");return}if(typeof c=="string"){l(a(c));return}if(typeof c=="boolean"){l(c?"true":"false");return}if(typeof c=="number"){if(!Number.isFinite(c))throw P("non-finite number");l(Object.is(c,-0)?"0":String(c));return}if(typeof c!="object")throw P("unsupported non-JSON value");if(z.isProxy(c))throw P("proxy value");if(Qt(c))throw P("unsupported exotic object");if(s.has(c))throw P("cyclic value");s.add(c);try{if(Object.getOwnPropertySymbols(c).length>0)throw P("symbol-keyed fields are unsupported");if(Array.isArray(c)){let d=Object.getPrototypeOf(c),y=0;for(;d!==null;){if(z.isProxy(d))throw P("proxy array prototype");if(y+=1,y>B.depth)throw P("array prototype depth limit exceeded");d=Object.getPrototypeOf(d)}if(c.length>B.arrayLength)throw P("array length limit exceeded");for(let O=0;O<c.length;O+=1){let N=Object.getOwnPropertyDescriptor(c,String(O));if(!N||!Object.hasOwn(N,"value")||N.enumerable!==!0)throw P("array entries must be dense enumerable own data")}let E=0;for(let O in c){if(i+=1,i>B.fields)throw P("enumeration limit exceeded");if(Object.hasOwn(c,O)&&(E+=1,E>c.length))throw P("named array fields are unsupported")}if(E!==c.length)throw P("array entries must be dense enumerable own data");l("[");for(let O=0;O<c.length;O+=1)O&&l(","),u(Object.getOwnPropertyDescriptor(c,String(O)).value,p+1);l("]");return}let f=Object.getPrototypeOf(c);if(f!==Object.prototype&&f!==null)throw P("non-plain object");let h=[];for(let d in c){if(i+=1,i>B.fields)throw P("enumeration limit exceeded");if(!Object.hasOwn(c,d))continue;if(o+=1,o>B.fields)throw P("field limit exceeded");let y=Object.getOwnPropertyDescriptor(c,d);if(!y||!Object.hasOwn(y,"value")||y.enumerable!==!0)throw P("object fields must be enumerable own data");h.push([d,y.value])}l("{");for(let d=0;d<h.length;d+=1)d&&l(","),l(a(h[d][0])),l(":"),u(h[d][1],p+1);l("}")}finally{s.delete(c)}};return u(e,0),t.join("")}function tr(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(z.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let r=new Set;for(let n of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(n))throw new TypeError("HTTP header names must be valid tokens");let o=n.toLowerCase();if(r.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");r.add(o);let i=Object.getOwnPropertyDescriptor(e,n);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let s=i.value;if(s==null||["object","function","symbol"].includes(typeof s))throw new TypeError("HTTP header values must be scalar");t[n]=String(s)}return t}function rr(){return Object.assign(Object.create(null),{Accept:"application/json"})}function nr(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 or(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}var Ie=new Map,tt=new WeakMap,rt=1;function ue(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=tt.get(e);return t||(t=rt,rt+=1,tt.set(e,t)),`reference:${t}`}var sr=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),ir=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);function nt(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?sr.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function ot(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}if(Array.isArray(r))return r.length>0&&r.every(nt);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return nt(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&ir.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function ar(e,t,r,n={},o=null){let i=Gt("sha256"),s=(a,u)=>{let c=String(u);i.update(String(Buffer.byteLength(a,"utf8"))).update(":").update(a),i.update("=").update(String(Buffer.byteLength(c,"utf8"))).update(":").update(c).update(`
|
|
2
|
-
`)};s("method",e),s("url",t),Object.keys(r||{}).map((a,u)=>({name:a.toLowerCase(),order:u,value:String(r[a])})).sort((a,u)=>a.name.localeCompare(u.name)||a.order-u.order).forEach((a,u)=>{s(`header-name-${u}`,a.name),s(`header-value-${u}`,a.value)}),s("body",o??"-");for(let a of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])s(`context-${a}`,n[a]??"-");return i.digest("hex")}function cr(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,Qe):Math.min(250*2**e,Qe)+Math.floor(Math.random()*100)}var lr=e=>new Promise(t=>setTimeout(t,e));function G(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function Pe(e,t,r){return G(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function K(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function ur(e){return e?e.byteLength??e.length??0:0}async function dr(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&&(K(e),!n))throw Pe(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let p=await e.text(),f=Buffer.byteLength(p,"utf8");if(f>t){if(!n)throw Pe(r,`body ${f} bytes`,t);return Buffer.from(p,"utf8").subarray(0,t).toString("utf8")}return p}let l=[],a=0,u=!1;try{for(;;){let{value:p,done:f}=await s.read();if(f)break;if(p&&(l.push(Buffer.from(p)),a+=ur(p),a>t)){u=!0;break}}}finally{if(u)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!n))throw Pe(r,`streamed ${a} bytes`,t);let c=Buffer.concat(l);return(u?c.subarray(0,t):c).toString("utf8")}function fr(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function pr(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:l,untrustedUrl:a=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:c=!1,importUndici:p,validateResponse:f,signal:h,redirectPolicy:d="follow",maxRedirects:y=de}){let E=new AbortController,O=setTimeout(()=>E.abort(),i),N=h?et?et([h,E.signal]):h:E.signal,x=null,b=t,C=s?{lookupFn:s}:{};if(a&&!l&&!Ne(b))throw G(`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 L=async(w,{status:S=null}={})=>{let _=await ke(w,C);if(!_.ok)throw G(S==null?`HTTP refused ${w}: ${_.error}`:`HTTP redirect to ${w} ${_.error}`,S==null?{}:{status:S});let I=new URL(w).hostname;if(l){if(x&&(await x.close(),x=null),!x)try{x=await $e({requireUndici:!0,...p?{importUndici:p}:{}})}catch(m){throw G(S==null?`HTTP refused ${w}: ${m?.message||m}`:`HTTP redirect to ${w} refused: ${m?.message||m}`,S==null?{}:{status:S})}x.pin(I,_.addresses),b=x.fetch}else Xe(b,I,_.addresses);return _};try{let w=String(e),S=Object.assign(Object.create(null),n||{});a&&await L(w);for(let _=0;_<=y;_+=1){let I=Object.assign(Object.create(null),{method:r,headers:S,body:o,signal:N,redirect:"manual",dispatcher:void 0}),m=await b(w,I);if((d==="error"||y===0)&&m.status>=300&&m.status<400)throw K(m),G(`HTTP ${m.status} ${r} redirect refused`,{status:m.status,redirectRefused:!0});if(Zt.has(m.status)){let $=c===!0&&r==="POST"&&[307,308].includes(m.status)&&ot(r,o);if(r!=="GET"&&r!=="HEAD"&&!$){K(m);let A=new Error(`HTTP ${m.status} ${r} ${w} redirected non-idempotent request`);throw A.status=m.status,A}if(_===y)throw K(m),G(`HTTP ${m.status} ${r} redirect budget exhausted`,{status:m.status,redirectRefused:!0});let W=m.headers?.get?.("location"),g;try{g=nr(W,w)}catch(A){throw K(m),A}let j=!or(g,w);if(K(m),j&&r==="POST"){let A=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw A.status=m.status,A}if(j&&c){let A=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw A.status=m.status,A.retryable=!1,A}if(j&&(S=rr(S)),a)await L(g,{status:m.status});else if(j){let A=await ke(g,C);if(!A.ok){let T=new Error(`HTTP redirect from ${w} ${A.error}`);throw T.status=m.status,T.retryable=!1,T}l&&A.addresses?.length&&(x||(x=await $e(p?{importUndici:p}:{})),x&&(x.pin(new URL(g).hostname,A.addresses),b=x.fetch))}w=g;continue}if(typeof f=="function")try{await f(m,{url:w})}catch($){throw K(m),G($?.message||String($))}let k=await dr(m,u,{url:w,onOversize:()=>E.abort()}),v=fr(k);if(!m.ok){let $=new Error(`HTTP ${m.status} ${r} ${w}`);throw $.status=m.status,$.retryAfter=m.headers?.get?.("retry-after")??null,$.body=v??k.slice(0,300),$}return v??k}throw new Error(`HTTP redirect loop for ${e}`)}catch(w){if(E.signal.aborted&&!Ce(h)){let S=w&&(typeof w=="object"||typeof w=="function")&&!z.isProxy(w)?w:null,_=S?Object.getOwnPropertyDescriptor(S,"oversize"):null;if(!(_&&Object.hasOwn(_,"value")&&_.value===!0))try{if(!S)throw new TypeError("unsafe rejection");Object.defineProperties(S,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let m=new Error("HTTP request timed out");throw Object.defineProperties(m,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),m}}throw w}finally{clearTimeout(O),x&&await x.close()}}async function fe(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&z.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let r=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let T of Object.getOwnPropertyNames(t)){let R=Object.getOwnPropertyDescriptor(t,T);if(!(T==="toJSON"&&R&&Object.hasOwn(R,"value")&&R.value===void 0)){if(!r.has(T))throw new TypeError("HTTP options contain unknown fields");if(!R||!R.enumerable||!Object.hasOwn(R,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=T=>{if(t==null||!Object.hasOwn(t,T))return;let R=Object.getOwnPropertyDescriptor(t,T);if(!R||!Object.hasOwn(R,"value"))throw new TypeError("HTTP options must contain own data properties");return R.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=n("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let i=n("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let s=n("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>10))throw new TypeError("HTTP retries must be a bounded integer");let l=n("redirectPolicy");if(l!==void 0&&l!=="follow"&&l!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let a=n("maxRedirects");if(a!==void 0&&(!Number.isInteger(a)||a<0||a>de))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${de}`);if(l==="error"&&a!==void 0&&a!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=l??"follow",c=u==="error"?0:a??de;for(let T of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let R=n(T);if(R!==void 0&&typeof R!="boolean")throw new TypeError(`HTTP ${T} must be boolean`)}let p=n("maxResponseBytes");if(p!==void 0&&(!Number.isInteger(p)||p<1||p>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let f=n("signal");if(f!==void 0){if(z.isProxy(f)||!(f instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{Ce(f)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let T of["importUndici","lookupFn","validateResponse"]){let R=n(T);if(R!==void 0&&typeof R!="function")throw new TypeError(`HTTP ${T} must be a function`)}let h=n("fetchImpl"),d=h||globalThis.fetch;if(typeof d!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let y=i??12e3,E=(o||"GET").toUpperCase(),O=n("headers"),N=tr(O),x=Object.assign(Object.create(null),N);Object.keys(x).some(T=>T.toLowerCase()==="accept")||(x.Accept="application/json");let b=n("body");b!=null&&typeof b!="string"&&(Object.keys(x).find(R=>R.toLowerCase()==="content-type")||(x["Content-Type"]="application/json"),b=er(b));let C=s??qt,L=n("lookupFn"),w=!h,S=n("untrustedUrl")===!0,_=n("sameOriginRedirectsOnly")===!0,I=n("importUndici"),m=n("validateResponse"),k=f,v=p??null,$=async()=>{let T;for(let R=0;R<=C;R++){k&&Kt.call(k);try{return await pr(e,{fetchImpl:d,method:E,headers:x,body:b,timeoutMs:y,lookupFn:L,realFetch:w,untrustedUrl:S,maxResponseBytes:v,sameOriginRedirectsOnly:_,importUndici:I,validateResponse:m,signal:k,redirectPolicy:u,maxRedirects:c})}catch(q){T=q;let Q=Se=>{if(!q||typeof q!="object"&&typeof q!="function"||z.isProxy(q))return;let re=Object.getOwnPropertyDescriptor(q,Se);return re&&Object.hasOwn(re,"value")?re.value:void 0},xe=Q("status"),Nt=Q("oracleTimeout")===!0||Q("name")==="AbortError"||Q("name")==="TimeoutError"||Ce(k),It=new Set([408,425,429]),Pt=Q("retryable")===!1?!1:xe!=null?It.has(xe)||Wt.has(xe)&&Ze.has(E):!Nt&&Ze.has(E);if(R===C||!Pt)throw q;let qe=cr(R,Q("retryAfter"));k?await new Promise((Se,re)=>{let Ct=setTimeout(Se,qe);Yt.call(k,"abort",()=>{clearTimeout(Ct),re(Xt(k)||new DOMException("Aborted","AbortError"))},{once:!0})}):await lr(qe)}}throw T};if(!(n("dedupe")!==!1&&!k&&ot(E,b)))return $();let g=ar(E,e,x,{untrustedUrl:S,maxResponseBytes:v,sameOriginRedirectsOnly:_,redirectPolicy:u,maxRedirects:c,timeoutMs:y,retries:C,fetchImpl:ue(d),realFetch:w,lookupFn:ue(L),importUndici:ue(I),validateResponse:ue(m)},b),j=Ie.get(g);if(j)return j;let A=$().finally(()=>Ie.delete(g));return Ie.set(g,A),A}var st={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}},hr=new Map(Object.values(st).map(e=>[e.chainId,e]));function it(e){return hr.get(Number(e))||null}function at(e,t=process.env){let r=it(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as mr,getAddress as uo}from"ethers";var fo=new mr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var yr={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 wr(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=at(e,r);return n||yr[Number(e)]||null}var br=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function gr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!br.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}var ne=new Map,ct=new Map;function xr(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function Sr(e){if(e?.error)throw xr(e.error);return e?.result}function Er(e,t,r){return`${e}
|
|
1
|
+
var Ke="0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",Oe={1:["https://mainnet.gateway.tenderly.co","https://eth.drpc.org","https://rpc.flashbots.net"],8453:["https://base.gateway.tenderly.co","https://mainnet.base.org","https://base.drpc.org"],42161:["https://arbitrum.gateway.tenderly.co","https://arb1.arbitrum.io/rpc","https://arbitrum.drpc.org"]},Ht=1e4,vt=e=>new Promise(t=>setTimeout(t,e)),Ye=e=>"0x"+BigInt(e).toString(16),Ft=e=>"0x"+"0".repeat(24)+e.slice(2).toLowerCase(),Xe=e=>"0x"+e.slice(26).toLowerCase(),Ut=/timeout|timed out|too many requests|rate.?limit|429|502|503|504|internal error|temporarily|aborted|fetch failed|ECONNRESET|socket hang up/i,Mt=/too many|exceeds|limited to|not supported on free plan|response too large|range must not exceed|narrow your filter/i,J=class extends Error{constructor(t,{transient:r=!1,tooBig:n=!1,http:o=0}={}){super(t),this.transient=r,this.tooBig=n,this.http=o}};async function Dt(e,t,r,n){let o=new AbortController,i=setTimeout(()=>o.abort(),n),s,l;try{s=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:t,params:r}),signal:o.signal}),l=await s.text()}catch(u){throw new J(`${t} network: ${u.message}`,{transient:!0})}finally{clearTimeout(i)}let a;try{a=JSON.parse(l)}catch{throw new J(`${t} non-JSON http=${s.status}: ${l.slice(0,80)}`,{transient:s.status>=500||s.status===429,http:s.status})}if(a.error){let u=a.error.message||"rpc error";throw new J(`${t} rpc: ${u}`,{transient:Ut.test(u),tooBig:Mt.test(u),http:s.status})}if(s.status!==200)throw new J(`${t} http=${s.status}: ${l.slice(0,80)}`,{transient:s.status>=500||s.status===429,http:s.status});return a.result}async function Ze(e,t,r,{retries:n,timeoutMs:o,onWarn:i}){let s;for(let l of e){for(let a=0;a<=n;a++)try{return{result:await Dt(l,t,r,o),url:l}}catch(u){if(s=u,u.tooBig)throw u;if(!u.transient||a===n)break;let c=Math.min(2e3*2**a,8e3)+Math.random()*250;i?.(`retry ${l} (${u.message.slice(0,70)}) in ${Math.round(c)}ms`),await vt(c)}i?.(`endpoint exhausted: ${l} -> ${s?.message.slice(0,70)}`)}throw s??new J("no endpoints available")}async function Te(e,t,r,n,o,i){let s=[{...t,fromBlock:Ye(r),toBlock:Ye(n)}];try{let{result:a}=await Ze(e,"eth_getLogs",s,o);Array.isArray(a)&&i.push(...a);return}catch(a){if(!a.tooBig||n<=r)throw a;o.onWarn?.(`splitting ${r}-${n} (${a.message.slice(0,60)})`)}let l=r+Math.floor((n-r)/2);await Promise.all([Te(e,t,r,l,o,i),Te(e,t,l+1,n,o,i)])}async function _e(e,t={}){if(!/^0x[0-9a-fA-F]{40}$/.test(e||""))throw new Error(`invalid address: ${e}`);let{chains:r=[1,8453,42161],lookback:n=1e5,fromBlock:o,toBlock:i,chunkSize:s=Ht,tokens:l,direction:a="both",retries:u=3,timeoutMs:c=2e4,concurrency:p=4,endpoints:f=Oe,onWarn:h}=t,d={retries:u,timeoutMs:c,onWarn:h},y=Ft(e),b=[],S=[],R={},N=new Set;return await Promise.all(r.map(async x=>{let C=f[x];if(!C?.length){S.push({chainId:x,stage:"config",error:"no endpoints configured"});return}try{let L=i;if(L==null){let{result:g}=await Ze(C,"eth_blockNumber",[],d);L=parseInt(g,16)}let w=Math.max(0,o??L-n+1),E=Math.max(w,L);R[x]={fromBlock:w,toBlock:E,blocks:E-w+1};let _=[];for(let g=w;g<=E;g+=s)_.push([g,Math.min(g+s-1,E)]);let I=[],m=l?.length?{address:l}:{};(a==="in"||a==="both")&&I.push({...m,topics:[Ke,null,y]}),(a==="out"||a==="both")&&I.push({...m,topics:[Ke,y,null]});let A=[];for(let g of I)for(let j of _)A.push([g,j]);let v=[],k=0,W=Array.from({length:Math.min(p,A.length)},async()=>{for(;k<A.length;){let[g,[j,T]]=A[k++];try{await Te(C,g,j,T,d,v)}catch(O){S.push({chainId:x,stage:"getLogs",range:[j,T],error:O.message})}}});await Promise.all(W);for(let g of v){if(!g?.topics||g.topics.length<3)continue;let j=parseInt(g.logIndex,16),T=`${x}|${g.transactionHash}|${j}`;N.has(T)||(N.add(T),b.push({chainId:x,token:g.address.toLowerCase(),from:Xe(g.topics[1]),to:Xe(g.topics[2]),value:BigInt(g.data==="0x"?"0x0":g.data).toString(),blockNumber:parseInt(g.blockNumber,16),txHash:g.transactionHash,logIndex:j}))}}catch(L){S.push({chainId:x,stage:"range",error:L.message})}})),b.sort((x,C)=>C.blockNumber-x.blockNumber||C.logIndex-x.logIndex),{events:b,errors:S,ranges:R}}import{keccak_256 as je}from"@noble/hashes/sha3.js";import{createHash as qt}from"node:crypto";import{types as z}from"node:util";import V from"node:net";import Bt from"node:dns";var zt=new Set(["localhost","metadata.google.internal","metadata.goog"]);function de(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=c=>{if(!c)return[];let p=c.split(":"),f=p.at(-1);if(f?.includes(".")){let h=f.split(".").map(Number);if(h.length!==4||h.some(d=>!Number.isInteger(d)||d<0||d>255))return null;p.splice(p.length-1,1,(h[0]<<8|h[1]).toString(16),(h[2]<<8|h[3]).toString(16))}return p.some(h=>!/^[0-9a-f]{1,4}$/.test(h))?null:p.map(h=>Number.parseInt(h,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let l=t.includes("::"),a=8-i.length-s.length;if(!l&&a!==0||l&&a<1)return null;let u=[...i,...Array(Math.max(0,a)).fill(0),...s];return u.length!==8?null:Uint8Array.from(u.flatMap(c=>[c>>8,c&255]))}function ke(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 $e(e){if(V.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(V.isIPv6(e)){let t=de(e);if(!t)return!1;let r=de("::ffff:0:0");return ke(t,r,96)?$e([...t.slice(12)].join(".")):ke(t,de("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>ke(t,de(o),i)):!1}return!1}function Gt(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(zt.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=V.isIP(r);return n!==0&&!$e(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function Re(e,{lookupFn:t=Bt.promises.lookup}={}){let r=Gt(e);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 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=>!$e(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function Ne({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let p=await t();r=p.Agent,n=p.fetch}catch(p){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${p?.message||p}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let o=p=>String(p).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=p=>(Array.isArray(p)?p:[p]).map(f=>typeof f=="string"?{address:f}:f).filter(f=>f&&f.address).map(f=>({address:f.address,family:f.family||(V.isIPv6(f.address)?6:4)})),l=(p,f,h)=>{i.set(o(p),s(typeof f=="string"?[{address:f,family:h}]:f))},a=p=>{let f=o(p);if(V.isIP(f))return[{address:f,family:V.isIPv6(f)?6:4}];let h=i.get(f);if(!h||!h.length)throw new Error(`refused: unpinned host ${p} during pinned fetch`);return h},u=new r({connect:{lookup(p,f,h){let d;try{d=a(p)}catch(y){return h(y)}return f?.all?h(null,d):h(null,d[0].address,d[0].family)}}}),c=Wt((p,f={})=>n(p,{...f,dispatcher:u}),l);return{dispatcher:u,fetch:c,pin:l,resolve:a,async close(){try{await u.destroy()}catch{}}}}var Ie=Symbol.for("oracle.egressGuard.pinCapableFetch");function Wt(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[Ie]=Object.freeze({pin:t}),e}function Pe(e){return typeof e=="function"&&typeof e[Ie]?.pin=="function"}function Qe(e,t,r){if(!Pe(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Ie].pin(t,r)}var Jt=new Set([408,425,429,500,502,503,504]),et=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),Vt=2,tt=4e3,Kt=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,Yt=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,Xt=AbortSignal.prototype.throwIfAborted,Zt=EventTarget.prototype.addEventListener,rt=EventTarget.prototype.removeEventListener,nt=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,oe=e=>e?Kt.call(e):!1,Qt=e=>e?Yt.call(e):void 0,er=new Set([301,302,303,307,308]),pe=3,so=64*1024,B=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});function P(e){return G(`HTTP JSON body refused: ${e}`)}function tr(e){return["isArgumentsObject","isArrayBuffer","isAnyArrayBuffer","isArrayBufferView","isBoxedPrimitive","isDataView","isDate","isExternal","isGeneratorObject","isKeyObject","isCryptoKey","isMap","isMapIterator","isModuleNamespaceObject","isNativeError","isPromise","isRegExp","isSet","isSetIterator","isTypedArray","isWeakMap","isWeakSet"].some(t=>typeof z[t]=="function"&&z[t](e))}function rr(e){let t=[],r=0,n=0,o=0,i=0,s=new WeakSet,l=c=>{if(r+=Buffer.byteLength(c,"utf8"),r>B.bytes)throw P("serialized byte limit exceeded");t.push(c)},a=c=>{if(Buffer.byteLength(c,"utf8")>B.bytes)throw P("serialized byte limit exceeded");return JSON.stringify(c)},u=(c,p)=>{if(n+=1,n>B.nodes)throw P("node limit exceeded");if(p>B.depth)throw P("depth limit exceeded");if(c===null){l("null");return}if(typeof c=="string"){l(a(c));return}if(typeof c=="boolean"){l(c?"true":"false");return}if(typeof c=="number"){if(!Number.isFinite(c))throw P("non-finite number");l(Object.is(c,-0)?"0":String(c));return}if(typeof c!="object")throw P("unsupported non-JSON value");if(z.isProxy(c))throw P("proxy value");if(tr(c))throw P("unsupported exotic object");if(s.has(c))throw P("cyclic value");s.add(c);try{if(Object.getOwnPropertySymbols(c).length>0)throw P("symbol-keyed fields are unsupported");if(Array.isArray(c)){let d=Object.getPrototypeOf(c),y=0;for(;d!==null;){if(z.isProxy(d))throw P("proxy array prototype");if(y+=1,y>B.depth)throw P("array prototype depth limit exceeded");d=Object.getPrototypeOf(d)}if(c.length>B.arrayLength)throw P("array length limit exceeded");for(let S=0;S<c.length;S+=1){let R=Object.getOwnPropertyDescriptor(c,String(S));if(!R||!Object.hasOwn(R,"value")||R.enumerable!==!0)throw P("array entries must be dense enumerable own data")}let b=0;for(let S in c){if(i+=1,i>B.fields)throw P("enumeration limit exceeded");if(Object.hasOwn(c,S)&&(b+=1,b>c.length))throw P("named array fields are unsupported")}if(b!==c.length)throw P("array entries must be dense enumerable own data");l("[");for(let S=0;S<c.length;S+=1)S&&l(","),u(Object.getOwnPropertyDescriptor(c,String(S)).value,p+1);l("]");return}let f=Object.getPrototypeOf(c);if(f!==Object.prototype&&f!==null)throw P("non-plain object");let h=[];for(let d in c){if(i+=1,i>B.fields)throw P("enumeration limit exceeded");if(!Object.hasOwn(c,d))continue;if(o+=1,o>B.fields)throw P("field limit exceeded");let y=Object.getOwnPropertyDescriptor(c,d);if(!y||!Object.hasOwn(y,"value")||y.enumerable!==!0)throw P("object fields must be enumerable own data");h.push([d,y.value])}l("{");for(let d=0;d<h.length;d+=1)d&&l(","),l(a(h[d][0])),l(":"),u(h[d][1],p+1);l("}")}finally{s.delete(c)}};return u(e,0),t.join("")}function nr(e){let t=Object.create(null);if(e==null)return t;if(typeof e!="object"&&typeof e!="function")throw new TypeError("HTTP headers must be an object");if(z.isProxy(e))throw new TypeError("HTTP headers must not be a proxy");if(Object.getOwnPropertySymbols(e).length>0)throw new TypeError("HTTP headers must not contain symbol fields");let r=new Set;for(let n of Object.keys(e)){if(!/^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/u.test(n))throw new TypeError("HTTP header names must be valid tokens");let o=n.toLowerCase();if(r.has(o))throw new TypeError("HTTP headers contain a duplicate canonical name");r.add(o);let i=Object.getOwnPropertyDescriptor(e,n);if(!i||!Object.hasOwn(i,"value"))throw new TypeError("HTTP headers must contain own data properties");let s=i.value;if(s==null||["object","function","symbol"].includes(typeof s))throw new TypeError("HTTP header values must be scalar");t[n]=String(s)}return t}function or(){return Object.assign(Object.create(null),{Accept:"application/json"})}function sr(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 ir(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}var Ce=new Map,ot=new WeakMap,st=1;function fe(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=ot.get(e);return t||(t=st,st+=1,ot.set(e,t)),`reference:${t}`}var ar=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),cr=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);function it(e){if(!e||typeof e!="object"||Array.isArray(e)||!Object.hasOwn(e,"jsonrpc")||!Object.hasOwn(e,"method")||e.jsonrpc!=="2.0")return!1;let t=typeof e.method=="string"?e.method:"";return t?ar.has(t)||/^get[A-Z0-9_]/u.test(t)||/^is[A-Z0-9_]/u.test(t)||/^eth_get[A-Z0-9_]/u.test(t):!1}function at(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}if(Array.isArray(r))return r.length>0&&r.every(it);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return it(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&cr.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function lr(e,t,r,n={},o=null){let i=qt("sha256"),s=(a,u)=>{let c=String(u);i.update(String(Buffer.byteLength(a,"utf8"))).update(":").update(a),i.update("=").update(String(Buffer.byteLength(c,"utf8"))).update(":").update(c).update(`
|
|
2
|
+
`)};s("method",e),s("url",t),Object.keys(r||{}).map((a,u)=>({name:a.toLowerCase(),order:u,value:String(r[a])})).sort((a,u)=>a.name.localeCompare(u.name)||a.order-u.order).forEach((a,u)=>{s(`header-name-${u}`,a.name),s(`header-value-${u}`,a.value)}),s("body",o??"-");for(let a of["untrustedUrl","maxResponseBytes","sameOriginRedirectsOnly","redirectPolicy","maxRedirects","timeoutMs","retries","fetchImpl","realFetch","lookupFn","importUndici","validateResponse"])s(`context-${a}`,n[a]??"-");return i.digest("hex")}function ur(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,tt):Math.min(250*2**e,tt)+Math.floor(Math.random()*100)}var dr=e=>new Promise(t=>setTimeout(t,e));function G(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function Le(e,t,r){return G(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function K(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function fr(e){return e?e.byteLength??e.length??0:0}async function pr(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&&(K(e),!n))throw Le(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let p=await e.text(),f=Buffer.byteLength(p,"utf8");if(f>t){if(!n)throw Le(r,`body ${f} bytes`,t);return Buffer.from(p,"utf8").subarray(0,t).toString("utf8")}return p}let l=[],a=0,u=!1;try{for(;;){let{value:p,done:f}=await s.read();if(f)break;if(p&&(l.push(Buffer.from(p)),a+=fr(p),a>t)){u=!0;break}}}finally{if(u)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(u&&(typeof o=="function"&&o(),!n))throw Le(r,`streamed ${a} bytes`,t);let c=Buffer.concat(l);return(u?c.subarray(0,t):c).toString("utf8")}function hr(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function mr(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:l,untrustedUrl:a=!1,maxResponseBytes:u=null,sameOriginRedirectsOnly:c=!1,importUndici:p,validateResponse:f,signal:h,redirectPolicy:d="follow",maxRedirects:y=pe}){let b=null,S=t,R=s?{lookupFn:s}:{};if(a&&!l&&!Pe(S))throw G(`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 N=new AbortController,x=setTimeout(()=>N.abort(),i),C=h?nt?nt([h,N.signal]):h:N.signal,L=async(w,{status:E=null}={})=>{let _=await Re(w,R);if(!_.ok)throw G(E==null?`HTTP refused ${w}: ${_.error}`:`HTTP redirect to ${w} ${_.error}`,E==null?{}:{status:E});let I=new URL(w).hostname;if(l){if(b&&(await b.close(),b=null),!b)try{b=await Ne({requireUndici:!0,...p?{importUndici:p}:{}})}catch(m){throw G(E==null?`HTTP refused ${w}: ${m?.message||m}`:`HTTP redirect to ${w} refused: ${m?.message||m}`,E==null?{}:{status:E})}b.pin(I,_.addresses),S=b.fetch}else Qe(S,I,_.addresses);return _};try{let w=String(e),E=Object.assign(Object.create(null),n||{});a&&await L(w);for(let _=0;_<=y;_+=1){let I=Object.assign(Object.create(null),{method:r,headers:E,body:o,signal:C,redirect:"manual",dispatcher:void 0}),m=await S(w,I);if((d==="error"||y===0)&&m.status>=300&&m.status<400)throw K(m),G(`HTTP ${m.status} ${r} redirect refused`,{status:m.status,redirectRefused:!0});if(er.has(m.status)){let k=c===!0&&r==="POST"&&[307,308].includes(m.status)&&at(r,o);if(r!=="GET"&&r!=="HEAD"&&!k){K(m);let T=new Error(`HTTP ${m.status} ${r} ${w} redirected non-idempotent request`);throw T.status=m.status,T}if(_===y)throw K(m),G(`HTTP ${m.status} ${r} redirect budget exhausted`,{status:m.status,redirectRefused:!0});let W=m.headers?.get?.("location"),g;try{g=sr(W,w)}catch(T){throw K(m),T}let j=!ir(g,w);if(K(m),j&&r==="POST"){let T=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw T.status=m.status,T}if(j&&c){let T=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw T.status=m.status,T.retryable=!1,T}if(j&&(E=or(E)),a)await L(g,{status:m.status});else if(j){let T=await Re(g,R);if(!T.ok){let O=new Error(`HTTP redirect from ${w} ${T.error}`);throw O.status=m.status,O.retryable=!1,O}l&&T.addresses?.length&&(b||(b=await Ne(p?{importUndici:p}:{})),b&&(b.pin(new URL(g).hostname,T.addresses),S=b.fetch))}w=g;continue}if(typeof f=="function")try{await f(m,{url:w})}catch(k){throw K(m),G(k?.message||String(k))}let A=await pr(m,u,{url:w,onOversize:()=>N.abort()}),v=hr(A);if(!m.ok){let k=new Error(`HTTP ${m.status} ${r} ${w}`);throw k.status=m.status,k.retryAfter=m.headers?.get?.("retry-after")??null,k.body=v??A.slice(0,300),k}return v??A}throw new Error(`HTTP redirect loop for ${e}`)}catch(w){if(N.signal.aborted&&!oe(h)){let E=w&&(typeof w=="object"||typeof w=="function")&&!z.isProxy(w)?w:null,_=E?Object.getOwnPropertyDescriptor(E,"oversize"):null;if(!(_&&Object.hasOwn(_,"value")&&_.value===!0))try{if(!E)throw new TypeError("unsafe rejection");Object.defineProperties(E,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}})}catch{let m=new Error("HTTP request timed out");throw Object.defineProperties(m,{oracleTimeout:{value:!0,enumerable:!1},retryable:{value:!1,enumerable:!1}}),m}}throw w}finally{clearTimeout(x),b&&await b.close()}}async function he(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&z.isProxy(t))throw new TypeError("HTTP options must not be a proxy");let r=new Set(["body","dedupe","fetchImpl","headers","importUndici","lookupFn","maxRedirects","maxResponseBytes","method","redirectPolicy","retries","sameOriginRedirectsOnly","signal","timeoutMs","untrustedUrl","validateResponse"]);if(t!=null){if(Object.getOwnPropertySymbols(t).length>0)throw new TypeError("HTTP options contain unknown fields");for(let O of Object.getOwnPropertyNames(t)){let $=Object.getOwnPropertyDescriptor(t,O);if(!(O==="toJSON"&&$&&Object.hasOwn($,"value")&&$.value===void 0)){if(!r.has(O))throw new TypeError("HTTP options contain unknown fields");if(!$||!$.enumerable||!Object.hasOwn($,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=O=>{if(t==null||!Object.hasOwn(t,O))return;let $=Object.getOwnPropertyDescriptor(t,O);if(!$||!Object.hasOwn($,"value"))throw new TypeError("HTTP options must contain own data properties");return $.value};if(typeof e!="string"||e.length===0||e.length>8192)throw new TypeError("HTTP URL must be a bounded string");let o=n("method");if(o!==void 0&&(typeof o!="string"||!/^[A-Za-z]+$/u.test(o)))throw new TypeError("HTTP method must be a string token");let i=n("timeoutMs");if(i!==void 0&&(!Number.isInteger(i)||i<1||i>12e4))throw new TypeError("HTTP timeoutMs must be a bounded integer");let s=n("retries");if(s!==void 0&&(!Number.isInteger(s)||s<0||s>10))throw new TypeError("HTTP retries must be a bounded integer");let l=n("redirectPolicy");if(l!==void 0&&l!=="follow"&&l!=="error")throw new TypeError('HTTP redirectPolicy must be "follow" or "error"');let a=n("maxRedirects");if(a!==void 0&&(!Number.isInteger(a)||a<0||a>pe))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${pe}`);if(l==="error"&&a!==void 0&&a!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let u=l??"follow",c=u==="error"?0:a??pe;for(let O of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let $=n(O);if($!==void 0&&typeof $!="boolean")throw new TypeError(`HTTP ${O} must be boolean`)}let p=n("maxResponseBytes");if(p!==void 0&&(!Number.isInteger(p)||p<1||p>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let f=n("signal");if(f!==void 0){if(z.isProxy(f)||!(f instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{oe(f)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let O of["importUndici","lookupFn","validateResponse"]){let $=n(O);if($!==void 0&&typeof $!="function")throw new TypeError(`HTTP ${O} must be a function`)}let h=n("fetchImpl"),d=h||globalThis.fetch;if(typeof d!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let y=i??12e3,b=(o||"GET").toUpperCase(),S=n("headers"),R=nr(S),N=Object.assign(Object.create(null),R);Object.keys(N).some(O=>O.toLowerCase()==="accept")||(N.Accept="application/json");let x=n("body");x!=null&&typeof x!="string"&&(Object.keys(N).find($=>$.toLowerCase()==="content-type")||(N["Content-Type"]="application/json"),x=rr(x));let C=s??Vt,L=n("lookupFn"),w=!h,E=n("untrustedUrl")===!0,_=n("sameOriginRedirectsOnly")===!0,I=n("importUndici"),m=n("validateResponse"),A=f,v=p??null,k=async()=>{let O;for(let $=0;$<=C;$++){A&&Xt.call(A);try{return await mr(e,{fetchImpl:d,method:b,headers:N,body:x,timeoutMs:y,lookupFn:L,realFetch:w,untrustedUrl:E,maxResponseBytes:v,sameOriginRedirectsOnly:_,importUndici:I,validateResponse:m,signal:A,redirectPolicy:u,maxRedirects:c})}catch(q){O=q;let Q=Ae=>{if(!q||typeof q!="object"&&typeof q!="function"||z.isProxy(q))return;let re=Object.getOwnPropertyDescriptor(q,Ae);return re&&Object.hasOwn(re,"value")?re.value:void 0},Ee=Q("status"),Ct=Q("oracleTimeout")===!0||Q("name")==="AbortError"||Q("name")==="TimeoutError"||oe(A),Lt=new Set([408,425,429]),jt=Q("retryable")===!1?!1:Ee!=null?Lt.has(Ee)||Jt.has(Ee)&&et.has(b):!Ct&&et.has(b);if($===C||!jt)throw q;let Je=ur($,Q("retryAfter"));A?await new Promise((Ae,re)=>{let Ve,ne=()=>{clearTimeout(Ve),rt.call(A,"abort",ne),re(Qt(A)||new DOMException("Aborted","AbortError"))};if(oe(A)){ne();return}Ve=setTimeout(()=>{rt.call(A,"abort",ne),Ae()},Je),Zt.call(A,"abort",ne,{once:!0}),oe(A)&&ne()}):await dr(Je)}}throw O};if(!(n("dedupe")!==!1&&!A&&at(b,x)))return k();let g=lr(b,e,N,{untrustedUrl:E,maxResponseBytes:v,sameOriginRedirectsOnly:_,redirectPolicy:u,maxRedirects:c,timeoutMs:y,retries:C,fetchImpl:fe(d),realFetch:w,lookupFn:fe(L),importUndici:fe(I),validateResponse:fe(m)},x),j=Ce.get(g);if(j)return j;let T=k().finally(()=>Ce.delete(g));return Ce.set(g,T),T}var ct={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}},yr=new Map(Object.values(ct).map(e=>[e.chainId,e]));function lt(e){return yr.get(Number(e))||null}function ut(e,t=process.env){let r=lt(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as wr,getAddress as po}from"ethers";var ho=new wr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var br={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 gr(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=ut(e,r);return n||br[Number(e)]||null}var xr=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Sr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!xr.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}var se=new Map,dt=new Map;function Er(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function Ar(e){if(e?.error)throw Er(e.error);return e?.result}function Tr(e,t,r){return`${e}
|
|
3
3
|
${t}
|
|
4
|
-
${JSON.stringify(r??[])}`}async function Ar(e,t,r){return fe(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function pe(e,t,r=[],n={}){let o=String(t||""),i=gr(o),s=wr(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 c=ct.get(s);if(c!=null)return c}let a=n.dedupe!==!1&&!n.signal?Er(s,o,r):null;if(a&&ne.has(a))return ne.get(a);let u=(async()=>{let c=await Ar(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),p=Sr(c);return i==="eth_chainid"&&typeof p=="string"&&ct.set(s,p),p})();return a&&(ne.set(a,u),u.finally(()=>{ne.get(a)===u&&ne.delete(a)}).catch(()=>{})),u}var He=999,je=1,Tr=8453,lt="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",Or="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",ut="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",_r="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",kr=".80002105.reverse",dt=/^0x[a-fA-F0-9]{40}$/,ft=new TextEncoder,pt=e=>"0x"+Buffer.from(e).toString("hex"),Y=e=>pt(Le(ft.encode(e))).slice(0,10),ht=e=>e.toLowerCase().replace(/^0x/,"").padStart(64,"0");function he(e){let t=new Uint8Array(32);if(e)for(let r of String(e).split(".").reverse()){let n=Le(ft.encode(r)),o=new Uint8Array(64);o.set(t,0),o.set(n,32),t=Le(o)}return pt(t)}function ve(e){if(!e||e==="0x"||/^0x0*$/.test(e))return"";try{let t=e.slice(2),r=parseInt(t.slice(0,64),16)*2,n=parseInt(t.slice(r,r+64),16);if(!Number.isFinite(n)||n<=0)return"";let o=t.slice(r+64,r+64+n*2);return Buffer.from(o,"hex").toString("utf8")}catch{return""}}async function X(e,t,r){try{return await pe(e,"eth_call",[{to:t,data:r},"latest"])}catch{return null}}async function $r(e){let t=await X(He,lt,Y("primaryName(address)")+ht(e)),r=ve(t);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function Rr(e){let t=await X(He,Or,Y("getName(address)")+ht(e)),r=ve(t);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function mt(e,t,r){let n=await X(e,r,Y("name(bytes32)")+t.slice(2));return ve(n)||null}async function Nr(e){let t=he(`${e.slice(2).toLowerCase()}.addr.reverse`),r=await X(je,ut,Y("resolver(bytes32)")+t.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:mt(je,t,n)}async function Ir(e){let t=he(e.slice(2).toLowerCase()+kr);return mt(Tr,t,_r)}var Pr=[{source:"hl",fn:$r},{source:"hype",fn:Rr},{source:"ens",fn:Nr},{source:"basename",fn:Ir}];async function Cr(e){let t=he(e),r=await X(He,lt,Y("ownerOf(uint256)")+t.slice(2));if(!r||r.length<66)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:n}async function Lr(e,t,r){let n=he(t),o=await X(e,r,Y("resolver(bytes32)")+n.slice(2));if(!o)return null;let i="0x"+o.slice(-40);if(/^0x0+$/.test(i))return null;let s=await X(e,i,Y("addr(bytes32)")+n.slice(2));if(!s)return null;let l="0x"+s.slice(-40);return/^0x0+$/.test(l)?null:l}async function yt(e){let t=String(e||"").trim().toLowerCase();if(!t||!t.includes("."))return null;if(t.endsWith(".hl")){let r=await Cr(t);return r?{address:r,source:"hl",name:t}:null}if(t.endsWith(".eth")){let r=await Lr(je,t,ut);return r?{address:r,source:t.endsWith(".base.eth")?"basename":"ens",name:t}:null}return null}var yo=Pr.map(e=>e.source);var jr="protective-monitors",Hr="read-only",go=Object.freeze(["depeg","oracleDeviation","exploitFeed","goplus","liquidationLadder"]),vr="https://hermes.pyth.network",Fr="https://coins.llama.fi",Ur="https://api.llama.fi/hacks",Mr="https://api.gopluslabs.io/api/v1/token_security",Dr="https://api.v3.aave.com/user",Br=Object.freeze({USDT:"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",USDC:"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"}),zr=Object.freeze({USDT:"coingecko:tether",USDC:"coingecko:usd-coin",DAI:"coingecko:dai"}),Gr=Object.freeze(["is_honeypot","is_proxy","is_mintable","owner_change_balance","hidden_owner","selfdestruct","cannot_buy","cannot_sell_all","is_blacklisted"]),wt=Object.freeze({liquidatable:0,danger:1,critical:2,warning:3,healthy:4}),Wr=/^0x[0-9a-fA-F]{40}$/,qr=/^[0-9a-fA-F]{64}$/;function oe(e,t={}){return{ok:!0,provider:jr,op:e,alertOnly:!0,execution:Hr,exec:!1,...t}}function H(e,t){throw new Error(`protective-monitors: ${e}${t?` ${t}`:""}`)}async function se(e,t={}){return typeof t.http=="function"?t.http(e,t):typeof t.httpJson=="function"?t.httpJson(e,t):fe(e,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3,retries:t.retries??0})}function me(e){return String(e||"USDT").trim().toUpperCase().replace(/\/USD$/,"")}function Jr(e={}){if(e.feedId){let n=String(e.feedId).replace(/^0x/i,"");return qr.test(n)||H("feedId must be a 32-byte hex id"),n.toLowerCase()}let t=me(e.symbol),r=Br[t];return r||H("unknown symbol",t),r}function Vr(e={}){if(e.llamaCoin)return String(e.llamaCoin);let t=me(e.symbol);return zr[t]||`coingecko:${t.toLowerCase()}`}function bt(e,t){let r=Number(e.thresholdBps??t);return(!Number.isFinite(r)||r<0)&&H("thresholdBps must be a non-negative number"),r}function Kr(e){let t=Array.isArray(e?.parsed)?e.parsed[0]:e?.price?e:null,r=Number(t?.price?.price),n=Number(t?.price?.expo);return(!Number.isFinite(r)||!Number.isFinite(n))&&H("no pyth price returned"),n<0?r/10**-n:r*10**n}function Yr(e,t){let r=e?.coins?.[t]||e?.coins?.[String(t).toLowerCase()],n=Number(r?.price);return Number.isFinite(n)?n:null}function Xr(e,t={}){let r=String(t.pythBaseUrl||vr).replace(/\/$/,""),n=new URL(`${r}/v2/updates/price/latest`);return n.searchParams.append("ids[]",e),n.searchParams.set("parsed","true"),n.toString()}function Zr(e,t={}){return`${String(t.llamaCoinsBaseUrl||Fr).replace(/\/$/,"")}/prices/current/${encodeURIComponent(e)}`}async function gt(e,t){let r=Jr(e),n=await se(Xr(r,t),t),o=Kr(n);return o>0||H("pyth price must be positive"),{id:r,price:o}}async function xt(e,t){let r=Vr(e),n=await se(Zr(r,t),t);return{coin:r,price:Yr(n,r)}}async function Qr(e={},t={}){let r=Number(e.peg??1);(!Number.isFinite(r)||r<=0)&&H("peg must be a positive number");let n=bt(e,50),o=await gt(e,t),i=Math.round(Math.abs(o.price-r)*1e4),s={required:!1,llamaPrice:null};try{let l=await xt(e,t);s={required:!1,llamaPrice:l.price,llamaCoin:l.coin}}catch{s={required:!1,llamaPrice:null}}return oe("depeg",{symbol:me(e.symbol),feedId:o.id,price:o.price,peg:r,thresholdBps:n,deviationBps:i,alert:i>n,crossCheck:s})}async function en(e={},t={}){let r=bt(e,100),n=await gt(e,t),o=await xt(e,t);o.price>0||H("llama price required for oracleDeviation");let i=(n.price+o.price)/2,s=Math.round(Math.abs(n.price-o.price)/i*1e4);return oe("oracleDeviation",{symbol:me(e.symbol),pythPrice:n.price,llamaPrice:o.price,mid:i,thresholdBps:r,deviationBps:s,alert:s>r})}function tn(e,t){return String(e.id||e.defillamaId||e.slug||`hack-${t}`)}function rn(e,t){return{id:tn(e,t),name:String(e.name||e.protocol||"unknown"),classification:e.classification?String(e.classification):null,technique:e.technique?String(e.technique):null,amount:Number.isFinite(Number(e.amount))?Number(e.amount):null,chain:Array.isArray(e.chain)?e.chain.map(String):e.chain?[String(e.chain)]:[],source:e.source?String(e.source):null}}function nn(e){return(String(e).match(/<item\b[\s\S]*?<\/item>/gi)||[]).map((r,n)=>{let o=i=>{let s=r.match(new RegExp(`<${i}[^>]*>([\\s\\S]*?)</${i}>`,"i"));return s?s[1].replace(/<!\[CDATA\[|\]\]>/g,"").trim():""};return{id:o("guid")||o("link")||o("title")||`rss-${n}`,name:o("title")||"unknown",classification:"rss",technique:null,amount:null,chain:[],source:o("link")||null}})}function St(e){if(typeof e=="string"){let t=e.trim();if(t.startsWith("<"))return nn(t);try{return St(JSON.parse(t))}catch{H("exploitFeed payload is not JSON or RSS")}}return Array.isArray(e)?e:Array.isArray(e?.hacks)?e.hacks:Array.isArray(e?.items)?e.items:[]}function on(e){return e.map((t,r)=>({item:t,index:r})).sort((t,r)=>{let n=String(t.item.id).localeCompare(String(r.item.id));return n!==0?n:t.index-r.index}).map(t=>t.item)}async function sn(e={},t={}){let r=Ur,n=e.payload??await se(r,t),o=on(St(n).map(rn));return oe("exploitFeed",{count:o.length,fingerprint:o.map(i=>i.id).join("|"),items:o,alert:o.length>0})}function an(e){return e===!0||e===1||e==="1"}function cn(e,t){let r=e?.result&&typeof e.result=="object"?e.result:e,n=String(t).toLowerCase();if(r&&typeof r=="object"){for(let[o,i]of Object.entries(r))if(String(o).toLowerCase()===n&&i&&typeof i=="object")return{address:o,token:i}}return null}async function Fe(e={},t={}){e.asSoleGate===!0&&H("goplus is a second opinion and must never be a sole gate");let r=String(e.address||e.token||"").trim();Wr.test(r)||H("goplus requires an EVM token address");let n=Number(e.chainId??1);(!Number.isInteger(n)||n<=0)&&H("chainId must be a positive integer");let i=`${String(t.goplusBaseUrl||Mr).replace(/\/$/,"")}/${n}?contract_addresses=${r}`,s=e.payload??await se(i,t),l=cn(s,r);l||H("goplus returned no result for",r);let a=Gr.filter(u=>an(l.token[u]));return oe("goplus",{chainId:n,address:r.toLowerCase(),role:"second-opinion",secondOpinion:!0,soleGate:!1,neverSoleGate:!0,token:{address:l.address,name:l.token.token_name||null,symbol:l.token.token_symbol||null},findings:a,alert:a.length>0,note:"second opinion only \u2014 never the sole gate"})}function ln(e){let t=Number(e);return(!Number.isFinite(t)||t<0)&&H("healthFactor must be a non-negative number"),t<1?"liquidatable":t<1.05?"danger":t<1.2?"critical":t<1.5?"warning":"healthy"}function un(e,t){let r=Number(e.healthFactor??e.hf);Number.isFinite(r)||H("position healthFactor required");let n=ln(r);return{id:String(e.id||e.protocol||`pos-${t}`),protocol:String(e.protocol||"unknown"),healthFactor:r,collateralUsd:e.collateralUsd!=null?Number(e.collateralUsd):null,debtUsd:e.debtUsd!=null?Number(e.debtUsd):null,rung:n}}async function dn(e={},t={}){let r=null;if(Array.isArray(e.positions))r=e;else if(Array.isArray(e))r={positions:e};else{let s=String(e.user||"").trim();s||H("liquidationLadder requires user or positions");let l=String(t.aaveUrl||`${Dr}/${s}`);r=await se(l,t)}let o=(Array.isArray(r?.positions)?r.positions:[]).map(un),i=o.reduce((s,l)=>s?wt[l.rung]<wt[s]?l.rung:s:l.rung,null);return oe("liquidationLadder",{user:r?.user||e.user||null,chainId:r?.chainId??e.chainId??null,ladder:o,worstRung:i,alert:o.some(s=>s.rung!=="healthy")})}var xo=Object.freeze({depeg:Qr,oracleDeviation:en,exploitFeed:sn,goplus:Fe,liquidationLadder:dn});import ee from"node:fs";import kn from"node:os";import we from"node:path";import{randomUUID as $n}from"node:crypto";var Eo=Object.freeze(["wallet","pool","nft_floor","hl_flow","prediction_market"]),Ao=Object.freeze({wallets:"wallet",smart_wallet:"wallet",pools:"pool",new_pool:"pool",nft:"nft_floor",nft_floors:"nft_floor",hyperliquid:"hl_flow",prediction:"prediction_market",prediction_markets:"prediction_market"}),M=(e,t=0,r=1)=>Math.min(r,Math.max(t,e)),F=e=>Number.isFinite(Number(e))?Number(e):null,fn=e=>Math.round(e*1e4)/1e4;function U(e,t,r,n=!0){!n||r===null||!Number.isFinite(r)||e.push({feature:t,value:fn(r)})}function pn(e,t){let r=F(e.repeatBuys??e.repeat_buys??e.buyCount),n=F(e.walletWinRate??e.winRate);U(t,"repeat_buys",r===null?null:M((r-1)/4)*.38),U(t,"wallet_win_rate",n===null?null:(M(n)-.5)*.5)}function hn(e,t){let r=F(e.ageHours??e.poolAgeHours),n=F(e.liquidityUsd??e.liquidity),o=e.liquidityLocked??e.locked;U(t,"pool_age",r===null?null:r<24?-.42:M(r/720)*.12),U(t,"liquidity",n===null?null:(M(Math.log10(Math.max(1,n))/7)-.5)*.28),U(t,"liquidity_lock",o==null?null:o?.12:-.28)}function mn(e,t){let r=F(e.floorChange??e.floorChangePct),n=F(e.sales??e.saleCount);U(t,"floor_change",r===null?null:M(r,-1,1)*.35),U(t,"sales_depth",n===null?null:M(n/50)*.18)}function yn(e,t){let r=F(e.flowImbalance??e.imbalance),n=F(e.fundingRate??e.funding);U(t,"flow_imbalance",r===null?null:M(r,-1,1)*.42),U(t,"funding",n===null?null:-M(n*100,-1,1)*.12)}function wn(e,t){let r=F(e.marketProbability??e.marketPrice??e.probability),n=F(e.fairProbability??e.referenceProbability??e.fairValue);U(t,"probability_mispricing",r===null||n===null?null:M(n-r,-1,1)*.65);let o=F(e.liquidityUsd??e.liquidity);U(t,"market_liquidity",o===null?null:M(Math.log10(Math.max(1,o))/6)*.12)}var To=Object.freeze({wallet:pn,pool:hn,nft_floor:mn,hl_flow:yn,prediction_market:wn});import{createHash as En}from"node:crypto";var _o=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),ko=Object.freeze(["read","simulate"]);var $o=1440*60;var ie=class extends Error{constructor(t,r){super(`secret material must never appear in a public API object (at ${t}, rule: ${r})`),this.name="SecretLeakError",this.path=t,this.rule=r}},bn=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,gn=Object.freeze(["privkey","wif","xprv","seed"]);function Et(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return bn.test(t)||gn.includes(r)}var xn=Object.freeze([{rule:"raw-32-byte-hex-key",re:/^0x[0-9a-fA-F]{64}$/},{rule:"raw-32-byte-hex-bare",re:/^[0-9a-fA-F]{64}$/},{rule:"extended-private-key",re:/\b(?:xprv|tprv|yprv|zprv)[1-9A-HJ-NP-Za-km-z]{107}\b/},{rule:"bitcoin-wif",re:/\b[59KLc][1-9A-HJ-NP-Za-km-z]{50,51}\b/},{rule:"bip39-mnemonic",re:/\b(?:[a-z]{3,8}\s+){11,23}[a-z]{3,8}\b/},{rule:"bearer-token",re:/bearer\s+[A-Za-z0-9._~+/=-]+/i},{rule:"pem-private-key",re:/-----BEGIN[A-Z ]*PRIVATE KEY-----/},{rule:"keystore-path",re:/keystore/i},{rule:"signer-url",re:/https?:\/\/\S*sign/i},{rule:"authorization-header",re:/authorization\s*:/i}]),Sn=Object.freeze(["grantid","id","hash","sha256","sha256hex","checksum","txhash","transactionhash","blockhash","digest","userophash","commithash","prevhash","intenthash","canonicalhash","payloadhash","requestid"]);function Z(e,t="$",r=new Set,n=""){if(e==null)return e;if(typeof e=="string"){let o=Sn.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:i,re:s}of xn)if(!(o&&i.startsWith("raw-32-byte-hex"))&&s.test(e))throw new ie(t,i);return e}if(typeof e!="object"||r.has(e)||(r.add(e),ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e;if(e instanceof Map){for(let[o,i]of e.entries()){if(typeof o=="string"&&Et(o))throw new ie(`${t}[${JSON.stringify(o)}]`,"forbidden-key-name");Z(o,`${t}[key]`,r),Z(i,`${t}[${String(o)}]`,r)}return e}if(e instanceof Set){let o=0;for(let i of e.values())Z(i,`${t}[${o++}]`,r);return e}if(Array.isArray(e))return e.forEach((o,i)=>Z(o,`${t}[${i}]`,r)),e;for(let[o,i]of Object.entries(e)){if(Et(o))throw new ie(`${t}.${o}`,"forbidden-key-name");Z(i,`${t}.${o}`,r,o)}return e}var Ue=Object.freeze(["intent","quote_comparison","simulation","prepared","approval","signed","broadcast","settlement","balance_delta","position"]),Mo=Object.freeze(Object.fromEntries(Ue.map((e,t)=>[e,Object.freeze(t+1<Ue.length?[Ue[t+1]]:[])])));function Me(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(Me).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${Me(e[t])}`).join(",")}}`}function An(e){return e===void 0?null:JSON.parse(JSON.stringify(e))}function De(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))De(t)}return e}function Tn(e,t="fact"){try{Z(e,t)}catch{throw new Error(`${t} contains custody material and is forbidden`)}}function On(e){return En("sha256").update(Me(e)).digest("hex")}function _n({tradeId:e,state:t,fact:r,asOf:n,previousHash:o,external:i}){let s={tradeId:e,state:t,asOf:n,previousHash:o??null,external:i===!0,fact:An(r)};return De({...s,hash:On(s)})}function At({tradeId:e,intent:t,asOf:r=0}={}){if(!e||typeof e!="string")throw new Error("tradeId is required");if(!t||typeof t!="object"||Array.isArray(t))throw new Error("intent fact is required");Tn(t,"intent");let n=_n({tradeId:e,state:"intent",fact:t,asOf:r,previousHash:null,external:!1});return De({tradeId:e,state:"intent",events:[n],headHash:n.hash,custody:"none",execution:"prepare-only"})}function Tt(e,t={}){if(!e||typeof e!="object")throw new TypeError("signal required");if(e.noTrade===!0)throw new Error("NO_TRADE signal cannot open a trade lifecycle");if(e.executionAllowed===!0)throw new Error("executionAllowed must be false on public plane");let r=String(t.tradeId||`sig-${e.id||"unknown"}`).slice(0,128),n={source:"signal_score",signalId:e.id,signalType:e.type,score:e.score,confidence:e.confidence,flags:e.flags||[],promote:"research_only",execution:"prepare-only",custody:"none",note:"Cold signal \u2192 prepare intent only. Owner wallet must sign any later tx.",...t.intentExtra&&typeof t.intentExtra=="object"?t.intentExtra:{}},o=At({tradeId:r,intent:n,asOf:t.asOf??Date.now()});return{tradeId:r,intent:n,lifecycle:o,recommendation:"PREPARE_RESEARCH_ONLY"}}var kt=1,Be=5e3,Rn=Object.freeze({1:new Set(["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0xdac17f958d2ee523a2206206994597c13d831ec","0x6b175474e89094c44da98b954eedeac495271d0","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]),8453:new Set(["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","0x4200000000000000000000000000000000000006"]),42161:new Set(["0xaf88d065e77c8cc2239327c5edb3a432268e5831","0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9","0x82af49447d8a07e3bd95bd0d56f35241523fbab1"])}),Nn=/^0x[0-9a-fA-F]{40}$/,In=/^0x[0-9a-fA-F]{64}$/,Pn=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/;function D(e,t){let r=String(e||"").trim();if(!Nn.test(r))throw new TypeError(`${t} must be a 0x-prefixed EVM address`);return r.toLowerCase()}function $t(e,t){let r=Rn[Number(e)];if(!r)return!1;try{return r.has(D(t,"token"))}catch{return!1}}function ae(e,t="usd"){let r=typeof e=="number"?String(e):e;if(typeof r!="string"||!Pn.test(r))throw new TypeError(`${t} must be a non-negative decimal string with at most 2 decimal places`);let[n,o=""]=r.split("."),i=(o+"00").slice(0,2);return BigInt(n)*100n+BigInt(i)}function ce(e){let t=BigInt(e);if(t<0n)throw new RangeError("centsToUsd: cents must be non-negative");let r=t/100n,n=t%100n;return`${r.toString()}.${n.toString().padStart(2,"0")}`}function Cn({dailyCapUsd:e,spentTodayUsd:t,proportionalUsd:r=null}){let n=ae(e,"dailyCapUsd"),o=ae(t,"spentTodayUsd"),i=n-o;if(i<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"daily-cap-exhausted"};if(r==null)return{sizeCents:i,sizeUsd:ce(i),basis:"cap-only"};let s=ae(r,"proportionalUsd");if(s<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"sized-to-zero"};let l=s<i?s:i;return{sizeCents:l,sizeUsd:ce(l),basis:l===i?"cap-limited":"proportional"}}function Ln(e={}){let t=String(e.txHash||"").trim().toLowerCase();if(!In.test(t))throw new TypeError("event.txHash must be a 32-byte tx hash");let r=D(e.token,"event.token"),n=D(e.from,"event.from"),o=D(e.to,"event.to"),i=e.txFrom==null?null:D(e.txFrom,"event.txFrom");return{txHash:t,token:r,from:n,to:o,txFrom:i,chainId:Number(e.chainId),blockNumber:Number.isFinite(Number(e.blockNumber))?Number(e.blockNumber):null,logIndex:Number.isFinite(Number(e.logIndex))?Number(e.logIndex):null,valueUsd:e.valueUsd==null?null:String(e.valueUsd)}}function jn(e,{followedWallet:t}={}){let r=D(t,"followedWallet");return e.txFrom?e.txFrom!==r?{included:!1,reason:"not-initiated-by-followed-wallet"}:$t(e.chainId,e.token)?{included:!1,reason:"quote-asset-transfer"}:e.to===r?{included:!0,side:"buy"}:e.from===r?{included:!0,side:"sell"}:{included:!1,reason:"wallet-not-a-party"}:{included:!1,reason:"tx-from-unknown"}}function Hn({chainId:e,txHash:t,noTrade:r}){return{id:`follow-mirror:${e}:${t}`,type:"wallet_mirror",score:r?0:1,confidence:r?0:1,noTrade:r,executionAllowed:!1,flags:r?["FOLLOW_MIRROR","NO_TRADE"]:["FOLLOW_MIRROR"]}}function ye({chainId:e,txHash:t,token:r,side:n,sizeUsd:o,sizeBasis:i,followedWallet:s,refuseReason:l=null}={}){let a=Hn({chainId:e,txHash:t,noTrade:l!=null});try{let u=Tt(a,{tradeId:`follow-mirror-${e}-${t}`,intentExtra:{source:"follow_mirror",chain:e,followedWallet:s,token:r,side:n,sizeUsd:o,sizeBasis:i,txHash:t,executionAllowed:!1,backendSigner:!1,note:"Wallet-follow mirror. Cold, prepare-only. Owner wallet must sign any later tx."}});return{ok:!0,requiresWalletSignature:!0,backendSigner:!1,executionAllowed:!1,tradeId:u.tradeId,chain:e,token:r,side:n,sizeUsd:o,sizeBasis:i,txHash:t,followedWallet:s,recommendation:u.recommendation,lifecycle:u.lifecycle,intent:u.intent}}catch(u){return{ok:!1,reason:l||String(u?.message||u)}}}function vn(e=[],{followedWallet:t,dailyCapUsd:r,spentTodayUsd:n="0",seenTxHashes:o=new Set,honeypotResults:i={}}={}){if(!Array.isArray(e))throw new TypeError("rawEvents must be an array");let s=D(t,"followedWallet"),l=new Set(o),a=ae(n,"spentTodayUsd"),u=ae(r,"dailyCapUsd"),c=[],p=[],f=[];for(let h of e){let d;try{d=Ln(h)}catch(b){f.push({txHash:h?.txHash??null,reason:`malformed-event: ${b.message}`});continue}if(l.has(d.txHash)){f.push({txHash:d.txHash,reason:"duplicate-tx"});continue}let y=jn(d,{followedWallet:s});if(!y.included){f.push({txHash:d.txHash,reason:y.reason});continue}let E=i[d.token];if(E?.flagged){l.add(d.txHash);let b=ye({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:"0.00",sizeBasis:"refused",followedWallet:s,refuseReason:`token flagged: ${E.reason||"security check flagged this token"}`});p.push({txHash:d.txHash,token:d.token,side:y.side,reason:b.reason});continue}if(u-a<=0n){l.add(d.txHash);let b=ye({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:"0.00",sizeBasis:"refused",followedWallet:s,refuseReason:"daily-cap-exhausted"});p.push({txHash:d.txHash,token:d.token,side:y.side,reason:b.reason});continue}let N=Cn({dailyCapUsd:ce(u),spentTodayUsd:ce(a),proportionalUsd:d.valueUsd});if(N.sizeCents<=0n){l.add(d.txHash);let b=ye({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:"0.00",sizeBasis:N.basis,followedWallet:s,refuseReason:N.basis});p.push({txHash:d.txHash,token:d.token,side:y.side,reason:b.reason});continue}let x=ye({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:N.sizeUsd,sizeBasis:N.basis,followedWallet:s});l.add(d.txHash),x.ok?(c.push(x),a+=N.sizeCents):p.push({txHash:d.txHash,token:d.token,side:y.side,reason:x.reason})}return{intents:c,refusals:p,skipped:f,seenTxHashes:l,spentTodayUsd:ce(a)}}function ze(e=process.env){let t=e.ORACLE_CONFIG_DIR||we.join(kn.homedir(),".config","oracle");return we.join(t,"follow-mirror.json")}function Ot(){return{version:kt,targets:{}}}function _t(e,t){return`${String(e).toLowerCase()}:${D(t,"address")}`}function be(e){try{let t=ee.readFileSync(e,"utf8"),r=JSON.parse(t);return!r||typeof r!="object"||r.version!==kt||!r.targets||typeof r.targets!="object"?Ot():r}catch{return Ot()}}function Fn(e,t){let r=we.dirname(e);ee.mkdirSync(r,{recursive:!0,mode:448});let n=we.join(r,`.follow-mirror.${process.pid}.${Date.now()}.${$n()}.tmp`);try{ee.writeFileSync(n,`${JSON.stringify(t)}
|
|
5
|
-
`,{mode:384,flag:"wx"}),ee.renameSync(n,e);try{ee.chmodSync(e,384)}catch{}}catch(o){try{ee.unlinkSync(n)}catch{}throw o}}function
|
|
4
|
+
${JSON.stringify(r??[])}`}async function Or(e,t,r){return he(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function me(e,t,r=[],n={}){let o=String(t||""),i=Sr(o),s=gr(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 c=dt.get(s);if(c!=null)return c}let a=n.dedupe!==!1&&!n.signal?Tr(s,o,r):null;if(a&&se.has(a))return se.get(a);let u=(async()=>{let c=await Or(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),p=Ar(c);return i==="eth_chainid"&&typeof p=="string"&&dt.set(s,p),p})();return a&&(se.set(a,u),u.finally(()=>{se.get(a)===u&&se.delete(a)}).catch(()=>{})),u}var ve=999,He=1,_r=8453,ft="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",kr="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",pt="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",$r="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",Rr=".80002105.reverse",ht=/^0x[a-fA-F0-9]{40}$/,mt=new TextEncoder,yt=e=>"0x"+Buffer.from(e).toString("hex"),Y=e=>yt(je(mt.encode(e))).slice(0,10),wt=e=>e.toLowerCase().replace(/^0x/,"").padStart(64,"0");function ye(e){let t=new Uint8Array(32);if(e)for(let r of String(e).split(".").reverse()){let n=je(mt.encode(r)),o=new Uint8Array(64);o.set(t,0),o.set(n,32),t=je(o)}return yt(t)}function Fe(e){if(!e||e==="0x"||/^0x0*$/.test(e))return"";try{let t=e.slice(2),r=parseInt(t.slice(0,64),16)*2,n=parseInt(t.slice(r,r+64),16);if(!Number.isFinite(n)||n<=0)return"";let o=t.slice(r+64,r+64+n*2);return Buffer.from(o,"hex").toString("utf8")}catch{return""}}async function X(e,t,r){try{return await me(e,"eth_call",[{to:t,data:r},"latest"])}catch{return null}}async function Nr(e){let t=await X(ve,ft,Y("primaryName(address)")+wt(e)),r=Fe(t);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function Ir(e){let t=await X(ve,kr,Y("getName(address)")+wt(e)),r=Fe(t);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function bt(e,t,r){let n=await X(e,r,Y("name(bytes32)")+t.slice(2));return Fe(n)||null}async function Pr(e){let t=ye(`${e.slice(2).toLowerCase()}.addr.reverse`),r=await X(He,pt,Y("resolver(bytes32)")+t.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:bt(He,t,n)}async function Cr(e){let t=ye(e.slice(2).toLowerCase()+Rr);return bt(_r,t,$r)}var Lr=[{source:"hl",fn:Nr},{source:"hype",fn:Ir},{source:"ens",fn:Pr},{source:"basename",fn:Cr}];async function jr(e){let t=ye(e),r=await X(ve,ft,Y("ownerOf(uint256)")+t.slice(2));if(!r||r.length<66)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:n}async function Hr(e,t,r){let n=ye(t),o=await X(e,r,Y("resolver(bytes32)")+n.slice(2));if(!o)return null;let i="0x"+o.slice(-40);if(/^0x0+$/.test(i))return null;let s=await X(e,i,Y("addr(bytes32)")+n.slice(2));if(!s)return null;let l="0x"+s.slice(-40);return/^0x0+$/.test(l)?null:l}async function gt(e){let t=String(e||"").trim().toLowerCase();if(!t||!t.includes("."))return null;if(t.endsWith(".hl")){let r=await jr(t);return r?{address:r,source:"hl",name:t}:null}if(t.endsWith(".eth")){let r=await Hr(He,t,pt);return r?{address:r,source:t.endsWith(".base.eth")?"basename":"ens",name:t}:null}return null}var bo=Lr.map(e=>e.source);var vr="protective-monitors",Fr="read-only",So=Object.freeze(["depeg","oracleDeviation","exploitFeed","goplus","liquidationLadder"]),Ur="https://hermes.pyth.network",Mr="https://coins.llama.fi",Dr="https://api.llama.fi/hacks",Br="https://api.gopluslabs.io/api/v1/token_security",zr="https://api.v3.aave.com/user",Gr=Object.freeze({USDT:"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",USDC:"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"}),Wr=Object.freeze({USDT:"coingecko:tether",USDC:"coingecko:usd-coin",DAI:"coingecko:dai"}),qr=Object.freeze(["is_honeypot","is_proxy","is_mintable","owner_change_balance","hidden_owner","selfdestruct","cannot_buy","cannot_sell_all","is_blacklisted"]),xt=Object.freeze({liquidatable:0,danger:1,critical:2,warning:3,healthy:4}),Jr=/^0x[0-9a-fA-F]{40}$/,Vr=/^[0-9a-fA-F]{64}$/;function ie(e,t={}){return{ok:!0,provider:vr,op:e,alertOnly:!0,execution:Fr,exec:!1,...t}}function H(e,t){throw new Error(`protective-monitors: ${e}${t?` ${t}`:""}`)}async function ae(e,t={}){return typeof t.http=="function"?t.http(e,t):typeof t.httpJson=="function"?t.httpJson(e,t):he(e,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3,retries:t.retries??0})}function we(e){return String(e||"USDT").trim().toUpperCase().replace(/\/USD$/,"")}function Kr(e={}){if(e.feedId){let n=String(e.feedId).replace(/^0x/i,"");return Vr.test(n)||H("feedId must be a 32-byte hex id"),n.toLowerCase()}let t=we(e.symbol),r=Gr[t];return r||H("unknown symbol",t),r}function Yr(e={}){if(e.llamaCoin)return String(e.llamaCoin);let t=we(e.symbol);return Wr[t]||`coingecko:${t.toLowerCase()}`}function St(e,t){let r=Number(e.thresholdBps??t);return(!Number.isFinite(r)||r<0)&&H("thresholdBps must be a non-negative number"),r}function Xr(e){let t=Array.isArray(e?.parsed)?e.parsed[0]:e?.price?e:null,r=Number(t?.price?.price),n=Number(t?.price?.expo);return(!Number.isFinite(r)||!Number.isFinite(n))&&H("no pyth price returned"),n<0?r/10**-n:r*10**n}function Zr(e,t){let r=e?.coins?.[t]||e?.coins?.[String(t).toLowerCase()],n=Number(r?.price);return Number.isFinite(n)?n:null}function Qr(e,t={}){let r=String(t.pythBaseUrl||Ur).replace(/\/$/,""),n=new URL(`${r}/v2/updates/price/latest`);return n.searchParams.append("ids[]",e),n.searchParams.set("parsed","true"),n.toString()}function en(e,t={}){return`${String(t.llamaCoinsBaseUrl||Mr).replace(/\/$/,"")}/prices/current/${encodeURIComponent(e)}`}async function Et(e,t){let r=Kr(e),n=await ae(Qr(r,t),t),o=Xr(n);return o>0||H("pyth price must be positive"),{id:r,price:o}}async function At(e,t){let r=Yr(e),n=await ae(en(r,t),t);return{coin:r,price:Zr(n,r)}}async function tn(e={},t={}){let r=Number(e.peg??1);(!Number.isFinite(r)||r<=0)&&H("peg must be a positive number");let n=St(e,50),o=await Et(e,t),i=Math.round(Math.abs(o.price-r)*1e4),s={required:!1,llamaPrice:null};try{let l=await At(e,t);s={required:!1,llamaPrice:l.price,llamaCoin:l.coin}}catch{s={required:!1,llamaPrice:null}}return ie("depeg",{symbol:we(e.symbol),feedId:o.id,price:o.price,peg:r,thresholdBps:n,deviationBps:i,alert:i>n,crossCheck:s})}async function rn(e={},t={}){let r=St(e,100),n=await Et(e,t),o=await At(e,t);o.price>0||H("llama price required for oracleDeviation");let i=(n.price+o.price)/2,s=Math.round(Math.abs(n.price-o.price)/i*1e4);return ie("oracleDeviation",{symbol:we(e.symbol),pythPrice:n.price,llamaPrice:o.price,mid:i,thresholdBps:r,deviationBps:s,alert:s>r})}function nn(e,t){return String(e.id||e.defillamaId||e.slug||`hack-${t}`)}function on(e,t){return{id:nn(e,t),name:String(e.name||e.protocol||"unknown"),classification:e.classification?String(e.classification):null,technique:e.technique?String(e.technique):null,amount:Number.isFinite(Number(e.amount))?Number(e.amount):null,chain:Array.isArray(e.chain)?e.chain.map(String):e.chain?[String(e.chain)]:[],source:e.source?String(e.source):null}}function sn(e){return(String(e).match(/<item\b[\s\S]*?<\/item>/gi)||[]).map((r,n)=>{let o=i=>{let s=r.match(new RegExp(`<${i}[^>]*>([\\s\\S]*?)</${i}>`,"i"));return s?s[1].replace(/<!\[CDATA\[|\]\]>/g,"").trim():""};return{id:o("guid")||o("link")||o("title")||`rss-${n}`,name:o("title")||"unknown",classification:"rss",technique:null,amount:null,chain:[],source:o("link")||null}})}function Tt(e){if(typeof e=="string"){let t=e.trim();if(t.startsWith("<"))return sn(t);try{return Tt(JSON.parse(t))}catch{H("exploitFeed payload is not JSON or RSS")}}return Array.isArray(e)?e:Array.isArray(e?.hacks)?e.hacks:Array.isArray(e?.items)?e.items:[]}function an(e){return e.map((t,r)=>({item:t,index:r})).sort((t,r)=>{let n=String(t.item.id).localeCompare(String(r.item.id));return n!==0?n:t.index-r.index}).map(t=>t.item)}async function cn(e={},t={}){let r=Dr,n=e.payload??await ae(r,t),o=an(Tt(n).map(on));return ie("exploitFeed",{count:o.length,fingerprint:o.map(i=>i.id).join("|"),items:o,alert:o.length>0})}function ln(e){return e===!0||e===1||e==="1"}function un(e,t){let r=e?.result&&typeof e.result=="object"?e.result:e,n=String(t).toLowerCase();if(r&&typeof r=="object"){for(let[o,i]of Object.entries(r))if(String(o).toLowerCase()===n&&i&&typeof i=="object")return{address:o,token:i}}return null}async function Ue(e={},t={}){e.asSoleGate===!0&&H("goplus is a second opinion and must never be a sole gate");let r=String(e.address||e.token||"").trim();Jr.test(r)||H("goplus requires an EVM token address");let n=Number(e.chainId??1);(!Number.isInteger(n)||n<=0)&&H("chainId must be a positive integer");let i=`${String(t.goplusBaseUrl||Br).replace(/\/$/,"")}/${n}?contract_addresses=${r}`,s=e.payload??await ae(i,t),l=un(s,r);l||H("goplus returned no result for",r);let a=qr.filter(u=>ln(l.token[u]));return ie("goplus",{chainId:n,address:r.toLowerCase(),role:"second-opinion",secondOpinion:!0,soleGate:!1,neverSoleGate:!0,token:{address:l.address,name:l.token.token_name||null,symbol:l.token.token_symbol||null},findings:a,alert:a.length>0,note:"second opinion only \u2014 never the sole gate"})}function dn(e){let t=Number(e);return(!Number.isFinite(t)||t<0)&&H("healthFactor must be a non-negative number"),t<1?"liquidatable":t<1.05?"danger":t<1.2?"critical":t<1.5?"warning":"healthy"}function fn(e,t){let r=Number(e.healthFactor??e.hf);Number.isFinite(r)||H("position healthFactor required");let n=dn(r);return{id:String(e.id||e.protocol||`pos-${t}`),protocol:String(e.protocol||"unknown"),healthFactor:r,collateralUsd:e.collateralUsd!=null?Number(e.collateralUsd):null,debtUsd:e.debtUsd!=null?Number(e.debtUsd):null,rung:n}}async function pn(e={},t={}){let r=null;if(Array.isArray(e.positions))r=e;else if(Array.isArray(e))r={positions:e};else{let s=String(e.user||"").trim();s||H("liquidationLadder requires user or positions");let l=String(t.aaveUrl||`${zr}/${s}`);r=await ae(l,t)}let o=(Array.isArray(r?.positions)?r.positions:[]).map(fn),i=o.reduce((s,l)=>s?xt[l.rung]<xt[s]?l.rung:s:l.rung,null);return ie("liquidationLadder",{user:r?.user||e.user||null,chainId:r?.chainId??e.chainId??null,ladder:o,worstRung:i,alert:o.some(s=>s.rung!=="healthy")})}var Eo=Object.freeze({depeg:tn,oracleDeviation:rn,exploitFeed:cn,goplus:Ue,liquidationLadder:pn});import ee from"node:fs";import Rn from"node:os";import ge from"node:path";import{randomUUID as Nn}from"node:crypto";var To=Object.freeze(["wallet","pool","nft_floor","hl_flow","prediction_market"]),Oo=Object.freeze({wallets:"wallet",smart_wallet:"wallet",pools:"pool",new_pool:"pool",nft:"nft_floor",nft_floors:"nft_floor",hyperliquid:"hl_flow",prediction:"prediction_market",prediction_markets:"prediction_market"}),M=(e,t=0,r=1)=>Math.min(r,Math.max(t,e)),F=e=>Number.isFinite(Number(e))?Number(e):null,hn=e=>Math.round(e*1e4)/1e4;function U(e,t,r,n=!0){!n||r===null||!Number.isFinite(r)||e.push({feature:t,value:hn(r)})}function mn(e,t){let r=F(e.repeatBuys??e.repeat_buys??e.buyCount),n=F(e.walletWinRate??e.winRate);U(t,"repeat_buys",r===null?null:M((r-1)/4)*.38),U(t,"wallet_win_rate",n===null?null:(M(n)-.5)*.5)}function yn(e,t){let r=F(e.ageHours??e.poolAgeHours),n=F(e.liquidityUsd??e.liquidity),o=e.liquidityLocked??e.locked;U(t,"pool_age",r===null?null:r<24?-.42:M(r/720)*.12),U(t,"liquidity",n===null?null:(M(Math.log10(Math.max(1,n))/7)-.5)*.28),U(t,"liquidity_lock",o==null?null:o?.12:-.28)}function wn(e,t){let r=F(e.floorChange??e.floorChangePct),n=F(e.sales??e.saleCount);U(t,"floor_change",r===null?null:M(r,-1,1)*.35),U(t,"sales_depth",n===null?null:M(n/50)*.18)}function bn(e,t){let r=F(e.flowImbalance??e.imbalance),n=F(e.fundingRate??e.funding);U(t,"flow_imbalance",r===null?null:M(r,-1,1)*.42),U(t,"funding",n===null?null:-M(n*100,-1,1)*.12)}function gn(e,t){let r=F(e.marketProbability??e.marketPrice??e.probability),n=F(e.fairProbability??e.referenceProbability??e.fairValue);U(t,"probability_mispricing",r===null||n===null?null:M(n-r,-1,1)*.65);let o=F(e.liquidityUsd??e.liquidity);U(t,"market_liquidity",o===null?null:M(Math.log10(Math.max(1,o))/6)*.12)}var _o=Object.freeze({wallet:mn,pool:yn,nft_floor:wn,hl_flow:bn,prediction_market:gn});import{createHash as Tn}from"node:crypto";var $o=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),Ro=Object.freeze(["read","simulate"]);var No=1440*60;var ce=class extends Error{constructor(t,r){super(`secret material must never appear in a public API object (at ${t}, rule: ${r})`),this.name="SecretLeakError",this.path=t,this.rule=r}},xn=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,Sn=Object.freeze(["privkey","wif","xprv","seed"]);function Ot(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return xn.test(t)||Sn.includes(r)}var En=Object.freeze([{rule:"raw-32-byte-hex-key",re:/^0x[0-9a-fA-F]{64}$/},{rule:"raw-32-byte-hex-bare",re:/^[0-9a-fA-F]{64}$/},{rule:"extended-private-key",re:/\b(?:xprv|tprv|yprv|zprv)[1-9A-HJ-NP-Za-km-z]{107}\b/},{rule:"bitcoin-wif",re:/\b[59KLc][1-9A-HJ-NP-Za-km-z]{50,51}\b/},{rule:"bip39-mnemonic",re:/\b(?:[a-z]{3,8}\s+){11,23}[a-z]{3,8}\b/},{rule:"bearer-token",re:/bearer\s+[A-Za-z0-9._~+/=-]+/i},{rule:"pem-private-key",re:/-----BEGIN[A-Z ]*PRIVATE KEY-----/},{rule:"keystore-path",re:/keystore/i},{rule:"signer-url",re:/https?:\/\/\S*sign/i},{rule:"authorization-header",re:/authorization\s*:/i}]),An=Object.freeze(["grantid","id","hash","sha256","sha256hex","checksum","txhash","transactionhash","blockhash","digest","userophash","commithash","prevhash","intenthash","canonicalhash","payloadhash","requestid"]);function Z(e,t="$",r=new Set,n=""){if(e==null)return e;if(typeof e=="string"){let o=An.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:i,re:s}of En)if(!(o&&i.startsWith("raw-32-byte-hex"))&&s.test(e))throw new ce(t,i);return e}if(typeof e!="object"||r.has(e)||(r.add(e),ArrayBuffer.isView(e)||e instanceof ArrayBuffer))return e;if(e instanceof Map){for(let[o,i]of e.entries()){if(typeof o=="string"&&Ot(o))throw new ce(`${t}[${JSON.stringify(o)}]`,"forbidden-key-name");Z(o,`${t}[key]`,r),Z(i,`${t}[${String(o)}]`,r)}return e}if(e instanceof Set){let o=0;for(let i of e.values())Z(i,`${t}[${o++}]`,r);return e}if(Array.isArray(e))return e.forEach((o,i)=>Z(o,`${t}[${i}]`,r)),e;for(let[o,i]of Object.entries(e)){if(Ot(o))throw new ce(`${t}.${o}`,"forbidden-key-name");Z(i,`${t}.${o}`,r,o)}return e}var Me=Object.freeze(["intent","quote_comparison","simulation","prepared","approval","signed","broadcast","settlement","balance_delta","position"]),Bo=Object.freeze(Object.fromEntries(Me.map((e,t)=>[e,Object.freeze(t+1<Me.length?[Me[t+1]]:[])])));function De(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(De).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${De(e[t])}`).join(",")}}`}function On(e){return e===void 0?null:JSON.parse(JSON.stringify(e))}function Be(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))Be(t)}return e}function _n(e,t="fact"){try{Z(e,t)}catch{throw new Error(`${t} contains custody material and is forbidden`)}}function kn(e){return Tn("sha256").update(De(e)).digest("hex")}function $n({tradeId:e,state:t,fact:r,asOf:n,previousHash:o,external:i}){let s={tradeId:e,state:t,asOf:n,previousHash:o??null,external:i===!0,fact:On(r)};return Be({...s,hash:kn(s)})}function _t({tradeId:e,intent:t,asOf:r=0}={}){if(!e||typeof e!="string")throw new Error("tradeId is required");if(!t||typeof t!="object"||Array.isArray(t))throw new Error("intent fact is required");_n(t,"intent");let n=$n({tradeId:e,state:"intent",fact:t,asOf:r,previousHash:null,external:!1});return Be({tradeId:e,state:"intent",events:[n],headHash:n.hash,custody:"none",execution:"prepare-only"})}function kt(e,t={}){if(!e||typeof e!="object")throw new TypeError("signal required");if(e.noTrade===!0)throw new Error("NO_TRADE signal cannot open a trade lifecycle");if(e.executionAllowed===!0)throw new Error("executionAllowed must be false on public plane");let r=String(t.tradeId||`sig-${e.id||"unknown"}`).slice(0,128),n={source:"signal_score",signalId:e.id,signalType:e.type,score:e.score,confidence:e.confidence,flags:e.flags||[],promote:"research_only",execution:"prepare-only",custody:"none",note:"Cold signal \u2192 prepare intent only. Owner wallet must sign any later tx.",...t.intentExtra&&typeof t.intentExtra=="object"?t.intentExtra:{}},o=_t({tradeId:r,intent:n,asOf:t.asOf??Date.now()});return{tradeId:r,intent:n,lifecycle:o,recommendation:"PREPARE_RESEARCH_ONLY"}}var Nt=1,ze=5e3,In=Object.freeze({1:new Set(["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0xdac17f958d2ee523a2206206994597c13d831ec","0x6b175474e89094c44da98b954eedeac495271d0","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]),8453:new Set(["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","0x4200000000000000000000000000000000000006"]),42161:new Set(["0xaf88d065e77c8cc2239327c5edb3a432268e5831","0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9","0x82af49447d8a07e3bd95bd0d56f35241523fbab1"])}),Pn=/^0x[0-9a-fA-F]{40}$/,Cn=/^0x[0-9a-fA-F]{64}$/,Ln=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/;function D(e,t){let r=String(e||"").trim();if(!Pn.test(r))throw new TypeError(`${t} must be a 0x-prefixed EVM address`);return r.toLowerCase()}function It(e,t){let r=In[Number(e)];if(!r)return!1;try{return r.has(D(t,"token"))}catch{return!1}}function le(e,t="usd"){let r=typeof e=="number"?String(e):e;if(typeof r!="string"||!Ln.test(r))throw new TypeError(`${t} must be a non-negative decimal string with at most 2 decimal places`);let[n,o=""]=r.split("."),i=(o+"00").slice(0,2);return BigInt(n)*100n+BigInt(i)}function ue(e){let t=BigInt(e);if(t<0n)throw new RangeError("centsToUsd: cents must be non-negative");let r=t/100n,n=t%100n;return`${r.toString()}.${n.toString().padStart(2,"0")}`}function jn({dailyCapUsd:e,spentTodayUsd:t,proportionalUsd:r=null}){let n=le(e,"dailyCapUsd"),o=le(t,"spentTodayUsd"),i=n-o;if(i<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"daily-cap-exhausted"};if(r==null)return{sizeCents:i,sizeUsd:ue(i),basis:"cap-only"};let s=le(r,"proportionalUsd");if(s<=0n)return{sizeCents:0n,sizeUsd:"0.00",basis:"sized-to-zero"};let l=s<i?s:i;return{sizeCents:l,sizeUsd:ue(l),basis:l===i?"cap-limited":"proportional"}}function Hn(e={}){let t=String(e.txHash||"").trim().toLowerCase();if(!Cn.test(t))throw new TypeError("event.txHash must be a 32-byte tx hash");let r=D(e.token,"event.token"),n=D(e.from,"event.from"),o=D(e.to,"event.to"),i=e.txFrom==null?null:D(e.txFrom,"event.txFrom");return{txHash:t,token:r,from:n,to:o,txFrom:i,chainId:Number(e.chainId),blockNumber:Number.isFinite(Number(e.blockNumber))?Number(e.blockNumber):null,logIndex:Number.isFinite(Number(e.logIndex))?Number(e.logIndex):null,valueUsd:e.valueUsd==null?null:String(e.valueUsd)}}function vn(e,{followedWallet:t}={}){let r=D(t,"followedWallet");return e.txFrom?e.txFrom!==r?{included:!1,reason:"not-initiated-by-followed-wallet"}:It(e.chainId,e.token)?{included:!1,reason:"quote-asset-transfer"}:e.to===r?{included:!0,side:"buy"}:e.from===r?{included:!0,side:"sell"}:{included:!1,reason:"wallet-not-a-party"}:{included:!1,reason:"tx-from-unknown"}}function Fn({chainId:e,txHash:t,noTrade:r}){return{id:`follow-mirror:${e}:${t}`,type:"wallet_mirror",score:r?0:1,confidence:r?0:1,noTrade:r,executionAllowed:!1,flags:r?["FOLLOW_MIRROR","NO_TRADE"]:["FOLLOW_MIRROR"]}}function be({chainId:e,txHash:t,token:r,side:n,sizeUsd:o,sizeBasis:i,followedWallet:s,refuseReason:l=null}={}){let a=Fn({chainId:e,txHash:t,noTrade:l!=null});try{let u=kt(a,{tradeId:`follow-mirror-${e}-${t}`,intentExtra:{source:"follow_mirror",chain:e,followedWallet:s,token:r,side:n,sizeUsd:o,sizeBasis:i,txHash:t,executionAllowed:!1,backendSigner:!1,note:"Wallet-follow mirror. Cold, prepare-only. Owner wallet must sign any later tx."}});return{ok:!0,requiresWalletSignature:!0,backendSigner:!1,executionAllowed:!1,tradeId:u.tradeId,chain:e,token:r,side:n,sizeUsd:o,sizeBasis:i,txHash:t,followedWallet:s,recommendation:u.recommendation,lifecycle:u.lifecycle,intent:u.intent}}catch(u){return{ok:!1,reason:l||String(u?.message||u)}}}function Un(e=[],{followedWallet:t,dailyCapUsd:r,spentTodayUsd:n="0",seenTxHashes:o=new Set,honeypotResults:i={}}={}){if(!Array.isArray(e))throw new TypeError("rawEvents must be an array");let s=D(t,"followedWallet"),l=new Set(o),a=le(n,"spentTodayUsd"),u=le(r,"dailyCapUsd"),c=[],p=[],f=[];for(let h of e){let d;try{d=Hn(h)}catch(x){f.push({txHash:h?.txHash??null,reason:`malformed-event: ${x.message}`});continue}if(l.has(d.txHash)){f.push({txHash:d.txHash,reason:"duplicate-tx"});continue}let y=vn(d,{followedWallet:s});if(!y.included){f.push({txHash:d.txHash,reason:y.reason});continue}let b=i[d.token];if(b?.flagged){l.add(d.txHash);let x=be({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:"0.00",sizeBasis:"refused",followedWallet:s,refuseReason:`token flagged: ${b.reason||"security check flagged this token"}`});p.push({txHash:d.txHash,token:d.token,side:y.side,reason:x.reason});continue}if(u-a<=0n){l.add(d.txHash);let x=be({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:"0.00",sizeBasis:"refused",followedWallet:s,refuseReason:"daily-cap-exhausted"});p.push({txHash:d.txHash,token:d.token,side:y.side,reason:x.reason});continue}let R=jn({dailyCapUsd:ue(u),spentTodayUsd:ue(a),proportionalUsd:d.valueUsd});if(R.sizeCents<=0n){l.add(d.txHash);let x=be({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:"0.00",sizeBasis:R.basis,followedWallet:s,refuseReason:R.basis});p.push({txHash:d.txHash,token:d.token,side:y.side,reason:x.reason});continue}let N=be({chainId:d.chainId,txHash:d.txHash,token:d.token,side:y.side,sizeUsd:R.sizeUsd,sizeBasis:R.basis,followedWallet:s});l.add(d.txHash),N.ok?(c.push(N),a+=R.sizeCents):p.push({txHash:d.txHash,token:d.token,side:y.side,reason:N.reason})}return{intents:c,refusals:p,skipped:f,seenTxHashes:l,spentTodayUsd:ue(a)}}function Ge(e=process.env){let t=e.ORACLE_CONFIG_DIR||ge.join(Rn.homedir(),".config","oracle");return ge.join(t,"follow-mirror.json")}function $t(){return{version:Nt,targets:{}}}function Rt(e,t){return`${String(e).toLowerCase()}:${D(t,"address")}`}function xe(e){try{let t=ee.readFileSync(e,"utf8"),r=JSON.parse(t);return!r||typeof r!="object"||r.version!==Nt||!r.targets||typeof r.targets!="object"?$t():r}catch{return $t()}}function Mn(e,t){let r=ge.dirname(e);ee.mkdirSync(r,{recursive:!0,mode:448});let n=ge.join(r,`.follow-mirror.${process.pid}.${Date.now()}.${Nn()}.tmp`);try{ee.writeFileSync(n,`${JSON.stringify(t)}
|
|
5
|
+
`,{mode:384,flag:"wx"}),ee.renameSync(n,e);try{ee.chmodSync(e,384)}catch{}}catch(o){try{ee.unlinkSync(n)}catch{}throw o}}function Dn(e){return new Date(e).toISOString().slice(0,10)}function Bn(e,t,r){let n=e.targets[t],o=new Set(Array.isArray(n?.seenTxHashes)?n.seenTxHashes:[]),i=typeof n?.days?.[r]=="string"?n.days[r]:"0";return{seenTxHashes:o,spentTodayUsd:i}}function zn(e,t,{seenTxHashes:r,spentTodayUsd:n,day:o,newIntents:i,newRefusals:s}){let l=e.targets[t]||{seenTxHashes:[],days:{},intents:[],refusals:[]},a=[...r].slice(-ze),u=[...l.intents||[],...i].slice(-ze),c=[...l.refusals||[],...s].slice(-ze);e.targets[t]={seenTxHashes:a,days:{...l.days||{},[o]:n},intents:u,refusals:c}}function We({now:e=()=>Date.now(),fetchWallet:t,fetchTxFrom:r,checkHoneypot:n,estimateUsdValue:o=async()=>null,storePath:i=Ge()}={}){if(typeof t!="function")throw new TypeError("createFollowMirror requires fetchWallet");if(typeof r!="function")throw new TypeError("createFollowMirror requires fetchTxFrom");if(typeof n!="function")throw new TypeError("createFollowMirror requires checkHoneypot");async function s({address:a,chain:u,chainId:c,dailyCapUsd:p,lookback:f}={}){let h=D(a,"address"),d=Number(c);if(!Number.isInteger(d)||d<=0)throw new TypeError("observe requires a numeric chainId");let y=e(),b=Dn(y),S=Rt(u||d,h),R=xe(i),{seenTxHashes:N,spentTodayUsd:x}=Bn(R,S,b),C=await t(h,{chains:[d],lookback:f}),L=Array.isArray(C?.events)?C.events:[],w=[],E={},_=new Set;for(let m of L){let A=null;try{A=await r(d,m.txHash)}catch{A=null}let v=null;try{v=await o({...m,chainId:d,txFrom:A})}catch{v=null}let k=String(m.token||"").toLowerCase();if(A===h&&!It(d,k)&&!_.has(k)&&k){_.add(k);try{E[k]=await n(d,k)}catch(W){E[k]={flagged:!0,reason:`security check unavailable: ${String(W?.message||W).slice(0,160)}`}}}w.push({...m,chainId:d,txFrom:A,valueUsd:v})}let I=Un(w,{followedWallet:h,dailyCapUsd:String(p),spentTodayUsd:x,seenTxHashes:N,honeypotResults:E});return zn(R,S,{seenTxHashes:I.seenTxHashes,spentTodayUsd:I.spentTodayUsd,day:b,newIntents:I.intents.map(m=>({tradeId:m.tradeId,txHash:m.txHash,token:m.token,side:m.side,sizeUsd:m.sizeUsd,createdAt:y})),newRefusals:I.refusals.map(m=>({...m,createdAt:y}))}),Mn(i,R),{ok:!0,cold:!0,executionAllowed:!1,chain:u||d,chainId:d,address:h,observed:L.length,intents:I.intents,refusals:I.refusals,skipped:I.skipped,spentTodayUsd:I.spentTodayUsd,dailyCapUsd:String(p),errors:C?.errors||[]}}function l({address:a,chain:u}={}){let c=D(a,"address"),p=xe(i),f=Rt(u,c),h=p.targets[f]||{intents:[],refusals:[],days:{}};return{ok:!0,address:c,chain:u,intents:h.intents||[],refusals:h.refusals||[],days:h.days||{}}}return Object.freeze({observe:s,status:l,storePath:i})}var te={1:"ethereum",8453:"base",42161:"arbitrum"},Gn=Object.fromEntries(Object.entries(te).map(([e,t])=>[t,Number(e)])),Wn=new Set(["is_honeypot","cannot_sell_all","cannot_buy","is_blacklisted","selfdestruct","owner_change_balance"]),Pt=`oracle follow <name-or-address> [--chain <name>] [--blocks <n>] [--json]
|
|
6
6
|
oracle follow <name-or-address> --chain <name> --mirror --max-usd <n> [--json]
|
|
7
7
|
oracle follow status [<name-or-address>] [--chain <name>] [--json]
|
|
8
8
|
|
|
@@ -34,35 +34,35 @@ Chains: ${Object.values(te).join(", ")}. Default: ethereum.
|
|
|
34
34
|
Lookback defaults to 40000 blocks. Endpoints are keyless.
|
|
35
35
|
|
|
36
36
|
Note publicnode-class RPCs are deliberately excluded: they retain only ~128
|
|
37
|
-
blocks, so they return an empty result instead of an error.`;function
|
|
38
|
-
`),1;let{address:l,resolvedFrom:a}=await
|
|
39
|
-
`),1;let c=await
|
|
37
|
+
blocks, so they return an empty result instead of an error.`;function Se(e,t){let r=e.indexOf(t);return r>=0?e[r+1]:void 0}function qn(e){let t=String(e??"");return t.length>22?`${t.slice(0,19)}...`:t}async function Jn(e,t){let n=(await me(e,"eth_getTransactionByHash",[t]))?.from;return typeof n!="string"||!/^0x[0-9a-fA-F]{40}$/.test(n)?null:n.toLowerCase()}async function Vn(e,t){try{let n=((await Ue({address:t,chainId:e},{})).findings||[]).filter(o=>Wn.has(o));return n.length>0?{flagged:!0,reason:`goplus: ${n.join(", ")}`}:{flagged:!1,reason:null}}catch(r){return{flagged:!0,reason:`goplus check unavailable: ${String(r?.message||r).slice(0,160)}`}}}async function qe(e){if(ht.test(e))return{address:e,resolvedFrom:null};let t=await gt(e);return t?.address?{address:t.address,resolvedFrom:e}:{address:null,resolvedFrom:null}}async function Kn(e,{query:t,chainArg:r,chainId:n,lookbackBlocks:o,asJson:i}){let s=Se(e,"--max-usd");if(!s||!/^\d+(?:\.\d{1,2})?$/.test(s))return process.stderr.write(`follow --mirror: --max-usd must be a positive decimal (at most 2 decimal places), got "${s??""}"
|
|
38
|
+
`),1;let{address:l,resolvedFrom:a}=await qe(t);if(!l)return process.stderr.write(`follow: could not resolve "${t}" to an address
|
|
39
|
+
`),1;let c=await We({fetchWallet:_e,fetchTxFrom:Jn,checkHoneypot:Vn}).observe({address:l,chain:te[n]||String(n),chainId:n,dailyCapUsd:s,lookback:o});if(i)return process.stdout.write(`${JSON.stringify({resolvedFrom:a,...c})}
|
|
40
40
|
`),0;let p=a?`${a} ${l}`:l;process.stdout.write(`${p}
|
|
41
41
|
`),process.stdout.write(` ${c.chain} \xB7 observed ${c.observed} transfer${c.observed===1?"":"s"} \xB7 spent ${c.spentTodayUsd}/${c.dailyCapUsd} today
|
|
42
42
|
`),c.intents.length||process.stdout.write(` no new prepared mirror intents this run
|
|
43
43
|
`);for(let f of c.intents)process.stdout.write(` PREPARED ${f.side} ${f.token} $${f.sizeUsd} tx ${f.txHash}
|
|
44
44
|
`);for(let f of c.refusals)process.stdout.write(` REFUSED ${f.side} ${f.token} ${f.reason} tx ${f.txHash}
|
|
45
45
|
`);for(let f of c.errors||[])process.stderr.write(` error: ${f.stage||"rpc"}: ${f.error}
|
|
46
|
-
`);return 0}async function
|
|
47
|
-
`),1;let c=
|
|
46
|
+
`);return 0}async function Yn(e,t){let r=(Se(e,"--chain")||"").toLowerCase(),o=(e.filter((a,u)=>a==="--json"||a==="status"||a==="--chain"&&e[u+1]!=null||e[u-1]==="--chain"?!1:!a.startsWith("--"))[0]||"").trim();if(o){let{address:a,resolvedFrom:u}=await qe(o);if(!a)return process.stderr.write(`follow status: could not resolve "${o}" to an address
|
|
47
|
+
`),1;let c=We({fetchWallet:async()=>({events:[],errors:[]}),fetchTxFrom:async()=>null,checkHoneypot:async()=>({flagged:!1})}),p=r||"ethereum",f=c.status({address:a,chain:p});if(t)return process.stdout.write(`${JSON.stringify({resolvedFrom:u,...f})}
|
|
48
48
|
`),0;process.stdout.write(`${u?`${u} ${a}`:a} (${p})
|
|
49
49
|
`),!f.intents.length&&!f.refusals.length&&process.stdout.write(` no prepared mirror intents on disk for this target
|
|
50
50
|
`);for(let h of f.intents)process.stdout.write(` PREPARED ${h.side} ${h.token} $${h.sizeUsd} tx ${h.txHash}
|
|
51
51
|
`);for(let h of f.refusals)process.stdout.write(` REFUSED ${h.side} ${h.token} ${h.reason} tx ${h.txHash}
|
|
52
|
-
`);return 0}let i=
|
|
52
|
+
`);return 0}let i=Ge(),s=xe(i),l=Object.entries(s.targets||{});if(t)return process.stdout.write(`${JSON.stringify({storePath:i,targets:Object.fromEntries(l)})}
|
|
53
53
|
`),0;if(!l.length)return process.stdout.write(`no follow --mirror targets on disk yet
|
|
54
54
|
`),0;for(let[a,u]of l)process.stdout.write(`${a} ${(u.intents||[]).length} prepared, ${(u.refusals||[]).length} refused
|
|
55
|
-
`);return 0}async function
|
|
56
|
-
`),o?0:1;let i=(
|
|
57
|
-
`),1;let l=
|
|
58
|
-
`),1;try{if(r)return await
|
|
59
|
-
`),1;let p=await
|
|
55
|
+
`);return 0}async function Xn(e=[]){let t=e.includes("--json"),r=e.includes("--mirror"),n=[];for(let u=0;u<e.length;u+=1){let c=e[u];if(!(c==="--json"||c==="--mirror")){if(c==="--chain"||c==="--blocks"||c==="--max-usd"){u+=1;continue}n.push(c)}}if(n[0]==="status")return Yn(e,t);let o=(n[0]||"").trim();if(!o||o==="--help"||o==="-h")return process.stdout.write(`${Pt}
|
|
56
|
+
`),o?0:1;let i=(Se(e,"--chain")||"ethereum").toLowerCase(),s=Gn[i]??Number(i);if(!Oe[s])return process.stderr.write(`follow: unsupported chain "${i}". Supported: ${Object.values(te).join(", ")}
|
|
57
|
+
`),1;let l=Se(e,"--blocks"),a=l?Number(l):4e4;if(!Number.isFinite(a)||a<=0)return process.stderr.write(`follow: --blocks must be a positive number, got "${l}"
|
|
58
|
+
`),1;try{if(r)return await Kn(e,{query:o,chainArg:i,chainId:s,lookbackBlocks:a,asJson:t});let{address:u,resolvedFrom:c}=await qe(o);if(!u)return process.stderr.write(`follow: could not resolve "${o}" to an address
|
|
59
|
+
`),1;let p=await _e(u,{chains:[s],lookback:a,onWarn:t?void 0:d=>process.stderr.write(` warn: ${d}
|
|
60
60
|
`)}),f=p.events||[];if(t)return process.stdout.write(`${JSON.stringify({address:u,resolvedFrom:c,chain:te[s]||String(s),lookbackBlocks:a,count:f.length,errors:p.errors||[],events:f})}
|
|
61
61
|
`),0;let h=c?`${c} ${u}`:u;process.stdout.write(`${h}
|
|
62
62
|
`),process.stdout.write(` ${te[s]||s} \xB7 last ${a} blocks \xB7 ${f.length} transfer${f.length===1?"":"s"}
|
|
63
63
|
`),f.length||process.stdout.write(` no ERC20 transfers in this window
|
|
64
|
-
`);for(let d of f.slice(0,25)){let y=d.to?.toLowerCase()===u.toLowerCase()?"in ":"out";process.stdout.write(` ${y} blk ${d.blockNumber} token ${d.token} ${
|
|
64
|
+
`);for(let d of f.slice(0,25)){let y=d.to?.toLowerCase()===u.toLowerCase()?"in ":"out";process.stdout.write(` ${y} blk ${d.blockNumber} token ${d.token} ${qn(d.value)}
|
|
65
65
|
`)}f.length>25&&process.stdout.write(` ... ${f.length-25} more (use --json for all)
|
|
66
66
|
`);for(let d of p.errors||[])process.stderr.write(` error: ${d.stage||"rpc"}: ${d.error}
|
|
67
67
|
`);return 0}catch(u){return process.stderr.write(`follow failed: ${u?.message||u}
|
|
68
|
-
`),1}}var
|
|
68
|
+
`),1}}var ss={name:"follow",summary:"read a wallet's recent ERC20 transfer activity, or --mirror it to prepared intents",group:"read",usage:Pt,async run(e){return Xn(e.argv||[])}};export{ss as default};
|