@oracle-agent/oracle 0.35.44 → 0.35.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/dist/agent-sessions.mjs +24 -24
  2. package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
  3. package/dist/bin/desk-server.mjs +26 -26
  4. package/dist/bin/oracle-data-mcp.mjs +14 -14
  5. package/dist/bin/oracle-gateway.mjs +47 -47
  6. package/dist/bin/oracle-investigate.mjs +4 -4
  7. package/dist/bin/oracle-launch-radar-shadow.mjs +5 -5
  8. package/dist/bin/oracle-mev-arb-shadow.mjs +5 -5
  9. package/dist/bin/oracle-mev-shadow.mjs +5 -5
  10. package/dist/bin/oracle-public-server.mjs +5 -5
  11. package/dist/bin/oracle-route.mjs +23 -23
  12. package/dist/bin/oracle-scan.mjs +6 -6
  13. package/dist/bin/oracle.mjs +1 -0
  14. package/dist/cli/commands/account.mjs +39 -0
  15. package/dist/cli/commands/agent-session.mjs +23 -23
  16. package/dist/cli/commands/airdrop.mjs +7 -7
  17. package/dist/cli/commands/chat.mjs +198 -198
  18. package/dist/cli/commands/data.mjs +29 -29
  19. package/dist/cli/commands/doctor.mjs +7 -7
  20. package/dist/cli/commands/eval.mjs +123 -123
  21. package/dist/cli/commands/farm.mjs +16 -16
  22. package/dist/cli/commands/follow.mjs +36 -36
  23. package/dist/cli/commands/mint.mjs +10 -10
  24. package/dist/cli/commands/model.mjs +205 -205
  25. package/dist/cli/commands/quickstart.mjs +6 -6
  26. package/dist/cli/commands/receipt.mjs +11 -11
  27. package/dist/cli/commands/resolve.mjs +9 -9
  28. package/dist/cli/commands/session-vault.mjs +5 -5
  29. package/dist/cli/commands/sign.mjs +12 -12
  30. package/dist/cli/commands/signer.mjs +25 -25
  31. package/dist/cli/commands/snipe.mjs +7 -7
  32. package/dist/cli/commands/strategy.mjs +5 -5
  33. package/dist/cli/commands/swap.mjs +14 -14
  34. package/dist/cli/commands/venues.mjs +2 -2
  35. package/dist/data/desk-data.mjs +24 -24
  36. package/dist/data/names.mjs +3 -3
  37. package/dist/data/providers/farming.mjs +2 -2
  38. package/dist/data/providers/lp-destination-discovery.mjs +4 -4
  39. package/dist/index.mjs +44 -44
  40. package/dist/investigator/index.mjs +2 -2
  41. package/dist/launch-radar/index.mjs +5 -5
  42. package/dist/local-signer/anvil-attestation-worker.mjs +1 -1
  43. package/dist/local-signer/index.mjs +7 -3
  44. package/dist/local-signer/runtime.mjs +22 -22
  45. package/dist/nft/universal-mint-router.mjs +4 -4
  46. package/dist/notifications/index.mjs +7 -7
  47. package/dist/router/index.mjs +3 -3
  48. package/dist/router/prepare-bridge.mjs +2 -2
  49. package/dist/router/prepare-route.mjs +3 -3
  50. package/dist/scanner/index.mjs +4 -4
  51. package/dist/strategy/index.mjs +3 -3
  52. package/dist/tui/standalone-client.mjs +85 -85
  53. package/package.json +1 -1
  54. package/public/oracle-splash/docs/browser-and-web/index.html +2 -2
  55. package/public/oracle-splash/docs/connectors/index.html +2 -2
  56. package/public/oracle-splash/docs/getting-started/index.html +2 -2
  57. package/public/oracle-splash/docs/index.html +3 -3
  58. package/public/oracle-splash/docs/reference/index.html +2 -2
  59. package/public/oracle-splash/docs/security/index.html +2 -2
  60. package/public/oracle-splash/docs/using-oracle/index.html +2 -2
  61. package/public/oracle-splash/download/index.html +3 -3
  62. package/public/oracle-splash/downloads/index.html +1 -1
  63. package/public/oracle-splash/index.html +6 -6
  64. package/server.json +2 -2
