@oracle-agent/oracle 0.35.4 → 0.35.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +25 -23
- package/dist/bin/oracle-data-mcp.mjs +13 -11
- package/dist/bin/oracle-gateway.mjs +35 -35
- package/dist/bin/oracle-mev-arb-shadow.mjs +7 -5
- package/dist/bin/oracle-mev-shadow.mjs +7 -5
- package/dist/bin/oracle-public-server.mjs +6 -4
- package/dist/bin/oracle-route.mjs +22 -20
- package/dist/bin/oracle-scan.mjs +14 -12
- package/dist/bin/oracle-telegram-mcp.mjs +10 -10
- package/dist/bin/oracle.mjs +7 -5
- package/dist/cli/commands/chat.mjs +166 -164
- package/dist/cli/commands/doctor.mjs +3 -3
- package/dist/cli/commands/eval.mjs +113 -113
- package/dist/cli/commands/farm.mjs +14 -14
- package/dist/cli/commands/follow.mjs +16 -14
- package/dist/cli/commands/model.mjs +170 -168
- package/dist/cli/commands/project.mjs +17 -0
- package/dist/cli/commands/resolve.mjs +8 -6
- package/dist/cli/commands/shadow.mjs +21 -0
- package/dist/cli/commands/signer.mjs +10 -10
- package/dist/cli/commands/snipe.mjs +10 -8
- package/dist/cli/commands/strategy.mjs +5 -5
- package/dist/cli/commands/swap.mjs +27 -25
- package/dist/cli/commands/telegram.mjs +10 -10
- package/dist/cli/commands/venues.mjs +2 -2
- package/dist/data/desk-data.mjs +23 -21
- package/dist/data/names.mjs +4 -2
- package/dist/data/providers/farming.mjs +2 -2
- package/dist/index.mjs +37 -35
- package/dist/local-signer/index.mjs +3 -3
- package/dist/local-signer/runtime.mjs +9 -9
- package/dist/nft/universal-mint-router.mjs +5 -3
- package/dist/router/index.mjs +4 -2
- package/dist/router/prepare-bridge.mjs +2 -2
- package/dist/scanner/index.mjs +5 -3
- package/dist/strategy/index.mjs +3 -3
- package/package.json +1 -1
- package/public/oracle-splash/index.html +2 -2
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
var
|
|
3
|
-
`),l=mr("sha256").update(u).digest("hex").slice(0,32),d=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`;return`${e} ${t} ${d} ${l}`}function Ir(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,Qe):Math.min(250*2**e,Qe)+Math.floor(Math.random()*100)}function Y(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function Oe(e,t,r){return Y(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function J(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function Cr(e){return e?e.byteLength??e.length??0:0}async function tt(e,t,{url:r,truncate:n=!1,onOversize:o}={}){if(t==null)return await e.text();let s=Number(e.headers?.get?.("content-length"));if(Number.isFinite(s)&&s>t&&(J(e),!n))throw Oe(r,`content-length ${s}`,t);let a=e.body?.getReader?.();if(!a){let c=await e.text(),i=Buffer.byteLength(c,"utf8");if(i>t){if(!n)throw Oe(r,`body ${i} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let u=[],l=0,d=!1;try{for(;;){let{value:c,done:i}=await a.read();if(i)break;if(c&&(u.push(Buffer.from(c)),l+=Cr(c),l>t)){d=!0;break}}}finally{if(d)try{await a.cancel()}catch{}try{a.releaseLock?.()}catch{}}if(d&&(typeof o=="function"&&o(),!n))throw Oe(r,`streamed ${l} bytes`,t);let p=Buffer.concat(u);return(d?p.subarray(0,t):p).toString("utf8")}function rt(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Nr(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s,lookupFn:a,realFetch:u,untrustedUrl:l=!1,maxResponseBytes:d=null,importUndici:p,validateResponse:c,signal:i}){let f=new AbortController,h=setTimeout(()=>f.abort(),s),y=i?typeof AbortSignal.any=="function"?AbortSignal.any([i,f.signal]):i:f.signal,A=null,E=t,x=a?{lookupFn:a}:{};if(l&&!u&&!Ce(E))throw Y(`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 I=async(m,{status:b=null}={})=>{let w=await Se(m,x);if(!w.ok)throw Y(b==null?`HTTP refused ${m}: ${w.error}`:`HTTP redirect to ${m} ${w.error}`,b==null?{}:{status:b});let g=new URL(m).hostname;if(u){if(A&&(await A.close(),A=null),!A)try{A=await Ie({requireUndici:!0,...p?{importUndici:p}:{}})}catch(S){throw Y(b==null?`HTTP refused ${m}: ${S?.message||S}`:`HTTP redirect to ${m} refused: ${S?.message||S}`,b==null?{}:{status:b})}A.pin(g,w.addresses),E=A.fetch}else Ye(E,g,w.addresses);return w};try{let m=String(e),b={...n||{}};l&&await I(m);for(let w=0;w<=et;w+=1){let g=await E(m,{method:r,headers:b,body:o,signal:y,redirect:"manual"});if(wr.has(g.status)){if(r!=="GET"&&r!=="HEAD"){let _=await tt(g,d??gr,{url:m,truncate:!0}),O=new Error(`HTTP ${g.status} ${r} ${m} redirected non-idempotent request`);throw O.status=g.status,O.body=rt(_)??_.slice(0,300),O}if(w===et)throw J(g),new Error(`HTTP redirect loop for ${e}`);let C=g.headers?.get?.("location"),k;try{k=Ar(C,m)}catch(_){throw J(g),_}let P=!xr(k,m);if(J(g),P&&(b=yr(b)),l)await I(k,{status:g.status});else if(P){let _=await Se(k,x);if(!_.ok){let O=new Error(`HTTP redirect from ${m} ${_.error}`);throw O.status=g.status,O.retryable=!1,O}u&&_.addresses?.length&&(A||(A=await Ie(p?{importUndici:p}:{})),A&&(A.pin(new URL(k).hostname,_.addresses),E=A.fetch))}m=k;continue}if(typeof c=="function")try{await c(g,{url:m})}catch(C){throw J(g),Y(C?.message||String(C))}let S=await tt(g,d,{url:m,onOversize:()=>f.abort()}),N=rt(S);if(!g.ok){let C=new Error(`HTTP ${g.status} ${r} ${m}`);throw C.status=g.status,C.retryAfter=g.headers?.get?.("retry-after")??null,C.body=N??S.slice(0,300),C}return N??S}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(h),A&&await A.close()}}async function ne(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,o=(t.method||"GET").toUpperCase(),s={Accept:"application/json",...t.headers||{}},a=t.body;a!=null&&typeof a!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",a=JSON.stringify(a));let u=Number.isInteger(t.retries)?Math.max(t.retries,0):br,l=t.lookupFn,d=!t.fetchImpl,p=t.untrustedUrl===!0,c=t.importUndici,i=t.validateResponse,f=t.signal,h=Number(t.maxResponseBytes),y=Number.isFinite(h)&&h>0?Math.floor(h):null,A=async()=>{let b;for(let w=0;w<=u;w++){f?.throwIfAborted?.();try{return await Nr(e,{fetchImpl:r,method:o,headers:s,body:a,timeoutMs:n,lookupFn:l,realFetch:d,untrustedUrl:p,maxResponseBytes:y,importUndici:c,validateResponse:i,signal:f})}catch(g){b=g;let S=g?.status,N=g?.name==="AbortError"||g?.name==="TimeoutError"||f?.aborted,C=new Set([408,425,429]),k=g?.retryable===!1?!1:S!=null?C.has(S)||hr.has(S)&&Ze.has(o):!N&&Ze.has(o);if(w===u||!k)throw g;let P=Ir(w,g?.retryAfter);f?await new Promise((_,O)=>{let Ee=setTimeout(_,P);f.addEventListener("abort",()=>{clearTimeout(Ee),O(f.reason||new DOMException("Aborted","AbortError"))},{once:!0})}):await _r(P)}}throw b};if(!(t.dedupe!==!1&&!f&&o==="GET"&&a==null))return A();let x=Sr(o,e,s,{untrustedUrl:p,maxResponseBytes:y}),I=Ne.get(x);if(I)return I;let m=A().finally(()=>Ne.delete(x));return Ne.set(x,m),m}var hr,Ze,br,Qe,nt,wr,et,gr,Ne,_r,Te=R(()=>{Je();hr=new Set([408,425,429,500,502,503,504]),Ze=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),br=2,Qe=4e3,nt=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],wr=new Set([301,302,303,307,308]),et=3,gr=64*1024;Ne=new Map;_r=e=>new Promise(t=>setTimeout(t,e))});function Re(e){return ot.get(Number(e))||null}function st(e,t=process.env){let r=Re(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}function it(e){return ot.has(Number(e))}var ke,ot,at=R(()=>{ke={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}},ot=new Map(Object.values(ke).map(e=>[e.chainId,e]))});var ut={};Ke(ut,{PUBLIC_RPC_FALLBACKS:()=>$e,erc20Allowance:()=>Dr,erc20BalanceOf:()=>vr,resolveRpcUrl:()=>Le,rpcBlockNumber:()=>Pe,rpcCall:()=>T,rpcChainId:()=>$r,rpcGasPrice:()=>Lr,rpcGetBalance:()=>Pr,rpcHealth:()=>ct,rpcHealthAll:()=>Fr,transactionReceipt:()=>Mr});import{Interface as Or,getAddress as Tr}from"ethers";function W(e,t){try{return Tr(e).toLowerCase()}catch{throw new Error(`${t} must be a valid EVM address`)}}function kr(e){let t=String(e||"").trim();if(!/^0x[0-9a-fA-F]{64}$/.test(t))throw new Error("txHash must be a 32-byte hex transaction hash");return t.toLowerCase()}function Be(e){return e==null?null:Number.parseInt(String(e),16)}function Le(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=st(e,r);return n||$e[Number(e)]||null}function Br(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}async function T(e,t,r=[],n={}){let o=String(t||"");Br(o);let s=Le(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let u=await ne(s,{method:"POST",body:{jsonrpc:"2.0",id:1,method:t,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3,signal:n.signal});if(u?.error){let l=new Error(u.error.message||JSON.stringify(u.error));throw l.code=u.error.code,l}return u.result}async function ct(e,t={}){let r=await T(e,"eth_blockNumber",[],t),n=parseInt(r,16),o=await T(e,"eth_chainId",[],t),s=parseInt(o,16);return{ok:Number.isFinite(n)&&s===Number(e),chainId:Number(e),reportedChainId:s,blockNumber:n,name:Re(e)?.name||null}}async function Pe(e,t={}){let r=await T(e,"eth_blockNumber",[],t);return parseInt(r,16)}async function $r(e,t={}){let r=await T(e,"eth_chainId",[],t);return parseInt(r,16)}async function Lr(e,t={}){let r=await T(e,"eth_gasPrice",[],t);if(r==null)return null;try{return BigInt(r)}catch{return null}}async function Pr(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await T(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function Dr(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=W(e.token||e.tokenAddress,"token"),o=W(e.owner,"owner"),s=W(e.spender,"spender"),a=oe.encodeFunctionData("allowance",[o,s]),u=await T(r,"eth_call",[{to:n,data:a},e.blockTag||"latest"],t),l=oe.decodeFunctionResult("allowance",u),d=BigInt(l[0]);return{chainId:r,token:n,owner:o,spender:s,allowance:d.toString(),allowanceHex:`0x${d.toString(16)}`,blockTag:e.blockTag||"latest"}}async function vr(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=W(e.token||e.tokenAddress,"token"),o=W(e.account||e.owner||e.address,"account"),s=oe.encodeFunctionData("balanceOf",[o]),a=await T(r,"eth_call",[{to:n,data:s},e.blockTag||"latest"],t),u=oe.decodeFunctionResult("balanceOf",a),l=BigInt(u[0]);return{chainId:r,token:n,account:o,balance:l.toString(),balanceHex:`0x${l.toString(16)}`,blockTag:e.blockTag||"latest"}}async function Mr(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=kr(e.txHash||e.hash||e.transactionHash),o=await T(r,"eth_getTransactionReceipt",[n],t);if(!o)return{ok:!1,chainId:r,txHash:n,status:"pending",receipt:null,reason:"receipt pending"};let s=Be(o.status),a=s===1,u=s===1?"success":s===0?"reverted":"unknown",l=a?null:u==="reverted"?"transaction reverted":"unknown receipt status",d=e.expectedTo?W(e.expectedTo,"expectedTo"):null,p=o.to?W(o.to,"receipt.to"):null;return d&&p!==d&&(a=!1,l=`to mismatch: expected ${d}, got ${p||"null"}`),{ok:a,chainId:r,txHash:n,status:u,reason:l,statusCode:s,to:p,from:o.from?W(o.from,"receipt.from"):null,blockNumber:Be(o.blockNumber),transactionIndex:Be(o.transactionIndex),logs:Array.isArray(o.logs)?o.logs:[],receipt:o}}async function Fr(e={}){let t=e.chainIds||Object.values(ke).map(n=>n.chainId),r={};return await Promise.all(t.map(async n=>{if(!it(n)&&!$e[n]&&!Le(n,e)){r[n]={ok:!1,error:"no rpc configured",chainId:n};return}try{r[n]=await ct(n,e)}catch(o){r[n]={ok:!1,chainId:n,error:String(o.message||o)}}})),r}var oe,$e,Rr,se=R(()=>{Te();at();oe=new Or(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);$e={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"};Rr=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/});var Ct=R(()=>{});function pn(e,t,r){let n=D(t),o=D(r),s=D(e?.baseToken?.address),a=D(e?.quoteToken?.address);return s===n&&a===o||s===o&&a===n}function mn(e){let t=Number(e?.liquidity?.usd);return Number.isFinite(t)&&t>=0?t:null}function hn(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||ln).replace(/\/$/,"")}async function bn(e,t={}){if(!e)throw new Error("tokenAddress required");return ne(`${hn(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}async function Nt({chainId:e,tokenA:t,tokenB:r,dexIds:n=[]}={},o={}){if(e==null||!t||!r)throw new Error("chainId, tokenA, and tokenB required");let s=D(fn[Number(e)]||e),a=new Set(dn(n).filter(Boolean).map(D)),u=[...new Set([t,r].map(i=>String(i)).filter(Boolean))],l=await Promise.allSettled(u.map(i=>bn(i,{...o,baseUrl:o.dexscreenerBaseUrl,timeoutMs:o.dexscreenerTimeoutMs??Math.min(Number(o.timeoutMs??4e3),4e3)}))),d=new Set,p=[];for(let i of l)if(i.status==="fulfilled")for(let f of i.value?.pairs||i.value?.data?.pairs||[]){let h=`${D(f?.chainId)}:${D(f?.dexId)}:${D(f?.pairAddress)}`;d.has(h)||(d.add(h),p.push(f))}return p.filter(i=>D(i?.chainId)===s).filter(i=>pn(i,t,r)).filter(i=>!a.size||a.has(D(i?.dexId))).map(i=>({pairAddress:i.pairAddress??null,dexId:i.dexId??null,chainId:i.chainId??null,liquidityUsd:mn(i),pairCreatedAt:i.pairCreatedAt??null})).filter(i=>i.liquidityUsd!=null).sort((i,f)=>f.liquidityUsd-i.liquidityUsd)}var ln,fn,D,dn,Ot=R(()=>{Te();Ct();ln="https://api.dexscreener.com",fn=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"}),D=e=>String(e??"").toLowerCase(),dn=e=>Array.isArray(e)?e:e==null?[]:[e]});import{readFileSync as wn}from"node:fs";import{homedir as gn}from"node:os";import{join as ue}from"node:path";function En(){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){let r=(process.env.ORACLE_EXEC_ENV_FILE||"").trim();return r?[r]:[]}let e=(process.env.ORACLE_EXEC_ENV_FILE||process.env.MAD_EXEC_ENV_FILE||"").trim(),t=gn();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||ue(t,".config","oracle")).trim();return[e,ue(r,"exec.env")].filter(Boolean)}return[e,ue(t,".config","oracle","exec.env"),ue(t,".config","mad-desk","exec.env")].filter(Boolean)}function Tt(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of En())try{let s=wn(o,"utf8"),a=s.match(new RegExp(`^${t}=(.*)$`,"m"))||s.match(new RegExp(`^${r}=(.*)$`,"m"));if(a&&(n=a[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}var kt=R(()=>{});var Rt=R(()=>{});import{createHash as vo,createHmac as yn,timingSafeEqual as Mo}from"node:crypto";function qe(e){return Array.isArray(e)?`[${e.map(qe).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${qe(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function An(e,{required:t=!1}={}){try{return Tt(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function xn(e){let{signature:t,...r}=e;return r}function Sn(e,{secret:t}={}){let r=An(t);return r?{...e,signature:yn("sha256",r).update(qe(xn(e))).digest("hex")}:e}function We(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function In(e){let t=e==null?Bt:Number(e);if(!Number.isInteger(t)||t<0)throw new Error("auto-slippage cap must be a non-negative integer bps value");return Math.min(t,Bt)}function _n({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let s=We(e,0),a=s>0?s>=25e4?5:s>=1e5?10:s>=5e4?20:s>=1e4?40:70:n?30:10,u=Math.min(60,Math.abs(We(t,0))*2),l=Math.min(40,Math.floor(Math.max(0,We(r,0))/5e3)*5),d=Math.max(25,Math.ceil(20+a+u+l)),p=In(o);return{mode:"auto",requiredBps:d,selectedBps:Math.min(d,p),capBps:p,executable:d<=p}}function Cn({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:s=0,crossChain:a=!1,requestedCapBps:u,quotedAtMs:l=Date.now(),ttlMs:d=$t,secret:p}={}){let c=BigInt(r??0);if(c<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let i=_n({liquidityUsd:n,priceChange5m:o,quoteAgeMs:s,crossChain:a,requestedCapBps:u});if(!i.executable)throw new Error(`auto-slippage requires ${i.requiredBps} bps above hard/requested cap ${i.capBps}; route blocked`);let f=Number(l);if(!Number.isFinite(f))throw new Error("auto-slippage: quotedAtMs must be a finite number");let h=Math.min(3e4,Math.max(1e3,Number(d)||$t)),y=c*BigInt(1e4-i.selectedBps),A=y/10000n;if(y%10000n!==0n&&(A+=1n),A>c&&(A=c),c>0n&&A<=0n)throw new Error(`auto-slippage: quote ${c} is too small to express a ${i.selectedBps} bps floor without rounding to zero`);let E=Number((c-A)*10000n/(c===0n?1n:c));if(E>i.capBps)throw new Error(`auto-slippage: realised floor implies ${E} bps, above cap ${i.capBps} \u2014 refusing to issue a guard weaker than advertised`);return Sn({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:c.toString(),minAmountOut:A.toString(),requiredBps:i.requiredBps,selectedBps:i.selectedBps,capBps:i.capBps,quotedAtMs:f,expiresAtMs:f+h},{secret:p})}function Lt(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:a,requestedCapBps:u,quotedAtMs:l=Date.now(),ttlMs:d}={}){let p=Cn({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:a,requestedCapBps:u,quotedAtMs:l,ttlMs:d});return{...e,autoSlippage:p,amountOutMinimum:p.minAmountOut}}var Bt,$t,Pt=R(()=>{kt();Rt();Bt=100,$t=2e4});var qo,Ho,Dt=R(()=>{qo=300*1e3,Ho=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});import{Interface as Ft,getAddress as le,isAddress as Ut}from"ethers";function Bn(e,t){let r=Number(e),n=ee[r];if(!n)throw new Error(`uniswap-v3: unsupported chainId ${e} (supported: ${Object.keys(ee).join(", ")})`);let o=Rn[r]||{};if(!t){if(!n.quoter||!n.router){let l=Object.keys(o).join(", ")||"none registered";throw new Error(`uniswap-v3: chain ${r} (${n.name}) has no canonical Uniswap v3 deployment -- name a venue explicitly (known: ${l})`)}return{chainId:r,venue:n.name,...n}}let s=String(t).toLowerCase();if(s===n.name&&n.quoter&&n.router)return{chainId:r,venue:n.name,...n};let a=o,u=a[s];if(!u){let l=[...n.quoter&&n.router?[n.name]:[],...Object.keys(a)].join(", ");throw new Error(`uniswap-v3: unknown venue "${t}" on chain ${r} (known: ${l})`)}return{chainId:r,venue:s,...n,quoter:u.quoter,router:u.router,feeTiers:u.feeTiers||null}}function Mt(e,t){let r=ee[Number(t)];if(!e||e===Tn||e===kn||/^eth$/i.test(String(e)))return le(r.weth);let n=String(e);if(/^weth$/i.test(n))return le(r.weth);if(/^usdc$/i.test(n))return le(r.usdc);if(!Ut(n))throw new Error(`invalid token address: ${e}`);return le(n)}function $n(e){let t=String(e||"uniswap").toLowerCase();return t==="uniswap"?["uniswap-v3","uniswap"]:t==="pancakeswap"?["pancakeswap-v3","pancakeswap"]:t==="hyperswap"?["hyperswap-v3","hyperswap"]:[t,`${t}-v3`]}async function Wt(e={},t={}){let{chainId:r,quoter:n,router:o,feeTiers:s}=Bn(e.chainId??8453,e.venue),a=Mt(e.tokenIn||"WETH",r),u=Mt(e.tokenOut||ee[r].usdc,r),l=BigInt(e.amountIn??0);if(l<=0n)throw new Error("amountIn required (raw base units)");let d=s&&s.length?s:Nn,p=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[d[Math.min(2,d.length-1)]]:[...d],c=[],i=null;for(let w of p){let g=vt.encodeFunctionData("quoteExactInputSingle",[{tokenIn:a,tokenOut:u,amountIn:l,fee:w,sqrtPriceLimitX96:0n}]);try{let S=await T(r,"eth_call",[{to:n,data:g},"latest"],t);if(!S||S==="0x"){c.push({fee:w,ok:!1,error:"empty result"});continue}let N=vt.decodeFunctionResult("quoteExactInputSingle",S),C={fee:w,ok:!0,amountOut:N[0].toString(),sqrtPriceX96After:N[1].toString(),initializedTicksCrossed:Number(N[2]),gasEstimate:N[3].toString()};c.push(C),(!i||BigInt(C.amountOut)>BigInt(i.amountOut))&&(i=C)}catch(S){c.push({fee:w,ok:!1,error:String(S.message||S).slice(0,160)})}}if(!i){let w=c.map(g=>`${g.fee}:${g.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${w}`)}let f=e.liquidityUsd==null?await Nt({chainId:r,tokenA:a,tokenB:u,dexIds:$n(e.venue)},t).catch(()=>[]):[],h={};for(let w of f.slice(0,8))if(!(!w.pairAddress||!Ut(w.pairAddress)))try{let g=await T(r,"eth_call",[{to:w.pairAddress,data:On},"latest"],t),S=g&&g!=="0x"&&g.length<=66?Number.parseInt(g,16):NaN;if(!Number.isFinite(S)||S<=0||S>1e6)continue;(h[S]==null||w.liquidityUsd>h[S].liquidityUsd)&&(h[S]=w)}catch{}let y=e.liquidityBandBps==null?50:Number(e.liquidityBandBps),A=null;if(e.fee==null&&y>0&&BigInt(i.amountOut)>0n){let w=BigInt(i.amountOut),S=c.filter(N=>N.ok&&Number((w-BigInt(N.amountOut))*10000n/w)<=y).filter(N=>h[N.fee]?.liquidityUsd!=null).sort((N,C)=>h[C.fee].liquidityUsd-h[N.fee].liquidityUsd)[0];S&&S.fee!==i.fee&&(A={priceBestFee:i.fee,chosenFee:S.fee,chosenPoolUsd:h[S.fee].liquidityUsd,bandBps:y},i=S)}let E=h[i.fee]??null,x=f[0]??null,I=E??x,m=e.liquidityUsd??E?.liquidityUsd??x?.liquidityUsd??null,b=e.liquidityUsd!=null?"caller":E?"pool":x?"pair":null;return Lt({venue:"uniswap-v3",chainId:r,chain:ee[r].name,quoter:n,tokenIn:a,tokenOut:u,amountIn:l.toString(),fee:i.fee,amountOut:i.amountOut,gasEstimate:i.gasEstimate,liquidityUsd:m,liquiditySource:I,liquidityAttribution:b,liquidityPick:A,sqrtPriceX96After:i.sqrtPriceX96After,initializedTicksCrossed:i.initializedTicksCrossed,triedFees:c,best:!0},{chainId:r,venue:o,amountOut:i.amountOut,liquidityUsd:m,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}var ee,Nn,On,vt,Zo,Tn,kn,He,Rn,qt=R(()=>{se();Ot();Pt();Dt();ee={1:{name:"ethereum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},8453:{name:"base",quoter:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",router:"0x2626664c2603336E57B271c5C0b26F421741e481",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},4663:{name:"robinhood",quoter:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",router:"0xcaf681a66d020601342297493863e78c959e5cb2",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"},999:{name:"hyperevm",weth:"0x5555555555555555555555555555555555555555",usdc:"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"},10:{name:"optimism",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",quoter:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",router:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},43114:{name:"avalanche",quoter:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",router:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}},Nn=[100,500,3e3,1e4],On="0xddca3f43",vt=new Ft(["function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)","function quoteExactInput(bytes path, uint256 amountIn) returns (uint256 amountOut, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)"]),Zo=new Ft(["function exactInputSingle((address tokenIn,address tokenOut,uint24 fee,address recipient,uint256 amountIn,uint256 amountOutMinimum,uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)","function multicall(uint256 deadline,bytes[] data) payable returns (bytes[] results)"]),Tn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",kn="0x0000000000000000000000000000000000000000",He=[100,500,2500,1e4],Rn={56:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:He}},8453:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:He}},42161:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:He}},999:{hyperswap:{name:"hyperswap",quoter:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",router:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D"}}}});var Xt={};Ke(Xt,{ARB_UNI_FEE_TIERS:()=>Vt,collectArbRoundTripCycles:()=>vn});function je(e,{positive:t=!1}={}){return typeof e=="string"&&/^(?:0|[1-9][0-9]*)$/.test(e)&&(!t||e!=="0")&&BigInt(e)<=Ln}function Ht(e){if(!je(e,{positive:!0})){let t=typeof e=="string"&&/^[1-9][0-9]*$/.test(e)?" and fit uint256":"";throw new TypeError(`amountInWei must be a positive strict decimal string${t}`)}return e}function jt(e,t){let r=e?.amountOut;if(!je(r,{positive:!0}))throw new Error(`${t} returned an invalid amountOut`);return r}function zt(e,t){let r=e?.gasEstimate??e?.gasUnits;if(!je(r))throw new Error(`${t} returned invalid gas units`);return r}function fe(e,t,r,n,o,s){return{status:"UNAVAILABLE",entryVenue:e,exitVenue:t,amountInWei:r,intermediateAmountBase:n,amountOutWei:null,gasUnits:null,source:o,error:String(s?.message||s)}}function Gt(e){return`uniswap-v3-${e}`}async function Pn({entryFee:e,exitFee:t,amountInWei:r,blockTag:n,quoteUniswap:o}){let s=Gt(e),a=Gt(t),u;try{u=await o({chainId:te,tokenIn:"WETH",tokenOut:"USDC",amountIn:r,fee:e,tryFees:!1,blockTag:n})}catch(c){return fe(s,a,r,null,{},c)}let l,d;try{l=jt(u,s),d=zt(u,s)}catch(c){return fe(s,a,r,null,{entry:{venue:"uniswap-v3",fee:e}},c)}let p;try{p=await o({chainId:te,tokenIn:"USDC",tokenOut:"WETH",amountIn:l,fee:t,tryFees:!1,blockTag:n})}catch(c){return fe(s,a,r,l,{entry:{venue:"uniswap-v3",fee:e}},c)}try{let c=jt(p,a),i=(BigInt(d)+BigInt(zt(p,a))).toString();return{status:"OK",entryVenue:s,exitVenue:a,amountInWei:r,intermediateAmountBase:l,amountOutWei:c,gasUnits:i,source:{entry:{venue:"uniswap-v3",fee:e},exit:{venue:"uniswap-v3",fee:t}}}}catch(c){return fe(s,a,r,l,{entry:{venue:"uniswap-v3",fee:e},exit:{venue:"uniswap-v3",fee:t}},c)}}async function Dn(e){let t=await T(te,"eth_gasPrice",[],e);return BigInt(t).toString()}async function vn(e={}){let t=Ht(e.amountInWei),r=e.quoteUniswap??(y=>Wt(y,e)),n=e.getBlockNumber??(()=>Pe(te,e)),o=e.getGasPriceWei??(()=>Dn(e)),s=e.now??(()=>new Date().toISOString()),a=e.maxBlockDrift??1,u=Array.isArray(e.feeTiers)&&e.feeTiers.length?e.feeTiers.map(Number):[...Vt];if(!Number.isSafeInteger(a)||a<0)throw new TypeError("maxBlockDrift must be a non-negative safe integer");for(let y of u)if(![100,500,3e3,1e4].includes(y))throw new TypeError(`unsupported Uni fee tier: ${y}`);let l=e.pinnedBlock??await n();if(!Number.isSafeInteger(l)||l<0)throw new Error("block provider returned invalid height");let d=`0x${l.toString(16)}`,p=Ht(await o()),c=[];for(let y of u)for(let A of u)y!==A&&c.push({entryFee:y,exitFee:A});let i=await Promise.all(c.map(({entryFee:y,exitFee:A})=>Pn({entryFee:y,exitFee:A,amountInWei:t,blockTag:d,quoteUniswap:r}))),f=await n();if(!Number.isSafeInteger(f)||f<0)throw new Error("block provider returned invalid height");let h=Math.abs(f-l);return{mode:"shadow",executionReady:!1,chainId:te,pair:"WETH-USDC",capturedAt:s(),amountInWei:t,blockStart:l,blockEnd:f,pinnedBlock:l,blockTag:d,blockConsistency:"PINNED",blockDrift:h,maxBlockDrift:a,stale:h>a,gasPriceWei:p,cycles:i,venueNote:"uniswap-v3-fee-tiers-only; camelot/pancake deferred"}}var te,Ln,Vt,Kt=R(()=>{se();qt();te=42161,Ln=(1n<<256n)-1n,Vt=Object.freeze([100,500,3e3])});import{homedir as Qn}from"node:os";import{isAbsolute as eo,join as to}from"node:path";var De=Object.freeze({premium:"0x074b2e43",provider:"0x0542975c",reserves:"0xd1946dbc"}),ft=/^0x[0-9a-fA-F]{64}$/,Ur=/^0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)$/,Wr=256,qr=100;async function Hr(...e){let{rpcCall:t}=await Promise.resolve().then(()=>(se(),ut));return t(...e)}function ve(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))ve(t);Object.freeze(e)}return e}var M=ve({chainId:42161,pool:"0x794a61358D6845594F94dc1DB02A252b5b4814aD",addressesProvider:"0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb",WETH:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",USDC:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",requiredReserves:["0x82aF49447D8a07e3bd95BD0d56f35241523fBab1","0xaf88d065e77c8cC2239327C5EDb3A432268e5831"],observedPremiumBps:5});function jr(e){if(typeof e!="string"||!Ur.test(e))throw new Error("malformed eth_blockNumber result");let t=BigInt(e);if(t>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("malformed eth_blockNumber result: outside safe range");return Number(t)}function zr(e,t){if(typeof e!="string"||!ft.test(e))throw new Error(`malformed ${t} result`);return BigInt(e)}function dt(e,t){if(typeof e!="string"||!ft.test(e)||e.slice(2,26)!=="0".repeat(24))throw new Error(`malformed ${t} result`);return`0x${e.slice(26).toLowerCase()}`}function Gr(e){if(typeof e!="string"||!/^0x[0-9a-fA-F]+$/.test(e)||e.length<130)throw new Error("malformed getReservesList result");let t=e.slice(2);if(t.length%64!==0||BigInt(`0x${t.slice(0,64)}`)!==32n)throw new Error("malformed getReservesList result");let r=BigInt(`0x${t.slice(64,128)}`);if(r>BigInt(Wr)||r>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("malformed getReservesList result: unreasonable reserve count");let n=Number(r);if(t.length!==128+n*64)throw new Error("malformed getReservesList result: invalid length");let o=[];for(let s=0;s<n;s+=1){let a=`0x${t.slice(128+s*64,192+s*64)}`;o.push(dt(a,"getReservesList address"))}return o}function lt(e,t,r,n){return ve({mode:"shadow",executionReady:!1,status:e,chainId:M.chainId,block:t,premiumBps:r,reasons:n})}async function pt(e={}){let t=e.rpc??Hr;if(typeof t!="function")throw new TypeError("rpc must be a function");let r=null,n=null;try{let o=await t(M.chainId,"eth_blockNumber",[],e);r=jr(o);let s=c=>t(M.chainId,"eth_call",[{to:M.pool,data:c},o],e),a=zr(await s(De.premium),"FLASHLOAN_PREMIUM_TOTAL");if(a>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("malformed FLASHLOAN_PREMIUM_TOTAL result: outside safe range");n=Number(a);let u=dt(await s(De.provider),"ADDRESSES_PROVIDER"),l=Gr(await s(De.reserves)),d=[];n>qr?d.push(`premium ${n} bps exceeds reasonable bound`):n!==M.observedPremiumBps&&d.push(`premium ${n} bps differs from observed ${M.observedPremiumBps} bps`),u!==M.addressesProvider.toLowerCase()&&d.push(`addresses provider mismatch: received ${u}`);let p=new Set(l);for(let[c,i]of[["WETH",M.WETH],["USDC",M.USDC]])p.has(i.toLowerCase())||d.push(`${c} required reserve is missing`);return lt(d.length===0?"AVAILABLE":"MISMATCH",r,n,d)}catch(o){return lt("UNAVAILABLE",r,n,[String(o?.message||o)])}}var Vr=/^(?:0|[1-9][0-9]*)$/,mt=10000n,Me=(1n<<256n)-1n;function B(e,t="value"){let r;if(typeof e=="bigint"&&e>=0n)r=e;else if(typeof e=="string"&&Vr.test(e))r=BigInt(e);else throw new TypeError(`${t} must be a non-negative plain decimal string or bigint`);if(r>Me)throw new RangeError(`${t} must fit uint256`);return r}function ie(e,t){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?BigInt(e):B(e,t)}function Xr(e,t){let r=B(e,"amount"),n=ie(t,"basisPoints");if(n>mt)throw new RangeError("basisPoints must be at most 10000");let o=r*n;return o===0n?0n:(o-1n)/mt+1n}function Z(e){if(typeof e!="bigint")throw new TypeError("value must be a bigint");return e.toString(10)}function ht(e,t){if(e===null||typeof e!="object"||Array.isArray(e))throw new TypeError(`${t} must be an object`);return e}function bt(e){for(let t of Object.values(e))t!==null&&typeof t=="object"&&!Object.isFrozen(t)&&bt(t);return Object.freeze(e)}function wt(e,t){ht(e,"cycle"),ht(t,"policy");let r=B(e.amountInWei,"cycle.amountInWei"),n=B(e.amountOutWei,"cycle.amountOutWei"),o=ie(e.gasUnits,"cycle.gasUnits"),s=B(e.gasPriceWei,"cycle.gasPriceWei"),a=ie(t.loanPremiumBps,"policy.loanPremiumBps"),u=B(t.builderFeeWei,"policy.builderFeeWei"),l=B(t.extraCostWei,"policy.extraCostWei"),d=B(t.minProfitWei,"policy.minProfitWei"),p=B(t.maxGasWei,"policy.maxGasWei"),c=B(t.maxLoanWei,"policy.maxLoanWei");ie(t.maxBlockDrift,"policy.maxBlockDrift");let i=n-r,f=o*s;if(f>Me)throw new RangeError("gas cost must fit uint256");let h=Xr(r,a),y=f+h+u+l;if(y>Me)throw new RangeError("total cost must fit uint256");let A=i-y,E=A>=d&&f<=p&&r<=c;return bt({grossProfitWei:Z(i),gasCostWei:Z(f),loanPremiumWei:Z(h),totalCostWei:Z(y),netProfitWei:Z(A),status:E?"PROFITABLE":"UNPROFITABLE",executionReady:!1,mode:"shadow"})}var Kr=/^(?:0|[1-9][0-9]*)$/,Yr=(1n<<256n)-1n;function Q(e){let t=null;return typeof e=="bigint"&&e>=0n&&(t=e),typeof e=="string"&&Kr.test(e)&&(t=BigInt(e)),t!==null&&t<=Yr?t:null}function ae(e){return typeof e=="string"&&e.length>0?e:null}function Fe(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")?e:null}function $(e,t){e.push(`MALFORMED_${t.replaceAll(/[^A-Za-z0-9]+/g,"_").toUpperCase()}`)}function Jr(e){return Object.freeze(e.reasonCodes),Object.freeze(e)}function gt(e,t,r){let n=[],o=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{},s=t!==null&&typeof t=="object"&&!Array.isArray(t)?t:{},a=r!==null&&typeof r=="object"&&!Array.isArray(r)?r:{},u=ae(o.chainId),l=ae(a.chainId),d=ae(o.lender),p=ae(o.strategy),c=Fe(s.supportedChainIds),i=Fe(s.allowedLenders),f=Fe(s.allowedStrategies);u||$(n,"chainId"),l||$(n,"opts.chainId"),u&&l&&u!==l&&n.push("CHAIN_MISMATCH"),c?(!u||!c.includes(u))&&n.push("UNSUPPORTED_CHAIN"):$(n,"supportedChainIds"),d||$(n,"lender"),i?(!d||!i.includes(d))&&n.push("LENDER_NOT_ALLOWED"):$(n,"allowedLenders"),p||$(n,"strategy"),f?(!p||!f.includes(p))&&n.push("STRATEGY_NOT_ALLOWED"):$(n,"allowedStrategies");let h=Q(o.blockNumber),y=Q(a.currentBlock),A=Q(s.maxBlockDrift);h===null&&$(n,"blockNumber"),y===null&&$(n,"opts.currentBlock"),A===null&&$(n,"maxBlockDrift"),h!==null&&y!==null&&A!==null&&(h>y||y-h>A)&&n.push("STALE_BLOCK"),o.simulationStatus!=="PASS"&&n.push("SIMULATION_NOT_PASS"),o.repaymentStatus!=="PASS"&&n.push("REPAYMENT_NOT_PASS");let E=[["realizedProfitWei","minRealizedProfitWei","PROFIT_BELOW_MINIMUM",(m,b)=>m<b],["gasCostWei","maxGasWei","GAS_LIMIT_EXCEEDED",(m,b)=>m>b],["builderFeeWei","maxBuilderFeeWei","BUILDER_FEE_EXCEEDED",(m,b)=>m>b],["loanPremiumWei","maxLoanPremiumWei","LOAN_PREMIUM_EXCEEDED",(m,b)=>m>b],["loanAmountWei","maxLoanWei","LOAN_LIMIT_EXCEEDED",(m,b)=>m>b]],x={};for(let[m,b,w,g]of E){let S=Q(o[m]),N=Q(s[b]);x[m]=S,S===null&&$(n,m),N===null&&$(n,b),S!==null&&N!==null&&g(S,N)&&n.push(w)}a.armed!==!1&&n.push("NOT_DISARMED");let I={status:n.length===0?"ELIGIBLE":"BLOCKED",reasonCodes:[...new Set(n)],executionReady:!1,mode:"shadow"};return u&&(I.chainId=u),d&&(I.lender=d),p&&(I.strategy=p),h!==null&&(I.blockNumber=h.toString(10)),x.realizedProfitWei!==null&&(I.realizedProfitWei=x.realizedProfitWei.toString(10)),Jr(I)}function q(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))q(t);Object.freeze(e)}return e}function ce(e){return e instanceof Error&&e.message?e.message.slice(0,300):String(e||"unknown error").slice(0,300)}function Zr(e,t){for(let r of[e?.cycleId,e?.id])if(typeof r=="string"&&r.trim())return r.trim().slice(0,160);return`cycle-${t}`}function Qr(e,t){if(!e||typeof e!="object"||e.profitable===!1)return!1;if(typeof t=="function")return t(e)===!0;if(typeof t?.isProfitable=="function")return t.isProfitable(e)===!0;let r=Number(t?.minNetProfitUsd??0);return Number.isFinite(e.netProfitUsd)&&e.netProfitUsd>=(Number.isFinite(r)?r:0)}function Et({collectCycles:e,evaluateCycle:t,store:r,policy:n={},intervalMs:o=6e4,now:s=Date.now}={}){if(typeof e!="function")throw new Error("collectCycles must be a function");if(typeof t!="function")throw new Error("evaluateCycle must be a function");if(!r||typeof r.append!="function"||typeof r.latest!="function")throw new Error("store must provide append() and latest()");if(!Number.isInteger(o)||o<=0)throw new Error("intervalMs must be a positive integer");if(typeof s!="function")throw new Error("now must be a function");let a=null,u=!1,l=0,d=0,p=null,c=[];function i(){return q({mode:"shadow",execution:!1,signer:!1,broadcaster:!1,running:a!==null,inFlight:u,ticks:l,failures:d,lastError:p})}async function f(){if(u)return q({ok:!1,skipped:"overlap"});u=!0;let I=s(),m=[],b=[],w=[],g=[],S=[];try{try{let C=await e();if(!Array.isArray(C))throw new Error("collectCycles must return an array");S=C}catch(C){m.push({stage:"collect",message:ce(C)})}for(let C=0;C<S.length;C+=1){let k=S[C],P=Zr(k,C);b.push({id:P});try{let _=await t(k,n),O={..._,cycleId:_?.cycleId??P};w.push(O),Qr(_,n)&&g.push({...O,profitable:!0})}catch(_){m.push({stage:"evaluate",cycleId:P,message:ce(_)})}}let N={id:`shadow-${I}-${l+1}`,observedAt:I,cyclesEvaluated:S.length,cycles:b,candidates:w,opportunities:g,errors:m};try{await r.append(N)}catch(C){m.push({stage:"persist",message:ce(C)})}return l+=1,m.length?(d+=1,p=m.map(C=>C.message).join("; ")):p=null,c=r.latest()?.opportunities??q(structuredClone(g)),q({ok:m.length===0,observation:r.latest()??N})}catch(N){return l+=1,d+=1,p=ce(N),q({ok:!1,error:p})}finally{u=!1}}function h(){return a!==null?!1:(a=setInterval(()=>f().catch(()=>{}),o),!0)}function y(){return a===null?!1:(clearInterval(a),a=null,!0)}async function A({timeoutMs:I=3e4}={}){if(!Number.isInteger(I)||I<=0)throw new Error("timeoutMs must be a positive integer");let m=Date.now()+I;for(;u;){if(Date.now()>=m)throw new Error("shadow engine drain timed out");await new Promise(b=>setTimeout(b,5))}return typeof r.drain=="function"&&await r.drain(),!0}function E(){return r.latest()}function x(){return q(structuredClone(c))}return q({tick:f,start:h,stop:y,drain:A,status:i,latest:E,opportunities:x})}import{mkdir as en,open as yt,readFile as At,rename as tn,unlink as rn}from"node:fs/promises";import{dirname as nn,basename as on,join as sn}from"node:path";var an=1e3;function G(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))G(t);Object.freeze(e)}return e}function Ue(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function V(e,t=300){return typeof e=="string"&&e.trim()?e.trim().slice(0,t):void 0}function cn(e){if(!e||typeof e!="object")return null;let t={},r=V(e.stage,30),n=V(e.message,300),o=V(e.cycleId,160);return r&&(t.stage=r),n&&(t.message=n),o&&(t.cycleId=o),Object.keys(t).length?t:null}function xt(e,{signed:t=!1,max:r=96}={}){return typeof e!="string"||e.length>r?void 0:(t?/^-?(?:0|[1-9][0-9]*)$/:/^(?:0|[1-9][0-9]*)$/).test(e)?e:void 0}function St(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of["cycleId","chain","pair","tokenIn","tokenOut","strategy","venue","lender","qualification","economicStatus","eligibilityStatus","costModel","blockConsistency"]){let n=V(e[r],160);n&&(t[r]=n)}for(let r of["netProfitUsd","grossProfitUsd","costUsd","gasCostUsd","confidence"]){let n=Ue(e[r]);n!==void 0&&(t[r]=n)}for(let r of["amountInWei","amountOutWei","gasUnits","gasCostWei","loanPremiumWei","totalCostWei"]){let n=xt(e[r]);n!==void 0&&(t[r]=n)}for(let r of["grossProfitWei","netProfitWei"]){let n=xt(e[r],{signed:!0});n!==void 0&&(t[r]=n)}return["PROFITABLE","UNPROFITABLE","STALE","UNAVAILABLE","THEORETICAL"].includes(e.status)&&(t.status=e.status),typeof e.profitable=="boolean"&&(t.profitable=e.profitable),typeof e.economicallyProfitable=="boolean"&&(t.economicallyProfitable=e.economicallyProfitable),e.executionReady===!1&&(t.executionReady=!1),Array.isArray(e.reasonCodes)&&(t.reasonCodes=e.reasonCodes.map(r=>V(r,80)).filter(Boolean).slice(0,32)),Object.keys(t).length?t:null}function un(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of["id","cycleId","chain","tokenIn","tokenOut","strategy"]){let n=V(e[r],160);n&&(t[r]=n)}return Object.keys(t).length?t:null}function It(e,t){let r=e&&typeof e=="object"&&!Array.isArray(e)?e:{},n=Ue(r.observedAt)??Ue(r.timestamp)??t(),o=V(r.id,160)??`shadow-${n}`,s=Array.isArray(r.cycles)?r.cycles.map(un).filter(Boolean):[],a=Array.isArray(r.opportunities)?r.opportunities.map(St).filter(Boolean):[],u=Array.isArray(r.candidates)?r.candidates.map(St).filter(Boolean):[],l=Array.isArray(r.errors)?r.errors.map(cn).filter(Boolean):[];return{id:o,observedAt:n,mode:"shadow",cyclesEvaluated:Number.isInteger(r.cyclesEvaluated)&&r.cyclesEvaluated>=0?r.cyclesEvaluated:s.length,cycles:s,candidates:u,opportunities:a,errors:l}}function _t({filePath:e,maxRecords:t=an,now:r=Date.now,persist:n=!0}={}){if(!Number.isInteger(t)||t<=0)throw new Error("maxRecords must be a positive integer");if(typeof r!="function")throw new Error("now must be a function");if(typeof n!="boolean")throw new Error("persist must be a boolean");if(n&&(typeof e!="string"||!e.trim()))throw new Error("filePath is required when persistence is enabled");let o=[],s=Promise.resolve(),a=()=>G(structuredClone(o));async function u(E){let x=JSON.parse(await At(E,"utf8")),I=Array.isArray(x)?x:x?.records;if(!Array.isArray(I))throw new Error("shadow store payload is malformed");return I.map(m=>It(m,r)).slice(-t)}async function l(){if(!n)return a();let E=s.then(async()=>{try{o=await u(e)}catch(x){if(x?.code==="ENOENT")try{o=await u(`${e}.bak`)}catch(I){if(I?.code==="ENOENT")o=[];else throw new Error("shadow store backup is corrupted")}else try{o=await u(`${e}.bak`)}catch{throw new Error("shadow store primary and backup are corrupted")}}return a()});return s=E.catch(()=>{}),E}let d=0;async function p(E,x){let I=nn(E),m=sn(I,`.${on(E)}.${process.pid}.${Date.now()}.${d+=1}.tmp`);await en(I,{recursive:!0,mode:448});let b;try{b=await yt(m,"wx",384),await b.writeFile(x,"utf8"),await b.sync(),await b.close(),b=null,await tn(m,E);let w=await yt(I,"r");try{await w.sync()}finally{await w.close()}}finally{b&&await b.close().catch(()=>{}),await rn(m).catch(()=>{})}}async function c(E){try{let x=await At(e,"utf8"),I=JSON.parse(x);if(!Array.isArray(I)&&!Array.isArray(I?.records))throw new Error("shadow store payload is malformed");await p(`${e}.bak`,x)}catch(x){if(x?.code!=="ENOENT")throw new Error("refusing to overwrite corrupted shadow store")}await p(e,`${JSON.stringify({version:1,records:E})}
|
|
4
|
-
`)}async function i(E){let x=It(E,r),I=s.then(async()=>{let m=[...o,x].slice(-t);return n&&await c(m),o=m,G(structuredClone(x))});return s=I.catch(()=>{}),I}async function f(){return await s,!0}function h({limit:E}={}){let x=Number.isInteger(E)&&E>=0?o.slice(-E):o;return G(structuredClone(x))}function y(){let E=o.at(-1);return E?G(structuredClone(E)):null}function A(){return G({records:o.length,maxRecords:t,candidates:o.reduce((E,x)=>E+x.candidates.length,0),opportunities:o.reduce((E,x)=>E+x.opportunities.length,0),errors:o.reduce((E,x)=>E+x.errors.length,0)})}return G({append:i,record:i,load:l,drain:f,list:h,latest:y,stats:A})}var Mn=/^(?:0|[1-9][0-9]*)$/,de="42161",Yt="arbitrum",Jt="WETH-USDC",pe="arb-weth-usdc-uni-fee-round-trip",me="aave-v3";async function Fn(e){let{collectArbRoundTripCycles:t}=await Promise.resolve().then(()=>(Kt(),Xt));return t(e)}function F(e,t,{positive:r=!1}={}){if(typeof e!="string"||!Mn.test(e)||r&&e==="0")throw new TypeError(`${t} must be ${r?"a positive":"a non-negative"} decimal string`);return B(e,t),e}function ze(e,t,r,n){if(!Number.isSafeInteger(e)||e<r||e>n)throw new TypeError(`${t} must be an integer from ${r} through ${n}`);return e}function H(e){return e==null?e:structuredClone(e)}function L(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))L(t);Object.freeze(e)}return e}function Un(e){return String(e?.message||e||"unknown provider failure").slice(0,300)}function Zt(e={}){let t=F(e.amountInWei,"amountInWei",{positive:!0}),r=F(e.minProfitWei,"minProfitWei"),n=F(e.maxLoanWei,"maxLoanWei"),o=F(e.maxGasWei,"maxGasWei"),s=F(e.builderFeeWei,"builderFeeWei"),a=F(e.extraCostWei,"extraCostWei"),u=F(e.extraGasUnits,"extraGasUnits"),l=ze(e.intervalMs,"intervalMs",1,864e5),d=ze(e.maxBlockDrift,"maxBlockDrift",0,1e3),p=ze(e.maxRecords,"maxRecords",1,1e5),c=e.dependencies??{},i=e.collectCycles??c.collectArbRoundTripCycles??Fn,f=e.readLenderState??c.readArbAaveLenderState??pt,h=e.evaluateEconomics??c.evaluateCycleEconomics??wt,y=e.evaluateEligibility??c.evaluateFlashLoanCandidate??gt,A=e.createEngine??c.createShadowEngine??Et,E=e.createStore??c.createShadowStore??_t;for(let[_,O]of Object.entries({collect:i,readLender:f,evaluateEconomics:h,evaluateEligibility:y,makeEngine:A,makeStore:E}))if(typeof O!="function")throw new TypeError(`${_} dependency must be a function`);let x=E({filePath:e.filePath,persist:e.persist??!0,maxRecords:p,now:e.now??Date.now}),I=[],m=null,b=null,w=null,g=L({async append(_){return await x.append(_),I=[...I,L(H(_))].slice(-p),L(H(_))},async drain(){return typeof x.drain=="function"&&await x.drain(),!0},latest(){return I.length?L(H(I.at(-1))):null}});async function S(){try{w=await f(e.lenderOptions??e)}catch(_){w={status:"UNAVAILABLE",block:null,premiumBps:null,reasons:[Un(_)]}}if(m=L(H(w)),!w||w.status!=="AVAILABLE")throw new Error(`lender ${w?.status?.toLowerCase()||"unavailable"}: ${(w?.reasons||[]).join("; ")}`);if(!Number.isSafeInteger(w.block)||!Number.isSafeInteger(w.premiumBps)||w.premiumBps<0)throw new Error("lender returned malformed live state");if(b=await i({...e.collectorOptions,amountInWei:t,maxBlockDrift:d,pinnedBlock:w.block}),!b||!Array.isArray(b.cycles))throw new Error("quote provider returned malformed snapshot");if(b.stale===!0||b.blockDrift>d)throw new Error("stale quote snapshot");if(!Number.isSafeInteger(b.blockEnd)||Math.abs(b.blockEnd-w.block)>d)throw new Error("stale lender snapshot relative to quotes");return F(b.gasPriceWei,"quoteSnapshot.gasPriceWei",{positive:!0}),b.cycles}async function N(_){if(!_||_.status!=="OK")throw new Error(_?.error||"cycle quote unavailable");let O=(BigInt(F(_.gasUnits,"cycle.gasUnits"))+BigInt(u)).toString(),Ee={..._,gasUnits:O,gasPriceWei:b.gasPriceWei},v=await h(Ee,{loanPremiumBps:w.premiumBps,builderFeeWei:s,extraCostWei:a,minProfitWei:r,maxGasWei:o,maxLoanWei:n,maxBlockDrift:d}),ye=await y({chainId:de,lender:me,strategy:pe,blockNumber:String(b.blockEnd),realizedProfitWei:v.netProfitWei.startsWith("-")?"0":v.netProfitWei,gasCostWei:v.gasCostWei,builderFeeWei:s,loanPremiumWei:v.loanPremiumWei,loanAmountWei:_.amountInWei},{supportedChainIds:[de],allowedLenders:[me],allowedStrategies:[pe],maxBlockDrift:String(d),minRealizedProfitWei:r,maxGasWei:o,maxBuilderFeeWei:s,maxLoanPremiumWei:v.loanPremiumWei,maxLoanWei:n},{chainId:de,currentBlock:String(b.blockEnd),armed:!1}),Xe=[...new Set([...ye.reasonCodes,"L1_DATA_FEE_NOT_MODELED","EXECUTOR_GAS_NOT_SIMULATED","LENDER_LIQUIDITY_NOT_CHECKED","CROSS_VENUE_CAMELOT_PANCAKE_NOT_QUOTED",...b.blockConsistency==="PINNED"?[]:["QUOTE_BLOCK_NOT_PINNED"]])],cr=v.status==="PROFITABLE"&&ye.status==="ELIGIBLE"&&Xe.length===0;return L({cycleId:`${_.entryVenue||"unknown"}->${_.exitVenue||"unknown"}`,chain:Yt,pair:Jt,strategy:pe,lender:me,amountInWei:_.amountInWei,amountOutWei:_.amountOutWei,gasUnits:O,...v,status:"THEORETICAL",economicStatus:v.status,economicallyProfitable:v.status==="PROFITABLE",qualification:"THEORETICAL_ONLY",eligibilityStatus:ye.status,reasonCodes:Xe,costModel:"INCOMPLETE_ESTIMATE",blockConsistency:b.blockConsistency??"RANGE_ONLY",profitable:cr,executionReady:!1,mode:"shadow"})}let C=A({collectCycles:S,evaluateCycle:N,store:g,policy:{isProfitable:_=>_?.profitable===!0},intervalMs:l,now:e.now??Date.now});async function k(){let _=await x.load();return I=H(_).slice(-p),L(H(I))}function P(){return L({mode:"shadow",execution:!1,signer:!1,broadcaster:!1,chain:Yt,chainId:de,pair:Jt,strategy:pe,lender:me,...C.status(),lastProviderState:L(H(m))})}return L({load:k,tick:C.tick,start:C.start,stop:C.stop,drain:C.drain,status:P,latest:g.latest,opportunities:()=>L(H(g.latest()?.opportunities??[]))})}import{createServer as jn}from"node:http";var cs=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),us=Object.freeze(["read","simulate"]);var ls=1440*60;var U=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}},Wn=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,qn=Object.freeze(["privkey","wif","xprv","seed"]);function Ge(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return Wn.test(t)||qn.includes(r)}var Qt=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}]),er=Object.freeze(["grantid","id","hash","sha256","sha256hex","checksum","txhash","transactionhash","blockhash","digest","userophash","commithash","prevhash","intenthash","canonicalhash","payloadhash","requestid"]);function Hn(e){return e.replace(/"([A-Za-z0-9_-]+)"\s*:\s*"(?:0x)?([0-9a-fA-F]{64})"/g,(t,r)=>er.includes(String(r).toLowerCase().replace(/[_-]/g,""))?`"${r}":"<hex64>"`:t)}function tr(e){let t;try{t=JSON.stringify(e)}catch(o){throw new U("$",`unserializable-payload: ${String(o?.message||o)}`)}if(t===void 0)return"null";let r=Hn(t);for(let{rule:o,re:s}of Qt)if(s.test(r))throw new U("$<serialized>",o);if(/(?:^|[^0-9a-fA-Fx])0x[0-9a-fA-F]{64}(?![0-9a-fA-F])/.test(r))throw new U("$<serialized>","raw-32-byte-hex-embedded");return JSON.parse(t,(o,s)=>{if(o&&Ge(o))throw new U(`$<serialized>.${o}`,"forbidden-key-name");return s}),t}function X(e,t="$",r=new Set,n=""){if(e==null)return e;if(typeof e=="string"){let o=er.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:s,re:a}of Qt)if(!(o&&s.startsWith("raw-32-byte-hex"))&&a.test(e))throw new U(t,s);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,s]of e.entries()){if(typeof o=="string"&&Ge(o))throw new U(`${t}[${JSON.stringify(o)}]`,"forbidden-key-name");X(o,`${t}[key]`,r),X(s,`${t}[${String(o)}]`,r)}return e}if(e instanceof Set){let o=0;for(let s of e.values())X(s,`${t}[${o++}]`,r);return e}if(Array.isArray(e))return e.forEach((o,s)=>X(o,`${t}[${s}]`,r)),e;for(let[o,s]of Object.entries(e)){if(Ge(o))throw new U(`${t}.${o}`,"forbidden-key-name");X(s,`${t}.${o}`,r,o)}return e}var rr=null,zn="127.0.0.1",Gn=8798,Vn=1e6,Xn='{"error":"redacted"}',Kn=Object.freeze({"content-type":"application/json; charset=utf-8","cache-control":"no-store","content-security-policy":"default-src 'none'","x-content-type-options":"nosniff","x-frame-options":"DENY"});function Yn(e){if(!((e==="localhost"||e==="::1"||/^127(?:\.\d{1,3}){3}$/.test(e))&&(!e.startsWith("127.")||e.split(".").slice(1).every(t=>Number(t)<=255))))throw new Error("host must be a loopback address")}function Jn(e){if(!e||["status","latest","opportunities"].some(t=>typeof e[t]!="function"))throw new Error("runtime must provide status(), latest(), and opportunities()")}function Zn(e){typeof rr=="function"&&rr(e),X(e);let t=tr(e);if(Buffer.byteLength(t)>Vn)throw new Error("response too large");return t}function j(e,t,r){let n,o=t;try{n=Zn(r)}catch{o=500,n=Xn}e.writeHead(o,{...Kn,"content-length":Buffer.byteLength(n)}),e.end(n)}function nr({runtime:e,host:t=zn,port:r=Gn}={}){if(Jn(e),typeof t!="string")throw new Error("host must be a loopback address");if(Yn(t),!Number.isInteger(r)||r<0||r>65535)throw new Error("port must be an integer between 0 and 65535");function n(){let c=e.status(),i=Number.isSafeInteger(c?.ticks)?c.ticks:0,f=typeof c?.lastProviderState?.status=="string"?c.lastProviderState.status:"UNKNOWN",h=c?.running===!0&&i>0&&c?.lastError==null&&f==="AVAILABLE";return{httpStatus:h?200:503,body:{ok:h,ready:h,service:"oracle-mev-shadow",mode:"shadow",execution:!1,signer:!1,broadcaster:!1,ticks:i,provider:f}}}let o=new Map([["/status",()=>e.status()],["/latest",()=>e.latest()],["/opportunities",()=>e.opportunities()]]);async function s(c,i){if(c.method!=="GET"){j(i,405,{error:"method-not-allowed"});return}let f;try{f=new URL(c.url||"/","http://localhost").pathname}catch{j(i,404,{error:"not-found"});return}if(f==="/health"){try{let y=n();j(i,y.httpStatus,y.body)}catch{j(i,503,{error:"redacted"})}return}let h=o.get(f);if(!h){j(i,404,{error:"not-found"});return}try{j(i,200,await h())}catch{j(i,500,{error:"redacted"})}}let a=jn((c,i)=>{s(c,i).catch(()=>{i.headersSent?i.destroy():j(i,500,{error:"redacted"})})}),u=null;function l(){let c=a.address();return c&&typeof c=="object"?{address:c.address,family:c.family,port:c.port}:null}function d(){return a.listening?Promise.resolve(l()):u||(u=new Promise((c,i)=>{let f=y=>{a.off("listening",h),u=null,i(y)},h=()=>{a.off("error",f);let y=l();u=null,c(y)};a.once("error",f),a.once("listening",h),a.listen(r,t)}),u)}async function p(){if(u)try{await u}catch{return!1}return a.listening?(await new Promise((c,i)=>a.close(f=>f?i(f):c())),!0):!1}return Object.freeze({start:d,stop:p,address:l,handler:s})}var or=/^(?:0|[1-9][0-9]*)$/,ro=/^127(?:\.\d{1,3}){3}$/,no=(1n<<256n)-1n;function be(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))be(t);Object.freeze(e)}return e}function Ve(e,t){let r=String(e??"").trim().toLowerCase();if(!["","0","false","off"].includes(r))throw new Error(`${t} must remain disarmed for the arb paper shadow service`)}function oo(e){return e==="localhost"||e==="::1"?!0:ro.test(e)?e.split(".").slice(1).every(t=>Number(t)<=255):!1}function K(e,t,r,{positive:n=!1}={}){let o=String(e[t]??r);if(!or.test(o)||n&&o==="0")throw new TypeError(`${t} must be ${n?"a positive":"a non-negative"} decimal string`);if(BigInt(o)>no)throw new RangeError(`${t} must fit uint256`);return o}function he(e,t,r,n,o,s){let a=String(e[t]??r);if(!or.test(a))throw new TypeError(`${s} must be an integer`);let u=Number(a);if(!Number.isSafeInteger(u)||u<n||u>o)throw new TypeError(`${s} must be an integer from ${n} through ${o}`);return u}function so(e=process.env){Ve(e.ORACLE_EXECUTE_ENABLED,"ORACLE_EXECUTE_ENABLED"),Ve(e.MAD_EXECUTE_ENABLED,"MAD_EXECUTE_ENABLED"),Ve(e.ORACLE_MEV_EXECUTE_ENABLED,"ORACLE_MEV_EXECUTE_ENABLED");let t=String(e.ORACLE_MEV_ARB_SHADOW_HOST??"127.0.0.1").trim();if(!oo(t))throw new Error("ORACLE_MEV_ARB_SHADOW_HOST must be loopback-only");let r=String(e.HOME||Qn()),n=String(e.ORACLE_MEV_ARB_SHADOW_STATE??to(r,".local/state/oracle/mev-arb-shadow/observations.json"));if(!eo(n))throw new Error("ORACLE_MEV_ARB_SHADOW_STATE must be an absolute path");let o=String(e.ORACLE_MEV_ARB_SHADOW_PERSIST??"1").trim();if(!["0","1"].includes(o))throw new Error("persist must be 0 or 1");return be({host:t,port:he(e,"ORACLE_MEV_ARB_SHADOW_PORT","8809",0,65535,"port"),intervalMs:he(e,"ORACLE_MEV_ARB_SHADOW_INTERVAL_MS","15000",1e3,864e5,"intervalMs"),amountInWei:K(e,"ORACLE_MEV_ARB_SHADOW_AMOUNT_IN_WEI","1000000000000000000",{positive:!0}),minProfitWei:K(e,"ORACLE_MEV_ARB_SHADOW_MIN_PROFIT_WEI","10000000000000"),maxLoanWei:K(e,"ORACLE_MEV_ARB_SHADOW_MAX_LOAN_WEI","5000000000000000000",{positive:!0}),maxGasWei:K(e,"ORACLE_MEV_ARB_SHADOW_MAX_GAS_WEI","500000000000000"),builderFeeWei:K(e,"ORACLE_MEV_ARB_SHADOW_BUILDER_FEE_WEI","0"),extraCostWei:K(e,"ORACLE_MEV_ARB_SHADOW_EXTRA_COST_WEI","0"),extraGasUnits:K(e,"ORACLE_MEV_ARB_SHADOW_EXTRA_GAS_UNITS","250000"),maxBlockDrift:he(e,"ORACLE_MEV_ARB_SHADOW_MAX_BLOCK_DRIFT","40",0,1e3,"maxBlockDrift"),maxRecords:he(e,"ORACLE_MEV_ARB_SHADOW_MAX_RECORDS","500",1,1e5,"maxRecords"),filePath:n,persist:o==="1"})}function sr({env:e=process.env,runtimeFactory:t=Zt,serverFactory:r=nr}={}){if(typeof t!="function"||typeof r!="function")throw new TypeError("runtimeFactory and serverFactory must be functions");let n=so(e),o=t(n),s=r({runtime:o,host:n.host,port:n.port}),a=null,u=null;async function l(){return a||u||(u=(async()=>{let c=!1;try{await o.load();let i=await o.tick();o.start(),c=!0;let f=await s.start();return a=be({mode:"shadow",chain:"arbitrum",chainId:42161,execution:!1,signer:!1,broadcaster:!1,address:f,initialTick:i}),a}catch(i){try{await s.stop()}catch{}if(c)try{o.stop(),typeof o.drain=="function"&&await o.drain()}catch{}throw i}finally{u=null}})(),u)}async function d(){if(u)try{await u}catch{}if(!a)return!1;let c=null;try{await s.stop()}catch(i){c=i}if(o.stop(),typeof o.drain=="function"&&await o.drain(),a=null,c)throw c;return!0}function p(){return be({mode:"shadow",chain:"arbitrum",chainId:42161,execution:!1,signer:!1,broadcaster:!1,listening:!!a,address:s.address(),runtime:o.status()})}return Object.freeze({start:l,stop:d,status:p,config:n})}var we="oracle-mev-arb-shadow";function ge(e,t){e.write(`${JSON.stringify(t)}
|
|
5
|
-
`)}async function ir({env:e=process.env,appFactory:t=sr,stdout:r=process.stdout,stderr:n=process.stderr,processLike:o=process}={}){if(typeof t!="function")throw new TypeError("appFactory must be a function");if(!r||typeof r.write!="function"||!n||typeof n.write!="function")throw new TypeError("stdout and stderr must be writable streams");if(!o||typeof o.once!="function")throw new TypeError("processLike must provide once()");let s=t({env:e}),a=null;async function u(p="shutdown"){return a||(a=(async()=>{try{return await s.stop(),ge(r,{event:"stopped",service:we,signal:p}),!0}catch{return o.exitCode=1,ge(n,{event:"fatal",service:we,error:"shutdown failed"}),!1}})(),a)}for(let p of["SIGINT","SIGTERM"])o.once(p,()=>{u(p).catch(()=>{o.exitCode=1})});let l;try{l=await s.start()}catch{throw o.exitCode=1,ge(n,{event:"fatal",service:we,error:"startup failed"}),new Error("arb paper shadow service failed to start")}let d=l?.address&&typeof l.address=="object"?l.address:{};return ge(r,{event:"listening",service:we,mode:"shadow",chain:"arbitrum",chainId:42161,execution:!1,signer:!1,broadcaster:!1,address:d.address??null,family:d.family??null,port:d.port??null}),Object.freeze({app:s,stop:u})}var ar=process.argv.slice(2);(ar.includes("--help")||ar.includes("-h"))&&(process.stdout.write(`Usage: oracle-mev-arb-shadow [--help]
|
|
2
|
+
var gr=Object.defineProperty;var R=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var Ye=(e,t)=>{for(var r in t)gr(e,r,{get:t[r],enumerable:!0})};import z from"node:net";import Er from"node:dns";function ne(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=p=>{if(!p)return[];let c=p.split(":"),a=c.at(-1);if(a?.includes(".")){let l=a.split(".").map(Number);if(l.length!==4||l.some(w=>!Number.isInteger(w)||w<0||w>255))return null;c.splice(c.length-1,1,(l[0]<<8|l[1]).toString(16),(l[2]<<8|l[3]).toString(16))}return c.some(l=>!/^[0-9a-f]{1,4}$/.test(l))?null:c.map(l=>Number.parseInt(l,16))},[n,o]=t.split("::"),s=r(n),i=r(o);if(!s||!i)return null;let u=t.includes("::"),f=8-s.length-i.length;if(!u&&f!==0||u&&f<1)return null;let d=[...s,...Array(Math.max(0,f)).fill(0),...i];return d.length!==8?null:Uint8Array.from(d.flatMap(p=>[p>>8,p&255]))}function Se(e,t,r){let n=Math.floor(r/8),o=r%8;for(let i=0;i<n;i+=1)if(e[i]!==t[i])return!1;if(!o)return!0;let s=255<<8-o;return(e[n]&s)===(t[n]&s)}function _e(e){if(z.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(z.isIPv6(e)){let t=ne(e);if(!t)return!1;let r=ne("::ffff:0:0");return Se(t,r,96)?_e([...t.slice(12)].join(".")):Se(t,ne("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,s])=>Se(t,ne(o),s)):!1}return!1}function Ar(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(yr.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=z.isIP(r);return n!==0&&!_e(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function Ie(e,{lookupFn:t=Er.promises.lookup}={}){let r=Ar(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:z.isIPv6(r.host)?6:4}]};let n;try{n=await t(r.host,{all:!0,verbatim:!0})}catch{return{ok:!1,error:`refused: ${r.host} did not resolve`}}return!Array.isArray(n)||n.length===0||n.some(o=>!_e(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function Ce({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let c=await t();r=c.Agent,n=c.fetch}catch(c){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${c?.message||c}`);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=c=>String(c).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),s=new Map,i=c=>(Array.isArray(c)?c:[c]).map(a=>typeof a=="string"?{address:a}:a).filter(a=>a&&a.address).map(a=>({address:a.address,family:a.family||(z.isIPv6(a.address)?6:4)})),u=(c,a,l)=>{s.set(o(c),i(typeof a=="string"?[{address:a,family:l}]:a))},f=c=>{let a=o(c);if(z.isIP(a))return[{address:a,family:z.isIPv6(a)?6:4}];let l=s.get(a);if(!l||!l.length)throw new Error(`refused: unpinned host ${c} during pinned fetch`);return l},d=new r({connect:{lookup(c,a,l){let w;try{w=f(c)}catch(g){return l(g)}return a?.all?l(null,w):l(null,w[0].address,w[0].family)}}}),p=xr((c,a={})=>n(c,{...a,dispatcher:d}),u);return{dispatcher:d,fetch:p,pin:u,resolve:f,async close(){try{await d.destroy()}catch{}}}}function xr(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[Ne]=Object.freeze({pin:t}),e}function Oe(e){return typeof e=="function"&&typeof e[Ne]?.pin=="function"}function Je(e,t,r){if(!Oe(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Ne].pin(t,r)}var yr,Ne,Ze=R(()=>{yr=new Set(["localhost","metadata.google.internal","metadata.goog"]);Ne=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as Qe}from"node:crypto";function Nr(e){let t=String(e||"").toLowerCase();return it.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function Or(e){let t={};for(let[r,n]of Object.entries(e||{}))Nr(r)||(t[r]=n);return t}function Tr(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 kr(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function nt(e){let t=String(e?.method||"");return t?!Rr.test(t):!1}function $r(e,t){if(e==="GET"&&t==null)return!0;if(e!=="POST"||t==null)return!1;let r=t;if(typeof t=="string")try{r=JSON.parse(t)}catch{return!1}return Array.isArray(r)?r.length>0&&r.every(nt):!r||typeof r!="object"?!1:r.jsonrpc&&r.method?nt(r):typeof r.type=="string"&&Br.has(r.type)&&r.action==null&&r.signature==null&&r.nonce==null}function Lr(e,t,r,n={},o=null){let s={};for(let[a,l]of Object.entries(r||{}))s[a.toLowerCase()]=l;let i=Object.keys(s).filter(a=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(a)),f=[...new Set([...it,...i])].sort().map(a=>`${a}=${s[a]??""}`).join(`
|
|
3
|
+
`),d=Qe("sha256").update(f).digest("hex").slice(0,32),p=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`,c=o==null?"-":Qe("sha256").update(String(o)).digest("hex").slice(0,32);return`${e} ${t} ${p} ${d} ${c}`}function Pr(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,tt):Math.min(250*2**e,tt)+Math.floor(Math.random()*100)}function Y(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function ke(e,t,r){return Y(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function J(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function vr(e){return e?e.byteLength??e.length??0:0}async function ot(e,t,{url:r,truncate:n=!1,onOversize:o}={}){if(t==null)return await e.text();let s=Number(e.headers?.get?.("content-length"));if(Number.isFinite(s)&&s>t&&(J(e),!n))throw ke(r,`content-length ${s}`,t);let i=e.body?.getReader?.();if(!i){let c=await e.text(),a=Buffer.byteLength(c,"utf8");if(a>t){if(!n)throw ke(r,`body ${a} bytes`,t);return Buffer.from(c,"utf8").subarray(0,t).toString("utf8")}return c}let u=[],f=0,d=!1;try{for(;;){let{value:c,done:a}=await i.read();if(a)break;if(c&&(u.push(Buffer.from(c)),f+=vr(c),f>t)){d=!0;break}}}finally{if(d)try{await i.cancel()}catch{}try{i.releaseLock?.()}catch{}}if(d&&(typeof o=="function"&&o(),!n))throw ke(r,`streamed ${f} bytes`,t);let p=Buffer.concat(u);return(d?p.subarray(0,t):p).toString("utf8")}function st(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Mr(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s,lookupFn:i,realFetch:u,untrustedUrl:f=!1,maxResponseBytes:d=null,importUndici:p,validateResponse:c,signal:a}){let l=new AbortController,w=setTimeout(()=>l.abort(),s),g=a?typeof AbortSignal.any=="function"?AbortSignal.any([a,l.signal]):a:l.signal,E=null,y=t,x=i?{lookupFn:i}:{};if(f&&!u&&!Oe(y))throw Y(`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 S=async(m,{status:b=null}={})=>{let I=await Ie(m,x);if(!I.ok)throw Y(b==null?`HTTP refused ${m}: ${I.error}`:`HTTP redirect to ${m} ${I.error}`,b==null?{}:{status:b});let h=new URL(m).hostname;if(u){if(E&&(await E.close(),E=null),!E)try{E=await Ce({requireUndici:!0,...p?{importUndici:p}:{}})}catch(C){throw Y(b==null?`HTTP refused ${m}: ${C?.message||C}`:`HTTP redirect to ${m} refused: ${C?.message||C}`,b==null?{}:{status:b})}E.pin(h,I.addresses),y=E.fetch}else Je(y,h,I.addresses);return I};try{let m=String(e),b={...n||{}};f&&await S(m);for(let I=0;I<=rt;I+=1){let h=await y(m,{method:r,headers:b,body:o,signal:g,redirect:"manual"});if(Ir.has(h.status)){if(r!=="GET"&&r!=="HEAD"){let _=await ot(h,d??Cr,{url:m,truncate:!0}),O=new Error(`HTTP ${h.status} ${r} ${m} redirected non-idempotent request`);throw O.status=h.status,O.body=st(_)??_.slice(0,300),O}if(I===rt)throw J(h),new Error(`HTTP redirect loop for ${e}`);let A=h.headers?.get?.("location"),T;try{T=Tr(A,m)}catch(_){throw J(h),_}let P=!kr(T,m);if(J(h),P&&(b=Or(b)),f)await S(T,{status:h.status});else if(P){let _=await Ie(T,x);if(!_.ok){let O=new Error(`HTTP redirect from ${m} ${_.error}`);throw O.status=h.status,O.retryable=!1,O}u&&_.addresses?.length&&(E||(E=await Ce(p?{importUndici:p}:{})),E&&(E.pin(new URL(T).hostname,_.addresses),y=E.fetch))}m=T;continue}if(typeof c=="function")try{await c(h,{url:m})}catch(A){throw J(h),Y(A?.message||String(A))}let C=await ot(h,d,{url:m,onOversize:()=>l.abort()}),N=st(C);if(!h.ok){let A=new Error(`HTTP ${h.status} ${r} ${m}`);throw A.status=h.status,A.retryAfter=h.headers?.get?.("retry-after")??null,A.body=N??C.slice(0,300),A}return N??C}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(w),E&&await E.close()}}async function oe(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,o=(t.method||"GET").toUpperCase(),s={Accept:"application/json",...t.headers||{}},i=t.body;i!=null&&typeof i!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",i=JSON.stringify(i));let u=Number.isInteger(t.retries)?Math.max(t.retries,0):_r,f=t.lookupFn,d=!t.fetchImpl,p=t.untrustedUrl===!0,c=t.importUndici,a=t.validateResponse,l=t.signal,w=Number(t.maxResponseBytes),g=Number.isFinite(w)&&w>0?Math.floor(w):null,E=async()=>{let b;for(let I=0;I<=u;I++){l?.throwIfAborted?.();try{return await Mr(e,{fetchImpl:r,method:o,headers:s,body:i,timeoutMs:n,lookupFn:f,realFetch:d,untrustedUrl:p,maxResponseBytes:g,importUndici:c,validateResponse:a,signal:l})}catch(h){b=h;let C=h?.status,N=h?.name==="AbortError"||h?.name==="TimeoutError"||l?.aborted,A=new Set([408,425,429]),T=h?.retryable===!1?!1:C!=null?A.has(C)||Sr.has(C)&&et.has(o):!N&&et.has(o);if(I===u||!T)throw h;let P=Pr(I,h?.retryAfter);l?await new Promise((_,O)=>{let Ae=setTimeout(_,P);l.addEventListener("abort",()=>{clearTimeout(Ae),O(l.reason||new DOMException("Aborted","AbortError"))},{once:!0})}):await Dr(P)}}throw b};if(!(t.dedupe!==!1&&!l&&$r(o,i)))return E();let x=Lr(o,e,s,{untrustedUrl:p,maxResponseBytes:g},i),S=Te.get(x);if(S)return S;let m=E().finally(()=>Te.delete(x));return Te.set(x,m),m}var Sr,et,_r,tt,it,Ir,rt,Cr,Te,Rr,Br,Dr,Re=R(()=>{Ze();Sr=new Set([408,425,429,500,502,503,504]),et=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),_r=2,tt=4e3,it=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ir=new Set([301,302,303,307,308]),rt=3,Cr=64*1024;Te=new Map,Rr=/(?:^|_)(send|submit|broadcast|sign|requestAirdrop)(?=[A-Z_]|$)/i,Br=new Set(["allMids","l2Book","outcomeMeta","spotClearinghouseState","userFills","meta","metaAndAssetCtxs","perpDexs","candleSnapshot","fundingHistory","openOrders","frontendOpenOrders","clearinghouseState","spotMeta","validatorSummaries","delegatorSummary","delegations","delegatorRewards","delegatorHistory","maxBuilderFee"]);Dr=e=>new Promise(t=>setTimeout(t,e))});function $e(e){return at.get(Number(e))||null}function ct(e,t=process.env){let r=$e(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}function ut(e){return at.has(Number(e))}var Be,at,lt=R(()=>{Be={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}},at=new Map(Object.values(Be).map(e=>[e.chainId,e]))});var gt={};Ye(gt,{PUBLIC_RPC_FALLBACKS:()=>Pe,erc20Allowance:()=>Xr,erc20BalanceOf:()=>Kr,resolveRpcUrl:()=>ie,rpcBatch:()=>bt,rpcBlockNumber:()=>De,rpcCall:()=>k,rpcChainId:()=>zr,rpcGasPrice:()=>Gr,rpcGetBalance:()=>Vr,rpcHealth:()=>wt,rpcHealthAll:()=>Jr,transactionReceipt:()=>Yr});import{Interface as Fr,getAddress as Ur}from"ethers";function W(e,t){try{return Ur(e).toLowerCase()}catch{throw new Error(`${t} must be a valid EVM address`)}}function Wr(e){let t=String(e||"").trim();if(!/^0x[0-9a-fA-F]{64}$/.test(t))throw new Error("txHash must be a 32-byte hex transaction hash");return t.toLowerCase()}function Le(e){return e==null?null:Number.parseInt(String(e),16)}function ie(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=ct(e,r);return n||Pe[Number(e)]||null}function pt(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!qr.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}function Hr(e){let t=new Error(e?.message||JSON.stringify(e));return t.code=e?.code,t}function mt(e){if(e?.error)throw Hr(e.error);return e?.result}function jr(e,t,r){return`${e}
|
|
4
|
+
${t}
|
|
5
|
+
${JSON.stringify(r??[])}`}async function ht(e,t,r){return oe(e,{method:"POST",body:t,fetchImpl:r.fetchImpl,timeoutMs:r.timeoutMs??12e3,signal:r.signal})}async function bt(e,t,r={}){if(!Array.isArray(t)||t.length===0)throw new Error("rpcBatch requires a non-empty calls array");if(t.length>ft)throw new Error(`rpcBatch: at most ${ft} calls`);for(let s of t)pt(s?.method);let n=ie(e,r);if(!n)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let o=t.map((s,i)=>({jsonrpc:"2.0",id:i+1,method:s.method,params:s.params||[]}));try{let s=await ht(n,o,r);if(Array.isArray(s)&&s.length===t.length){let i=new Map(s.map(u=>[Number(u?.id),u]));return t.map((u,f)=>mt(i.get(f+1)??s[f]))}}catch{}return Promise.all(t.map(s=>k(e,s.method,s.params||[],r)))}async function k(e,t,r=[],n={}){let o=String(t||""),s=pt(o),i=ie(e,n);if(!i)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);if(s==="eth_chainid"&&n.cacheChainId!==!1){let p=dt.get(i);if(p!=null)return p}let f=n.dedupe!==!1&&!n.signal?jr(i,o,r):null;if(f&&Z.has(f))return Z.get(f);let d=(async()=>{let p=await ht(i,{jsonrpc:"2.0",id:1,method:t,params:r},n),c=mt(p);return s==="eth_chainid"&&typeof c=="string"&&dt.set(i,c),c})();return f&&(Z.set(f,d),d.finally(()=>{Z.get(f)===d&&Z.delete(f)}).catch(()=>{})),d}async function wt(e,t={}){let[r,n]=await bt(e,[{method:"eth_blockNumber",params:[]},{method:"eth_chainId",params:[]}],t),o=parseInt(r,16),s=parseInt(n,16);return{ok:Number.isFinite(o)&&s===Number(e),chainId:Number(e),reportedChainId:s,blockNumber:o,name:$e(e)?.name||null}}async function De(e,t={}){let r=await k(e,"eth_blockNumber",[],t);return parseInt(r,16)}async function zr(e,t={}){let r=await k(e,"eth_chainId",[],t);return parseInt(r,16)}async function Gr(e,t={}){let r=await k(e,"eth_gasPrice",[],t);if(r==null)return null;try{return BigInt(r)}catch{return null}}async function Vr(e,t,r={}){if(!t)throw new Error("rpcGetBalance requires address");let n=await k(e,"eth_getBalance",[t,"latest"],r);return{chainId:Number(e),address:t,balanceWei:BigInt(n).toString(),balanceHex:n}}async function Xr(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=W(e.token||e.tokenAddress,"token"),o=W(e.owner,"owner"),s=W(e.spender,"spender"),i=se.encodeFunctionData("allowance",[o,s]),u=await k(r,"eth_call",[{to:n,data:i},e.blockTag||"latest"],t),f=se.decodeFunctionResult("allowance",u),d=BigInt(f[0]);return{chainId:r,token:n,owner:o,spender:s,allowance:d.toString(),allowanceHex:`0x${d.toString(16)}`,blockTag:e.blockTag||"latest"}}async function Kr(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=W(e.token||e.tokenAddress,"token"),o=W(e.account||e.owner||e.address,"account"),s=se.encodeFunctionData("balanceOf",[o]),i=await k(r,"eth_call",[{to:n,data:s},e.blockTag||"latest"],t),u=se.decodeFunctionResult("balanceOf",i),f=BigInt(u[0]);return{chainId:r,token:n,account:o,balance:f.toString(),balanceHex:`0x${f.toString(16)}`,blockTag:e.blockTag||"latest"}}async function Yr(e={},t={}){let r=Number(e.chainId??t.chainId??1),n=Wr(e.txHash||e.hash||e.transactionHash),o=await k(r,"eth_getTransactionReceipt",[n],t);if(!o)return{ok:!1,chainId:r,txHash:n,status:"pending",receipt:null,reason:"receipt pending"};let s=Le(o.status),i=s===1,u=s===1?"success":s===0?"reverted":"unknown",f=i?null:u==="reverted"?"transaction reverted":"unknown receipt status",d=e.expectedTo?W(e.expectedTo,"expectedTo"):null,p=o.to?W(o.to,"receipt.to"):null;return d&&p!==d&&(i=!1,f=`to mismatch: expected ${d}, got ${p||"null"}`),{ok:i,chainId:r,txHash:n,status:u,reason:f,statusCode:s,to:p,from:o.from?W(o.from,"receipt.from"):null,blockNumber:Le(o.blockNumber),transactionIndex:Le(o.transactionIndex),logs:Array.isArray(o.logs)?o.logs:[],receipt:o}}async function Jr(e={}){let t=e.chainIds||Object.values(Be).map(n=>n.chainId),r={};return await Promise.all(t.map(async n=>{if(!ut(n)&&!Pe[n]&&!ie(n,e)){r[n]={ok:!1,error:"no rpc configured",chainId:n};return}try{r[n]=await wt(n,e)}catch(o){r[n]={ok:!1,chainId:n,error:String(o.message||o)}}})),r}var se,Pe,qr,ft,Z,dt,ae=R(()=>{Re();lt();se=new Fr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);Pe={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"};qr=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;ft=32,Z=new Map,dt=new Map});var Pt=R(()=>{});function In(e,t,r){let n=D(t),o=D(r),s=D(e?.baseToken?.address),i=D(e?.quoteToken?.address);return s===n&&i===o||s===o&&i===n}function Cn(e){let t=Number(e?.liquidity?.usd);return Number.isFinite(t)&&t>=0?t:null}function Nn(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||xn).replace(/\/$/,"")}async function On(e,t={}){if(!e)throw new Error("tokenAddress required");return oe(`${Nn(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}async function Dt({chainId:e,tokenA:t,tokenB:r,dexIds:n=[]}={},o={}){if(e==null||!t||!r)throw new Error("chainId, tokenA, and tokenB required");let s=D(Sn[Number(e)]||e),i=new Set(_n(n).filter(Boolean).map(D)),u=[...new Set([t,r].map(a=>String(a)).filter(Boolean))],f=await Promise.allSettled(u.map(a=>On(a,{...o,baseUrl:o.dexscreenerBaseUrl,timeoutMs:o.dexscreenerTimeoutMs??Math.min(Number(o.timeoutMs??4e3),4e3)}))),d=new Set,p=[];for(let a of f)if(a.status==="fulfilled")for(let l of a.value?.pairs||a.value?.data?.pairs||[]){let w=`${D(l?.chainId)}:${D(l?.dexId)}:${D(l?.pairAddress)}`;d.has(w)||(d.add(w),p.push(l))}return p.filter(a=>D(a?.chainId)===s).filter(a=>In(a,t,r)).filter(a=>!i.size||i.has(D(a?.dexId))).map(a=>({pairAddress:a.pairAddress??null,dexId:a.dexId??null,chainId:a.chainId??null,liquidityUsd:Cn(a),pairCreatedAt:a.pairCreatedAt??null})).filter(a=>a.liquidityUsd!=null).sort((a,l)=>l.liquidityUsd-a.liquidityUsd)}var xn,Sn,D,_n,vt=R(()=>{Re();Pt();xn="https://api.dexscreener.com",Sn=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"}),D=e=>String(e??"").toLowerCase(),_n=e=>Array.isArray(e)?e:e==null?[]:[e]});import{readFileSync as Tn}from"node:fs";import{homedir as kn}from"node:os";import{join as fe}from"node:path";function Rn(){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){let r=(process.env.ORACLE_EXEC_ENV_FILE||"").trim();return r?[r]:[]}let e=(process.env.ORACLE_EXEC_ENV_FILE||process.env.MAD_EXEC_ENV_FILE||"").trim(),t=kn();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||fe(t,".config","oracle")).trim();return[e,fe(r,"exec.env")].filter(Boolean)}return[e,fe(t,".config","oracle","exec.env"),fe(t,".config","mad-desk","exec.env")].filter(Boolean)}function Mt(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of Rn())try{let s=Tn(o,"utf8"),i=s.match(new RegExp(`^${t}=(.*)$`,"m"))||s.match(new RegExp(`^${r}=(.*)$`,"m"));if(i&&(n=i[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}var Ft=R(()=>{});var Ut=R(()=>{});import{createHash as Ko,createHmac as Bn,timingSafeEqual as Yo}from"node:crypto";function He(e){return Array.isArray(e)?`[${e.map(He).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${He(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function $n(e,{required:t=!1}={}){try{return Mt(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function Ln(e){let{signature:t,...r}=e;return r}function Pn(e,{secret:t}={}){let r=$n(t);return r?{...e,signature:Bn("sha256",r).update(He(Ln(e))).digest("hex")}:e}function qe(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function Dn(e){let t=e==null?Wt:Number(e);if(!Number.isInteger(t)||t<0)throw new Error("auto-slippage cap must be a non-negative integer bps value");return Math.min(t,Wt)}function vn({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let s=qe(e,0),i=s>0?s>=25e4?5:s>=1e5?10:s>=5e4?20:s>=1e4?40:70:n?30:10,u=Math.min(60,Math.abs(qe(t,0))*2),f=Math.min(40,Math.floor(Math.max(0,qe(r,0))/5e3)*5),d=Math.max(25,Math.ceil(20+i+u+f)),p=Dn(o);return{mode:"auto",requiredBps:d,selectedBps:Math.min(d,p),capBps:p,executable:d<=p}}function Mn({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:s=0,crossChain:i=!1,requestedCapBps:u,quotedAtMs:f=Date.now(),ttlMs:d=qt,secret:p}={}){let c=BigInt(r??0);if(c<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let a=vn({liquidityUsd:n,priceChange5m:o,quoteAgeMs:s,crossChain:i,requestedCapBps:u});if(!a.executable)throw new Error(`auto-slippage requires ${a.requiredBps} bps above hard/requested cap ${a.capBps}; route blocked`);let l=Number(f);if(!Number.isFinite(l))throw new Error("auto-slippage: quotedAtMs must be a finite number");let w=Math.min(3e4,Math.max(1e3,Number(d)||qt)),g=c*BigInt(1e4-a.selectedBps),E=g/10000n;if(g%10000n!==0n&&(E+=1n),E>c&&(E=c),c>0n&&E<=0n)throw new Error(`auto-slippage: quote ${c} is too small to express a ${a.selectedBps} bps floor without rounding to zero`);let y=Number((c-E)*10000n/(c===0n?1n:c));if(y>a.capBps)throw new Error(`auto-slippage: realised floor implies ${y} bps, above cap ${a.capBps} \u2014 refusing to issue a guard weaker than advertised`);return Pn({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:c.toString(),minAmountOut:E.toString(),requiredBps:a.requiredBps,selectedBps:a.selectedBps,capBps:a.capBps,quotedAtMs:l,expiresAtMs:l+w},{secret:p})}function Ht(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:i,requestedCapBps:u,quotedAtMs:f=Date.now(),ttlMs:d}={}){let p=Mn({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:i,requestedCapBps:u,quotedAtMs:f,ttlMs:d});return{...e,autoSlippage:p,amountOutMinimum:p.minAmountOut}}var Wt,qt,jt=R(()=>{Ft();Ut();Wt=100,qt=2e4});var es,ts,zt=R(()=>{es=300*1e3,ts=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});import{Interface as Xt,getAddress as de,isAddress as Kt}from"ethers";function jn(e,t){let r=Number(e),n=te[r];if(!n)throw new Error(`uniswap-v3: unsupported chainId ${e} (supported: ${Object.keys(te).join(", ")})`);let o=Hn[r]||{};if(!t){if(!n.quoter||!n.router){let f=Object.keys(o).join(", ")||"none registered";throw new Error(`uniswap-v3: chain ${r} (${n.name}) has no canonical Uniswap v3 deployment -- name a venue explicitly (known: ${f})`)}return{chainId:r,venue:n.name,...n}}let s=String(t).toLowerCase();if(s===n.name&&n.quoter&&n.router)return{chainId:r,venue:n.name,...n};let i=o,u=i[s];if(!u){let f=[...n.quoter&&n.router?[n.name]:[],...Object.keys(i)].join(", ");throw new Error(`uniswap-v3: unknown venue "${t}" on chain ${r} (known: ${f})`)}return{chainId:r,venue:s,...n,quoter:u.quoter,router:u.router,feeTiers:u.feeTiers||null}}function Vt(e,t){let r=te[Number(t)];if(!e||e===Wn||e===qn||/^eth$/i.test(String(e)))return de(r.weth);let n=String(e);if(/^weth$/i.test(n))return de(r.weth);if(/^usdc$/i.test(n))return de(r.usdc);if(!Kt(n))throw new Error(`invalid token address: ${e}`);return de(n)}function zn(e){let t=String(e||"uniswap").toLowerCase();return t==="uniswap"?["uniswap-v3","uniswap"]:t==="pancakeswap"?["pancakeswap-v3","pancakeswap"]:t==="hyperswap"?["hyperswap-v3","hyperswap"]:[t,`${t}-v3`]}async function Yt(e={},t={}){let{chainId:r,quoter:n,router:o,feeTiers:s}=jn(e.chainId??8453,e.venue),i=Vt(e.tokenIn||"WETH",r),u=Vt(e.tokenOut||te[r].usdc,r),f=BigInt(e.amountIn??0);if(f<=0n)throw new Error("amountIn required (raw base units)");let d=s&&s.length?s:Fn,p=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[d[Math.min(2,d.length-1)]]:[...d],a=await Promise.all(p.map(async h=>{let C=Gt.encodeFunctionData("quoteExactInputSingle",[{tokenIn:i,tokenOut:u,amountIn:f,fee:h,sqrtPriceLimitX96:0n}]);try{let N=await k(r,"eth_call",[{to:n,data:C},"latest"],t);if(!N||N==="0x")return{fee:h,ok:!1,error:"empty result"};let A=Gt.decodeFunctionResult("quoteExactInputSingle",N);return{fee:h,ok:!0,amountOut:A[0].toString(),sqrtPriceX96After:A[1].toString(),initializedTicksCrossed:Number(A[2]),gasEstimate:A[3].toString()}}catch(N){return{fee:h,ok:!1,error:String(N.message||N).slice(0,160)}}})),l=null;for(let h of a)h.ok&&(!l||BigInt(h.amountOut)>BigInt(l.amountOut))&&(l=h);if(!l){let h=a.map(C=>`${C.fee}:${C.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${h}`)}let w=e.liquidityUsd==null?await Dt({chainId:r,tokenA:i,tokenB:u,dexIds:zn(e.venue)},t).catch(()=>[]):[],g={};await Promise.all(w.slice(0,8).map(async h=>{if(!(!h.pairAddress||!Kt(h.pairAddress)))try{let C=await k(r,"eth_call",[{to:h.pairAddress,data:Un},"latest"],t),N=C&&C!=="0x"&&C.length<=66?Number.parseInt(C,16):NaN;if(!Number.isFinite(N)||N<=0||N>1e6)return;let A=g[N];(A==null||h.liquidityUsd>A.liquidityUsd)&&(g[N]=h)}catch{}}));let E=e.liquidityBandBps==null?50:Number(e.liquidityBandBps),y=null;if(e.fee==null&&E>0&&BigInt(l.amountOut)>0n){let h=BigInt(l.amountOut),N=a.filter(A=>A.ok&&Number((h-BigInt(A.amountOut))*10000n/h)<=E).filter(A=>g[A.fee]?.liquidityUsd!=null).sort((A,T)=>g[T.fee].liquidityUsd-g[A.fee].liquidityUsd)[0];N&&N.fee!==l.fee&&(y={priceBestFee:l.fee,chosenFee:N.fee,chosenPoolUsd:g[N.fee].liquidityUsd,bandBps:E},l=N)}let x=g[l.fee]??null,S=w[0]??null,m=x??S,b=e.liquidityUsd??x?.liquidityUsd??S?.liquidityUsd??null,I=e.liquidityUsd!=null?"caller":x?"pool":S?"pair":null;return Ht({venue:"uniswap-v3",chainId:r,chain:te[r].name,quoter:n,tokenIn:i,tokenOut:u,amountIn:f.toString(),fee:l.fee,amountOut:l.amountOut,gasEstimate:l.gasEstimate,liquidityUsd:b,liquiditySource:m,liquidityAttribution:I,liquidityPick:y,sqrtPriceX96After:l.sqrtPriceX96After,initializedTicksCrossed:l.initializedTicksCrossed,triedFees:a,best:!0},{chainId:r,venue:o,amountOut:l.amountOut,liquidityUsd:b,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}var te,Fn,Un,Gt,ls,Wn,qn,je,Hn,Jt=R(()=>{ae();vt();jt();zt();te={1:{name:"ethereum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},8453:{name:"base",quoter:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",router:"0x2626664c2603336E57B271c5C0b26F421741e481",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},4663:{name:"robinhood",quoter:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",router:"0xcaf681a66d020601342297493863e78c959e5cb2",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"},999:{name:"hyperevm",weth:"0x5555555555555555555555555555555555555555",usdc:"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"},10:{name:"optimism",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",quoter:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",router:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},43114:{name:"avalanche",quoter:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",router:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}},Fn=[100,500,3e3,1e4],Un="0xddca3f43",Gt=new Xt(["function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)","function quoteExactInput(bytes path, uint256 amountIn) returns (uint256 amountOut, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)"]),ls=new Xt(["function exactInputSingle((address tokenIn,address tokenOut,uint24 fee,address recipient,uint256 amountIn,uint256 amountOutMinimum,uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)","function multicall(uint256 deadline,bytes[] data) payable returns (bytes[] results)"]),Wn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",qn="0x0000000000000000000000000000000000000000",je=[100,500,2500,1e4],Hn={56:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:je}},8453:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:je}},42161:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:je}},999:{hyperswap:{name:"hyperswap",quoter:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",router:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D"}}}});var nr={};Ye(nr,{ARB_UNI_FEE_TIERS:()=>rr,collectArbRoundTripCycles:()=>Kn});function ze(e,{positive:t=!1}={}){return typeof e=="string"&&/^(?:0|[1-9][0-9]*)$/.test(e)&&(!t||e!=="0")&&BigInt(e)<=Gn}function Zt(e){if(!ze(e,{positive:!0})){let t=typeof e=="string"&&/^[1-9][0-9]*$/.test(e)?" and fit uint256":"";throw new TypeError(`amountInWei must be a positive strict decimal string${t}`)}return e}function Qt(e,t){let r=e?.amountOut;if(!ze(r,{positive:!0}))throw new Error(`${t} returned an invalid amountOut`);return r}function er(e,t){let r=e?.gasEstimate??e?.gasUnits;if(!ze(r))throw new Error(`${t} returned invalid gas units`);return r}function pe(e,t,r,n,o,s){return{status:"UNAVAILABLE",entryVenue:e,exitVenue:t,amountInWei:r,intermediateAmountBase:n,amountOutWei:null,gasUnits:null,source:o,error:String(s?.message||s)}}function tr(e){return`uniswap-v3-${e}`}async function Vn({entryFee:e,exitFee:t,amountInWei:r,blockTag:n,quoteUniswap:o}){let s=tr(e),i=tr(t),u;try{u=await o({chainId:re,tokenIn:"WETH",tokenOut:"USDC",amountIn:r,fee:e,tryFees:!1,blockTag:n})}catch(c){return pe(s,i,r,null,{},c)}let f,d;try{f=Qt(u,s),d=er(u,s)}catch(c){return pe(s,i,r,null,{entry:{venue:"uniswap-v3",fee:e}},c)}let p;try{p=await o({chainId:re,tokenIn:"USDC",tokenOut:"WETH",amountIn:f,fee:t,tryFees:!1,blockTag:n})}catch(c){return pe(s,i,r,f,{entry:{venue:"uniswap-v3",fee:e}},c)}try{let c=Qt(p,i),a=(BigInt(d)+BigInt(er(p,i))).toString();return{status:"OK",entryVenue:s,exitVenue:i,amountInWei:r,intermediateAmountBase:f,amountOutWei:c,gasUnits:a,source:{entry:{venue:"uniswap-v3",fee:e},exit:{venue:"uniswap-v3",fee:t}}}}catch(c){return pe(s,i,r,f,{entry:{venue:"uniswap-v3",fee:e},exit:{venue:"uniswap-v3",fee:t}},c)}}async function Xn(e){let t=await k(re,"eth_gasPrice",[],e);return BigInt(t).toString()}async function Kn(e={}){let t=Zt(e.amountInWei),r=e.quoteUniswap??(g=>Yt(g,e)),n=e.getBlockNumber??(()=>De(re,e)),o=e.getGasPriceWei??(()=>Xn(e)),s=e.now??(()=>new Date().toISOString()),i=e.maxBlockDrift??1,u=Array.isArray(e.feeTiers)&&e.feeTiers.length?e.feeTiers.map(Number):[...rr];if(!Number.isSafeInteger(i)||i<0)throw new TypeError("maxBlockDrift must be a non-negative safe integer");for(let g of u)if(![100,500,3e3,1e4].includes(g))throw new TypeError(`unsupported Uni fee tier: ${g}`);let f=e.pinnedBlock??await n();if(!Number.isSafeInteger(f)||f<0)throw new Error("block provider returned invalid height");let d=`0x${f.toString(16)}`,p=Zt(await o()),c=[];for(let g of u)for(let E of u)g!==E&&c.push({entryFee:g,exitFee:E});let a=await Promise.all(c.map(({entryFee:g,exitFee:E})=>Vn({entryFee:g,exitFee:E,amountInWei:t,blockTag:d,quoteUniswap:r}))),l=await n();if(!Number.isSafeInteger(l)||l<0)throw new Error("block provider returned invalid height");let w=Math.abs(l-f);return{mode:"shadow",executionReady:!1,chainId:re,pair:"WETH-USDC",capturedAt:s(),amountInWei:t,blockStart:f,blockEnd:l,pinnedBlock:f,blockTag:d,blockConsistency:"PINNED",blockDrift:w,maxBlockDrift:i,stale:w>i,gasPriceWei:p,cycles:a,venueNote:"uniswap-v3-fee-tiers-only; camelot/pancake deferred"}}var re,Gn,rr,or=R(()=>{ae();Jt();re=42161,Gn=(1n<<256n)-1n,rr=Object.freeze([100,500,3e3])});import{homedir as fo}from"node:os";import{isAbsolute as po,join as mo}from"node:path";var ve=Object.freeze({premium:"0x074b2e43",provider:"0x0542975c",reserves:"0xd1946dbc"}),yt=/^0x[0-9a-fA-F]{64}$/,Zr=/^0x(?:0|[1-9a-fA-F][0-9a-fA-F]*)$/,Qr=256,en=100;async function tn(...e){let{rpcCall:t}=await Promise.resolve().then(()=>(ae(),gt));return t(...e)}function Me(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))Me(t);Object.freeze(e)}return e}var M=Me({chainId:42161,pool:"0x794a61358D6845594F94dc1DB02A252b5b4814aD",addressesProvider:"0xa97684ead0e402dC232d5A977953DF7ECBaB3CDb",WETH:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",USDC:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",requiredReserves:["0x82aF49447D8a07e3bd95BD0d56f35241523fBab1","0xaf88d065e77c8cC2239327C5EDb3A432268e5831"],observedPremiumBps:5});function rn(e){if(typeof e!="string"||!Zr.test(e))throw new Error("malformed eth_blockNumber result");let t=BigInt(e);if(t>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("malformed eth_blockNumber result: outside safe range");return Number(t)}function nn(e,t){if(typeof e!="string"||!yt.test(e))throw new Error(`malformed ${t} result`);return BigInt(e)}function At(e,t){if(typeof e!="string"||!yt.test(e)||e.slice(2,26)!=="0".repeat(24))throw new Error(`malformed ${t} result`);return`0x${e.slice(26).toLowerCase()}`}function on(e){if(typeof e!="string"||!/^0x[0-9a-fA-F]+$/.test(e)||e.length<130)throw new Error("malformed getReservesList result");let t=e.slice(2);if(t.length%64!==0||BigInt(`0x${t.slice(0,64)}`)!==32n)throw new Error("malformed getReservesList result");let r=BigInt(`0x${t.slice(64,128)}`);if(r>BigInt(Qr)||r>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("malformed getReservesList result: unreasonable reserve count");let n=Number(r);if(t.length!==128+n*64)throw new Error("malformed getReservesList result: invalid length");let o=[];for(let s=0;s<n;s+=1){let i=`0x${t.slice(128+s*64,192+s*64)}`;o.push(At(i,"getReservesList address"))}return o}function Et(e,t,r,n){return Me({mode:"shadow",executionReady:!1,status:e,chainId:M.chainId,block:t,premiumBps:r,reasons:n})}async function xt(e={}){let t=e.rpc??tn;if(typeof t!="function")throw new TypeError("rpc must be a function");let r=null,n=null;try{let o=await t(M.chainId,"eth_blockNumber",[],e);r=rn(o);let s=c=>t(M.chainId,"eth_call",[{to:M.pool,data:c},o],e),i=nn(await s(ve.premium),"FLASHLOAN_PREMIUM_TOTAL");if(i>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("malformed FLASHLOAN_PREMIUM_TOTAL result: outside safe range");n=Number(i);let u=At(await s(ve.provider),"ADDRESSES_PROVIDER"),f=on(await s(ve.reserves)),d=[];n>en?d.push(`premium ${n} bps exceeds reasonable bound`):n!==M.observedPremiumBps&&d.push(`premium ${n} bps differs from observed ${M.observedPremiumBps} bps`),u!==M.addressesProvider.toLowerCase()&&d.push(`addresses provider mismatch: received ${u}`);let p=new Set(f);for(let[c,a]of[["WETH",M.WETH],["USDC",M.USDC]])p.has(a.toLowerCase())||d.push(`${c} required reserve is missing`);return Et(d.length===0?"AVAILABLE":"MISMATCH",r,n,d)}catch(o){return Et("UNAVAILABLE",r,n,[String(o?.message||o)])}}var sn=/^(?:0|[1-9][0-9]*)$/,St=10000n,Fe=(1n<<256n)-1n;function B(e,t="value"){let r;if(typeof e=="bigint"&&e>=0n)r=e;else if(typeof e=="string"&&sn.test(e))r=BigInt(e);else throw new TypeError(`${t} must be a non-negative plain decimal string or bigint`);if(r>Fe)throw new RangeError(`${t} must fit uint256`);return r}function ce(e,t){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?BigInt(e):B(e,t)}function an(e,t){let r=B(e,"amount"),n=ce(t,"basisPoints");if(n>St)throw new RangeError("basisPoints must be at most 10000");let o=r*n;return o===0n?0n:(o-1n)/St+1n}function Q(e){if(typeof e!="bigint")throw new TypeError("value must be a bigint");return e.toString(10)}function _t(e,t){if(e===null||typeof e!="object"||Array.isArray(e))throw new TypeError(`${t} must be an object`);return e}function It(e){for(let t of Object.values(e))t!==null&&typeof t=="object"&&!Object.isFrozen(t)&&It(t);return Object.freeze(e)}function Ct(e,t){_t(e,"cycle"),_t(t,"policy");let r=B(e.amountInWei,"cycle.amountInWei"),n=B(e.amountOutWei,"cycle.amountOutWei"),o=ce(e.gasUnits,"cycle.gasUnits"),s=B(e.gasPriceWei,"cycle.gasPriceWei"),i=ce(t.loanPremiumBps,"policy.loanPremiumBps"),u=B(t.builderFeeWei,"policy.builderFeeWei"),f=B(t.extraCostWei,"policy.extraCostWei"),d=B(t.minProfitWei,"policy.minProfitWei"),p=B(t.maxGasWei,"policy.maxGasWei"),c=B(t.maxLoanWei,"policy.maxLoanWei");ce(t.maxBlockDrift,"policy.maxBlockDrift");let a=n-r,l=o*s;if(l>Fe)throw new RangeError("gas cost must fit uint256");let w=an(r,i),g=l+w+u+f;if(g>Fe)throw new RangeError("total cost must fit uint256");let E=a-g,y=E>=d&&l<=p&&r<=c;return It({grossProfitWei:Q(a),gasCostWei:Q(l),loanPremiumWei:Q(w),totalCostWei:Q(g),netProfitWei:Q(E),status:y?"PROFITABLE":"UNPROFITABLE",executionReady:!1,mode:"shadow"})}var cn=/^(?:0|[1-9][0-9]*)$/,un=(1n<<256n)-1n;function ee(e){let t=null;return typeof e=="bigint"&&e>=0n&&(t=e),typeof e=="string"&&cn.test(e)&&(t=BigInt(e)),t!==null&&t<=un?t:null}function ue(e){return typeof e=="string"&&e.length>0?e:null}function Ue(e){return Array.isArray(e)&&e.every(t=>typeof t=="string")?e:null}function $(e,t){e.push(`MALFORMED_${t.replaceAll(/[^A-Za-z0-9]+/g,"_").toUpperCase()}`)}function ln(e){return Object.freeze(e.reasonCodes),Object.freeze(e)}function Nt(e,t,r){let n=[],o=e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{},s=t!==null&&typeof t=="object"&&!Array.isArray(t)?t:{},i=r!==null&&typeof r=="object"&&!Array.isArray(r)?r:{},u=ue(o.chainId),f=ue(i.chainId),d=ue(o.lender),p=ue(o.strategy),c=Ue(s.supportedChainIds),a=Ue(s.allowedLenders),l=Ue(s.allowedStrategies);u||$(n,"chainId"),f||$(n,"opts.chainId"),u&&f&&u!==f&&n.push("CHAIN_MISMATCH"),c?(!u||!c.includes(u))&&n.push("UNSUPPORTED_CHAIN"):$(n,"supportedChainIds"),d||$(n,"lender"),a?(!d||!a.includes(d))&&n.push("LENDER_NOT_ALLOWED"):$(n,"allowedLenders"),p||$(n,"strategy"),l?(!p||!l.includes(p))&&n.push("STRATEGY_NOT_ALLOWED"):$(n,"allowedStrategies");let w=ee(o.blockNumber),g=ee(i.currentBlock),E=ee(s.maxBlockDrift);w===null&&$(n,"blockNumber"),g===null&&$(n,"opts.currentBlock"),E===null&&$(n,"maxBlockDrift"),w!==null&&g!==null&&E!==null&&(w>g||g-w>E)&&n.push("STALE_BLOCK"),o.simulationStatus!=="PASS"&&n.push("SIMULATION_NOT_PASS"),o.repaymentStatus!=="PASS"&&n.push("REPAYMENT_NOT_PASS");let y=[["realizedProfitWei","minRealizedProfitWei","PROFIT_BELOW_MINIMUM",(m,b)=>m<b],["gasCostWei","maxGasWei","GAS_LIMIT_EXCEEDED",(m,b)=>m>b],["builderFeeWei","maxBuilderFeeWei","BUILDER_FEE_EXCEEDED",(m,b)=>m>b],["loanPremiumWei","maxLoanPremiumWei","LOAN_PREMIUM_EXCEEDED",(m,b)=>m>b],["loanAmountWei","maxLoanWei","LOAN_LIMIT_EXCEEDED",(m,b)=>m>b]],x={};for(let[m,b,I,h]of y){let C=ee(o[m]),N=ee(s[b]);x[m]=C,C===null&&$(n,m),N===null&&$(n,b),C!==null&&N!==null&&h(C,N)&&n.push(I)}i.armed!==!1&&n.push("NOT_DISARMED");let S={status:n.length===0?"ELIGIBLE":"BLOCKED",reasonCodes:[...new Set(n)],executionReady:!1,mode:"shadow"};return u&&(S.chainId=u),d&&(S.lender=d),p&&(S.strategy=p),w!==null&&(S.blockNumber=w.toString(10)),x.realizedProfitWei!==null&&(S.realizedProfitWei=x.realizedProfitWei.toString(10)),ln(S)}function q(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))q(t);Object.freeze(e)}return e}function le(e){return e instanceof Error&&e.message?e.message.slice(0,300):String(e||"unknown error").slice(0,300)}function fn(e,t){for(let r of[e?.cycleId,e?.id])if(typeof r=="string"&&r.trim())return r.trim().slice(0,160);return`cycle-${t}`}function dn(e,t){if(!e||typeof e!="object"||e.profitable===!1)return!1;if(typeof t=="function")return t(e)===!0;if(typeof t?.isProfitable=="function")return t.isProfitable(e)===!0;let r=Number(t?.minNetProfitUsd??0);return Number.isFinite(e.netProfitUsd)&&e.netProfitUsd>=(Number.isFinite(r)?r:0)}function Ot({collectCycles:e,evaluateCycle:t,store:r,policy:n={},intervalMs:o=6e4,now:s=Date.now}={}){if(typeof e!="function")throw new Error("collectCycles must be a function");if(typeof t!="function")throw new Error("evaluateCycle must be a function");if(!r||typeof r.append!="function"||typeof r.latest!="function")throw new Error("store must provide append() and latest()");if(!Number.isInteger(o)||o<=0)throw new Error("intervalMs must be a positive integer");if(typeof s!="function")throw new Error("now must be a function");let i=null,u=!1,f=0,d=0,p=null,c=[];function a(){return q({mode:"shadow",execution:!1,signer:!1,broadcaster:!1,running:i!==null,inFlight:u,ticks:f,failures:d,lastError:p})}async function l(){if(u)return q({ok:!1,skipped:"overlap"});u=!0;let S=s(),m=[],b=[],I=[],h=[],C=[];try{try{let A=await e();if(!Array.isArray(A))throw new Error("collectCycles must return an array");C=A}catch(A){m.push({stage:"collect",message:le(A)})}for(let A=0;A<C.length;A+=1){let T=C[A],P=fn(T,A);b.push({id:P});try{let _=await t(T,n),O={..._,cycleId:_?.cycleId??P};I.push(O),dn(_,n)&&h.push({...O,profitable:!0})}catch(_){m.push({stage:"evaluate",cycleId:P,message:le(_)})}}let N={id:`shadow-${S}-${f+1}`,observedAt:S,cyclesEvaluated:C.length,cycles:b,candidates:I,opportunities:h,errors:m};try{await r.append(N)}catch(A){m.push({stage:"persist",message:le(A)})}return f+=1,m.length?(d+=1,p=m.map(A=>A.message).join("; ")):p=null,c=r.latest()?.opportunities??q(structuredClone(h)),q({ok:m.length===0,observation:r.latest()??N})}catch(N){return f+=1,d+=1,p=le(N),q({ok:!1,error:p})}finally{u=!1}}function w(){return i!==null?!1:(i=setInterval(()=>l().catch(()=>{}),o),!0)}function g(){return i===null?!1:(clearInterval(i),i=null,!0)}async function E({timeoutMs:S=3e4}={}){if(!Number.isInteger(S)||S<=0)throw new Error("timeoutMs must be a positive integer");let m=Date.now()+S;for(;u;){if(Date.now()>=m)throw new Error("shadow engine drain timed out");await new Promise(b=>setTimeout(b,5))}return typeof r.drain=="function"&&await r.drain(),!0}function y(){return r.latest()}function x(){return q(structuredClone(c))}return q({tick:l,start:w,stop:g,drain:E,status:a,latest:y,opportunities:x})}import{mkdir as pn,open as Tt,readFile as kt,rename as mn,unlink as hn}from"node:fs/promises";import{dirname as bn,basename as wn,join as gn}from"node:path";var En=1e3;function G(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))G(t);Object.freeze(e)}return e}function We(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function V(e,t=300){return typeof e=="string"&&e.trim()?e.trim().slice(0,t):void 0}function yn(e){if(!e||typeof e!="object")return null;let t={},r=V(e.stage,30),n=V(e.message,300),o=V(e.cycleId,160);return r&&(t.stage=r),n&&(t.message=n),o&&(t.cycleId=o),Object.keys(t).length?t:null}function Rt(e,{signed:t=!1,max:r=96}={}){return typeof e!="string"||e.length>r?void 0:(t?/^-?(?:0|[1-9][0-9]*)$/:/^(?:0|[1-9][0-9]*)$/).test(e)?e:void 0}function Bt(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of["cycleId","chain","pair","tokenIn","tokenOut","strategy","venue","lender","qualification","economicStatus","eligibilityStatus","costModel","blockConsistency"]){let n=V(e[r],160);n&&(t[r]=n)}for(let r of["netProfitUsd","grossProfitUsd","costUsd","gasCostUsd","confidence"]){let n=We(e[r]);n!==void 0&&(t[r]=n)}for(let r of["amountInWei","amountOutWei","gasUnits","gasCostWei","loanPremiumWei","totalCostWei"]){let n=Rt(e[r]);n!==void 0&&(t[r]=n)}for(let r of["grossProfitWei","netProfitWei"]){let n=Rt(e[r],{signed:!0});n!==void 0&&(t[r]=n)}return["PROFITABLE","UNPROFITABLE","STALE","UNAVAILABLE","THEORETICAL"].includes(e.status)&&(t.status=e.status),typeof e.profitable=="boolean"&&(t.profitable=e.profitable),typeof e.economicallyProfitable=="boolean"&&(t.economicallyProfitable=e.economicallyProfitable),e.executionReady===!1&&(t.executionReady=!1),Array.isArray(e.reasonCodes)&&(t.reasonCodes=e.reasonCodes.map(r=>V(r,80)).filter(Boolean).slice(0,32)),Object.keys(t).length?t:null}function An(e){if(!e||typeof e!="object"||Array.isArray(e))return null;let t={};for(let r of["id","cycleId","chain","tokenIn","tokenOut","strategy"]){let n=V(e[r],160);n&&(t[r]=n)}return Object.keys(t).length?t:null}function $t(e,t){let r=e&&typeof e=="object"&&!Array.isArray(e)?e:{},n=We(r.observedAt)??We(r.timestamp)??t(),o=V(r.id,160)??`shadow-${n}`,s=Array.isArray(r.cycles)?r.cycles.map(An).filter(Boolean):[],i=Array.isArray(r.opportunities)?r.opportunities.map(Bt).filter(Boolean):[],u=Array.isArray(r.candidates)?r.candidates.map(Bt).filter(Boolean):[],f=Array.isArray(r.errors)?r.errors.map(yn).filter(Boolean):[];return{id:o,observedAt:n,mode:"shadow",cyclesEvaluated:Number.isInteger(r.cyclesEvaluated)&&r.cyclesEvaluated>=0?r.cyclesEvaluated:s.length,cycles:s,candidates:u,opportunities:i,errors:f}}function Lt({filePath:e,maxRecords:t=En,now:r=Date.now,persist:n=!0}={}){if(!Number.isInteger(t)||t<=0)throw new Error("maxRecords must be a positive integer");if(typeof r!="function")throw new Error("now must be a function");if(typeof n!="boolean")throw new Error("persist must be a boolean");if(n&&(typeof e!="string"||!e.trim()))throw new Error("filePath is required when persistence is enabled");let o=[],s=Promise.resolve(),i=()=>G(structuredClone(o));async function u(y){let x=JSON.parse(await kt(y,"utf8")),S=Array.isArray(x)?x:x?.records;if(!Array.isArray(S))throw new Error("shadow store payload is malformed");return S.map(m=>$t(m,r)).slice(-t)}async function f(){if(!n)return i();let y=s.then(async()=>{try{o=await u(e)}catch(x){if(x?.code==="ENOENT")try{o=await u(`${e}.bak`)}catch(S){if(S?.code==="ENOENT")o=[];else throw new Error("shadow store backup is corrupted")}else try{o=await u(`${e}.bak`)}catch{throw new Error("shadow store primary and backup are corrupted")}}return i()});return s=y.catch(()=>{}),y}let d=0;async function p(y,x){let S=bn(y),m=gn(S,`.${wn(y)}.${process.pid}.${Date.now()}.${d+=1}.tmp`);await pn(S,{recursive:!0,mode:448});let b;try{b=await Tt(m,"wx",384),await b.writeFile(x,"utf8"),await b.sync(),await b.close(),b=null,await mn(m,y);let I=await Tt(S,"r");try{await I.sync()}finally{await I.close()}}finally{b&&await b.close().catch(()=>{}),await hn(m).catch(()=>{})}}async function c(y){try{let x=await kt(e,"utf8"),S=JSON.parse(x);if(!Array.isArray(S)&&!Array.isArray(S?.records))throw new Error("shadow store payload is malformed");await p(`${e}.bak`,x)}catch(x){if(x?.code!=="ENOENT")throw new Error("refusing to overwrite corrupted shadow store")}await p(e,`${JSON.stringify({version:1,records:y})}
|
|
6
|
+
`)}async function a(y){let x=$t(y,r),S=s.then(async()=>{let m=[...o,x].slice(-t);return n&&await c(m),o=m,G(structuredClone(x))});return s=S.catch(()=>{}),S}async function l(){return await s,!0}function w({limit:y}={}){let x=Number.isInteger(y)&&y>=0?o.slice(-y):o;return G(structuredClone(x))}function g(){let y=o.at(-1);return y?G(structuredClone(y)):null}function E(){return G({records:o.length,maxRecords:t,candidates:o.reduce((y,x)=>y+x.candidates.length,0),opportunities:o.reduce((y,x)=>y+x.opportunities.length,0),errors:o.reduce((y,x)=>y+x.errors.length,0)})}return G({append:a,record:a,load:f,drain:l,list:w,latest:g,stats:E})}var Yn=/^(?:0|[1-9][0-9]*)$/,me="42161",sr="arbitrum",ir="WETH-USDC",he="arb-weth-usdc-uni-fee-round-trip",be="aave-v3";async function Jn(e){let{collectArbRoundTripCycles:t}=await Promise.resolve().then(()=>(or(),nr));return t(e)}function F(e,t,{positive:r=!1}={}){if(typeof e!="string"||!Yn.test(e)||r&&e==="0")throw new TypeError(`${t} must be ${r?"a positive":"a non-negative"} decimal string`);return B(e,t),e}function Ge(e,t,r,n){if(!Number.isSafeInteger(e)||e<r||e>n)throw new TypeError(`${t} must be an integer from ${r} through ${n}`);return e}function H(e){return e==null?e:structuredClone(e)}function L(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))L(t);Object.freeze(e)}return e}function Zn(e){return String(e?.message||e||"unknown provider failure").slice(0,300)}function ar(e={}){let t=F(e.amountInWei,"amountInWei",{positive:!0}),r=F(e.minProfitWei,"minProfitWei"),n=F(e.maxLoanWei,"maxLoanWei"),o=F(e.maxGasWei,"maxGasWei"),s=F(e.builderFeeWei,"builderFeeWei"),i=F(e.extraCostWei,"extraCostWei"),u=F(e.extraGasUnits,"extraGasUnits"),f=Ge(e.intervalMs,"intervalMs",1,864e5),d=Ge(e.maxBlockDrift,"maxBlockDrift",0,1e3),p=Ge(e.maxRecords,"maxRecords",1,1e5),c=e.dependencies??{},a=e.collectCycles??c.collectArbRoundTripCycles??Jn,l=e.readLenderState??c.readArbAaveLenderState??xt,w=e.evaluateEconomics??c.evaluateCycleEconomics??Ct,g=e.evaluateEligibility??c.evaluateFlashLoanCandidate??Nt,E=e.createEngine??c.createShadowEngine??Ot,y=e.createStore??c.createShadowStore??Lt;for(let[_,O]of Object.entries({collect:a,readLender:l,evaluateEconomics:w,evaluateEligibility:g,makeEngine:E,makeStore:y}))if(typeof O!="function")throw new TypeError(`${_} dependency must be a function`);let x=y({filePath:e.filePath,persist:e.persist??!0,maxRecords:p,now:e.now??Date.now}),S=[],m=null,b=null,I=null,h=L({async append(_){return await x.append(_),S=[...S,L(H(_))].slice(-p),L(H(_))},async drain(){return typeof x.drain=="function"&&await x.drain(),!0},latest(){return S.length?L(H(S.at(-1))):null}});async function C(){try{I=await l(e.lenderOptions??e)}catch(_){I={status:"UNAVAILABLE",block:null,premiumBps:null,reasons:[Zn(_)]}}if(m=L(H(I)),!I||I.status!=="AVAILABLE")throw new Error(`lender ${I?.status?.toLowerCase()||"unavailable"}: ${(I?.reasons||[]).join("; ")}`);if(!Number.isSafeInteger(I.block)||!Number.isSafeInteger(I.premiumBps)||I.premiumBps<0)throw new Error("lender returned malformed live state");if(b=await a({...e.collectorOptions,amountInWei:t,maxBlockDrift:d,pinnedBlock:I.block}),!b||!Array.isArray(b.cycles))throw new Error("quote provider returned malformed snapshot");if(b.stale===!0||b.blockDrift>d)throw new Error("stale quote snapshot");if(!Number.isSafeInteger(b.blockEnd)||Math.abs(b.blockEnd-I.block)>d)throw new Error("stale lender snapshot relative to quotes");return F(b.gasPriceWei,"quoteSnapshot.gasPriceWei",{positive:!0}),b.cycles}async function N(_){if(!_||_.status!=="OK")throw new Error(_?.error||"cycle quote unavailable");let O=(BigInt(F(_.gasUnits,"cycle.gasUnits"))+BigInt(u)).toString(),Ae={..._,gasUnits:O,gasPriceWei:b.gasPriceWei},v=await w(Ae,{loanPremiumBps:I.premiumBps,builderFeeWei:s,extraCostWei:i,minProfitWei:r,maxGasWei:o,maxLoanWei:n,maxBlockDrift:d}),xe=await g({chainId:me,lender:be,strategy:he,blockNumber:String(b.blockEnd),realizedProfitWei:v.netProfitWei.startsWith("-")?"0":v.netProfitWei,gasCostWei:v.gasCostWei,builderFeeWei:s,loanPremiumWei:v.loanPremiumWei,loanAmountWei:_.amountInWei},{supportedChainIds:[me],allowedLenders:[be],allowedStrategies:[he],maxBlockDrift:String(d),minRealizedProfitWei:r,maxGasWei:o,maxBuilderFeeWei:s,maxLoanPremiumWei:v.loanPremiumWei,maxLoanWei:n},{chainId:me,currentBlock:String(b.blockEnd),armed:!1}),Ke=[...new Set([...xe.reasonCodes,"L1_DATA_FEE_NOT_MODELED","EXECUTOR_GAS_NOT_SIMULATED","LENDER_LIQUIDITY_NOT_CHECKED","CROSS_VENUE_CAMELOT_PANCAKE_NOT_QUOTED",...b.blockConsistency==="PINNED"?[]:["QUOTE_BLOCK_NOT_PINNED"]])],wr=v.status==="PROFITABLE"&&xe.status==="ELIGIBLE"&&Ke.length===0;return L({cycleId:`${_.entryVenue||"unknown"}->${_.exitVenue||"unknown"}`,chain:sr,pair:ir,strategy:he,lender:be,amountInWei:_.amountInWei,amountOutWei:_.amountOutWei,gasUnits:O,...v,status:"THEORETICAL",economicStatus:v.status,economicallyProfitable:v.status==="PROFITABLE",qualification:"THEORETICAL_ONLY",eligibilityStatus:xe.status,reasonCodes:Ke,costModel:"INCOMPLETE_ESTIMATE",blockConsistency:b.blockConsistency??"RANGE_ONLY",profitable:wr,executionReady:!1,mode:"shadow"})}let A=E({collectCycles:C,evaluateCycle:N,store:h,policy:{isProfitable:_=>_?.profitable===!0},intervalMs:f,now:e.now??Date.now});async function T(){let _=await x.load();return S=H(_).slice(-p),L(H(S))}function P(){return L({mode:"shadow",execution:!1,signer:!1,broadcaster:!1,chain:sr,chainId:me,pair:ir,strategy:he,lender:be,...A.status(),lastProviderState:L(H(m))})}return L({load:T,tick:A.tick,start:A.start,stop:A.stop,drain:A.drain,status:P,latest:h.latest,opportunities:()=>L(H(h.latest()?.opportunities??[]))})}import{createServer as ro}from"node:http";var ys=Object.freeze(["chainId","agentAddress","accountAddress","actions","targets","maxValueWei","maxGasWei","maxSlippageBps","expiresAt","nonce","revocationKey"]),As=Object.freeze(["read","simulate"]);var xs=1440*60;var U=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}},Qn=/(private[_-]?key|secret|bearer|keystore|mnemonic|seed[_-]?phrase|passphrase|password|api[_-]?key|access[_-]?token|auth[_-]?token|session[_-]?token|signer[_-]?url|signature)/i,eo=Object.freeze(["privkey","wif","xprv","seed"]);function Ve(e){let t=String(e),r=t.toLowerCase().replace(/[\s._-]+/g,"");return Qn.test(t)||eo.includes(r)}var cr=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}]),ur=Object.freeze(["grantid","id","hash","sha256","sha256hex","checksum","txhash","transactionhash","blockhash","digest","userophash","commithash","prevhash","intenthash","canonicalhash","payloadhash","requestid"]);function to(e){return e.replace(/"([A-Za-z0-9_-]+)"\s*:\s*"(?:0x)?([0-9a-fA-F]{64})"/g,(t,r)=>ur.includes(String(r).toLowerCase().replace(/[_-]/g,""))?`"${r}":"<hex64>"`:t)}function lr(e){let t;try{t=JSON.stringify(e)}catch(o){throw new U("$",`unserializable-payload: ${String(o?.message||o)}`)}if(t===void 0)return"null";let r=to(t);for(let{rule:o,re:s}of cr)if(s.test(r))throw new U("$<serialized>",o);if(/(?:^|[^0-9a-fA-Fx])0x[0-9a-fA-F]{64}(?![0-9a-fA-F])/.test(r))throw new U("$<serialized>","raw-32-byte-hex-embedded");return JSON.parse(t,(o,s)=>{if(o&&Ve(o))throw new U(`$<serialized>.${o}`,"forbidden-key-name");return s}),t}function X(e,t="$",r=new Set,n=""){if(e==null)return e;if(typeof e=="string"){let o=ur.includes(String(n).toLowerCase().replace(/[_-]/g,""));for(let{rule:s,re:i}of cr)if(!(o&&s.startsWith("raw-32-byte-hex"))&&i.test(e))throw new U(t,s);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,s]of e.entries()){if(typeof o=="string"&&Ve(o))throw new U(`${t}[${JSON.stringify(o)}]`,"forbidden-key-name");X(o,`${t}[key]`,r),X(s,`${t}[${String(o)}]`,r)}return e}if(e instanceof Set){let o=0;for(let s of e.values())X(s,`${t}[${o++}]`,r);return e}if(Array.isArray(e))return e.forEach((o,s)=>X(o,`${t}[${s}]`,r)),e;for(let[o,s]of Object.entries(e)){if(Ve(o))throw new U(`${t}.${o}`,"forbidden-key-name");X(s,`${t}.${o}`,r,o)}return e}var fr=null,no="127.0.0.1",oo=8798,so=1e6,io='{"error":"redacted"}',ao=Object.freeze({"content-type":"application/json; charset=utf-8","cache-control":"no-store","content-security-policy":"default-src 'none'","x-content-type-options":"nosniff","x-frame-options":"DENY"});function co(e){if(!((e==="localhost"||e==="::1"||/^127(?:\.\d{1,3}){3}$/.test(e))&&(!e.startsWith("127.")||e.split(".").slice(1).every(t=>Number(t)<=255))))throw new Error("host must be a loopback address")}function uo(e){if(!e||["status","latest","opportunities"].some(t=>typeof e[t]!="function"))throw new Error("runtime must provide status(), latest(), and opportunities()")}function lo(e){typeof fr=="function"&&fr(e),X(e);let t=lr(e);if(Buffer.byteLength(t)>so)throw new Error("response too large");return t}function j(e,t,r){let n,o=t;try{n=lo(r)}catch{o=500,n=io}e.writeHead(o,{...ao,"content-length":Buffer.byteLength(n)}),e.end(n)}function dr({runtime:e,host:t=no,port:r=oo}={}){if(uo(e),typeof t!="string")throw new Error("host must be a loopback address");if(co(t),!Number.isInteger(r)||r<0||r>65535)throw new Error("port must be an integer between 0 and 65535");function n(){let c=e.status(),a=Number.isSafeInteger(c?.ticks)?c.ticks:0,l=typeof c?.lastProviderState?.status=="string"?c.lastProviderState.status:"UNKNOWN",w=c?.running===!0&&a>0&&c?.lastError==null&&l==="AVAILABLE";return{httpStatus:w?200:503,body:{ok:w,ready:w,service:"oracle-mev-shadow",mode:"shadow",execution:!1,signer:!1,broadcaster:!1,ticks:a,provider:l}}}let o=new Map([["/status",()=>e.status()],["/latest",()=>e.latest()],["/opportunities",()=>e.opportunities()]]);async function s(c,a){if(c.method!=="GET"){j(a,405,{error:"method-not-allowed"});return}let l;try{l=new URL(c.url||"/","http://localhost").pathname}catch{j(a,404,{error:"not-found"});return}if(l==="/health"){try{let g=n();j(a,g.httpStatus,g.body)}catch{j(a,503,{error:"redacted"})}return}let w=o.get(l);if(!w){j(a,404,{error:"not-found"});return}try{j(a,200,await w())}catch{j(a,500,{error:"redacted"})}}let i=ro((c,a)=>{s(c,a).catch(()=>{a.headersSent?a.destroy():j(a,500,{error:"redacted"})})}),u=null;function f(){let c=i.address();return c&&typeof c=="object"?{address:c.address,family:c.family,port:c.port}:null}function d(){return i.listening?Promise.resolve(f()):u||(u=new Promise((c,a)=>{let l=g=>{i.off("listening",w),u=null,a(g)},w=()=>{i.off("error",l);let g=f();u=null,c(g)};i.once("error",l),i.once("listening",w),i.listen(r,t)}),u)}async function p(){if(u)try{await u}catch{return!1}return i.listening?(await new Promise((c,a)=>i.close(l=>l?a(l):c())),!0):!1}return Object.freeze({start:d,stop:p,address:f,handler:s})}var pr=/^(?:0|[1-9][0-9]*)$/,ho=/^127(?:\.\d{1,3}){3}$/,bo=(1n<<256n)-1n;function ge(e){if(e&&typeof e=="object"&&!Object.isFrozen(e)){for(let t of Object.values(e))ge(t);Object.freeze(e)}return e}function Xe(e,t){let r=String(e??"").trim().toLowerCase();if(!["","0","false","off"].includes(r))throw new Error(`${t} must remain disarmed for the arb paper shadow service`)}function wo(e){return e==="localhost"||e==="::1"?!0:ho.test(e)?e.split(".").slice(1).every(t=>Number(t)<=255):!1}function K(e,t,r,{positive:n=!1}={}){let o=String(e[t]??r);if(!pr.test(o)||n&&o==="0")throw new TypeError(`${t} must be ${n?"a positive":"a non-negative"} decimal string`);if(BigInt(o)>bo)throw new RangeError(`${t} must fit uint256`);return o}function we(e,t,r,n,o,s){let i=String(e[t]??r);if(!pr.test(i))throw new TypeError(`${s} must be an integer`);let u=Number(i);if(!Number.isSafeInteger(u)||u<n||u>o)throw new TypeError(`${s} must be an integer from ${n} through ${o}`);return u}function go(e=process.env){Xe(e.ORACLE_EXECUTE_ENABLED,"ORACLE_EXECUTE_ENABLED"),Xe(e.MAD_EXECUTE_ENABLED,"MAD_EXECUTE_ENABLED"),Xe(e.ORACLE_MEV_EXECUTE_ENABLED,"ORACLE_MEV_EXECUTE_ENABLED");let t=String(e.ORACLE_MEV_ARB_SHADOW_HOST??"127.0.0.1").trim();if(!wo(t))throw new Error("ORACLE_MEV_ARB_SHADOW_HOST must be loopback-only");let r=String(e.HOME||fo()),n=String(e.ORACLE_MEV_ARB_SHADOW_STATE??mo(r,".local/state/oracle/mev-arb-shadow/observations.json"));if(!po(n))throw new Error("ORACLE_MEV_ARB_SHADOW_STATE must be an absolute path");let o=String(e.ORACLE_MEV_ARB_SHADOW_PERSIST??"1").trim();if(!["0","1"].includes(o))throw new Error("persist must be 0 or 1");return ge({host:t,port:we(e,"ORACLE_MEV_ARB_SHADOW_PORT","8809",0,65535,"port"),intervalMs:we(e,"ORACLE_MEV_ARB_SHADOW_INTERVAL_MS","15000",1e3,864e5,"intervalMs"),amountInWei:K(e,"ORACLE_MEV_ARB_SHADOW_AMOUNT_IN_WEI","1000000000000000000",{positive:!0}),minProfitWei:K(e,"ORACLE_MEV_ARB_SHADOW_MIN_PROFIT_WEI","10000000000000"),maxLoanWei:K(e,"ORACLE_MEV_ARB_SHADOW_MAX_LOAN_WEI","5000000000000000000",{positive:!0}),maxGasWei:K(e,"ORACLE_MEV_ARB_SHADOW_MAX_GAS_WEI","500000000000000"),builderFeeWei:K(e,"ORACLE_MEV_ARB_SHADOW_BUILDER_FEE_WEI","0"),extraCostWei:K(e,"ORACLE_MEV_ARB_SHADOW_EXTRA_COST_WEI","0"),extraGasUnits:K(e,"ORACLE_MEV_ARB_SHADOW_EXTRA_GAS_UNITS","250000"),maxBlockDrift:we(e,"ORACLE_MEV_ARB_SHADOW_MAX_BLOCK_DRIFT","40",0,1e3,"maxBlockDrift"),maxRecords:we(e,"ORACLE_MEV_ARB_SHADOW_MAX_RECORDS","500",1,1e5,"maxRecords"),filePath:n,persist:o==="1"})}function mr({env:e=process.env,runtimeFactory:t=ar,serverFactory:r=dr}={}){if(typeof t!="function"||typeof r!="function")throw new TypeError("runtimeFactory and serverFactory must be functions");let n=go(e),o=t(n),s=r({runtime:o,host:n.host,port:n.port}),i=null,u=null;async function f(){return i||u||(u=(async()=>{let c=!1;try{await o.load();let a=await o.tick();o.start(),c=!0;let l=await s.start();return i=ge({mode:"shadow",chain:"arbitrum",chainId:42161,execution:!1,signer:!1,broadcaster:!1,address:l,initialTick:a}),i}catch(a){try{await s.stop()}catch{}if(c)try{o.stop(),typeof o.drain=="function"&&await o.drain()}catch{}throw a}finally{u=null}})(),u)}async function d(){if(u)try{await u}catch{}if(!i)return!1;let c=null;try{await s.stop()}catch(a){c=a}if(o.stop(),typeof o.drain=="function"&&await o.drain(),i=null,c)throw c;return!0}function p(){return ge({mode:"shadow",chain:"arbitrum",chainId:42161,execution:!1,signer:!1,broadcaster:!1,listening:!!i,address:s.address(),runtime:o.status()})}return Object.freeze({start:f,stop:d,status:p,config:n})}var Ee="oracle-mev-arb-shadow";function ye(e,t){e.write(`${JSON.stringify(t)}
|
|
7
|
+
`)}async function hr({env:e=process.env,appFactory:t=mr,stdout:r=process.stdout,stderr:n=process.stderr,processLike:o=process}={}){if(typeof t!="function")throw new TypeError("appFactory must be a function");if(!r||typeof r.write!="function"||!n||typeof n.write!="function")throw new TypeError("stdout and stderr must be writable streams");if(!o||typeof o.once!="function")throw new TypeError("processLike must provide once()");let s=t({env:e}),i=null;async function u(p="shutdown"){return i||(i=(async()=>{try{return await s.stop(),ye(r,{event:"stopped",service:Ee,signal:p}),!0}catch{return o.exitCode=1,ye(n,{event:"fatal",service:Ee,error:"shutdown failed"}),!1}})(),i)}for(let p of["SIGINT","SIGTERM"])o.once(p,()=>{u(p).catch(()=>{o.exitCode=1})});let f;try{f=await s.start()}catch{throw o.exitCode=1,ye(n,{event:"fatal",service:Ee,error:"startup failed"}),new Error("arb paper shadow service failed to start")}let d=f?.address&&typeof f.address=="object"?f.address:{};return ye(r,{event:"listening",service:Ee,mode:"shadow",chain:"arbitrum",chainId:42161,execution:!1,signer:!1,broadcaster:!1,address:d.address??null,family:d.family??null,port:d.port??null}),Object.freeze({app:s,stop:u})}var br=process.argv.slice(2);(br.includes("--help")||br.includes("-h"))&&(process.stdout.write(`Usage: oracle-mev-arb-shadow [--help]
|
|
6
8
|
Loopback-only Arbitrum paper MEV observer. Never prepares, signs, or broadcasts.
|
|
7
|
-
`),process.exit(0));
|
|
9
|
+
`),process.exit(0));hr().catch(()=>{process.exitCode=1});
|