@@ -1,8 +1,8 @@
1
- var Ze="0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",_e={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"]},Ut=1e4,Dt=e=>new Promise(t=>setTimeout(t,e)),Qe=e=>"0x"+BigInt(e).toString(16),Bt=e=>"0x"+"0".repeat(24)+e.slice(2).toLowerCase(),et=e=>"0x"+e.slice(26).toLowerCase(),zt=/timeout|timed out|too many requests|rate.?limit|429|502|503|504|internal error|temporarily|aborted|fetch failed|ECONNRESET|socket hang up/i,Gt=/too many|exceeds|limited to|not supported on free plan|response too large|range must not exceed|narrow your filter/i,V=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 Wt(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 V(`${t} network: ${u.message}`,{transient:!0})}finally{clearTimeout(i)}let a;try{a=JSON.parse(l)}catch{throw new V(`${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 V(`${t} rpc: ${u}`,{transient:zt.test(u),tooBig:Gt.test(u),http:s.status})}if(s.status!==200)throw new V(`${t} http=${s.status}: ${l.slice(0,80)}`,{transient:s.status>=500||s.status===429,http:s.status});return a.result}async function tt(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 Wt(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 Dt(c)}i?.(`endpoint exhausted: ${l} -> ${s?.message.slice(0,70)}`)}throw s??new V("no endpoints available")}async function Oe(e,t,r,n,o,i){let s=[{...t,fromBlock:Qe(r),toBlock:Qe(n)}];try{let{result:a}=await tt(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([Oe(e,t,r,l,o,i),Oe(e,t,l+1,n,o,i)])}async function ke(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=Ut,tokens:l,direction:a="both",retries:u=3,timeoutMs:c=2e4,concurrency:p=4,endpoints:f=_e,onWarn:h}=t,d={retries:u,timeoutMs:c,onWarn:h},y=Bt(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 tt(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 k=[];for(let g=w;g<=E;g+=s)k.push([g,Math.min(g+s-1,E)]);let I=[],m=l?.length?{address:l}:{};(a==="in"||a==="both")&&I.push({...m,topics:[Ze,null,y]}),(a==="out"||a==="both")&&I.push({...m,topics:[Ze,y,null]});let A=[];for(let g of I)for(let j of k)A.push([g,j]);let v=[],$=0,q=Array.from({length:Math.min(p,A.length)},async()=>{for(;$<A.length;){let[g,[j,_]]=A[$++];try{await Oe(C,g,j,_,d,v)}catch(T){S.push({chainId:x,stage:"getLogs",range:[j,_],error:T.message})}}});await Promise.all(q);for(let g of v){if(!g?.topics||g.topics.length<3)continue;let j=parseInt(g.logIndex,16),_=`${x}|${g.transactionHash}|${j}`;N.has(_)||(N.add(_),b.push({chainId:x,token:g.address.toLowerCase(),from:et(g.topics[1]),to:et(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 He}from"@noble/hashes/sha3.js";import{createHash as er}from"node:crypto";import{types as G}from"node:util";import{AsyncLocalStorage as qt}from"node:async_hooks";var Vt=new qt,Jt=["http","retry","shared"],Kt=512;function fe(e){let t=Vt.getStore();if(!t||t.closed||!Jt.includes(e))return null;if(t.spans.length>=Kt)return t.droppedSpans++,null;let r={stage:e,startMs:t.now()-t.start,durationMs:null,outcome:"pending",status:null};return t.spans.push(r),(n,o=null)=>{t.closed||r.durationMs!==null||(r.durationMs=Math.max(0,t.now()-t.start-r.startMs),r.outcome=n==="succeeded"?"succeeded":"failed",r.status=Number.isInteger(o)&&o>=100&&o<=599?o:null)}}import J from"node:net";import Yt from"node:dns";var Xt=new Set(["localhost","metadata.google.internal","metadata.goog"]);function pe(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 $e(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 Re(e){if(J.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(J.isIPv6(e)){let t=pe(e);if(!t)return!1;let r=pe("::ffff:0:0");return $e(t,r,96)?Re([...t.slice(12)].join(".")):$e(t,pe("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>$e(t,pe(o),i)):!1}return!1}function Zt(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(Xt.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=J.isIP(r);return n!==0&&!Re(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function Ne(e,{lookupFn:t=Yt.promises.lookup}={}){let r=Zt(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:J.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=>!Re(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function Ie({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||(J.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(J.isIP(f))return[{address:f,family:J.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=Qt((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 Pe=Symbol.for("oracle.egressGuard.pinCapableFetch");function Qt(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[Pe]=Object.freeze({pin:t}),e}function Ce(e){return typeof e=="function"&&typeof e[Pe]?.pin=="function"}function rt(e,t,r){if(!Ce(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Pe].pin(t,r)}var tr=new Set([408,425,429,500,502,503,504]),nt=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),rr=2,ot=4e3,nr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,or=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,sr=AbortSignal.prototype.throwIfAborted,ir=EventTarget.prototype.addEventListener,st=EventTarget.prototype.removeEventListener,it=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,oe=e=>e?nr.call(e):!1,ar=e=>e?or.call(e):void 0,cr=new Set([301,302,303,307,308]),me=3,wo=64*1024,z=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});function P(e){return W(`HTTP JSON body refused: ${e}`)}function lr(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 G[t]=="function"&&G[t](e))}function ur(e){let t=[],r=0,n=0,o=0,i=0,s=new WeakSet,l=c=>{if(r+=Buffer.byteLength(c,"utf8"),r>z.bytes)throw P("serialized byte limit exceeded");t.push(c)},a=c=>{if(Buffer.byteLength(c,"utf8")>z.bytes)throw P("serialized byte limit exceeded");return JSON.stringify(c)},u=(c,p)=>{if(n+=1,n>z.nodes)throw P("node limit exceeded");if(p>z.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(G.isProxy(c))throw P("proxy value");if(lr(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(G.isProxy(d))throw P("proxy array prototype");if(y+=1,y>z.depth)throw P("array prototype depth limit exceeded");d=Object.getPrototypeOf(d)}if(c.length>z.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>z.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>z.fields)throw P("enumeration limit exceeded");if(!Object.hasOwn(c,d))continue;if(o+=1,o>z.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 dr(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(G.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 fr(){return Object.assign(Object.create(null),{Accept:"application/json"})}function pr(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 hr(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}var Le=new Map,at=new WeakMap,ct=1;function he(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=at.get(e);return t||(t=ct,ct+=1,at.set(e,t)),`reference:${t}`}var mr=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),yr=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);function lt(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?mr.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 ut(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(lt);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return lt(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&yr.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function wr(e,t,r,n={},o=null){let i=er("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 br(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ot):Math.min(250*2**e,ot)+Math.floor(Math.random()*100)}var gr=e=>new Promise(t=>setTimeout(t,e));function W(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function je(e,t,r){return W(`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 xr(e){return e?e.byteLength??e.length??0:0}async function Sr(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 je(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 je(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+=xr(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 je(r,`streamed ${a} bytes`,t);let c=Buffer.concat(l);return(u?c.subarray(0,t):c).toString("utf8")}function Er(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Ar(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=me}){let b=null,S=t,R=s?{lookupFn:s}:{};if(a&&!l&&!Ce(S))throw W(`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?it?it([h,N.signal]):h:N.signal,L=async(w,{status:E=null}={})=>{let k=await Ne(w,R);if(!k.ok)throw W(E==null?`HTTP refused ${w}: ${k.error}`:`HTTP redirect to ${w} ${k.error}`,E==null?{}:{status:E});let I=new URL(w).hostname;if(l){if(b&&(await b.close(),b=null),!b)try{b=await Ie({requireUndici:!0,...p?{importUndici:p}:{}})}catch(m){throw W(E==null?`HTTP refused ${w}: ${m?.message||m}`:`HTTP redirect to ${w} refused: ${m?.message||m}`,E==null?{}:{status:E})}b.pin(I,k.addresses),S=b.fetch}else rt(S,I,k.addresses);return k};try{let w=String(e),E=Object.assign(Object.create(null),n||{});a&&await L(w);for(let k=0;k<=y;k+=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),W(`HTTP ${m.status} ${r} redirect refused`,{status:m.status,redirectRefused:!0});if(cr.has(m.status)){let $=c===!0&&r==="POST"&&[307,308].includes(m.status)&&ut(r,o);if(r!=="GET"&&r!=="HEAD"&&!$){K(m);let _=new Error(`HTTP ${m.status} ${r} ${w} redirected non-idempotent request`);throw _.status=m.status,_}if(k===y)throw K(m),W(`HTTP ${m.status} ${r} redirect budget exhausted`,{status:m.status,redirectRefused:!0});let q=m.headers?.get?.("location"),g;try{g=pr(q,w)}catch(_){throw K(m),_}let j=!hr(g,w);if(K(m),j&&r==="POST"){let _=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw _.status=m.status,_}if(j&&c){let _=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw _.status=m.status,_.retryable=!1,_}if(j&&(E=fr(E)),a)await L(g,{status:m.status});else if(j){let _=await Ne(g,R);if(!_.ok){let T=new Error(`HTTP redirect from ${w} ${_.error}`);throw T.status=m.status,T.retryable=!1,T}l&&_.addresses?.length&&(b||(b=await Ie(p?{importUndici:p}:{})),b&&(b.pin(new URL(g).hostname,_.addresses),S=b.fetch))}w=g;continue}if(typeof f=="function")try{await f(m,{url:w})}catch($){throw K(m),W($?.message||String($))}let A=await Sr(m,u,{url:w,onOversize:()=>N.abort()}),v=Er(A);if(!m.ok){let $=new Error(`HTTP ${m.status} ${r} ${w}`);throw $.status=m.status,$.retryAfter=m.headers?.get?.("retry-after")??null,$.body=v??A.slice(0,300),$}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")&&!G.isProxy(w)?w:null,k=E?Object.getOwnPropertyDescriptor(E,"oversize"):null;if(!(k&&Object.hasOwn(k,"value")&&k.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 ye(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&G.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 O=Object.getOwnPropertyDescriptor(t,T);if(!(T==="toJSON"&&O&&Object.hasOwn(O,"value")&&O.value===void 0)){if(!r.has(T))throw new TypeError("HTTP options contain unknown fields");if(!O||!O.enumerable||!Object.hasOwn(O,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=T=>{if(t==null||!Object.hasOwn(t,T))return;let O=Object.getOwnPropertyDescriptor(t,T);if(!O||!Object.hasOwn(O,"value"))throw new TypeError("HTTP options must contain own data properties");return O.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>me))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${me}`);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??me;for(let T of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let O=n(T);if(O!==void 0&&typeof O!="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(G.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 T of["importUndici","lookupFn","validateResponse"]){let O=n(T);if(O!==void 0&&typeof O!="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,b=(o||"GET").toUpperCase(),S=n("headers"),R=dr(S),N=Object.assign(Object.create(null),R);Object.keys(N).some(T=>T.toLowerCase()==="accept")||(N.Accept="application/json");let x=n("body");x!=null&&typeof x!="string"&&(Object.keys(N).find(O=>O.toLowerCase()==="content-type")||(N["Content-Type"]="application/json"),x=ur(x));let C=s??rr,L=n("lookupFn"),w=!h,E=n("untrustedUrl")===!0,k=n("sameOriginRedirectsOnly")===!0,I=n("importUndici"),m=n("validateResponse"),A=f,v=p??null,$=async()=>{let T;for(let O=0;O<=C;O++){A&&sr.call(A);let Je=fe("http");try{let B=await Ar(e,{fetchImpl:d,method:b,headers:N,body:x,timeoutMs:y,lookupFn:L,realFetch:w,untrustedUrl:E,maxResponseBytes:v,sameOriginRedirectsOnly:k,importUndici:I,validateResponse:m,signal:A,redirectPolicy:u,maxRedirects:c});return Je?.("succeeded"),B}catch(B){T=B;let Q=Te=>{if(!B||typeof B!="object"&&typeof B!="function"||G.isProxy(B))return;let re=Object.getOwnPropertyDescriptor(B,Te);return re&&Object.hasOwn(re,"value")?re.value:void 0},de=Q("status");Je?.("failed",de);let Ht=Q("oracleTimeout")===!0||Q("name")==="AbortError"||Q("name")==="TimeoutError"||oe(A),vt=new Set([408,425,429]),Mt=Q("retryable")===!1?!1:de!=null?vt.has(de)||tr.has(de)&&nt.has(b):!Ht&&nt.has(b);if(O===C||!Mt)throw B;let Ke=br(O,Q("retryAfter")),Ft=fe("retry"),Ye=!1;try{A?await new Promise((Te,re)=>{let Xe,ne=()=>{clearTimeout(Xe),st.call(A,"abort",ne),re(ar(A)||new DOMException("Aborted","AbortError"))};if(oe(A)){ne();return}Xe=setTimeout(()=>{st.call(A,"abort",ne),Te()},Ke),ir.call(A,"abort",ne,{once:!0}),oe(A)&&ne()}):await gr(Ke),Ye=!0}finally{Ft?.(Ye?"succeeded":"failed")}}}throw T};if(!(n("dedupe")!==!1&&!A&&ut(b,x)))return $();let g=wr(b,e,N,{untrustedUrl:E,maxResponseBytes:v,sameOriginRedirectsOnly:k,redirectPolicy:u,maxRedirects:c,timeoutMs:y,retries:C,fetchImpl:he(d),realFetch:w,lookupFn:he(L),importUndici:he(I),validateResponse:he(m)},x),j=Le.get(g);if(j){let T=fe("shared");try{let O=await j;return T?.("succeeded"),O}catch(O){throw T?.("failed"),O}}let _=$().finally(()=>Le.delete(g));return Le.set(g,_),_}var dt={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}},Tr=new Map(Object.values(dt).map(e=>[e.chainId,e]));function ft(e){return Tr.get(Number(e))||null}function pt(e,t=process.env){let r=ft(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 Or,getAddress as To}from"ethers";var Oo=new Or(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var _r={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 kr(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=pt(e,r);return n||_r[Number(e)]||null}var $r=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Rr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!$r.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,ht=new Map;function Nr(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function Ir(e){if(e?.error)throw Nr(e.error);return e?.result}function Pr(e,t,r){return`${e}
1
+ var Ze="0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",_e={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"]},Ut=1e4,Dt=e=>new Promise(t=>setTimeout(t,e)),Qe=e=>"0x"+BigInt(e).toString(16),Bt=e=>"0x"+"0".repeat(24)+e.slice(2).toLowerCase(),et=e=>"0x"+e.slice(26).toLowerCase(),zt=/timeout|timed out|too many requests|rate.?limit|429|502|503|504|internal error|temporarily|aborted|fetch failed|ECONNRESET|socket hang up/i,Gt=/too many|exceeds|limited to|not supported on free plan|response too large|range must not exceed|narrow your filter/i,V=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 Wt(e,t,r,n){let o=new AbortController,i=setTimeout(()=>o.abort(),n),s,u;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}),u=await s.text()}catch(d){throw new V(`${t} network: ${d.message}`,{transient:!0})}finally{clearTimeout(i)}let a;try{a=JSON.parse(u)}catch{throw new V(`${t} non-JSON http=${s.status}: ${u.slice(0,80)}`,{transient:s.status>=500||s.status===429,http:s.status})}if(a.error){let d=a.error.message||"rpc error";throw new V(`${t} rpc: ${d}`,{transient:zt.test(d),tooBig:Gt.test(d),http:s.status})}if(s.status!==200)throw new V(`${t} http=${s.status}: ${u.slice(0,80)}`,{transient:s.status>=500||s.status===429,http:s.status});return a.result}async function tt(e,t,r,{retries:n,timeoutMs:o,onWarn:i}){let s;for(let u of e){for(let a=0;a<=n;a++)try{return{result:await Wt(u,t,r,o),url:u}}catch(d){if(s=d,d.tooBig)throw d;if(!d.transient||a===n)break;let l=Math.min(2e3*2**a,8e3)+Math.random()*250;i?.(`retry ${u} (${d.message.slice(0,70)}) in ${Math.round(l)}ms`),await Dt(l)}i?.(`endpoint exhausted: ${u} -> ${s?.message.slice(0,70)}`)}throw s??new V("no endpoints available")}async function Oe(e,t,r,n,o,i){let s=[{...t,fromBlock:Qe(r),toBlock:Qe(n)}];try{let{result:a}=await tt(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 u=r+Math.floor((n-r)/2);await Promise.all([Oe(e,t,r,u,o,i),Oe(e,t,u+1,n,o,i)])}async function ke(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=Ut,tokens:u,direction:a="both",retries:d=3,timeoutMs:l=2e4,concurrency:h=4,endpoints:p=_e,onWarn:f}=t,c={retries:d,timeoutMs:l,onWarn:f},y=Bt(e),w=[],S=[],R={},N=new Set;return await Promise.all(r.map(async x=>{let C=p[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 tt(C,"eth_blockNumber",[],c);L=parseInt(g,16)}let b=Math.max(0,o??L-n+1),E=Math.max(b,L);R[x]={fromBlock:b,toBlock:E,blocks:E-b+1};let k=[];for(let g=b;g<=E;g+=s)k.push([g,Math.min(g+s-1,E)]);let I=[],m=u?.length?{address:u}:{};(a==="in"||a==="both")&&I.push({...m,topics:[Ze,null,y]}),(a==="out"||a==="both")&&I.push({...m,topics:[Ze,y,null]});let A=[];for(let g of I)for(let H of k)A.push([g,H]);let v=[],$=0,q=Array.from({length:Math.min(h,A.length)},async()=>{for(;$<A.length;){let[g,[H,_]]=A[$++];try{await Oe(C,g,H,_,c,v)}catch(T){S.push({chainId:x,stage:"getLogs",range:[H,_],error:T.message})}}});await Promise.all(q);for(let g of v){if(!g?.topics||g.topics.length<3)continue;let H=parseInt(g.logIndex,16),_=`${x}|${g.transactionHash}|${H}`;N.has(_)||(N.add(_),w.push({chainId:x,token:g.address.toLowerCase(),from:et(g.topics[1]),to:et(g.topics[2]),value:BigInt(g.data==="0x"?"0x0":g.data).toString(),blockNumber:parseInt(g.blockNumber,16),txHash:g.transactionHash,logIndex:H}))}}catch(L){S.push({chainId:x,stage:"range",error:L.message})}})),w.sort((x,C)=>C.blockNumber-x.blockNumber||C.logIndex-x.logIndex),{events:w,errors:S,ranges:R}}import{keccak_256 as je}from"@noble/hashes/sha3.js";import{createHash as tr}from"node:crypto";import{types as G}from"node:util";import{AsyncLocalStorage as qt}from"node:async_hooks";var Vt=new qt,Jt=["http","retry","shared"],Kt=512;function fe(e){let t=Vt.getStore();if(!t||t.closed||!Jt.includes(e))return null;if(t.spans.length>=Kt)return t.droppedSpans++,null;let r={stage:e,startMs:t.now()-t.start,durationMs:null,outcome:"pending",status:null};return t.spans.push(r),(n,o=null)=>{t.closed||r.durationMs!==null||(r.durationMs=Math.max(0,t.now()-t.start-r.startMs),r.outcome=n==="succeeded"?"succeeded":"failed",r.status=Number.isInteger(o)&&o>=100&&o<=599?o:null)}}import J from"node:net";import Yt from"node:dns";var Xt=new Set(["localhost","metadata.google.internal","metadata.goog"]);function pe(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=l=>{if(!l)return[];let h=l.split(":"),p=h.at(-1);if(p?.includes(".")){let f=p.split(".").map(Number);if(f.length!==4||f.some(c=>!Number.isInteger(c)||c<0||c>255))return null;h.splice(h.length-1,1,(f[0]<<8|f[1]).toString(16),(f[2]<<8|f[3]).toString(16))}return h.some(f=>!/^[0-9a-f]{1,4}$/.test(f))?null:h.map(f=>Number.parseInt(f,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let u=t.includes("::"),a=8-i.length-s.length;if(!u&&a!==0||u&&a<1)return null;let d=[...i,...Array(Math.max(0,a)).fill(0),...s];return d.length!==8?null:Uint8Array.from(d.flatMap(l=>[l>>8,l&255]))}function $e(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 Re(e){if(J.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(J.isIPv6(e)){let t=pe(e);if(!t)return!1;let r=pe("::ffff:0:0");return $e(t,r,96)?Re([...t.slice(12)].join(".")):$e(t,pe("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>$e(t,pe(o),i)):!1}return!1}function Zt(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(Xt.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=J.isIP(r);return n!==0&&!Re(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function Ne(e,{lookupFn:t=Yt.promises.lookup}={}){let r=Zt(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:J.isIPv6(r.host)?6:4}]};let n;if(process.env.ORACLE_HOSTED_EGRESS_PROXY)return{ok:!0,url:r.url,addresses:[]};try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(o=>!Re(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}function Qt(e=process.env){let t=e.ORACLE_HOSTED_EGRESS_PROXY||"";if(!t)return null;let r;try{r=new URL(t)}catch{throw new Error("egress-guard: ORACLE_HOSTED_EGRESS_PROXY is not a URL")}if(r.protocol!=="http:"||!["127.0.0.1","::1","localhost","[::1]"].includes(r.hostname)||!r.port||r.username||r.password)throw new Error("egress-guard: egress proxy must be an exact loopback http origin");let n=e.ORACLE_HOSTED_EGRESS_TOKEN||"";if(!/^[A-Za-z0-9_-]{43}$/.test(n))throw new Error("egress-guard: egress proxy token is missing");return{uri:r.origin,token:n}}async function Ie({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n,o;try{o=await t(),r=o.Agent,n=o.fetch}catch(f){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${f?.message||f}`);return null}if(typeof r!="function"||typeof n!="function"){if(e)throw new Error("egress-guard: untrustedUrl pinning requires undici's Agent and fetch exports, which were not found on the imported module");return null}let i=f=>String(f).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),s=new Map,u=f=>(Array.isArray(f)?f:[f]).map(c=>typeof c=="string"?{address:c}:c).filter(c=>c&&c.address).map(c=>({address:c.address,family:c.family||(J.isIPv6(c.address)?6:4)})),a=(f,c,y)=>{s.set(i(f),u(typeof c=="string"?[{address:c,family:y}]:c))},d=f=>{let c=i(f);if(J.isIP(c))return[{address:c,family:J.isIPv6(c)?6:4}];let y=s.get(c);if(!y||!y.length)throw new Error(`refused: unpinned host ${f} during pinned fetch`);return y},l=Qt(),h=l&&typeof o.ProxyAgent=="function"?new o.ProxyAgent({uri:l.uri,token:`Bearer ${l.token}`,connectTimeout:1e4}):new r({connect:{lookup(f,c,y){let w;try{w=d(f)}catch(S){return y(S)}return c?.all?y(null,w):y(null,w[0].address,w[0].family)}}}),p=er((f,c={})=>n(f,{...c,dispatcher:h}),a);return{dispatcher:h,fetch:p,pin:a,resolve:d,async close(){try{await h.destroy()}catch{}}}}var Pe=Symbol.for("oracle.egressGuard.pinCapableFetch");function er(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[Pe]=Object.freeze({pin:t}),e}function Ce(e){return typeof e=="function"&&typeof e[Pe]?.pin=="function"}function rt(e,t,r){if(!Ce(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Pe].pin(t,r)}var rr=new Set([408,425,429,500,502,503,504]),nt=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),nr=2,ot=4e3,or=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"aborted")?.get,sr=Object.getOwnPropertyDescriptor(AbortSignal.prototype,"reason")?.get,ir=AbortSignal.prototype.throwIfAborted,ar=EventTarget.prototype.addEventListener,st=EventTarget.prototype.removeEventListener,it=typeof AbortSignal.any=="function"?AbortSignal.any.bind(AbortSignal):null,oe=e=>e?or.call(e):!1,cr=e=>e?sr.call(e):void 0,lr=new Set([301,302,303,307,308]),me=3,bo=64*1024,z=Object.freeze({depth:32,nodes:1e4,fields:1e4,arrayLength:1e4,bytes:1024*1024});function P(e){return W(`HTTP JSON body refused: ${e}`)}function ur(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 G[t]=="function"&&G[t](e))}function dr(e){let t=[],r=0,n=0,o=0,i=0,s=new WeakSet,u=l=>{if(r+=Buffer.byteLength(l,"utf8"),r>z.bytes)throw P("serialized byte limit exceeded");t.push(l)},a=l=>{if(Buffer.byteLength(l,"utf8")>z.bytes)throw P("serialized byte limit exceeded");return JSON.stringify(l)},d=(l,h)=>{if(n+=1,n>z.nodes)throw P("node limit exceeded");if(h>z.depth)throw P("depth limit exceeded");if(l===null){u("null");return}if(typeof l=="string"){u(a(l));return}if(typeof l=="boolean"){u(l?"true":"false");return}if(typeof l=="number"){if(!Number.isFinite(l))throw P("non-finite number");u(Object.is(l,-0)?"0":String(l));return}if(typeof l!="object")throw P("unsupported non-JSON value");if(G.isProxy(l))throw P("proxy value");if(ur(l))throw P("unsupported exotic object");if(s.has(l))throw P("cyclic value");s.add(l);try{if(Object.getOwnPropertySymbols(l).length>0)throw P("symbol-keyed fields are unsupported");if(Array.isArray(l)){let c=Object.getPrototypeOf(l),y=0;for(;c!==null;){if(G.isProxy(c))throw P("proxy array prototype");if(y+=1,y>z.depth)throw P("array prototype depth limit exceeded");c=Object.getPrototypeOf(c)}if(l.length>z.arrayLength)throw P("array length limit exceeded");for(let S=0;S<l.length;S+=1){let R=Object.getOwnPropertyDescriptor(l,String(S));if(!R||!Object.hasOwn(R,"value")||R.enumerable!==!0)throw P("array entries must be dense enumerable own data")}let w=0;for(let S in l){if(i+=1,i>z.fields)throw P("enumeration limit exceeded");if(Object.hasOwn(l,S)&&(w+=1,w>l.length))throw P("named array fields are unsupported")}if(w!==l.length)throw P("array entries must be dense enumerable own data");u("[");for(let S=0;S<l.length;S+=1)S&&u(","),d(Object.getOwnPropertyDescriptor(l,String(S)).value,h+1);u("]");return}let p=Object.getPrototypeOf(l);if(p!==Object.prototype&&p!==null)throw P("non-plain object");let f=[];for(let c in l){if(i+=1,i>z.fields)throw P("enumeration limit exceeded");if(!Object.hasOwn(l,c))continue;if(o+=1,o>z.fields)throw P("field limit exceeded");let y=Object.getOwnPropertyDescriptor(l,c);if(!y||!Object.hasOwn(y,"value")||y.enumerable!==!0)throw P("object fields must be enumerable own data");f.push([c,y.value])}u("{");for(let c=0;c<f.length;c+=1)c&&u(","),u(a(f[c][0])),u(":"),d(f[c][1],h+1);u("}")}finally{s.delete(l)}};return d(e,0),t.join("")}function fr(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(G.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 pr(){return Object.assign(Object.create(null),{Accept:"application/json"})}function hr(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 mr(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}var Le=new Map,at=new WeakMap,ct=1;function he(e){if((typeof e!="object"||e===null)&&typeof e!="function")return`${typeof e}:${String(e)}`;let t=at.get(e);return t||(t=ct,ct+=1,at.set(e,t)),`reference:${t}`}var yr=new Set(["eth_blockNumber","eth_call","eth_chainId","eth_estimateGas","getHealth","minimumLedgerSlot","net_version","simulateTransaction","web3_clientVersion"]),wr=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);function lt(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?yr.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 ut(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(lt);if(!r||typeof r!="object")return!1;if(Object.hasOwn(r,"jsonrpc")||Object.hasOwn(r,"method"))return lt(r);let n=Object.hasOwn(r,"type")?r.type:null;return typeof n=="string"&&wr.has(n)&&(!Object.hasOwn(r,"action")||r.action==null)&&(!Object.hasOwn(r,"signature")||r.signature==null)&&(!Object.hasOwn(r,"nonce")||r.nonce==null)}function br(e,t,r,n={},o=null){let i=tr("sha256"),s=(a,d)=>{let l=String(d);i.update(String(Buffer.byteLength(a,"utf8"))).update(":").update(a),i.update("=").update(String(Buffer.byteLength(l,"utf8"))).update(":").update(l).update(`
2
+ `)};s("method",e),s("url",t),Object.keys(r||{}).map((a,d)=>({name:a.toLowerCase(),order:d,value:String(r[a])})).sort((a,d)=>a.name.localeCompare(d.name)||a.order-d.order).forEach((a,d)=>{s(`header-name-${d}`,a.name),s(`header-value-${d}`,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 gr(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ot):Math.min(250*2**e,ot)+Math.floor(Math.random()*100)}var xr=e=>new Promise(t=>setTimeout(t,e));function W(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function He(e,t,r){return W(`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 Sr(e){return e?e.byteLength??e.length??0:0}async function Er(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 He(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let h=await e.text(),p=Buffer.byteLength(h,"utf8");if(p>t){if(!n)throw He(r,`body ${p} bytes`,t);return Buffer.from(h,"utf8").subarray(0,t).toString("utf8")}return h}let u=[],a=0,d=!1;try{for(;;){let{value:h,done:p}=await s.read();if(p)break;if(h&&(u.push(Buffer.from(h)),a+=Sr(h),a>t)){d=!0;break}}}finally{if(d)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(d&&(typeof o=="function"&&o(),!n))throw He(r,`streamed ${a} bytes`,t);let l=Buffer.concat(u);return(d?l.subarray(0,t):l).toString("utf8")}function Ar(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Tr(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:u,untrustedUrl:a=!1,maxResponseBytes:d=null,sameOriginRedirectsOnly:l=!1,importUndici:h,validateResponse:p,signal:f,redirectPolicy:c="follow",maxRedirects:y=me}){let w=null,S=t,R=s?{lookupFn:s}:{};if(a&&!u&&!Ce(S))throw W(`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=f?it?it([f,N.signal]):f:N.signal,L=async(b,{status:E=null}={})=>{let k=await Ne(b,R);if(!k.ok)throw W(E==null?`HTTP refused ${b}: ${k.error}`:`HTTP redirect to ${b} ${k.error}`,E==null?{}:{status:E});let I=new URL(b).hostname;if(u){if(w&&(await w.close(),w=null),!w)try{w=await Ie({requireUndici:!0,...h?{importUndici:h}:{}})}catch(m){throw W(E==null?`HTTP refused ${b}: ${m?.message||m}`:`HTTP redirect to ${b} refused: ${m?.message||m}`,E==null?{}:{status:E})}w.pin(I,k.addresses),S=w.fetch}else rt(S,I,k.addresses);return k};try{let b=String(e),E=Object.assign(Object.create(null),n||{});a&&await L(b);for(let k=0;k<=y;k+=1){let I=Object.assign(Object.create(null),{method:r,headers:E,body:o,signal:C,redirect:"manual",dispatcher:void 0}),m=await S(b,I);if((c==="error"||y===0)&&m.status>=300&&m.status<400)throw K(m),W(`HTTP ${m.status} ${r} redirect refused`,{status:m.status,redirectRefused:!0});if(lr.has(m.status)){let $=l===!0&&r==="POST"&&[307,308].includes(m.status)&&ut(r,o);if(r!=="GET"&&r!=="HEAD"&&!$){K(m);let _=new Error(`HTTP ${m.status} ${r} ${b} redirected non-idempotent request`);throw _.status=m.status,_}if(k===y)throw K(m),W(`HTTP ${m.status} ${r} redirect budget exhausted`,{status:m.status,redirectRefused:!0});let q=m.headers?.get?.("location"),g;try{g=hr(q,b)}catch(_){throw K(m),_}let H=!mr(g,b);if(K(m),H&&r==="POST"){let _=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw _.status=m.status,_}if(H&&l){let _=new Error(`HTTP ${m.status} ${r} cross-origin redirect refused`);throw _.status=m.status,_.retryable=!1,_}if(H&&(E=pr(E)),a)await L(g,{status:m.status});else if(H){let _=await Ne(g,R);if(!_.ok){let T=new Error(`HTTP redirect from ${b} ${_.error}`);throw T.status=m.status,T.retryable=!1,T}u&&_.addresses?.length&&(w||(w=await Ie(h?{importUndici:h}:{})),w&&(w.pin(new URL(g).hostname,_.addresses),S=w.fetch))}b=g;continue}if(typeof p=="function")try{await p(m,{url:b})}catch($){throw K(m),W($?.message||String($))}let A=await Er(m,d,{url:b,onOversize:()=>N.abort()}),v=Ar(A);if(!m.ok){let $=new Error(`HTTP ${m.status} ${r} ${b}`);throw $.status=m.status,$.retryAfter=m.headers?.get?.("retry-after")??null,$.body=v??A.slice(0,300),$}return v??A}throw new Error(`HTTP redirect loop for ${e}`)}catch(b){if(N.signal.aborted&&!oe(f)){let E=b&&(typeof b=="object"||typeof b=="function")&&!G.isProxy(b)?b:null,k=E?Object.getOwnPropertyDescriptor(E,"oversize"):null;if(!(k&&Object.hasOwn(k,"value")&&k.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 b}finally{clearTimeout(x),w&&await w.close()}}async function ye(e,t={}){if(t!=null&&typeof t!="object"&&typeof t!="function")throw new TypeError("HTTP options must be an object");if(t!=null&&G.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 O=Object.getOwnPropertyDescriptor(t,T);if(!(T==="toJSON"&&O&&Object.hasOwn(O,"value")&&O.value===void 0)){if(!r.has(T))throw new TypeError("HTTP options contain unknown fields");if(!O||!O.enumerable||!Object.hasOwn(O,"value"))throw new TypeError("HTTP options must contain enumerable own data properties")}}}let n=T=>{if(t==null||!Object.hasOwn(t,T))return;let O=Object.getOwnPropertyDescriptor(t,T);if(!O||!Object.hasOwn(O,"value"))throw new TypeError("HTTP options must contain own data properties");return O.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 u=n("redirectPolicy");if(u!==void 0&&u!=="follow"&&u!=="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>me))throw new TypeError(`HTTP maxRedirects must be an integer from 0 through ${me}`);if(u==="error"&&a!==void 0&&a!==0)throw new TypeError('HTTP redirectPolicy "error" requires maxRedirects 0 when supplied');let d=u??"follow",l=d==="error"?0:a??me;for(let T of["dedupe","untrustedUrl","sameOriginRedirectsOnly"]){let O=n(T);if(O!==void 0&&typeof O!="boolean")throw new TypeError(`HTTP ${T} must be boolean`)}let h=n("maxResponseBytes");if(h!==void 0&&(!Number.isInteger(h)||h<1||h>64*1024*1024))throw new TypeError("HTTP maxResponseBytes must be a bounded integer");let p=n("signal");if(p!==void 0){if(G.isProxy(p)||!(p instanceof AbortSignal))throw new TypeError("HTTP signal must be a native AbortSignal");try{oe(p)}catch{throw new TypeError("HTTP signal must be a native AbortSignal")}}for(let T of["importUndici","lookupFn","validateResponse"]){let O=n(T);if(O!==void 0&&typeof O!="function")throw new TypeError(`HTTP ${T} must be a function`)}let f=n("fetchImpl"),c=f||globalThis.fetch;if(typeof c!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let y=i??12e3,w=(o||"GET").toUpperCase(),S=n("headers"),R=fr(S),N=Object.assign(Object.create(null),R);Object.keys(N).some(T=>T.toLowerCase()==="accept")||(N.Accept="application/json");let x=n("body");x!=null&&typeof x!="string"&&(Object.keys(N).find(O=>O.toLowerCase()==="content-type")||(N["Content-Type"]="application/json"),x=dr(x));let C=s??nr,L=n("lookupFn"),b=!f,E=n("untrustedUrl")===!0,k=n("sameOriginRedirectsOnly")===!0,I=n("importUndici"),m=n("validateResponse"),A=p,v=h??null,$=async()=>{let T;for(let O=0;O<=C;O++){A&&ir.call(A);let Je=fe("http");try{let B=await Tr(e,{fetchImpl:c,method:w,headers:N,body:x,timeoutMs:y,lookupFn:L,realFetch:b,untrustedUrl:E,maxResponseBytes:v,sameOriginRedirectsOnly:k,importUndici:I,validateResponse:m,signal:A,redirectPolicy:d,maxRedirects:l});return Je?.("succeeded"),B}catch(B){T=B;let Q=Te=>{if(!B||typeof B!="object"&&typeof B!="function"||G.isProxy(B))return;let re=Object.getOwnPropertyDescriptor(B,Te);return re&&Object.hasOwn(re,"value")?re.value:void 0},de=Q("status");Je?.("failed",de);let jt=Q("oracleTimeout")===!0||Q("name")==="AbortError"||Q("name")==="TimeoutError"||oe(A),vt=new Set([408,425,429]),Mt=Q("retryable")===!1?!1:de!=null?vt.has(de)||rr.has(de)&&nt.has(w):!jt&&nt.has(w);if(O===C||!Mt)throw B;let Ke=gr(O,Q("retryAfter")),Ft=fe("retry"),Ye=!1;try{A?await new Promise((Te,re)=>{let Xe,ne=()=>{clearTimeout(Xe),st.call(A,"abort",ne),re(cr(A)||new DOMException("Aborted","AbortError"))};if(oe(A)){ne();return}Xe=setTimeout(()=>{st.call(A,"abort",ne),Te()},Ke),ar.call(A,"abort",ne,{once:!0}),oe(A)&&ne()}):await xr(Ke),Ye=!0}finally{Ft?.(Ye?"succeeded":"failed")}}}throw T};if(!(n("dedupe")!==!1&&!A&&ut(w,x)))return $();let g=br(w,e,N,{untrustedUrl:E,maxResponseBytes:v,sameOriginRedirectsOnly:k,redirectPolicy:d,maxRedirects:l,timeoutMs:y,retries:C,fetchImpl:he(c),realFetch:b,lookupFn:he(L),importUndici:he(I),validateResponse:he(m)},x),H=Le.get(g);if(H){let T=fe("shared");try{let O=await H;return T?.("succeeded"),O}catch(O){throw T?.("failed"),O}}let _=$().finally(()=>Le.delete(g));return Le.set(g,_),_}var dt={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}},Or=new Map(Object.values(dt).map(e=>[e.chainId,e]));function ft(e){return Or.get(Number(e))||null}function pt(e,t=process.env){let r=ft(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 _r,getAddress as Oo}from"ethers";var _o=new _r(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var kr={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 $r(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=pt(e,r);return n||kr[Number(e)]||null}var Rr=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Nr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!Rr.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,ht=new Map;function Ir(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function Pr(e){if(e?.error)throw Ir(e.error);return e?.result}function Cr(e,t,r){return`${e}
3
3
  ${t}
4
- ${JSON.stringify(r??[])}`}async function Cr(e,t,r){return ye(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function we(e,t,r=[],n={}){let o=String(t||""),i=Rr(o),s=kr(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=ht.get(s);if(c!=null)return c}let a=n.dedupe!==!1&&!n.signal?Pr(s,o,r):null;if(a&&se.has(a))return se.get(a);let u=(async()=>{let c=await Cr(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),p=Ir(c);return i==="eth_chainid"&&typeof p=="string"&&ht.set(s,p),p})();return a&&(se.set(a,u),u.finally(()=>{se.get(a)===u&&se.delete(a)}).catch(()=>{})),u}var Me=999,ve=1,Lr=8453,mt="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",jr="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",yt="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",Hr="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",vr=".80002105.reverse",wt=/^0x[a-fA-F0-9]{40}$/,bt=new TextEncoder,gt=e=>"0x"+Buffer.from(e).toString("hex"),Y=e=>gt(He(bt.encode(e))).slice(0,10),xt=e=>e.toLowerCase().replace(/^0x/,"").padStart(64,"0");function be(e){let t=new Uint8Array(32);if(e)for(let r of String(e).split(".").reverse()){let n=He(bt.encode(r)),o=new Uint8Array(64);o.set(t,0),o.set(n,32),t=He(o)}return gt(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 we(e,"eth_call",[{to:t,data:r},"latest"])}catch{return null}}async function Mr(e){let t=await X(Me,mt,Y("primaryName(address)")+xt(e)),r=Fe(t);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function Fr(e){let t=await X(Me,jr,Y("getName(address)")+xt(e)),r=Fe(t);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function St(e,t,r){let n=await X(e,r,Y("name(bytes32)")+t.slice(2));return Fe(n)||null}async function Ur(e){let t=be(`${e.slice(2).toLowerCase()}.addr.reverse`),r=await X(ve,yt,Y("resolver(bytes32)")+t.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:St(ve,t,n)}async function Dr(e){let t=be(e.slice(2).toLowerCase()+vr);return St(Lr,t,Hr)}var Br=[{source:"hl",fn:Mr},{source:"hype",fn:Fr},{source:"ens",fn:Ur},{source:"basename",fn:Dr}];async function zr(e){let t=be(e),r=await X(Me,mt,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 Gr(e,t,r){let n=be(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 Et(e){let t=String(e||"").trim().toLowerCase();if(!t||!t.includes("."))return null;if(t.endsWith(".hl")){let r=await zr(t);return r?{address:r,source:"hl",name:t}:null}if(t.endsWith(".eth")){let r=await Gr(ve,t,yt);return r?{address:r,source:t.endsWith(".base.eth")?"basename":"ens",name:t}:null}return null}var Ro=Br.map(e=>e.source);var Wr="protective-monitors",qr="read-only",Po=Object.freeze(["depeg","oracleDeviation","exploitFeed","goplus","liquidationLadder"]),Vr="https://hermes.pyth.network",Jr="https://coins.llama.fi",Kr="https://api.llama.fi/hacks",Yr="https://api.gopluslabs.io/api/v1/token_security",Xr="https://api.v3.aave.com/user",Zr=Object.freeze({USDT:"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",USDC:"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"}),Qr=Object.freeze({USDT:"coingecko:tether",USDC:"coingecko:usd-coin",DAI:"coingecko:dai"}),en=Object.freeze(["is_honeypot","is_proxy","is_mintable","owner_change_balance","hidden_owner","selfdestruct","cannot_buy","cannot_sell_all","is_blacklisted"]),At=Object.freeze({liquidatable:0,danger:1,critical:2,warning:3,healthy:4}),tn=/^0x[0-9a-fA-F]{40}$/,rn=/^[0-9a-fA-F]{64}$/;function ie(e,t={}){return{ok:!0,provider:Wr,op:e,alertOnly:!0,execution:qr,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):ye(e,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3,retries:t.retries??0})}function ge(e){return String(e||"USDT").trim().toUpperCase().replace(/\/USD$/,"")}function nn(e={}){if(e.feedId){let n=String(e.feedId).replace(/^0x/i,"");return rn.test(n)||H("feedId must be a 32-byte hex id"),n.toLowerCase()}let t=ge(e.symbol),r=Zr[t];return r||H("unknown symbol",t),r}function on(e={}){if(e.llamaCoin)return String(e.llamaCoin);let t=ge(e.symbol);return Qr[t]||`coingecko:${t.toLowerCase()}`}function Tt(e,t){let r=Number(e.thresholdBps??t);return(!Number.isFinite(r)||r<0)&&H("thresholdBps must be a non-negative number"),r}function sn(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 an(e,t){let r=e?.coins?.[t]||e?.coins?.[String(t).toLowerCase()],n=Number(r?.price);return Number.isFinite(n)?n:null}function cn(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 ln(e,t={}){return`${String(t.llamaCoinsBaseUrl||Jr).replace(/\/$/,"")}/prices/current/${encodeURIComponent(e)}`}async function Ot(e,t){let r=nn(e),n=await ae(cn(r,t),t),o=sn(n);return o>0||H("pyth price must be positive"),{id:r,price:o}}async function _t(e,t){let r=on(e),n=await ae(ln(r,t),t);return{coin:r,price:an(n,r)}}async function un(e={},t={}){let r=Number(e.peg??1);(!Number.isFinite(r)||r<=0)&&H("peg must be a positive number");let n=Tt(e,50),o=await Ot(e,t),i=Math.round(Math.abs(o.price-r)*1e4),s={required:!1,llamaPrice:null};try{let l=await _t(e,t);s={required:!1,llamaPrice:l.price,llamaCoin:l.coin}}catch{s={required:!1,llamaPrice:null}}return ie("depeg",{symbol:ge(e.symbol),feedId:o.id,price:o.price,peg:r,thresholdBps:n,deviationBps:i,alert:i>n,crossCheck:s})}async function dn(e={},t={}){let r=Tt(e,100),n=await Ot(e,t),o=await _t(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:ge(e.symbol),pythPrice:n.price,llamaPrice:o.price,mid:i,thresholdBps:r,deviationBps:s,alert:s>r})}function fn(e,t){return String(e.id||e.defillamaId||e.slug||`hack-${t}`)}function pn(e,t){return{id:fn(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 hn(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 kt(e){if(typeof e=="string"){let t=e.trim();if(t.startsWith("<"))return hn(t);try{return kt(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 mn(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 yn(e={},t={}){let r=Kr,n=e.payload??await ae(r,t),o=mn(kt(n).map(pn));return ie("exploitFeed",{count:o.length,fingerprint:o.map(i=>i.id).join("|"),items:o,alert:o.length>0})}function wn(e){return e===!0||e===1||e==="1"}function bn(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();tn.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||Yr).replace(/\/$/,"")}/${n}?contract_addresses=${r}`,s=e.payload??await ae(i,t),l=bn(s,r);l||H("goplus returned no result for",r);let a=en.filter(u=>wn(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 gn(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 xn(e,t){let r=Number(e.healthFactor??e.hf);Number.isFinite(r)||H("position healthFactor required");let n=gn(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 Sn(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||`${Xr}/${s}`);r=await ae(l,t)}let o=(Array.isArray(r?.positions)?r.positions:[]).map(xn),i=o.reduce((s,l)=>s?At[l.rung]<At[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 Co=Object.freeze({depeg:un,oracleDeviation:dn,exploitFeed:yn,goplus:Ue,liquidationLadder:Sn});import ee from"node:fs";import vn from"node:os";import Se from"node:path";import{randomUUID as Mn}from"node:crypto";var jo=Object.freeze(["wallet","pool","nft_floor","hl_flow","prediction_market"]),Ho=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"}),U=(e,t=0,r=1)=>Math.min(r,Math.max(t,e)),M=e=>Number.isFinite(Number(e))?Number(e):null,En=e=>Math.round(e*1e4)/1e4;function F(e,t,r,n=!0){!n||r===null||!Number.isFinite(r)||e.push({feature:t,value:En(r)})}function An(e,t){let r=M(e.repeatBuys??e.repeat_buys??e.buyCount),n=M(e.walletWinRate??e.winRate);F(t,"repeat_buys",r===null?null:U((r-1)/4)*.38),F(t,"wallet_win_rate",n===null?null:(U(n)-.5)*.5)}function Tn(e,t){let r=M(e.ageHours??e.poolAgeHours),n=M(e.liquidityUsd??e.liquidity),o=e.liquidityLocked??e.locked;F(t,"pool_age",r===null?null:r<24?-.42:U(r/720)*.12),F(t,"liquidity",n===null?null:(U(Math.log10(Math.max(1,n))/7)-.5)*.28),F(t,"liquidity_lock",o==null?null:o?.12:-.28)}function On(e,t){let r=M(e.floorChange??e.floorChangePct),n=M(e.sales??e.saleCount);F(t,"floor_change",r===null?null:U(r,-1,1)*.35),F(t,"sales_depth",n===null?null:U(n/50)*.18)}function _n(e,t){let r=M(e.flowImbalance??e.imbalance),n=M(e.fundingRate??e.funding);F(t,"flow_imbalance",r===null?null:U(r,-1,1)*.42),F(t,"funding",n===null?null:-U(n*100,-1,1)*.12)}function kn(e,t){let r=M(e.marketProbability??e.marketPrice??e.probability),n=M(e.fairProbability??e.referenceProbability??e.fairValue);F(t,"probability_mispricing",r===null||n===null?null:U(n-r,-1,1)*.65);let o=M(e.liquidityUsd??e.liquidity);F(t,"market_liquidity",o===null?null:U(Math.log10(Math.max(1,o))/6)*.12)}var vo=Object.freeze({wallet:An,pool:Tn,nft_floor:On,hl_flow:_n,prediction_market:kn});import{createHash as Pn}from"node:crypto";var Fo=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),Uo=Object.freeze(["read","simulate"]);var Do=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}},$n=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,Rn=Object.freeze(["privkey","wif","xprv","seed"]);function $t(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return $n.test(t)||Rn.includes(r)}var Nn=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}]),In=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=In.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:i,re:s}of Nn)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"&&$t(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($t(o))throw new ce(`${t}.${o}`,"forbidden-key-name");Z(i,`${t}.${o}`,r,o)}return e}var De=Object.freeze(["intent","quote_comparison","simulation","prepared","approval","signed","broadcast","settlement","balance_delta","position"]),Qo=Object.freeze(Object.fromEntries(De.map((e,t)=>[e,Object.freeze(t+1<De.length?[De[t+1]]:[])])));function Be(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(Be).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${Be(e[t])}`).join(",")}}`}function Cn(e){return e===void 0?null:JSON.parse(JSON.stringify(e))}function ze(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))ze(t)}return e}function Ln(e,t="fact"){try{Z(e,t)}catch{throw new Error(`${t} contains custody material and is forbidden`)}}function jn(e){return Pn("sha256").update(Be(e)).digest("hex")}function Hn({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:Cn(r)};return ze({...s,hash:jn(s)})}function Rt({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");Ln(t,"intent");let n=Hn({tradeId:e,state:"intent",fact:t,asOf:r,previousHash:null,external:!1});return ze({tradeId:e,state:"intent",events:[n],headHash:n.hash,custody:"none",execution:"prepare-only"})}function Nt(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=Rt({tradeId:r,intent:n,asOf:t.asOf??Date.now()});return{tradeId:r,intent:n,lifecycle:o,recommendation:"PREPARE_RESEARCH_ONLY"}}var Ct=1,Ge=5e3,Fn=Object.freeze({1:new Set(["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0xdac17f958d2ee523a2206206994597c13d831ec","0x6b175474e89094c44da98b954eedeac495271d0","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]),8453:new Set(["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","0x4200000000000000000000000000000000000006"]),42161:new Set(["0xaf88d065e77c8cc2239327c5edb3a432268e5831","0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9","0x82af49447d8a07e3bd95bd0d56f35241523fbab1"])}),Un=/^0x[0-9a-fA-F]{40}$/,Dn=/^0x[0-9a-fA-F]{64}$/,Bn=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/;function D(e,t){let r=String(e||"").trim();if(!Un.test(r))throw new TypeError(`${t} must be a 0x-prefixed EVM address`);return r.toLowerCase()}function Lt(e,t){let r=Fn[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"||!Bn.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 zn({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 Gn(e={}){let t=String(e.txHash||"").trim().toLowerCase();if(!Dn.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 Wn(e,{followedWallet:t}={}){let r=D(t,"followedWallet");return e.txFrom?e.txFrom!==r?{included:!1,reason:"not-initiated-by-followed-wallet"}:Lt(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 qn({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 xe({chainId:e,txHash:t,token:r,side:n,sizeUsd:o,sizeBasis:i,followedWallet:s,refuseReason:l=null}={}){let a=qn({chainId:e,txHash:t,noTrade:l!=null});try{let u=Nt(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=le(n,"spentTodayUsd"),u=le(r,"dailyCapUsd"),c=[],p=[],f=[];for(let h of e){let d;try{d=Gn(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=Wn(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=xe({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=xe({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=zn({dailyCapUsd:ue(u),spentTodayUsd:ue(a),proportionalUsd:d.valueUsd});if(R.sizeCents<=0n){l.add(d.txHash);let x=xe({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=xe({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 We(e=process.env){let t=e.ORACLE_CONFIG_DIR||Se.join(vn.homedir(),".config","oracle");return Se.join(t,"follow-mirror.json")}function It(){return{version:Ct,targets:{}}}function Pt(e,t){return`${String(e).toLowerCase()}:${D(t,"address")}`}function Ee(e){try{let t=ee.readFileSync(e,"utf8"),r=JSON.parse(t);return!r||typeof r!="object"||r.version!==Ct||!r.targets||typeof r.targets!="object"?It():r}catch{return It()}}function Jn(e,t){let r=Se.dirname(e);ee.mkdirSync(r,{recursive:!0,mode:448});let n=Se.join(r,`.follow-mirror.${process.pid}.${Date.now()}.${Mn()}.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 Kn(e){return new Date(e).toISOString().slice(0,10)}function Yn(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 Xn(e,t,{seenTxHashes:r,spentTodayUsd:n,day:o,newIntents:i,newRefusals:s}){let l=e.targets[t]||{seenTxHashes:[],days:{},intents:[],refusals:[]},a=[...r].slice(-Ge),u=[...l.intents||[],...i].slice(-Ge),c=[...l.refusals||[],...s].slice(-Ge);e.targets[t]={seenTxHashes:a,days:{...l.days||{},[o]:n},intents:u,refusals:c}}function qe({now:e=()=>Date.now(),fetchWallet:t,fetchTxFrom:r,checkHoneypot:n,estimateUsdValue:o=async()=>null,storePath:i=We()}={}){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=Kn(y),S=Pt(u||d,h),R=Ee(i),{seenTxHashes:N,spentTodayUsd:x}=Yn(R,S,b),C=await t(h,{chains:[d],lookback:f}),L=Array.isArray(C?.events)?C.events:[],w=[],E={},k=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 $=String(m.token||"").toLowerCase();if(A===h&&!Lt(d,$)&&!k.has($)&&$){k.add($);try{E[$]=await n(d,$)}catch(q){E[$]={flagged:!0,reason:`security check unavailable: ${String(q?.message||q).slice(0,160)}`}}}w.push({...m,chainId:d,txFrom:A,valueUsd:v})}let I=Vn(w,{followedWallet:h,dailyCapUsd:String(p),spentTodayUsd:x,seenTxHashes:N,honeypotResults:E});return Xn(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}))}),Jn(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=Ee(i),f=Pt(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"},Zn=Object.fromEntries(Object.entries(te).map(([e,t])=>[t,Number(e)])),Qn=new Set(["is_honeypot","cannot_sell_all","cannot_buy","is_blacklisted","selfdestruct","owner_change_balance"]),jt=`oracle follow <name-or-address> [--chain <name>] [--blocks <n>] [--json]
4
+ ${JSON.stringify(r??[])}`}async function Lr(e,t,r){return ye(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function we(e,t,r=[],n={}){let o=String(t||""),i=Nr(o),s=$r(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 l=ht.get(s);if(l!=null)return l}let a=n.dedupe!==!1&&!n.signal?Cr(s,o,r):null;if(a&&se.has(a))return se.get(a);let d=(async()=>{let l=await Lr(s,{jsonrpc:"2.0",id:1,method:t,params:r},n),h=Pr(l);return i==="eth_chainid"&&typeof h=="string"&&ht.set(s,h),h})();return a&&(se.set(a,d),d.finally(()=>{se.get(a)===d&&se.delete(a)}).catch(()=>{})),d}var Me=999,ve=1,Hr=8453,mt="0x1d9d87eBc14e71490bB87f1C39F65BDB979f3cb7",jr="0x4d5e4ed4D5e4A160Fa136853597cDc2eBBe66494",yt="0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e",vr="0xC6d566A56A1aFf6508b41f6c90ff131615583BCD",Mr=".80002105.reverse",wt=/^0x[a-fA-F0-9]{40}$/,bt=new TextEncoder,gt=e=>"0x"+Buffer.from(e).toString("hex"),Y=e=>gt(je(bt.encode(e))).slice(0,10),xt=e=>e.toLowerCase().replace(/^0x/,"").padStart(64,"0");function be(e){let t=new Uint8Array(32);if(e)for(let r of String(e).split(".").reverse()){let n=je(bt.encode(r)),o=new Uint8Array(64);o.set(t,0),o.set(n,32),t=je(o)}return gt(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 we(e,"eth_call",[{to:t,data:r},"latest"])}catch{return null}}async function Fr(e){let t=await X(Me,mt,Y("primaryName(address)")+xt(e)),r=Fe(t);return r?r.endsWith(".hl")?r:`${r}.hl`:null}async function Ur(e){let t=await X(Me,jr,Y("getName(address)")+xt(e)),r=Fe(t);return r?r.endsWith(".hype")?r:`${r}.hype`:null}async function St(e,t,r){let n=await X(e,r,Y("name(bytes32)")+t.slice(2));return Fe(n)||null}async function Dr(e){let t=be(`${e.slice(2).toLowerCase()}.addr.reverse`),r=await X(ve,yt,Y("resolver(bytes32)")+t.slice(2));if(!r)return null;let n="0x"+r.slice(-40);return/^0x0+$/.test(n)?null:St(ve,t,n)}async function Br(e){let t=be(e.slice(2).toLowerCase()+Mr);return St(Hr,t,vr)}var zr=[{source:"hl",fn:Fr},{source:"hype",fn:Ur},{source:"ens",fn:Dr},{source:"basename",fn:Br}];async function Gr(e){let t=be(e),r=await X(Me,mt,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 Wr(e,t,r){let n=be(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 u="0x"+s.slice(-40);return/^0x0+$/.test(u)?null:u}async function Et(e){let t=String(e||"").trim().toLowerCase();if(!t||!t.includes("."))return null;if(t.endsWith(".hl")){let r=await Gr(t);return r?{address:r,source:"hl",name:t}:null}if(t.endsWith(".eth")){let r=await Wr(ve,t,yt);return r?{address:r,source:t.endsWith(".base.eth")?"basename":"ens",name:t}:null}return null}var No=zr.map(e=>e.source);var qr="protective-monitors",Vr="read-only",Co=Object.freeze(["depeg","oracleDeviation","exploitFeed","goplus","liquidationLadder"]),Jr="https://hermes.pyth.network",Kr="https://coins.llama.fi",Yr="https://api.llama.fi/hacks",Xr="https://api.gopluslabs.io/api/v1/token_security",Zr="https://api.v3.aave.com/user",Qr=Object.freeze({USDT:"2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b",USDC:"eaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a"}),en=Object.freeze({USDT:"coingecko:tether",USDC:"coingecko:usd-coin",DAI:"coingecko:dai"}),tn=Object.freeze(["is_honeypot","is_proxy","is_mintable","owner_change_balance","hidden_owner","selfdestruct","cannot_buy","cannot_sell_all","is_blacklisted"]),At=Object.freeze({liquidatable:0,danger:1,critical:2,warning:3,healthy:4}),rn=/^0x[0-9a-fA-F]{40}$/,nn=/^[0-9a-fA-F]{64}$/;function ie(e,t={}){return{ok:!0,provider:qr,op:e,alertOnly:!0,execution:Vr,exec:!1,...t}}function j(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):ye(e,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3,retries:t.retries??0})}function ge(e){return String(e||"USDT").trim().toUpperCase().replace(/\/USD$/,"")}function on(e={}){if(e.feedId){let n=String(e.feedId).replace(/^0x/i,"");return nn.test(n)||j("feedId must be a 32-byte hex id"),n.toLowerCase()}let t=ge(e.symbol),r=Qr[t];return r||j("unknown symbol",t),r}function sn(e={}){if(e.llamaCoin)return String(e.llamaCoin);let t=ge(e.symbol);return en[t]||`coingecko:${t.toLowerCase()}`}function Tt(e,t){let r=Number(e.thresholdBps??t);return(!Number.isFinite(r)||r<0)&&j("thresholdBps must be a non-negative number"),r}function an(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))&&j("no pyth price returned"),n<0?r/10**-n:r*10**n}function cn(e,t){let r=e?.coins?.[t]||e?.coins?.[String(t).toLowerCase()],n=Number(r?.price);return Number.isFinite(n)?n:null}function ln(e,t={}){let r=String(t.pythBaseUrl||Jr).replace(/\/$/,""),n=new URL(`${r}/v2/updates/price/latest`);return n.searchParams.append("ids[]",e),n.searchParams.set("parsed","true"),n.toString()}function un(e,t={}){return`${String(t.llamaCoinsBaseUrl||Kr).replace(/\/$/,"")}/prices/current/${encodeURIComponent(e)}`}async function Ot(e,t){let r=on(e),n=await ae(ln(r,t),t),o=an(n);return o>0||j("pyth price must be positive"),{id:r,price:o}}async function _t(e,t){let r=sn(e),n=await ae(un(r,t),t);return{coin:r,price:cn(n,r)}}async function dn(e={},t={}){let r=Number(e.peg??1);(!Number.isFinite(r)||r<=0)&&j("peg must be a positive number");let n=Tt(e,50),o=await Ot(e,t),i=Math.round(Math.abs(o.price-r)*1e4),s={required:!1,llamaPrice:null};try{let u=await _t(e,t);s={required:!1,llamaPrice:u.price,llamaCoin:u.coin}}catch{s={required:!1,llamaPrice:null}}return ie("depeg",{symbol:ge(e.symbol),feedId:o.id,price:o.price,peg:r,thresholdBps:n,deviationBps:i,alert:i>n,crossCheck:s})}async function fn(e={},t={}){let r=Tt(e,100),n=await Ot(e,t),o=await _t(e,t);o.price>0||j("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:ge(e.symbol),pythPrice:n.price,llamaPrice:o.price,mid:i,thresholdBps:r,deviationBps:s,alert:s>r})}function pn(e,t){return String(e.id||e.defillamaId||e.slug||`hack-${t}`)}function hn(e,t){return{id:pn(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 mn(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 kt(e){if(typeof e=="string"){let t=e.trim();if(t.startsWith("<"))return mn(t);try{return kt(JSON.parse(t))}catch{j("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 yn(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 wn(e={},t={}){let r=Yr,n=e.payload??await ae(r,t),o=yn(kt(n).map(hn));return ie("exploitFeed",{count:o.length,fingerprint:o.map(i=>i.id).join("|"),items:o,alert:o.length>0})}function bn(e){return e===!0||e===1||e==="1"}function gn(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&&j("goplus is a second opinion and must never be a sole gate");let r=String(e.address||e.token||"").trim();rn.test(r)||j("goplus requires an EVM token address");let n=Number(e.chainId??1);(!Number.isInteger(n)||n<=0)&&j("chainId must be a positive integer");let i=`${String(t.goplusBaseUrl||Xr).replace(/\/$/,"")}/${n}?contract_addresses=${r}`,s=e.payload??await ae(i,t),u=gn(s,r);u||j("goplus returned no result for",r);let a=tn.filter(d=>bn(u.token[d]));return ie("goplus",{chainId:n,address:r.toLowerCase(),role:"second-opinion",secondOpinion:!0,soleGate:!1,neverSoleGate:!0,token:{address:u.address,name:u.token.token_name||null,symbol:u.token.token_symbol||null},findings:a,alert:a.length>0,note:"second opinion only \u2014 never the sole gate"})}function xn(e){let t=Number(e);return(!Number.isFinite(t)||t<0)&&j("healthFactor must be a non-negative number"),t<1?"liquidatable":t<1.05?"danger":t<1.2?"critical":t<1.5?"warning":"healthy"}function Sn(e,t){let r=Number(e.healthFactor??e.hf);Number.isFinite(r)||j("position healthFactor required");let n=xn(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 En(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||j("liquidationLadder requires user or positions");let u=String(t.aaveUrl||`${Zr}/${s}`);r=await ae(u,t)}let o=(Array.isArray(r?.positions)?r.positions:[]).map(Sn),i=o.reduce((s,u)=>s?At[u.rung]<At[s]?u.rung:s:u.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 Lo=Object.freeze({depeg:dn,oracleDeviation:fn,exploitFeed:wn,goplus:Ue,liquidationLadder:En});import ee from"node:fs";import Mn from"node:os";import Se from"node:path";import{randomUUID as Fn}from"node:crypto";var jo=Object.freeze(["wallet","pool","nft_floor","hl_flow","prediction_market"]),vo=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"}),U=(e,t=0,r=1)=>Math.min(r,Math.max(t,e)),M=e=>Number.isFinite(Number(e))?Number(e):null,An=e=>Math.round(e*1e4)/1e4;function F(e,t,r,n=!0){!n||r===null||!Number.isFinite(r)||e.push({feature:t,value:An(r)})}function Tn(e,t){let r=M(e.repeatBuys??e.repeat_buys??e.buyCount),n=M(e.walletWinRate??e.winRate);F(t,"repeat_buys",r===null?null:U((r-1)/4)*.38),F(t,"wallet_win_rate",n===null?null:(U(n)-.5)*.5)}function On(e,t){let r=M(e.ageHours??e.poolAgeHours),n=M(e.liquidityUsd??e.liquidity),o=e.liquidityLocked??e.locked;F(t,"pool_age",r===null?null:r<24?-.42:U(r/720)*.12),F(t,"liquidity",n===null?null:(U(Math.log10(Math.max(1,n))/7)-.5)*.28),F(t,"liquidity_lock",o==null?null:o?.12:-.28)}function _n(e,t){let r=M(e.floorChange??e.floorChangePct),n=M(e.sales??e.saleCount);F(t,"floor_change",r===null?null:U(r,-1,1)*.35),F(t,"sales_depth",n===null?null:U(n/50)*.18)}function kn(e,t){let r=M(e.flowImbalance??e.imbalance),n=M(e.fundingRate??e.funding);F(t,"flow_imbalance",r===null?null:U(r,-1,1)*.42),F(t,"funding",n===null?null:-U(n*100,-1,1)*.12)}function $n(e,t){let r=M(e.marketProbability??e.marketPrice??e.probability),n=M(e.fairProbability??e.referenceProbability??e.fairValue);F(t,"probability_mispricing",r===null||n===null?null:U(n-r,-1,1)*.65);let o=M(e.liquidityUsd??e.liquidity);F(t,"market_liquidity",o===null?null:U(Math.log10(Math.max(1,o))/6)*.12)}var Mo=Object.freeze({wallet:Tn,pool:On,nft_floor:_n,hl_flow:kn,prediction_market:$n});import{createHash as Cn}from"node:crypto";var Uo=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),Do=Object.freeze(["read","simulate"]);var Bo=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}},Rn=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,Nn=Object.freeze(["privkey","wif","xprv","seed"]);function $t(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return Rn.test(t)||Nn.includes(r)}var In=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}]),Pn=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=Pn.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:i,re:s}of In)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"&&$t(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($t(o))throw new ce(`${t}.${o}`,"forbidden-key-name");Z(i,`${t}.${o}`,r,o)}return e}var De=Object.freeze(["intent","quote_comparison","simulation","prepared","approval","signed","broadcast","settlement","balance_delta","position"]),es=Object.freeze(Object.fromEntries(De.map((e,t)=>[e,Object.freeze(t+1<De.length?[De[t+1]]:[])])));function Be(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(Be).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${Be(e[t])}`).join(",")}}`}function Ln(e){return e===void 0?null:JSON.parse(JSON.stringify(e))}function ze(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){Object.freeze(e);for(let t of Object.values(e))ze(t)}return e}function Hn(e,t="fact"){try{Z(e,t)}catch{throw new Error(`${t} contains custody material and is forbidden`)}}function jn(e){return Cn("sha256").update(Be(e)).digest("hex")}function vn({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:Ln(r)};return ze({...s,hash:jn(s)})}function Rt({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");Hn(t,"intent");let n=vn({tradeId:e,state:"intent",fact:t,asOf:r,previousHash:null,external:!1});return ze({tradeId:e,state:"intent",events:[n],headHash:n.hash,custody:"none",execution:"prepare-only"})}function Nt(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=Rt({tradeId:r,intent:n,asOf:t.asOf??Date.now()});return{tradeId:r,intent:n,lifecycle:o,recommendation:"PREPARE_RESEARCH_ONLY"}}var Ct=1,Ge=5e3,Un=Object.freeze({1:new Set(["0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48","0xdac17f958d2ee523a2206206994597c13d831ec","0x6b175474e89094c44da98b954eedeac495271d0","0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2"]),8453:new Set(["0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","0x4200000000000000000000000000000000000006"]),42161:new Set(["0xaf88d065e77c8cc2239327c5edb3a432268e5831","0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9","0x82af49447d8a07e3bd95bd0d56f35241523fbab1"])}),Dn=/^0x[0-9a-fA-F]{40}$/,Bn=/^0x[0-9a-fA-F]{64}$/,zn=/^(?:0|[1-9]\d*)(?:\.\d{1,2})?$/;function D(e,t){let r=String(e||"").trim();if(!Dn.test(r))throw new TypeError(`${t} must be a 0x-prefixed EVM address`);return r.toLowerCase()}function Lt(e,t){let r=Un[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"||!zn.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 Gn({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 u=s<i?s:i;return{sizeCents:u,sizeUsd:ue(u),basis:u===i?"cap-limited":"proportional"}}function Wn(e={}){let t=String(e.txHash||"").trim().toLowerCase();if(!Bn.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 qn(e,{followedWallet:t}={}){let r=D(t,"followedWallet");return e.txFrom?e.txFrom!==r?{included:!1,reason:"not-initiated-by-followed-wallet"}:Lt(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 Vn({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 xe({chainId:e,txHash:t,token:r,side:n,sizeUsd:o,sizeBasis:i,followedWallet:s,refuseReason:u=null}={}){let a=Vn({chainId:e,txHash:t,noTrade:u!=null});try{let d=Nt(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:d.tradeId,chain:e,token:r,side:n,sizeUsd:o,sizeBasis:i,txHash:t,followedWallet:s,recommendation:d.recommendation,lifecycle:d.lifecycle,intent:d.intent}}catch(d){return{ok:!1,reason:u||String(d?.message||d)}}}function Jn(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"),u=new Set(o),a=le(n,"spentTodayUsd"),d=le(r,"dailyCapUsd"),l=[],h=[],p=[];for(let f of e){let c;try{c=Wn(f)}catch(x){p.push({txHash:f?.txHash??null,reason:`malformed-event: ${x.message}`});continue}if(u.has(c.txHash)){p.push({txHash:c.txHash,reason:"duplicate-tx"});continue}let y=qn(c,{followedWallet:s});if(!y.included){p.push({txHash:c.txHash,reason:y.reason});continue}let w=i[c.token];if(w?.flagged){u.add(c.txHash);let x=xe({chainId:c.chainId,txHash:c.txHash,token:c.token,side:y.side,sizeUsd:"0.00",sizeBasis:"refused",followedWallet:s,refuseReason:`token flagged: ${w.reason||"security check flagged this token"}`});h.push({txHash:c.txHash,token:c.token,side:y.side,reason:x.reason});continue}if(d-a<=0n){u.add(c.txHash);let x=xe({chainId:c.chainId,txHash:c.txHash,token:c.token,side:y.side,sizeUsd:"0.00",sizeBasis:"refused",followedWallet:s,refuseReason:"daily-cap-exhausted"});h.push({txHash:c.txHash,token:c.token,side:y.side,reason:x.reason});continue}let R=Gn({dailyCapUsd:ue(d),spentTodayUsd:ue(a),proportionalUsd:c.valueUsd});if(R.sizeCents<=0n){u.add(c.txHash);let x=xe({chainId:c.chainId,txHash:c.txHash,token:c.token,side:y.side,sizeUsd:"0.00",sizeBasis:R.basis,followedWallet:s,refuseReason:R.basis});h.push({txHash:c.txHash,token:c.token,side:y.side,reason:x.reason});continue}let N=xe({chainId:c.chainId,txHash:c.txHash,token:c.token,side:y.side,sizeUsd:R.sizeUsd,sizeBasis:R.basis,followedWallet:s});u.add(c.txHash),N.ok?(l.push(N),a+=R.sizeCents):h.push({txHash:c.txHash,token:c.token,side:y.side,reason:N.reason})}return{intents:l,refusals:h,skipped:p,seenTxHashes:u,spentTodayUsd:ue(a)}}function We(e=process.env){let t=e.ORACLE_CONFIG_DIR||Se.join(Mn.homedir(),".config","oracle");return Se.join(t,"follow-mirror.json")}function It(){return{version:Ct,targets:{}}}function Pt(e,t){return`${String(e).toLowerCase()}:${D(t,"address")}`}function Ee(e){try{let t=ee.readFileSync(e,"utf8"),r=JSON.parse(t);return!r||typeof r!="object"||r.version!==Ct||!r.targets||typeof r.targets!="object"?It():r}catch{return It()}}function Kn(e,t){let r=Se.dirname(e);ee.mkdirSync(r,{recursive:!0,mode:448});let n=Se.join(r,`.follow-mirror.${process.pid}.${Date.now()}.${Fn()}.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 Yn(e){return new Date(e).toISOString().slice(0,10)}function Xn(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 u=e.targets[t]||{seenTxHashes:[],days:{},intents:[],refusals:[]},a=[...r].slice(-Ge),d=[...u.intents||[],...i].slice(-Ge),l=[...u.refusals||[],...s].slice(-Ge);e.targets[t]={seenTxHashes:a,days:{...u.days||{},[o]:n},intents:d,refusals:l}}function qe({now:e=()=>Date.now(),fetchWallet:t,fetchTxFrom:r,checkHoneypot:n,estimateUsdValue:o=async()=>null,storePath:i=We()}={}){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:d,chainId:l,dailyCapUsd:h,lookback:p}={}){let f=D(a,"address"),c=Number(l);if(!Number.isInteger(c)||c<=0)throw new TypeError("observe requires a numeric chainId");let y=e(),w=Yn(y),S=Pt(d||c,f),R=Ee(i),{seenTxHashes:N,spentTodayUsd:x}=Xn(R,S,w),C=await t(f,{chains:[c],lookback:p}),L=Array.isArray(C?.events)?C.events:[],b=[],E={},k=new Set;for(let m of L){let A=null;try{A=await r(c,m.txHash)}catch{A=null}let v=null;try{v=await o({...m,chainId:c,txFrom:A})}catch{v=null}let $=String(m.token||"").toLowerCase();if(A===f&&!Lt(c,$)&&!k.has($)&&$){k.add($);try{E[$]=await n(c,$)}catch(q){E[$]={flagged:!0,reason:`security check unavailable: ${String(q?.message||q).slice(0,160)}`}}}b.push({...m,chainId:c,txFrom:A,valueUsd:v})}let I=Jn(b,{followedWallet:f,dailyCapUsd:String(h),spentTodayUsd:x,seenTxHashes:N,honeypotResults:E});return Zn(R,S,{seenTxHashes:I.seenTxHashes,spentTodayUsd:I.spentTodayUsd,day:w,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}))}),Kn(i,R),{ok:!0,cold:!0,executionAllowed:!1,chain:d||c,chainId:c,address:f,observed:L.length,intents:I.intents,refusals:I.refusals,skipped:I.skipped,spentTodayUsd:I.spentTodayUsd,dailyCapUsd:String(h),errors:C?.errors||[]}}function u({address:a,chain:d}={}){let l=D(a,"address"),h=Ee(i),p=Pt(d,l),f=h.targets[p]||{intents:[],refusals:[],days:{}};return{ok:!0,address:l,chain:d,intents:f.intents||[],refusals:f.refusals||[],days:f.days||{}}}return Object.freeze({observe:s,status:u,storePath:i})}var te={1:"ethereum",8453:"base",42161:"arbitrum"},Qn=Object.fromEntries(Object.entries(te).map(([e,t])=>[t,Number(e)])),eo=new Set(["is_honeypot","cannot_sell_all","cannot_buy","is_blacklisted","selfdestruct","owner_change_balance"]),Ht=`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 Ae(e,t){let r=e.indexOf(t);return r>=0?e[r+1]:void 0}function eo(e){let t=String(e??"");return t.length>22?`${t.slice(0,19)}...`:t}async function to(e,t){let n=(await we(e,"eth_getTransactionByHash",[t]))?.from;return typeof n!="string"||!/^0x[0-9a-fA-F]{40}$/.test(n)?null:n.toLowerCase()}async function ro(e,t){try{let n=((await Ue({address:t,chainId:e},{})).findings||[]).filter(o=>Qn.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 Ve(e){if(wt.test(e))return{address:e,resolvedFrom:null};let t=await Et(e);return t?.address?{address:t.address,resolvedFrom:e}:{address:null,resolvedFrom:null}}async function no(e,{query:t,chainArg:r,chainId:n,lookbackBlocks:o,asJson:i}){let s=Ae(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 Ve(t);if(!l)return process.stderr.write(`follow: could not resolve "${t}" to an address
39
- `),1;let c=await qe({fetchWallet:ke,fetchTxFrom:to,checkHoneypot:ro}).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
- `),0;let p=a?`${a} ${l}`:l;process.stdout.write(`${p}
41
- `),process.stdout.write(` ${c.chain} \xB7 observed ${c.observed} transfer${c.observed===1?"":"s"} \xB7 spent ${c.spentTodayUsd}/${c.dailyCapUsd} today
42
- `),c.intents.length||process.stdout.write(` no new prepared mirror intents this run
43
- `);for(let f of c.intents)process.stdout.write(` PREPARED ${f.side} ${f.token} $${f.sizeUsd} tx ${f.txHash}
44
- `);for(let f of c.refusals)process.stdout.write(` REFUSED ${f.side} ${f.token} ${f.reason} tx ${f.txHash}
45
- `);for(let f of c.errors||[])process.stderr.write(` error: ${f.stage||"rpc"}: ${f.error}
46
- `);return 0}async function oo(e,t){let r=(Ae(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 Ve(o);if(!a)return process.stderr.write(`follow status: could not resolve "${o}" to an address
47
- `),1;let c=qe({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
- `),0;process.stdout.write(`${u?`${u} ${a}`:a} (${p})
49
- `),!f.intents.length&&!f.refusals.length&&process.stdout.write(` no prepared mirror intents on disk for this target
50
- `);for(let h of f.intents)process.stdout.write(` PREPARED ${h.side} ${h.token} $${h.sizeUsd} tx ${h.txHash}
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=We(),s=Ee(i),l=Object.entries(s.targets||{});if(t)return process.stdout.write(`${JSON.stringify({storePath:i,targets:Object.fromEntries(l)})}
53
- `),0;if(!l.length)return process.stdout.write(`no follow --mirror targets on disk yet
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 so(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 oo(e,t);let o=(n[0]||"").trim();if(!o||o==="--help"||o==="-h")return process.stdout.write(`${jt}
56
- `),o?0:1;let i=(Ae(e,"--chain")||"ethereum").toLowerCase(),s=Zn[i]??Number(i);if(!_e[s])return process.stderr.write(`follow: unsupported chain "${i}". Supported: ${Object.values(te).join(", ")}
57
- `),1;let l=Ae(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 no(e,{query:o,chainArg:i,chainId:s,lookbackBlocks:a,asJson:t});let{address:u,resolvedFrom:c}=await Ve(o);if(!u)return process.stderr.write(`follow: could not resolve "${o}" to an address
59
- `),1;let p=await ke(u,{chains:[s],lookback:a,onWarn:t?void 0:d=>process.stderr.write(` warn: ${d}
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
- `),0;let h=c?`${c} ${u}`:u;process.stdout.write(`${h}
62
- `),process.stdout.write(` ${te[s]||s} \xB7 last ${a} blocks \xB7 ${f.length} transfer${f.length===1?"":"s"}
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} ${eo(d.value)}
65
- `)}f.length>25&&process.stdout.write(` ... ${f.length-25} more (use --json for all)
66
- `);for(let d of p.errors||[])process.stderr.write(` error: ${d.stage||"rpc"}: ${d.error}
67
- `);return 0}catch(u){return process.stderr.write(`follow failed: ${u?.message||u}
68
- `),1}}var ys={name:"follow",summary:"read a wallet's recent ERC20 transfer activity, or --mirror it to prepared intents",group:"read",usage:jt,async run(e){return so(e.argv||[])}};export{ys as default};
37
+ blocks, so they return an empty result instead of an error.`;function Ae(e,t){let r=e.indexOf(t);return r>=0?e[r+1]:void 0}function to(e){let t=String(e??"");return t.length>22?`${t.slice(0,19)}...`:t}async function ro(e,t){let n=(await we(e,"eth_getTransactionByHash",[t]))?.from;return typeof n!="string"||!/^0x[0-9a-fA-F]{40}$/.test(n)?null:n.toLowerCase()}async function no(e,t){try{let n=((await Ue({address:t,chainId:e},{})).findings||[]).filter(o=>eo.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 Ve(e){if(wt.test(e))return{address:e,resolvedFrom:null};let t=await Et(e);return t?.address?{address:t.address,resolvedFrom:e}:{address:null,resolvedFrom:null}}async function oo(e,{query:t,chainArg:r,chainId:n,lookbackBlocks:o,asJson:i}){let s=Ae(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:u,resolvedFrom:a}=await Ve(t);if(!u)return process.stderr.write(`follow: could not resolve "${t}" to an address
39
+ `),1;let l=await qe({fetchWallet:ke,fetchTxFrom:ro,checkHoneypot:no}).observe({address:u,chain:te[n]||String(n),chainId:n,dailyCapUsd:s,lookback:o});if(i)return process.stdout.write(`${JSON.stringify({resolvedFrom:a,...l})}
40
+ `),0;let h=a?`${a} ${u}`:u;process.stdout.write(`${h}
41
+ `),process.stdout.write(` ${l.chain} \xB7 observed ${l.observed} transfer${l.observed===1?"":"s"} \xB7 spent ${l.spentTodayUsd}/${l.dailyCapUsd} today
42
+ `),l.intents.length||process.stdout.write(` no new prepared mirror intents this run
43
+ `);for(let p of l.intents)process.stdout.write(` PREPARED ${p.side} ${p.token} $${p.sizeUsd} tx ${p.txHash}
44
+ `);for(let p of l.refusals)process.stdout.write(` REFUSED ${p.side} ${p.token} ${p.reason} tx ${p.txHash}
45
+ `);for(let p of l.errors||[])process.stderr.write(` error: ${p.stage||"rpc"}: ${p.error}
46
+ `);return 0}async function so(e,t){let r=(Ae(e,"--chain")||"").toLowerCase(),o=(e.filter((a,d)=>a==="--json"||a==="status"||a==="--chain"&&e[d+1]!=null||e[d-1]==="--chain"?!1:!a.startsWith("--"))[0]||"").trim();if(o){let{address:a,resolvedFrom:d}=await Ve(o);if(!a)return process.stderr.write(`follow status: could not resolve "${o}" to an address
47
+ `),1;let l=qe({fetchWallet:async()=>({events:[],errors:[]}),fetchTxFrom:async()=>null,checkHoneypot:async()=>({flagged:!1})}),h=r||"ethereum",p=l.status({address:a,chain:h});if(t)return process.stdout.write(`${JSON.stringify({resolvedFrom:d,...p})}
48
+ `),0;process.stdout.write(`${d?`${d} ${a}`:a} (${h})
49
+ `),!p.intents.length&&!p.refusals.length&&process.stdout.write(` no prepared mirror intents on disk for this target
50
+ `);for(let f of p.intents)process.stdout.write(` PREPARED ${f.side} ${f.token} $${f.sizeUsd} tx ${f.txHash}
51
+ `);for(let f of p.refusals)process.stdout.write(` REFUSED ${f.side} ${f.token} ${f.reason} tx ${f.txHash}
52
+ `);return 0}let i=We(),s=Ee(i),u=Object.entries(s.targets||{});if(t)return process.stdout.write(`${JSON.stringify({storePath:i,targets:Object.fromEntries(u)})}
53
+ `),0;if(!u.length)return process.stdout.write(`no follow --mirror targets on disk yet
54
+ `),0;for(let[a,d]of u)process.stdout.write(`${a} ${(d.intents||[]).length} prepared, ${(d.refusals||[]).length} refused
55
+ `);return 0}async function io(e=[]){let t=e.includes("--json"),r=e.includes("--mirror"),n=[];for(let d=0;d<e.length;d+=1){let l=e[d];if(!(l==="--json"||l==="--mirror")){if(l==="--chain"||l==="--blocks"||l==="--max-usd"){d+=1;continue}n.push(l)}}if(n[0]==="status")return so(e,t);let o=(n[0]||"").trim();if(!o||o==="--help"||o==="-h")return process.stdout.write(`${Ht}
56
+ `),o?0:1;let i=(Ae(e,"--chain")||"ethereum").toLowerCase(),s=Qn[i]??Number(i);if(!_e[s])return process.stderr.write(`follow: unsupported chain "${i}". Supported: ${Object.values(te).join(", ")}
57
+ `),1;let u=Ae(e,"--blocks"),a=u?Number(u):4e4;if(!Number.isFinite(a)||a<=0)return process.stderr.write(`follow: --blocks must be a positive number, got "${u}"
58
+ `),1;try{if(r)return await oo(e,{query:o,chainArg:i,chainId:s,lookbackBlocks:a,asJson:t});let{address:d,resolvedFrom:l}=await Ve(o);if(!d)return process.stderr.write(`follow: could not resolve "${o}" to an address
59
+ `),1;let h=await ke(d,{chains:[s],lookback:a,onWarn:t?void 0:c=>process.stderr.write(` warn: ${c}
60
+ `)}),p=h.events||[];if(t)return process.stdout.write(`${JSON.stringify({address:d,resolvedFrom:l,chain:te[s]||String(s),lookbackBlocks:a,count:p.length,errors:h.errors||[],events:p})}
61
+ `),0;let f=l?`${l} ${d}`:d;process.stdout.write(`${f}
62
+ `),process.stdout.write(` ${te[s]||s} \xB7 last ${a} blocks \xB7 ${p.length} transfer${p.length===1?"":"s"}
63
+ `),p.length||process.stdout.write(` no ERC20 transfers in this window
64
+ `);for(let c of p.slice(0,25)){let y=c.to?.toLowerCase()===d.toLowerCase()?"in ":"out";process.stdout.write(` ${y} blk ${c.blockNumber} token ${c.token} ${to(c.value)}
65
+ `)}p.length>25&&process.stdout.write(` ... ${p.length-25} more (use --json for all)
66
+ `);for(let c of h.errors||[])process.stderr.write(` error: ${c.stage||"rpc"}: ${c.error}
67
+ `);return 0}catch(d){return process.stderr.write(`follow failed: ${d?.message||d}
68
+ `),1}}var ws={name:"follow",summary:"read a wallet's recent ERC20 transfer activity, or --mirror it to prepared intents",group:"read",usage:Ht,async run(e){return io(e.argv||[])}};export{ws as default};