@oracle-agent/oracle 0.35.0 → 0.35.2
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 +23 -23
- package/dist/bin/oracle-data-mcp.mjs +11 -11
- package/dist/bin/oracle-gateway.mjs +36 -37
- package/dist/bin/oracle-telegram-mcp.mjs +12 -13
- package/dist/cli/commands/chat.mjs +200 -189
- package/dist/cli/commands/doctor.mjs +3 -3
- package/dist/cli/commands/eval.mjs +68 -67
- package/dist/cli/commands/farm.mjs +15 -15
- package/dist/cli/commands/model.mjs +204 -193
- package/dist/cli/commands/setup.mjs +35 -35
- package/dist/cli/commands/telegram.mjs +10 -11
- package/dist/data/desk-data.mjs +21 -21
- package/dist/index.mjs +35 -35
- package/package.json +1 -1
- package/public/install.ps1 +3 -3
- package/public/oracle-splash/assets/oracle-cli-v035-poster.jpg +0 -0
- package/public/oracle-splash/assets/oracle-cli-v035.gif +0 -0
- package/public/oracle-splash/downloads/index.html +2 -16
- package/public/oracle-splash/index.html +202 -138
- package/public/oracle-splash/install.ps1 +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
var sr=Object.defineProperty;var _=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var ar=(e,t)=>{for(var r in t)sr(e,r,{get:t[r],enumerable:!0})};import q from"node:net";import cr from"node:dns";function ue(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=u=>{if(!u)return[];let d=u.split(":"),p=d.at(-1);if(p?.includes(".")){let h=p.split(".").map(Number);if(h.length!==4||h.some(f=>!Number.isInteger(f)||f<0||f>255))return null;d.splice(d.length-1,1,(h[0]<<8|h[1]).toString(16),(h[2]<<8|h[3]).toString(16))}return d.some(h=>!/^[0-9a-f]{1,4}$/.test(h))?null:d.map(h=>Number.parseInt(h,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let a=t.includes("::"),l=8-i.length-s.length;if(!a&&l!==0||a&&l<1)return null;let c=[...i,...Array(Math.max(0,l)).fill(0),...s];return c.length!==8?null:Uint8Array.from(c.flatMap(u=>[u>>8,u&255]))}function
|
|
2
|
-
`),l=pr("sha256").update(a).digest("hex").slice(0,32),c=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`;return`${e} ${t} ${c} ${l}`}function Sr(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,Ze):Math.min(250*2**e,Ze)+Math.floor(Math.random()*100)}function Q(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function Pe(e,t,r){return Q(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function Z(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function kr(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 i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(Z(e),!n))throw Pe(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let d=await e.text(),p=Buffer.byteLength(d,"utf8");if(p>t){if(!n)throw Pe(r,`body ${p} bytes`,t);return Buffer.from(d,"utf8").subarray(0,t).toString("utf8")}return d}let a=[],l=0,c=!1;try{for(;;){let{value:d,done:p}=await s.read();if(p)break;if(d&&(a.push(Buffer.from(d)),l+=kr(d),l>t)){c=!0;break}}}finally{if(c)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(c&&(typeof o=="function"&&o(),!n))throw Pe(r,`streamed ${l} bytes`,t);let u=Buffer.concat(a);return(c?u.subarray(0,t):u).toString("utf8")}function rt(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Ar(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:l=!1,maxResponseBytes:c=null,importUndici:u,validateResponse:d,signal:p}){let h=new AbortController,f=setTimeout(()=>h.abort(),i),b=p?typeof AbortSignal.any=="function"?AbortSignal.any([p,h.signal]):p:h.signal,w=null,E=t,y=s?{lookupFn:s}:{};if(l&&!a&&!Ae(E))throw Q(`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 x=async(m,{status:k=null}={})=>{let S=await Se(m,y);if(!S.ok)throw Q(k==null?`HTTP refused ${m}: ${S.error}`:`HTTP redirect to ${m} ${S.error}`,k==null?{}:{status:k});let g=new URL(m).hostname;if(a){if(w&&(await w.close(),w=null),!w)try{w=await Ie({requireUndici:!0,...u?{importUndici:u}:{}})}catch(P){throw Q(k==null?`HTTP refused ${m}: ${P?.message||P}`:`HTTP redirect to ${m} refused: ${P?.message||P}`,k==null?{}:{status:k})}w.pin(g,S.addresses),E=w.fetch}else Xe(E,g,S.addresses);return S};try{let m=String(e),k={...n||{}};l&&await x(m);for(let S=0;S<=et;S+=1){let g=await E(m,{method:r,headers:k,body:o,signal:b,redirect:"manual"});if(mr.has(g.status)){if(r!=="GET"&&r!=="HEAD"){let $=await tt(g,c??wr,{url:m,truncate:!0}),L=new Error(`HTTP ${g.status} ${r} ${m} redirected non-idempotent request`);throw L.status=g.status,L.body=rt($)??$.slice(0,300),L}if(S===et)throw Z(g),new Error(`HTTP redirect loop for ${e}`);let v=g.headers?.get?.("location"),D;try{D=yr(v,m)}catch($){throw Z(g),$}let Y=!xr(D,m);if(Z(g),Y&&(k=br(k)),l)await x(D,{status:g.status});else if(Y){let $=await Se(D,y);if(!$.ok){let L=new Error(`HTTP redirect from ${m} ${$.error}`);throw L.status=g.status,L.retryable=!1,L}a&&$.addresses?.length&&(w||(w=await Ie(u?{importUndici:u}:{})),w&&(w.pin(new URL(D).hostname,$.addresses),E=w.fetch))}m=D;continue}if(typeof d=="function")try{await d(g,{url:m})}catch(v){throw Z(g),Q(v?.message||String(v))}let P=await tt(g,c,{url:m,onOversize:()=>h.abort()}),le=rt(P);if(!g.ok){let v=new Error(`HTTP ${g.status} ${r} ${m}`);throw v.status=g.status,v.retryAfter=g.headers?.get?.("retry-after")??null,v.body=le??P.slice(0,300),v}return le??P}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(f),w&&await w.close()}}async function H(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,o=(t.method||"GET").toUpperCase(),i={Accept:"application/json",...t.headers||{}},s=t.body;s!=null&&typeof s!="string"&&(i["Content-Type"]=i["Content-Type"]||"application/json",s=JSON.stringify(s));let a=Number.isInteger(t.retries)?Math.max(t.retries,0):fr,l=t.lookupFn,c=!t.fetchImpl,u=t.untrustedUrl===!0,d=t.importUndici,p=t.validateResponse,h=t.signal,f=Number(t.maxResponseBytes),b=Number.isFinite(f)&&f>0?Math.floor(f):null,w=async()=>{let k;for(let S=0;S<=a;S++){h?.throwIfAborted?.();try{return await Ar(e,{fetchImpl:r,method:o,headers:i,body:s,timeoutMs:n,lookupFn:l,realFetch:c,untrustedUrl:u,maxResponseBytes:b,importUndici:d,validateResponse:p,signal:h})}catch(g){k=g;let P=g?.status,le=g?.name==="AbortError"||g?.name==="TimeoutError"||h?.aborted,v=new Set([408,425,429]),D=g?.retryable===!1?!1:P!=null?v.has(P)||hr.has(P)&&Qe.has(o):!le&&Qe.has(o);if(S===a||!D)throw g;let Y=Sr(S,g?.retryAfter);h?await new Promise(($,L)=>{let ir=setTimeout($,Y);h.addEventListener("abort",()=>{clearTimeout(ir),L(h.reason||new DOMException("Aborted","AbortError"))},{once:!0})}):await Ir(Y)}}throw k};if(!(t.dedupe!==!1&&!h&&o==="GET"&&s==null))return w();let y=Er(o,e,i,{untrustedUrl:u,maxResponseBytes:b}),x=Ne.get(y);if(x)return x;let m=w().finally(()=>Ne.delete(y));return Ne.set(y,m),m}var hr,Qe,fr,Ze,nt,mr,et,wr,Ne,Ir,de=_(()=>{Ye();hr=new Set([408,425,429,500,502,503,504]),Qe=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),fr=2,Ze=4e3,nt=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],mr=new Set([301,302,303,307,308]),et=3,wr=64*1024;Ne=new Map;Ir=e=>new Promise(t=>setTimeout(t,e))});function Cr({testnet:e,baseUrl:t}={}){if(t)return t.replace(/\/$/,"").endsWith("/info")?t:`${t.replace(/\/$/,"")}/info`;if(process.env.HL_INFO_URL)return process.env.HL_INFO_URL;if(process.env.HL_API_URL){let r=process.env.HL_API_URL.replace(/\/$/,"");return r.endsWith("/info")?r:`${r}/info`}return e||process.env.HL_TESTNET==="1"?Or:Lr}async function G(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=Cr(t);return H(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function at(e={}){return G({type:"allMids"},e)}async function te(e={}){let t={type:"metaAndAssetCtxs"};return e.dex&&(t.dex=e.dex),G(t,e)}var Lr,Or,pe=_(()=>{de();Lr="https://api.hyperliquid.xyz/info",Or="https://api.hyperliquid-testnet.xyz/info"});import{createHash as Rr,createHmac as Fr,timingSafeEqual as ao}from"node:crypto";function ve(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ve).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ve(e[r])}`).join(",")}}`}function ct(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function lt(e=process.env){return ct(process.env)||ct(e)}function zr(e){let{prepareHash:t,prepareMac:r,note:n,...o}=e||{};return o}function qr(e){let t=zr(e);return Rr("sha256").update(ve(t)).digest("hex")}function Hr(e,t=lt()){return t?Fr("sha256",t).update(String(e)).digest("hex"):""}function B(e,{provider:t,kind:r,env:n=process.env,nowMs:o=Date.now(),expiresAtMs:i}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let s=Object.prototype.hasOwnProperty.call(e,"oraclePrepared");if(s&&typeof e.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let a={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:s?e.oraclePrepared:!0};if(!a.provider)throw new Error("stampPrepared: provider required");if(!a.kind)throw new Error("stampPrepared: kind required");let l=Number(o),c=i==null?l+Br:Number(i),u=c-l;if(!Number.isSafeInteger(l)||!Number.isSafeInteger(c)||u<=0||u>Ur)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let p={...a,preparedAt:l,expiresAt:c,prepareVersion:Dr},h=qr(p),f=lt(n),b=f?Hr(h,f):void 0,w={...p,prepareHash:h};return b&&(w.prepareMac=b),w}var Dr,Br,Ur,he=_(()=>{Dr=2,Br=300*1e3,Ur=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});async function pt(e={}){let t=Date.now();if(ne.dexs&&t-ne.at<6e4&&!e.fetchImpl)return ne.dexs;let r=await G({type:"perpDexs"},e);return ne={at:t,dexs:Array.isArray(r)?r:[]},ne.dexs}async function ht(e="",t={}){let r=e||"",n=Date.now(),o=dt.get(r);if(o&&n-o.at<3e4&&!t.fetchImpl)return o;let i=e?await G({type:"metaAndAssetCtxs",dex:e},t):await te(t),s=i?.[0]?.universe??i?.universe??[],a=Array.isArray(i?.[1])?i[1]:[],l={at:n,universe:s,ctxs:a};return dt.set(r,l),l}function ge(e){if(typeof e!="string"||!/^#(?:0|[1-9]\d*)$/.test(e))return null;let t=Number(e.slice(1));if(!Number.isSafeInteger(t)||t<0)return null;let r=t%10;if(r!==0&&r!==1)return null;let n=Math.floor(t/10),o=mt+t;return Number.isSafeInteger(o)?{encoding:t,outcome:n,side:r,coin:`#${t}`,assetId:o}:null}function ft(e,t){let r=_e(e),n=_e(t);if(r==null)throw new Error("hl-assets: outcome id must be a non-negative integer");if(n!==0&&n!==1)throw new Error("hl-assets: outcome side must be 0 or 1");let o=10*r+n;if(!Number.isSafeInteger(o))throw new Error("hl-assets: outcome encoding exceeds safe integer range");let i=mt+o;if(!Number.isSafeInteger(i))throw new Error("hl-assets: outcome asset id exceeds safe integer range");return{encoding:o,outcome:r,side:n,coin:`#${o}`,assetId:i}}function _e(e){if(typeof e=="number")return Number.isSafeInteger(e)&&e>=0?e:null;if(typeof e!="string"||!/^(?:0|[1-9]\d*)$/.test(e))return null;let t=Number(e);return Number.isSafeInteger(t)?t:null}async function Te(e={},t={}){if(e.outcome!=null||typeof e.coin=="string"&&e.coin.startsWith("#")){let c=e.coin==null?null:ge(e.coin);if(e.coin!=null&&!c)throw new Error(`hl-assets: invalid outcome coin ${e.coin}`);let u=e.outcome==null?null:ft(e.outcome,0).outcome;if(u!=null&&c&&c.outcome!==u)throw new Error("hl-assets: coin does not match outcome");let d=e.outcomeSide==null?null:Gr(e.outcomeSide,"outcomeSide"),p=u??c?.outcome;if(e.outcome!=null&&e.coin==null&&d==null)throw new Error("hl-assets: outcomeSide required");let h=d??c?.side;if(h==null)throw new Error("hl-assets: outcomeSide required");if(p==null)throw new Error("hl-assets: outcome identity required");let f=ft(p,h);if(c&&(c.outcome!==f.outcome||c.side!==f.side))throw new Error("hl-assets: coin does not match outcome side");let b=e.szDecimals!=null?Number(e.szDecimals):2;return{kind:"outcome",coin:f.coin,assetId:f.assetId,encoding:f.encoding,outcome:f.outcome,side:f.side,szDecimals:b,maxLeverage:1,dex:null,markPx:null}}let r=String(e.coin||e.symbol||e.name||"").trim();if(!r)throw new Error("hl-assets: coin required");if(r.includes(":")){let[c,...u]=r.split(":"),d=u.join(":");if(!c||!d)throw new Error(`hl-assets: bad builder coin ${r}`);let h=(await pt(t)).findIndex(m=>m&&m.name===c);if(h<1)throw new Error(`hl-assets: unknown builder dex "${c}"`);let{universe:f,ctxs:b}=await ht(c,t),w=f.findIndex(m=>m.name===r||m.name===`${c}:${d}`||m.name.endsWith(`:${d}`));if(w<0)throw new Error(`hl-assets: ${r} not in dex ${c} meta`);let E=f[w];if(E.isDelisted)throw new Error(`hl-assets: ${r} is delisted`);let y=jr+h*1e4+w,x=b[w]||{};return{kind:"hip3",coin:E.name||r,assetId:y,szDecimals:E.szDecimals??0,maxLeverage:E.maxLeverage??null,dex:c,dexIndex:h,indexInMeta:w,markPx:x.markPx??null}}let{universe:n,ctxs:o}=await ht("",t),i=r.toUpperCase(),s=n.findIndex(c=>c.name===i);if(s<0){if(t.allowBareBuilderLeaf===!0)try{let c=await pt(t);for(let u=1;u<c.length;u++){let d=c[u];if(!d?.name)continue;let p=`${d.name}:${i}`;try{return await Te({coin:p},t)}catch{}}}catch{}throw new Error(`hl-perps: ${i} is not a listed perp`)}let a=n[s];if(a.isDelisted)throw new Error(`hl-assets: ${i} is delisted`);let l=o[s]||{};return{kind:"main",coin:a.name,assetId:s,szDecimals:a.szDecimals??0,maxLeverage:a.maxLeverage??null,dex:"",markPx:l.markPx??null}}function Gr(e,t){let r=_e(e);if(r!==0&&r!==1)throw new Error(`hl-assets: ${t} must be 0 or 1`);return r}var mt,jr,ne,dt,Me=_(()=>{pe();mt=1e8,jr=1e5,ne={at:0,dexs:null},dt=new Map});function I(e,t="value"){if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`${t} must be a finite number`);if(Math.abs(e)>Number.MAX_SAFE_INTEGER)throw new Error(`${t} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);if(Number.isInteger(e)&&!Number.isSafeInteger(e))throw new Error(`${t} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return String(e)}if(typeof e=="string"){if(e!==e.trim())throw new Error(`${t} must be a number or decimal string`);return e}throw new Error(`${t} must be a number or decimal string`)}function wt(e,t="value"){if(typeof e!="string"||e==="")throw new Error(`${t} must be a string`);return e}function V(e,t="amount"){if(typeof e=="bigint")return e;if(typeof e=="number"){if(!Number.isInteger(e))throw new Error(`${t} must be an integer`);if(!Number.isSafeInteger(e))throw new Error(`${t} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return BigInt(e)}let r=I(e,t);if(r==="")throw new Error(`${t} is required`);if(!/^-?\d+$/.test(r)&&!/^0x[0-9a-fA-F]+$/.test(r))throw new Error(`${t} must be an integer in decimal or 0x-hex form, got ${JSON.stringify(r)}`);try{return BigInt(r)}catch{throw new Error(`${t} must be an integer, got ${JSON.stringify(r)}`)}}function Le(e,t="amount"){let r=V(e,t);if(r<=0n)throw new Error(`${t} must be positive`);return r}function N(e,t,r="amount"){let n=I(e,r);if(!/^-?\d*(\.\d+)?$/.test(n)||n===""||n==="."||n==="-")throw new Error(`${r} must be a decimal number, got ${JSON.stringify(n)}`);let o=n.startsWith("-"),i=o?n.slice(1):n,[s="0",a=""]=i.split(".");if(a.length>t)throw new Error(`${r} has more than ${t} decimal places, which would lose precision`);let l=BigInt((s||"0")+a.padEnd(t,"0"));return o?-l:l}var be=_(()=>{});function Xr(e,t){let r=e.toString().padStart(t+1,"0");if(t===0)return r;let n=r.slice(0,-t),o=r.slice(-t).replace(/0+$/,"");return o?`${n}.${o}`:n}function gt(e,t){let r=I(e,`hl: ${t}`);if(!/^\d+(?:\.\d+)?$/.test(r))throw new Error(`hl: ${t} must be a positive decimal`);let[n,o=""]=r.split("."),i=BigInt(n+o);if(i<=0n)throw new Error(`hl: ${t} must be positive`);return{raw:i,decimals:o.length}}function M(e,t){if(e===null||typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`hl: ${t} must be finite JSON`);return JSON.stringify(e)}if(Array.isArray(e))return`[${e.map(n=>M(n,t)).join(",")}]`;if(!e||typeof e!="object")throw new Error(`hl: ${t} must be structured JSON`);return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${M(e[n],t)}`).join(",")}}`}function Yr(e){if(typeof e.orderType!="string"||!e.orderType)throw new Error("hl: order type must be a string");let t=e.orderType,r=e.orderWire;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("hl: declared order wire required");if(t==="limit"){let i=r.limit?.tif;if(!["Gtc","Ioc","Alo"].includes(i)||M(r,"declared order type")!==M({limit:{tif:i}},"expected order type"))throw new Error("hl: limit order type must match its wire shape");return}if(t==="market"){if(M(r,"declared order type")!==M({limit:{tif:"Ioc"}},"expected order type"))throw new Error("hl: market order type must match its IOC wire shape");return}let n={stopMarket:{isMarket:!0,tpsl:"sl"},stopLimit:{isMarket:!1,tpsl:"sl"},takeProfitMarket:{isMarket:!0,tpsl:"tp"},takeProfitLimit:{isMarket:!1,tpsl:"tp"}}[t];if(!n)throw new Error("hl: unsupported declared order type");let o=r.trigger?.triggerPx;if(o==null||M(r,"declared order type")!==M({trigger:{isMarket:n.isMarket,triggerPx:o,tpsl:n.tpsl}},"expected order type"))throw new Error("hl: trigger order type must match its wire shape")}function Qr(e,t,r){let n=gt(e.s,"signed size"),o=gt(e.p,"signed price"),i=n.decimals+o.decimals,s=n.raw*o.raw,a=N(t.notionalUsd,i,"hl: notionalUsd");if(a<=0n||s!==a)throw new Error("hl: signed notional must match");let l=N(r.maxNotionalUsd,i,"hl: maxNotionalUsd");if(s>l)throw new Error("hl: notional exceeds cap")}function Zr(e,t){let r=e.action.builder;if(r==null){if(e.builder!=null)throw new Error("hl: declared builder requires a signed builder");return}if(!r||typeof r!="object"||Array.isArray(r))throw new Error("hl: signed order builder must be structured");let n=U(r.b,"order builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(n))throw new Error("hl: order builder address required");if(wt(e.builder||"","hl: builder").toLowerCase()!==n)throw new Error("hl: signed order builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(a=>String(a).toLowerCase()):[]).includes(n))throw new Error("hl: order builder not allowed");let i=V(r.f,"hl: signed order builder fee");if(i<0n)throw new Error("hl: signed order builder fee must be non-negative");let s=N(t.maxBuilderFeeBps??0,1,"hl: maxBuilderFeeBps");if(i>s)throw new Error("hl: order builder fee exceeds cap")}function bt(e,t,r){if(!Number.isSafeInteger(e.a)||e.a!==r)throw new Error("hl: signed asset must match assetId");if(typeof e.b!="boolean"||e.b!==(t.side==="buy"))throw new Error("hl: signed side must match exactly");if(I(e.s,"hl: signed size")!==I(t.size,"hl: size"))throw new Error("hl: signed size must match");if(I(e.p,"hl: signed price")!==I(t.price,"hl: price"))throw new Error("hl: signed price must match");if(typeof t.reduceOnly!="boolean"||typeof e.r!="boolean"||e.r!==t.reduceOnly)throw new Error("hl: signed reduceOnly must match exactly");if(M(e.t,"signed order type")!==M(t.orderWire,"declared order type"))throw new Error("hl: signed order type must match declared order type");let n=Object.prototype.hasOwnProperty.call(e,"c");if(t.clientOrderId==null){if(n)throw new Error("hl: undeclared signed client order id")}else if(!n||typeof e.c!="string"||e.c!==t.clientOrderId)throw new Error("hl: signed client order id must match")}function yt(e,t,r,n,o){if(!Number.isSafeInteger(e.a)||e.a!==r)throw new Error("hl: bracket protection asset must match");if(typeof e.b!="boolean"||e.b===(t.side==="buy"))throw new Error("hl: bracket protection side must oppose entry");if(I(e.s,"hl: bracket protection size")!==I(t.size,"hl: size"))throw new Error("hl: bracket protection size must match");if(I(e.p,"hl: bracket protection price")!==I(n,"hl: protection price"))throw new Error("hl: bracket protection price must match");if(e.r!==!0)throw new Error("hl: bracket protection must be reduce-only");let i=e.t?.trigger;if(!i||i.isMarket!==!0||i.tpsl!==o)throw new Error("hl: bracket protection trigger must match");if(I(i.triggerPx,"hl: triggerPx")!==I(n,"hl: protection price"))throw new Error("hl: bracket protection trigger must match")}function en(e){let t=String(e||"").replace(/\/$/,"");if(!Vr.has(t))throw new Error("hl: submitTo must be the official Hyperliquid exchange");return t}function Oe(e){return ge(e)!=null}function tn(e,t){let r=String(e||""),n=Array.isArray(t.coins)?t.coins.map(String):[];if(Oe(r)){if(t.hip4!==!0)throw new Error("hl: HIP-4 outcome orders are disabled without explicit policy enablement");if(n.includes(r)||n.includes("#*")||n.includes("*")||n.length===0)return!0;throw new Error("hl: outcome coin not allowed")}if(n.length&&!n.includes(r)&&!n.includes("*"))throw new Error("hl: coin not allowed");return!0}function rn(e,t,r){let n=Array.isArray(r.hlMarkets)?r.hlMarkets:[];if(n.length){if(!n.some(s=>{if(typeof s=="string"){let[a,l]=String(s).split(":");return a===e&&Number(l)===t}return String(s?.coin)===e&&Number(s?.assetId)===t}))throw new Error("hl: coin/assetId pair not allowed");return!0}if(Oe(e)){let i=Array.isArray(r.coins)?r.coins.map(String):[];if(i.includes("#*")||i.includes("*")||i.length===0)return!0;throw new Error("hl: restricted coin policy requires hlMarkets pairs")}let o=Array.isArray(r.coins)?r.coins.map(String):[];if(o.length&&!o.includes("*"))throw new Error("hl: restricted coin policy requires hlMarkets pairs");return!0}function xt(e,t){if(e?.surface!=="hl")throw new Error("hl: surface hl required");let r=e.artifact;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("hl: structured artifact required");let n=U(r.kind,"kind",48),o=Jr[n];if(!o)throw new Error("hl: unsupported Hyperliquid kind");if(e.action!==o)throw new Error("hl: surface/action/kind mismatch");if(String(e.destination).toLowerCase()!=="hyperliquid")throw new Error("hl: destination must be hyperliquid");if(!/^0x[0-9a-fA-F]{40}$/.test(String(e.owner||"")))throw new Error("hl: owner required");let i=en(r.submitTo);if(Object.prototype.hasOwnProperty.call(r,"vaultAddress"))throw new Error("hl: vaultAddress is not public");if(Object.prototype.hasOwnProperty.call(r,"expiresAfter"))throw new Error("hl: expiresAfter is not public");let s=Number(r.nonce);if(!Number.isSafeInteger(s)||s<=0)throw new Error("hl: nonce must be a positive integer");if(!r.action||typeof r.action!="object")throw new Error("hl: signed action required");if(Object.prototype.hasOwnProperty.call(r.action,"vaultAddress"))throw new Error("hl: action vaultAddress is not public");if(Object.prototype.hasOwnProperty.call(r.action,"expiresAfter"))throw new Error("hl: action expiresAfter is not public");if(r.action.type!==Kr[n])throw new Error("hl: action type must match kind");let a=r.notionalUsd??0;if(Wr.has(n)||n==="perp-cancel"||n==="perp-leverage"||n==="perp-isolated-margin"){let l=U(r.coin,"coin",64),c=r.assetId??r.assetIndex;if(!Number.isSafeInteger(c)||c<0)throw new Error("hl: assetId required");if(n==="hip4-order"||c>=1e8){let u=ge(l);if(!u||u.coin!==l)throw new Error("hl: HIP-4 actions must use a canonical outcome coin");if(u.assetId!==c)throw new Error("hl: HIP-4 coin must bind to its canonical assetId")}if(tn(l,t),rn(l,c,t),n==="hip4-order"&&!Oe(l))throw new Error("hl: HIP-4 orders must use an outcome coin");if(n==="perp-order"||n==="hip3-order"||n==="hip4-order"||n==="perp-bracket"){if(r.side!=="buy"&&r.side!=="sell")throw new Error("hl: side must be buy or sell");if(r.action.type!=="order"||!Array.isArray(r.action.orders))throw new Error("hl: signed orders are required");Yr(r);let u=r.action.orders;if(n==="perp-bracket"){let d=r.takeProfitPx,p=r.stopLossPx,h=1+(d==null?0:1)+(p==null?0:1);if(h<2||u.length!==h||r.grouping!=="normalTpsl"||r.action.grouping!==r.grouping)throw new Error("hl: bracket must contain exactly the declared entry and protection legs");bt(u[0],r,c);let f=1;d!=null&&yt(u[f++],r,c,d,"tp"),p!=null&&yt(u[f],r,c,p,"sl")}else{if(u.length!==1)throw new Error("hl: exactly one signed order is required");if(r.grouping!=="na"||r.action.grouping!==r.grouping)throw new Error("hl: signed grouping must match declared grouping");bt(u[0],r,c)}Qr(u[0],r,t),Zr(r,t),a=I(r.notionalUsd,"hl: notionalUsd")}if(n==="perp-leverage"){let u=r.leverage;if(!Number.isSafeInteger(u)||u<1)throw new Error("hl: leverage must be a positive integer");let d=t.maxLeverage==null?50:t.maxLeverage;if(typeof d!="number"||!Number.isSafeInteger(d)||d<1)throw new Error("hl: maxLeverage must be a positive integer");if(u>d)throw new Error("hl: leverage exceeds cap")}if(n==="perp-cancel"){let u=r.action.cancels;if(!Array.isArray(u)||u.length!==1)throw new Error("hl: exactly one cancel is required");if(!Number.isSafeInteger(u[0].a)||u[0].a!==c)throw new Error("hl: signed cancel asset must match assetId");if(!Number.isSafeInteger(r.orderId)||r.orderId<0)throw new Error("hl: declared order id required");if(!Number.isSafeInteger(u[0].o)||u[0].o!==r.orderId)throw new Error("hl: signed cancel order id must match")}if(n==="perp-leverage"){if(!Number.isSafeInteger(r.action.asset)||r.action.asset!==c)throw new Error("hl: signed leverage asset must match assetId");if(!Number.isSafeInteger(r.action.leverage)||r.action.leverage!==r.leverage)throw new Error("hl: signed leverage must match");if(!["cross","isolated"].includes(r.marginMode))throw new Error("hl: declared margin mode required");let u=r.marginMode==="cross";if(typeof r.action.isCross!="boolean"||r.action.isCross!==u)throw new Error("hl: signed isCross must match declared margin mode")}if(n==="perp-isolated-margin"){if(!Number.isSafeInteger(r.action.asset)||r.action.asset!==c)throw new Error("hl: signed margin asset must match assetId");let u=U(r.usd,"margin usd",64),d=N(u,6,"hl: margin usd");if(V(r.action.ntli,"hl: signed margin ntli")!==d)throw new Error("hl: signed margin amount must match usd");if(typeof r.isBuy!="boolean"||r.action.isBuy!==r.isBuy)throw new Error("hl: signed margin isBuy must match");let h=N(t.maxNotionalUsd,6,"hl: maxNotionalUsd"),f=d<0n?-d:d;if(f>h)throw new Error("hl: margin notional exceeds cap");a=Xr(f,6)}}if(n==="builder-fee-approval"){let l=U(r.builder,"builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(l))throw new Error("hl: builder address required");if(U(r.action.builder,"signed builder",42).toLowerCase()!==l)throw new Error("hl: signed builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(f=>String(f).toLowerCase()):[]).includes(l))throw new Error("hl: builder not allowed");let u=U(r.maxFeeRate,"maxFeeRate",32);if(U(r.action.maxFeeRate,"signed maxFeeRate",32)!==u)throw new Error("hl: signed builder fee must match");if(!/^\d+(?:\.\d+)?%$/.test(u))throw new Error("hl: builder fee rate must be a percent");let d=N(u.slice(0,-1),12,"hl: builder fee percent"),p=N(t.maxBuilderFeeBps,12,"hl: maxBuilderFeeBps");if(p<0n||d*100n>p)throw new Error("hl: builder fee exceeds cap");if(Number(r.action.nonce)!==s)throw new Error("hl: signed builder nonce must match");let h=i.includes("testnet")?"Testnet":"Mainnet";if(r.hyperliquidChain!==h||r.action.hyperliquidChain!==r.hyperliquidChain)throw new Error("hl: signed Hyperliquid chain must match destination");if(r.signatureChainId!=="0x66eee"||r.action.signatureChainId!==r.signatureChainId)throw new Error("hl: signed signature chain id must match")}if(n.startsWith("hype-stake")||n==="hype-delegate"||n==="hype-undelegate"){if(n==="hype-delegate"||n==="hype-undelegate"){let l=n==="hype-undelegate";if(typeof r.action.isUndelegate!="boolean"||r.action.isUndelegate!==l)throw new Error("hl: signed isUndelegate must match delegate kind exactly")}if(t.maxHypeWei!=null&&BigInt(String(r.action.wei??r.caps?.amountHype??"0"))>BigInt(t.maxHypeWei))throw new Error("hl: stake amount exceeds cap")}return Object.freeze({unit:"usd",value:String(a??r.action.wei??0),notional:String(a??0),fee:"0",kind:n,actionType:r.action.type,amount:String(r.action.wei??a??0),coin:r.coin||null,submitTo:i})}var Vr,Wr,Jr,Kr,U,Et=_(()=>{be();Me();Vr=new Set(["https://api.hyperliquid.xyz/exchange","https://api.hyperliquid-testnet.xyz/exchange"]),Wr=new Set(["perp-order","hip3-order","hip4-order","perp-bracket"]),Jr=Object.freeze({"perp-order":"order","hip3-order":"order","hip4-order":"order","perp-bracket":"order","perp-cancel":"cancel","perp-leverage":"leverage","perp-isolated-margin":"margin","builder-fee-approval":"approveBuilder","hype-stake-deposit":"stake","hype-stake-withdraw":"unstake","hype-delegate":"delegate","hype-undelegate":"delegate"}),Kr=Object.freeze({"perp-order":"order","hip3-order":"order","hip4-order":"order","perp-bracket":"order","perp-cancel":"cancel","perp-leverage":"updateLeverage","perp-isolated-margin":"updateIsolatedMargin","builder-fee-approval":"approveBuilderFee","hype-stake-deposit":"cDeposit","hype-stake-withdraw":"cWithdraw","hype-delegate":"tokenDelegate","hype-undelegate":"tokenDelegate"}),U=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`hl: bounded ${t} required`);return e}});function on(e){let t=e.owner||e.user||e.from||e.recipient;if(!/^0x[0-9a-fA-F]{40}$/.test(String(t||"")))throw new Error("hl: owner/user address required for local-signer envelope");return String(t).toLowerCase()}function St(e,t={},r={}){let n=String(e?.kind||""),o=nn[n];if(!o)throw new Error("hl: prepared kind is not a local-signer surface");if(!e?.action||typeof e.action!="object")throw new Error("hl: prepared action required");let i=Number(r.nowMs??Date.now()),s=Math.min(6e4,Math.max(1e3,Number(t.ttlMs??t.expiresInMs??3e4)||3e4)),a=String(e.submitTo||"").replace(/\/$/,""),l={version:1,surface:"hl",action:o,owner:on(t),destination:"hyperliquid",tradeId:String(t.tradeId||`hl:${n}:${e.nonce}`),expiresAtMs:i+s,slippageBps:Number(t.slippageBps??0),fee:{oracleFeeBps:0},provider:e.provider,artifact:{kind:n,coin:e.coin??null,assetId:e.assetId??e.assetIndex??null,side:e.side??null,size:e.size??null,price:e.price??null,reduceOnly:e.reduceOnly??null,orderType:e.orderType??null,orderWire:e.action?.orders?.[0]?.t??null,clientOrderId:e.action?.orders?.[0]?.c??null,grouping:e.action?.grouping??null,orderId:e.orderId??null,leverage:e.leverage??null,marginMode:e.marginMode??null,notionalUsd:e.notionalUsd??0,usd:e.usd??null,isBuy:e.isBuy??null,takeProfitPx:e.takeProfitPx??null,stopLossPx:e.stopLossPx??null,builder:e.builderFee?.address??e.action?.builder??null,maxFeeRate:e.builderFee?.percent??e.action?.maxFeeRate??null,nonce:e.nonce,hyperliquidChain:e.action?.hyperliquidChain??null,signatureChainId:e.signatureChainId||e.action?.signatureChainId||"0xa4b1",submitTo:a,action:e.action,typedData:e.typedData||null,caps:e.caps||null}};return xt(l,{coins:t.coins||["*"],hip4:!0,maxNotionalUsd:t.maxNotionalUsd??Number.MAX_SAFE_INTEGER,maxLeverage:t.maxLeverage??50,hlBuilders:t.hlBuilders||(e.builderFee?.address?[e.builderFee.address]:[]),maxBuilderFeeBps:t.maxBuilderFeeBps??e.builderFee?.bps}),l}var nn,It=_(()=>{Et();nn=Object.freeze({"perp-order":"order","hip3-order":"order","hip4-order":"order","perp-bracket":"order","perp-cancel":"cancel","perp-leverage":"leverage","perp-isolated-margin":"margin","builder-fee-approval":"approveBuilder","hype-stake-deposit":"stake","hype-stake-withdraw":"unstake","hype-delegate":"delegate","hype-undelegate":"delegate"})});import{Contract as sn,JsonRpcProvider as an}from"ethers";function hn(e){return pn.test(String(e||""))}async function Ce(e,{contract:t=cn,rpc:r=un,chainId:n=ln,balanceOf:o}={}){if(!hn(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let i=new an(r,n,{staticNetwork:!0}),s=new sn(t,dn,i);return BigInt(await s.balanceOf(e))}var cn,ln,un,dn,pn,Re=_(()=>{cn="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",ln=999,un="https://rpc.hyperliquid.xyz/evm",dn=["function balanceOf(address owner) view returns (uint256)"],pn=/^0x[a-fA-F0-9]{40}$/});import{existsSync as fn,readFileSync as mn,lstatSync as wn}from"node:fs";import{homedir as kt}from"node:os";import{join as Fe}from"node:path";function gn(e=process.env){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){if(e[At])return String(e[At]);let t=e.ORACLE_CONFIG_DIR||Fe(kt(),".config","oracle");return Fe(t,"fee-recipient")}return Fe(kt(),".config","oracle","fee-recipient")}function Nt(e=process.env){try{let t=gn(e);if(!fn(t)||wn(t).isSymbolicLink())return"";let r=mn(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}var Ao,At,Pt=_(()=>{Re();Ao=Object.freeze({swap:5,bridge:5,perps:0,nft:0}),At="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN"});var Ct={};ar(Ct,{HL_BUILDER_ADDRESS_ENV:()=>ye,HL_BUILDER_DEFAULT_FEE_BPS:()=>bn,HL_BUILDER_FEE_ENV:()=>Be,HL_BUILDER_FEE_TIERS:()=>oe,HL_BUILDER_MAX_FEE_BPS:()=>De,HL_PERP_MAX_SIG_FIGS:()=>vt,HL_PERP_PRICE_DECIMALS:()=>$t,HL_SIGNATURE_CHAIN_ID:()=>ze,MARGIN_MODE:()=>ie,ORDER_TYPES:()=>A,TIF:()=>se,formatPerpPrice:()=>C,formatPerpSize:()=>Lt,hlBuilderFeeBpsForKind:()=>Mt,hlPerpAssetInfo:()=>W,hlPrepareBracketOrder:()=>$n,hlPrepareBuilderApproval:()=>An,hlPrepareCancelOrder:()=>Nn,hlPreparePerpOrder:()=>Ot,hlPrepareUpdateIsolatedMargin:()=>vn,hlPrepareUpdateLeverage:()=>Pn,resolveBuilderFee:()=>qe});function _t(e,t){if(typeof e=="number"){if(Number.isSafeInteger(e)&&e>=0)return e}else if(typeof e=="string"&&/^(?:0|[1-9]\d*)$/.test(e)){let r=Number(e);if(Number.isSafeInteger(r))return r}throw new Error(`hl-perps: ${t} must be a non-negative safe integer`)}function yn(e,t){let r=_t(e,t);if(r<1)throw new Error(`hl-perps: ${t} must be a positive integer`);return r}function xn(e={}){let t={...e};if(t.side==null)return t;if(t.side===0||t.side===1){if(t.outcomeSide!=null&&t.outcomeSide!==t.side)throw new Error("hl-perps: side conflict with outcomeSide");return t.outcomeSide=t.side,delete t.side,t}throw new Error("hl-assets: side must be 0 or 1")}function Tt(e,{defaultBuy:t=!1}={}){if(e.side!=null){if(typeof e.side!="string")throw new Error("hl-perps: side must be buy or sell");let r=e.side.toLowerCase();if(r!=="buy"&&r!=="sell")throw new Error("hl-perps: side must be buy or sell");let n=r==="buy";if(e.isBuy!=null&&(typeof e.isBuy!="boolean"||e.isBuy!==n))throw new Error("hl-perps: side and isBuy conflict");return n}if(e.isBuy==null&&t)return!0;if(typeof e.isBuy!="boolean")throw new Error("hl-perps: isBuy must be boolean when side is omitted");return e.isBuy}function Mt(e="perp"){if(e==="perp"||e==="main")return oe.perp;if(e==="spot")return oe.spot;if(e==="hip3")return oe.hip3;if(e==="outcome"||e==="hip4")return oe.hip4;throw new Error(`hl-perps: unknown builder fee kind ${e}`)}function qe({env:e=process.env,isHolder:t=!1,kind:r="perp"}={}){if(t)return null;let n=String(e?.[ye]||"").trim().toLowerCase();if(!n)return null;if(!/^0x[a-f0-9]{40}$/.test(n))throw new Error(`hl-perps: ${ye} must be an EVM address`);let o=Nt(e);if(!o||o!==n)return null;let i=e?.[Be],s=Mt(r),a=i==null?s:Number(i);if(!Number.isFinite(a)||a<=0||Math.abs(a*10-Math.round(a*10))>1e-9)throw new Error(`hl-perps: ${Be} must be a positive number in 0.1 bps increments`);if(a>De)throw new Error(`hl-perps: builder fee ${a} bps exceeds the ${De} bps cap`);if(a>s)throw new Error(`hl-perps: builder fee ${a} bps exceeds the ${s} bps product tier for ${r}`);let l=Math.round(a*10),c=(l/1e3).toFixed(3).replace(/0+$/,"").replace(/\.$/,"");return{wire:{b:n,f:l},disclosure:{address:n,bps:a,percent:`${c}%`}}}async function En(e,t={},r={}){if(!e)return{approved:!1,approvedFeeBps:0,status:"not-configured"};let n=String(t.user||r.user||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(n))return{approved:!1,approvedFeeBps:0,status:"wallet-required"};try{let o=Number(await G({type:"maxBuilderFee",user:n,builder:e.disclosure.address},r));return!Number.isInteger(o)||o<0?{approved:!1,approvedFeeBps:0,status:"invalid-response"}:{approved:o>=e.wire.f,approvedFeeBps:o/10,status:o>=e.wire.f?"approved":"insufficient"}}catch{return{approved:!1,approvedFeeBps:0,status:"unavailable"}}}async function Sn(e,t={},r={}){if(!e)return{exempt:!1,status:"not-configured"};let n=String(t.user||r.user||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(n))return{exempt:!1,status:"wallet-required"};try{let o=r.holderBalance||Ce;return BigInt(await o(n))>0n?{exempt:!0,status:"holder"}:{exempt:!1,status:"non-holder"}}catch{return{exempt:!1,status:"unavailable"}}}function He(e,t,{roundDown:r=null}={}){let n=typeof e=="number"?e.toFixed(Math.min(20,t+8)):e;if(typeof n!="string"||!/^-?\d+(\.\d+)?$/.test(n))throw new Error(`hl-perps: "${e}" is not a decimal number`);let o=n.startsWith("-"),[i,s=""]=n.replace(/^-/,"").split(".");if(s.length<=t){let f=s.replace(/0+$/,"");return(o?"-":"")+(f?`${i}.${f}`:i)}let a=s.slice(0,t),l=Number(s[t]),c=BigInt(i+a),u=s.slice(t).replace(/0+$/,"")!=="";r===!0||(r===!1?u&&(c+=1n):l>=5&&(c+=1n));let d=c.toString().padStart(t+1,"0"),h=(t===0?d:`${d.slice(0,-t)}.${d.slice(-t)}`).replace(/(\.\d*?)0+$/,"$1").replace(/\.$/,"");return(o?"-":"")+h}function In(e,t,r={}){if(typeof e!="number"&&typeof e!="string")throw new Error(`hl-perps: "${e}" is not a decimal number`);let n=typeof e=="number"?String(e):e;if(!n.includes("."))return n;let o=Number(n);if(!Number.isFinite(o)||o===0)return n;let i=Math.floor(Math.log10(Math.abs(o))),s=Math.max(0,t-1-i);return He(n,s,r)}function C(e,t,r={}){let n=$t-Number(t??0);if(n<0)throw new Error("hl-perps: szDecimals out of range");return He(In(e,vt,r),n,r)}function Lt(e,t){let r=He(e,Number(t??0));if(BigInt(r.split(".")[0])<0n)throw new Error("hl-perps: size must be positive");if(Number(r)<=0)throw new Error("hl-perps: size rounds to zero at this asset's precision");return r}function kn(e,t){let r=(u,d)=>{let p=String(u).trim();if(!/^\d+(?:\.\d+)?$/.test(p))throw new Error(`hl-perps: ${d} must be a positive decimal`);let[h,f=""]=p.split(".");return{raw:BigInt(h+f),decimals:f.length}},n=r(e,"size"),o=r(t,"price"),i=n.raw*o.raw,s=n.decimals+o.decimals,a=i.toString().padStart(s+1,"0");if(s===0)return a;let l=a.slice(0,-s),c=a.slice(-s).replace(/0+$/,"");return c?`${l}.${c}`:l}async function W(e={},t={}){let r=await Te(e,t);return{coin:r.coin,assetId:r.assetId,szDecimals:r.szDecimals,maxLeverage:r.maxLeverage,markPx:r.markPx,kind:r.kind,dex:r.dex??null,outcome:r.outcome??null,side:r.side??null}}function Ue(e,{tif:t=se.GTC,triggerPx:r,isMarket:n,szDecimals:o}={}){switch(e){case A.LIMIT:return{limit:{tif:t}};case A.MARKET:return{limit:{tif:se.IOC}};case A.STOP_MARKET:case A.TAKE_PROFIT_MARKET:return{trigger:{isMarket:!0,triggerPx:C(r,o),tpsl:e===A.STOP_MARKET?"sl":"tp"}};case A.STOP_LIMIT:case A.TAKE_PROFIT_LIMIT:return{trigger:{isMarket:!1,triggerPx:C(r,o),tpsl:e===A.STOP_LIMIT?"sl":"tp"}};default:throw new Error(`hl-perps: unknown order type ${e}`)}}function J(e,t,r={}){let n=r.testnet||process.env.HL_TESTNET==="1";return{action:e,nonce:t,signatureChainId:ze,submitTo:n?"https://api.hyperliquid-testnet.xyz/exchange":"https://api.hyperliquid.xyz/exchange",note:"Sign locally via Oracle local-signer or a wallet. Hosted Oracle does not submit."}}function K(e,t={},r={}){let n={...e};try{n.localSignerEnvelope=St(n,t,r),n.prepared=!0,n.signing="awaiting-hl-signer"}catch(o){n.prepared=!1,n.localSignerEnvelope=null,n.localSignerBlockedReason=String(o?.message||o).slice(0,200),n.signing="blocked"}return n.oraclePrepared=!!n.localSignerEnvelope,B(n,{provider:e.provider||"hl-perps",kind:e.kind})}function An(e={},t={}){let r=qe({env:t.env});if(!r)throw new Error(`hl-perps: ${ye} is required`);let n=Number(e.nonce??t.nonce??Date.now());if(!Number.isSafeInteger(n)||n<=0)throw new Error("hl-perps: nonce must be a positive integer");let o={type:"approveBuilderFee",hyperliquidChain:t.testnet||process.env.HL_TESTNET==="1"?"Testnet":"Mainnet",signatureChainId:ze,maxFeeRate:r.disclosure.percent,builder:r.disclosure.address,nonce:n};return K({provider:"hl-perps",venue:"hyperliquid",kind:"builder-fee-approval",builderFee:r.disclosure,...J(o,n,t)},e,t)}async function Ot(e={},t={}){let r=await W(e,t);if(e.type!=null&&(typeof e.type!="string"||!e.type))throw new Error("hl-perps: order type must be a string");let n=e.type??A.LIMIT;if(typeof n!="string"||!n)throw new Error("hl-perps: order type must be a string");let o=Tt(e);if(e.reduceOnly!=null&&typeof e.reduceOnly!="boolean")throw new Error("hl-perps: reduceOnly must be boolean");let i=e.reduceOnly===!0,s=Lt(e.size??e.sz,r.szDecimals),a;if(n===A.MARKET){let y=Number(r.markPx);if(!Number.isFinite(y)){let S=await at(t);y=Number(S?.[r.coin]??S?.[String(r.assetId)]??NaN)}if(!Number.isFinite(y))throw new Error("hl-perps: no mark price available for a market order");let x=Number(e.maxSlippageBps??50);if(!Number.isInteger(x)||x<0)throw new Error("hl-perps: maxSlippageBps must be a non-negative integer");if(x>100)throw new Error(`hl-perps: maxSlippageBps ${x} exceeds the hard 100 bps cap`);let m=o?y*(1+x/1e4):y*(1-x/1e4);a=C(m,r.szDecimals,{roundDown:o});let k=Math.abs(Number(a)/y-1)*1e4;if(k>x+1e-9)throw new Error(`hl-perps: tick rounding makes the limit ${k.toFixed(2)} bps from mark, above the ${x} bps cap`)}else{if(e.price==null&&e.limitPx==null)throw new Error("hl-perps: a limit order requires an explicit price");a=C(e.price??e.limitPx,r.szDecimals)}let l=Ue(n,{tif:e.tif??(n===A.MARKET?se.IOC:se.GTC),triggerPx:e.triggerPx,szDecimals:r.szDecimals}),c={a:r.assetId,b:o,p:a,s,r:i,t:l};if(e.clientOrderId!=null){if(typeof e.clientOrderId!="string"||!e.clientOrderId)throw new Error("hl-perps: clientOrderId must be a string");c.c=e.clientOrderId}if(e.grouping!=null&&(typeof e.grouping!="string"||!e.grouping))throw new Error("hl-perps: grouping must be a string");let u={type:"order",orders:[c],grouping:e.grouping??"na"},d=qe({env:t.env,kind:r.kind}),p=await Sn(d,e,t),h=p.exempt?null:d,f=await En(h,e,t),b=f.approved?h:null;b&&(u.builder=b.wire);let w=Number(e.nonce??Date.now()),E=kn(s,a);return K({provider:"hl-perps",venue:"hyperliquid",kind:r.kind==="outcome"?"hip4-order":r.kind==="hip3"?"hip3-order":"perp-order",coin:r.coin,assetId:r.assetId,assetKind:r.kind,outcome:r.outcome??null,outcomeSide:r.side??null,dex:r.dex??null,side:o?"buy":"sell",orderType:n,price:a,size:s,reduceOnly:i,notionalUsd:E,maxLeverage:r.maxLeverage,markPx:r.markPx,builderFee:b?.disclosure??null,holderExempt:p.exempt,holderVerificationStatus:p.status,builderApprovalRequired:h&&!b?{...d.disclosure,...f}:null,...J(u,w,t)},e,t)}async function Nn(e={},t={}){let r=await W(xn(e),t),n=e.orderId??e.oid;if(n==null)throw new Error("hl-perps: orderId required");let o=_t(n,"orderId"),i={type:"cancel",cancels:[{a:r.assetId,o}]};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-cancel",coin:r.coin,assetId:r.assetId,orderId:o,...J(i,Number(e.nonce??Date.now()),t)},e,t)}async function Pn(e={},t={}){let r=await W(e,t),n=yn(e.leverage,"leverage");if(r.maxLeverage!=null&&n>r.maxLeverage)throw new Error(`hl-perps: ${r.coin} allows at most ${r.maxLeverage}x, requested ${n}x`);if(e.marginMode!=null&&typeof e.marginMode!="string")throw new Error("hl-perps: marginMode must be a string");let o=(e.marginMode||ie.CROSS).toLowerCase();if(o!==ie.CROSS&&o!==ie.ISOLATED)throw new Error('hl-perps: marginMode must be "cross" or "isolated"');let i={type:"updateLeverage",asset:r.assetId,isCross:o===ie.CROSS,leverage:n};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-leverage",coin:r.coin,assetId:r.assetId,leverage:n,marginMode:o,maxLeverage:r.maxLeverage,liquidationWarning:n>=20?`${n}x liquidates on roughly a ${(100/n).toFixed(2)}% adverse move before fees`:null,...J(i,Number(e.nonce??Date.now()),t)},e,t)}async function vn(e={},t={}){let r=await W(e,t),n=e.usd??e.amountUsd;if(n==null)throw new Error("hl-perps: usd amount required");if(typeof n!="number"&&typeof n!="string")throw new Error("hl-perps: usd must be a decimal number");let o=typeof n=="number"?String(n):n;if(!/^-?\d+(\.\d+)?$/.test(o))throw new Error("hl-perps: usd must be a decimal number");let i=N(o,6,"hl-perps: usd"),s=Tt(e,{defaultBuy:!0}),a={type:"updateIsolatedMargin",asset:r.assetId,isBuy:s,ntli:i<=BigInt(Number.MAX_SAFE_INTEGER)?Number(i):i.toString()};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-isolated-margin",coin:r.coin,assetId:r.assetId,isBuy:s,usd:o,...J(a,Number(e.nonce??Date.now()),t)},e,t)}async function $n(e={},t={}){let r=await Ot(e,t),n=await W(e,t),o=r.side==="buy",i=[r.action.orders[0]];if(e.takeProfitPx!=null&&i.push({a:n.assetId,b:!o,p:C(e.takeProfitPx,n.szDecimals),s:r.size,r:!0,t:Ue(A.TAKE_PROFIT_MARKET,{triggerPx:e.takeProfitPx,szDecimals:n.szDecimals})}),e.stopLossPx!=null&&i.push({a:n.assetId,b:!o,p:C(e.stopLossPx,n.szDecimals),s:r.size,r:!0,t:Ue(A.STOP_MARKET,{triggerPx:e.stopLossPx,szDecimals:n.szDecimals})}),i.length===1)throw new Error("hl-perps: a bracket needs takeProfitPx and/or stopLossPx");let s={type:"order",orders:i,grouping:"normalTpsl",...r.action.builder?{builder:r.action.builder}:{}};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-bracket",coin:n.coin,assetId:n.assetId,side:r.side,price:r.price,size:r.size,reduceOnly:r.reduceOnly,orderType:r.orderType,notionalUsd:r.notionalUsd,legs:i.length,entry:{side:r.side,price:r.price,size:r.size},takeProfitPx:e.takeProfitPx==null?null:C(e.takeProfitPx,n.szDecimals),stopLossPx:e.stopLossPx==null?null:C(e.stopLossPx,n.szDecimals),builderFee:r.builderFee,...J(s,Number(e.nonce??Date.now()),t)},e,t)}var vt,$t,ze,bn,De,ye,Be,oe,A,se,ie,Rt=_(()=>{pe();Me();be();he();It();Re();Pt();vt=5,$t=6,ze="0x66eee",bn=2,De=10,ye="ORACLE_HL_BUILDER_ADDRESS",Be="ORACLE_HL_BUILDER_FEE_BPS",oe=Object.freeze({perp:2,spot:1,hip3:1,hip4:1}),A=Object.freeze({LIMIT:"limit",MARKET:"market",STOP_MARKET:"stopMarket",STOP_LIMIT:"stopLimit",TAKE_PROFIT_MARKET:"takeProfitMarket",TAKE_PROFIT_LIMIT:"takeProfitLimit"}),se=Object.freeze({GTC:"Gtc",IOC:"Ioc",ALO:"Alo"}),ie=Object.freeze({CROSS:"cross",ISOLATED:"isolated"})});de();var Nr="https://yields.llama.fi";async function ot(e={},t={}){let r=(t.yieldsBaseUrl||process.env.DEFILLAMA_YIELDS_URL||Nr).replace(/\/$/,""),n=await H(`${r}/pools`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??3e4}),o=Array.isArray(n?.data)?n.data:[];e.chain&&(o=o.filter(s=>String(s.chain).toLowerCase()===String(e.chain).toLowerCase())),e.project&&(o=o.filter(s=>String(s.project).toLowerCase()===String(e.project).toLowerCase())),e.stablecoin!=null&&(o=o.filter(s=>!!s.stablecoin==!!e.stablecoin)),o.sort((s,a)=>Number(a.tvlUsd||0)-Number(s.tvlUsd||0));let i=Math.min(5e3,Math.max(1,Number(e.limit||o.length||1)));return{...n,data:o.slice(0,i)}}var ee=Object.freeze([{id:"stable-loop",label:"Stablecoin loop",risk:"Conservative",targetDelta:"0.00",setup:"Supply USDC, borrow a second major stable, redeposit inside the same protocol or campaign.",exposure:"Borrow APR spike, depeg, collateral-factor change, protocol cap change.",hedge:"No perp hedge by default. Cap leverage, diversify stables, and keep unwind triggers explicit.",monitor:"Borrow APR, utilization, oracle health, depeg distance, reward dilution.",exit:"Unwind if borrow APR exceeds reward-adjusted APR or any stable trades outside the defined band."},{id:"collateral-hedge",label:"Collateral plus perp hedge",risk:"Balanced",targetDelta:"~0.00",setup:"Supply a volatile asset as collateral, borrow stables, and short the collateral notional on a liquid perp venue.",exposure:"Liquidation risk, funding cost, hedge slippage, borrow APR drift.",hedge:"Short collateral notional on a liquid perp venue; rebalance when delta drifts past the band.",monitor:"Health factor, funding, mark price, borrow APR, hedge margin.",exit:"Cut when funding turns persistently negative against the position or health factor nears the floor."},{id:"lp-hedge",label:"LP incentive hedge",risk:"Aggressive",targetDelta:"range-dependent",setup:"Provide concentrated liquidity for incentives and short the estimated volatile-token delta.",exposure:"Impermanent loss, range breaks, reward dilution, exit slippage.",hedge:"Short the estimated volatile-token delta and recompute after material price or range moves.",monitor:"Position delta, range utilization, fee APR, rewards, funding, exit slippage.",exit:"Withdraw when incentives dilute, liquidity caps fill, or expected reward no longer beats IL plus opportunity cost."},{id:"quest-farming",label:"Testnet and quest farming",risk:"Conservative",targetDelta:"n/a",setup:"Complete real protocol tasks with consistent, genuine usage from wallets you actually control.",exposure:"Eligibility rules change, sybil filters, unpaid effort, opportunity cost.",hedge:"No financial hedge. Diversify across campaigns so no single ruleset dominates the outcome.",monitor:"Campaign rules, snapshot windows, task eligibility evidence, wallet hygiene.",exit:"Stop once snapshot risk rises, campaign rules change, or the probability-adjusted expected value turns negative."},{id:"liquidity-usage",label:"Liquidity and route usage",risk:"Balanced",targetDelta:"varies",setup:"Route genuine volume and provide liquidity where usage is a stated eligibility signal.",exposure:"IL, slippage, gas burn, bridge fees, lockup discount.",hedge:"Size positions so IL and fees stay inside the modelled reward, and hedge volatile legs when material.",monitor:"Volume attribution, fee drag, reward accrual, lockup terms.",exit:"Withdraw when incentives dilute or expected reward no longer beats IL plus opportunity cost."},{id:"governance-usage",label:"Governance and ecosystem usage",risk:"Conservative",targetDelta:"n/a",setup:"Participate in governance and ecosystem surfaces where real contribution is the eligibility signal.",exposure:"Vanity activity with no eligibility weight, lock-up of governance assets.",hedge:"No financial hedge. Weight effort toward actions with documented eligibility evidence.",monitor:"Proposal participation, delegation terms, lock durations, published criteria.",exit:"Stop contributing effort once criteria change or the probability-adjusted value turns negative."}]),Pr={"stable-loop":"No default perp hedge. Bound leverage and monitor depeg plus borrow APR.","collateral-hedge":"Short the collateral notional on a liquid perp venue and rebalance when delta drifts.","lp-hedge":"Short the estimated volatile-token delta and recompute after material price or range moves."},vr={"stable-loop":"Borrow APR, utilization, stable peg, reward dilution, health factor.","collateral-hedge":"Health factor, funding, mark price, borrow APR, hedge margin.","lp-hedge":"Position delta, range utilization, fee APR, rewards, funding, exit slippage."},$r={"stable-loop":["Prepare supply for the stable collateral leg.","Prepare borrow only after health factor and borrow APR pass the method limits.","Prepare redeposit or unwind steps as separate wallet-signed actions."],"collateral-hedge":["Prepare collateral supply after sizing liquidation buffer.","Prepare stable borrow if borrow APR remains inside the method limit.","Open or adjust the perp short on the selected hedge venue, then record hedge size."],"lp-hedge":["Prepare LP add only after checking pool depth, range, and expected position delta.","Short the estimated volatile-token delta on the selected hedge venue.","Prepare LP remove if the range breaks or net APR turns negative."]};function j(e){let t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?t:null}function O(e,t="unknown"){if(typeof e!="string")return t;let r=e.trim();return r===""?t:r.slice(0,96)}function _r(e){let t=O(e.symbol,"").toUpperCase(),r=O(e.exposure,"").toLowerCase(),n=j(e.apy)??0,o=j(e.tvlUsd)??0;return n<=0||o<=0?null:e.stablecoin===!0?"stable-loop":t.includes("-")||r.includes("multi")?"lp-hedge":/ETH|BTC|SOL|HYPE|BNB|AVAX|MATIC|OP|ARB/.test(t)?"collateral-hedge":null}function Tr(e,t){let r=j(e.tvlUsd)??0,n=O(e.ilRisk,"").toLowerCase(),o=O(e.predictions?.predictedClass,"").toLowerCase(),i=t==="stable-loop"?3:t==="collateral-hedge"?6:9;return r<1e6?i+=6:r<1e7&&(i+=3),(n.includes("yes")||n.includes("high"))&&(i+=3),o.includes("down")&&(i+=2),Math.min(35,Math.max(0,i))}function Mr(e){let t=_r(e);if(!t)return null;let r=j(e.apy)??0,n=j(e.apyBase)??0,o=Math.max(0,j(e.apyReward)??Math.max(0,r-n)),i=Math.max(0,j(e.tvlUsd)??0),s=Tr(e,t),a=t==="stable-loop"?4:t==="collateral-hedge"?6:0,l=t==="stable-loop"?0:t==="collateral-hedge"?4:5,c=i<5e6?1.2:.5,u=r-a-l-c-s,d=u<1?"Avoid":r>80||i<1e7?"Watchlist":u>=8?"Farmable":"Watchlist",p=O(e.project),h=O(e.symbol),f=O(e.chain);return{id:O(e.pool,`${f}:${p}:${h}`),recipe:t,label:`${p} ${h}`,chain:f,project:p,symbol:h,tvlUsd:i,rewardApr:o,nativeApr:n,estimatedBorrowApr:a,estimatedFundingApr:l,gasApr:c,riskHaircut:s,netApr:u,verdict:d,exposure:O(e.exposure,t==="stable-loop"?"stablecoin":t==="lp-hedge"?"multi-asset LP":"single-asset collateral"),hedge:Pr[t],monitor:vr[t],prepareSteps:[`Verify ${p} contracts and reward terms on ${f}.`,"Set wallet grant with chain, protocol, max value, slippage, and TTL before preparing any transaction.",...$r[t]],source:"DeFiLlama yields"}}async function it(e={},t={}){let r=Math.min(24,Math.max(3,Number(e.limit??12)||12)),n=Number(e.minTvl??2e6),o=new Date().toISOString(),i="read-only discovery and prepare-plan design; no signing or broadcast";try{let s=await ot({chain:e.chain&&e.chain!=="all"?e.chain:void 0,limit:5e3},t),a=Array.isArray(s?.data)?s.data:[],l=a.map(Mr).filter(c=>c!==null).filter(c=>c.tvlUsd>=n).filter(c=>c.rewardApr+c.nativeApr<=300).sort((c,u)=>u.netApr-c.netApr||u.tvlUsd-c.tvlUsd).slice(0,r);return{configured:!0,live:!0,source:"DeFiLlama yields",generatedAt:o,chain:e.chain??"all",considered:a.length,consideredNote:"deepest pools by TVL from the DeFiLlama yields feed",candidates:l,posture:i}}catch(s){return{configured:!1,live:!1,source:"DeFiLlama yields",generatedAt:o,chain:e.chain??"all",considered:0,consideredNote:"deepest pools by TVL from the DeFiLlama yields feed",error:String(s?.message||s),candidates:[],posture:i}}}function T(e,t,r,n){let o=typeof e=="number"?e:Number(e);return Number.isFinite(o)?Math.min(n,Math.max(r,o)):t}function st(e={}){let t=T(e.wallets,5,1,500),r=T(e.tasksWeekly,6,0,500),n=T(e.hoursWeekly,4,0,168),o=T(e.hourlyCost,25,0,1e4),i=T(e.gasPerTask,.4,0,1e4),s=T(e.bridgeMonthly,12,0,1e5),a=T(e.expectedReward,900,0,1e7),l=T(e.probability,22,0,100)/100,c=T(e.sybilHaircut,25,0,100)/100,u=T(e.lockupMonths,6,0,120),d=r*t*4.33,p=d*i,h=n*4.33*o,f=p+h+s,b=Math.max(0,1-u*.015),w=t*a*l,E=w*(1-c)*b,y=E-f,x=f>0?y/f*100:null,m=t*a>0?f/(t*a*(1-c)*(b||1))*100:null;return{inputs:{wallets:t,tasksWeekly:r,hoursWeekly:n,hourlyCost:o,gasPerTask:i,bridgeMonthly:s,expectedReward:a,probabilityPct:l*100,sybilHaircutPct:c*100,lockupMonths:u},monthlyTasks:d,monthlyGas:p,laborMonthly:h,monthlyCost:f,lockupDiscount:b,grossExpectedValue:w,adjustedExpectedValue:E,netExpectedValue:y,roiPct:x,breakevenProbabilityPct:m,verdict:y>0?"positive-ev":"negative-ev",posture:"estimate on your own inputs; not a payout promise and not financial advice"}}pe();he();function ut(e={}){let t=e.spotSizes??e.spotHeldSizes;return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function me(e={},t,r){let n=String(t||""),o=ut(e);if(o){let s=re(o[n]);if(s==null)throw new Error(`${r}: held spot required for ${n}`);return s}let i=re(e.spotSize??e.spotHeldSize);if(i==null)throw new Error(`${r}: prepare requires spotSize of held spot`);return i}function we(e={},t=[],r){let n=ut(e);if(t.length>1){if(!n)throw new Error(`${r}: multi-coin live loop requires spotSizes map`);for(let o of t)if(re(n[o])==null)throw new Error(`${r}: held spot required for ${o}`);return}if(n){let o=t[0];if(o&&re(n[o])==null)throw new Error(`${r}: held spot required for ${o}`);return}if(re(e.spotSize??e.spotHeldSize)==null)throw new Error(`${r}: live loop requires spotSize of held spot`)}var $e=Number.MAX_SAFE_INTEGER,fe=String($e);function re(e){if(typeof e=="number")return Number.isFinite(e)&&e>0&&e<=$e?e:null;if(typeof e!="string"||!/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(e))return null;let[t,r=""]=e.split(".");if(t.length>fe.length||t.length===fe.length&&t>fe||t===fe&&/[1-9]/.test(r))return null;let n=Number(e);return Number.isFinite(n)&&n>0&&n<=$e?n:null}function R(e){let t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?t:null}function Ft(e){let t=R(e);if(t==null)throw new Error("hl-delta-neutral: funding rate required");return t*24*365*100}function _n(e,t,r=4){let n=R(e),o=R(t),i=Number.isInteger(Number(r))?Number(r):4;if(!(n>0))throw new Error("hl-delta-neutral: notionalUsd must be > 0");if(!(o>0))throw new Error("hl-delta-neutral: markPx must be > 0");let s=10**i;return String(Math.floor(n/o*s+1e-12)/s)}function Dt(e){let t=Array.isArray(e?.[0]?.universe)?e[0].universe:[],r=Array.isArray(e?.[1])?e[1]:[],n=[];for(let o=0;o<t.length;o+=1){let i=t[o]||{},s=r[o]||{},a=String(i.name||"").trim(),l=R(s.funding),c=R(s.markPx??s.oraclePx),u=R(s.openInterest)??0;!a||l==null||!(c>0)||n.push({coin:a,szDecimals:Number.isInteger(Number(i.szDecimals))?Number(i.szDecimals):4,funding:l,markPx:c,oraclePx:R(s.oraclePx),openInterest:u,fundingAprPct:Ft(l)})}return n}function Bt(e,t){if(!e?.coin)throw new Error("hl-delta-neutral: coin required");let r=R(e.funding);if(r==null)throw new Error("hl-delta-neutral: funding required");let n=Ft(r),o=r>0,i={coin:e.coin,notionalUsd:R(t),markPx:e.markPx,fundingHourly:r,fundingAprPct:n,targetDelta:0,spot:o?"hold-existing":"short-spot-not-in-light-path",perpSide:o?"sell":"buy",perpSize:o?_n(t,e.markPx,e.szDecimals):"0",verdict:o?n>=5?"carry":"watch":"skip",posture:"light hold-spot / short-perp carry. A farm tick may prepare the perp hedge unsigned. Hosted stays prepare-only."};if(!(i.notionalUsd>0))throw new Error("hl-delta-neutral: notionalUsd must be > 0");return i}async function je(e={},t={}){let r=Math.min(24,Math.max(1,Number(e.limit??8)||8)),n=Number(e.minOpenInterest??0),o=await te(t),i=Dt(o).filter(s=>s.funding>0&&s.openInterest>=n).sort((s,a)=>a.funding-s.funding||a.openInterest-s.openInterest).slice(0,r);return{live:!0,source:"Hyperliquid metaAndAssetCtxs",considered:Array.isArray(o?.[0]?.universe)?o[0].universe.length:0,candidates:i,posture:"read-only funding scan. Positive funding only. No signing."}}async function Ge(e={},t={}){let r=String(e.coin||"").trim();if(!r)throw new Error("hl-delta-neutral: coin required");let n=Number(e.notionalUsd??e.notional??1e3),o=await te(t),i=Dt(o).find(s=>s.coin===r);if(!i)throw new Error(`hl-delta-neutral: ${r} not in Hyperliquid meta`);return Bt(i,n)}async function Tn(e={},t={}){zt(e,t,"hl-delta-neutral");let r=qt(e.maxNotionalUsd??25e3,"hl-delta-neutral"),n=await Ge(e,t);if(n.verdict==="skip")return B({...n,prepared:!1,oraclePrepared:!1,surface:"hl",reason:"negative funding is outside the light hold-spot path"},{provider:"hl-delta-neutral",kind:"hl-carry-hedge"});let o=me(e,n.coin,"hl-delta-neutral");if(!Ut.test(String(e.owner||"")))throw new Error("hl-delta-neutral: prepare requires owner");if(Number(n.perpSize)-o>1e-12)throw new Error("hl-delta-neutral: hedge cannot exceed held spot");let{hlPreparePerpOrder:i}=await Promise.resolve().then(()=>(Rt(),Ct)),s=await i({coin:n.coin,side:n.perpSide,size:n.perpSize,type:e.orderType||"limit",price:e.price??n.markPx,owner:e.owner,maxNotionalUsd:r},{fetchImpl:t.fetchImpl,nowMs:t.nowMs});if(s?.signed===!0||s?.broadcast===!0)throw new Error("hl-delta-neutral: prepare cannot sign or broadcast");let a=s?.localSignerEnvelope||null,l=s?.localSignerBlockedReason||null;return B({...n,prepared:!!a,surface:"hl",hedge:s,localSignerEnvelope:a,localSignerBlockedReason:l,signed:!1,broadcast:!1,signing:a?"awaiting-hl-signer":"blocked",oraclePrepared:!!a},{provider:"hl-delta-neutral",kind:"hl-carry-hedge"})}var Ut=/^0x[0-9a-fA-F]{40}$/;function zt(e,t,r){if((t.hosted===!0||t.keyless===!0)&&(e.farming===!0||typeof t.signImpl=="function"))throw new Error(`${r}: hosted/keyless cannot sign`);if(e.farming===!0||typeof t.signImpl=="function"||typeof t.prepareImpl=="function")throw new Error(`${r}: farm cannot sign; use oracle signer`)}function Mn(e,t,r){zt(e,t,r)}function Ln(e={}){if(e.halted===!0)throw new Error("hl-delta-neutral: loop is halted");let t=e.mode==="live"?"live":"shadow",r=Array.isArray(e.coins||e.allowlist)?(e.coins||e.allowlist).map(String):[],n=e.maxCoins??1;if(typeof n!="number"&&!(typeof n=="string"&&/^(?:0|[1-9]\d*)$/.test(n)))throw new Error("hl-delta-neutral: maxCoins must be an integer");let o=Number(n);if(!Number.isSafeInteger(o))throw new Error("hl-delta-neutral: maxCoins must be an integer");if(o<1||o>8)throw new Error("hl-delta-neutral: maxCoins must be between 1 and 8");let i=qt(e.maxNotionalUsd??e.notionalUsd??e.notional??1e3,"hl-delta-neutral");if(t==="live"&&r.length===0)throw new Error("hl-delta-neutral: live loop requires a coin allowlist");if(t==="live"&&we(e,r,"hl-delta-neutral"),t==="live"&&!Ut.test(String(e.owner||"")))throw new Error("hl-delta-neutral: live loop requires owner");return{mode:t,allowlist:r,maxCoins:o,maxNotionalUsd:i,intervalMs:Math.max(3e4,Number(e.intervalMs??3e5)||3e5)}}function qt(e,t){let r=typeof e=="string"&&e===e.trim()&&/^(?:0\.\d+|[1-9]\d*(?:\.\d+)?)$/.test(e);if(typeof e!="number"&&!r)throw new Error(`${t}: maxNotionalUsd out of bounds`);let n=Number(e);if(!(n>0)||n>25e3)throw new Error(`${t}: maxNotionalUsd out of bounds`);return n}async function Ht(e={},t={}){Mn(e,t,"hl-delta-neutral");let r=Ln(e),n=await je({limit:e.limit??16,minOpenInterest:e.minOpenInterest},t),o=new Set(r.allowlist),i=[],s=Math.floor(r.maxNotionalUsd/r.maxCoins);for(let a of n.candidates){if(o.size&&!o.has(a.coin))continue;let l=Bt(a,s);if(l.verdict!=="carry")continue;if(i.length>=r.maxCoins)break;if(r.mode==="shadow"){i.push({...l,mode:"shadow",surface:"hl",prepared:!1,signed:!1,broadcast:!1});continue}let c=await Tn({coin:l.coin,notionalUsd:l.notionalUsd,owner:e.owner,orderType:e.orderType,price:e.price,maxNotionalUsd:s,spotSize:e.spotSize??e.spotHeldSize,spotSizes:e.spotSizes??e.spotHeldSizes},{fetchImpl:t.fetchImpl,nowMs:t.nowMs});i.push({...c,mode:"live",surface:"hl"})}return{loop:!0,mode:r.mode,surface:"hl",signer:"hl",considered:n.considered,actions:i,nextWaitMs:r.intervalMs,signed:i.some(a=>a.signed===!0),broadcast:i.some(a=>a.broadcast===!0),posture:"one tick. Prepares an unsigned hedge for oracle signer. Armed, not automated. Farm loop never signs or broadcasts."}}de();he();be();var On=new Set(["https://mainnet.zklighter.elliot.ai/api/v1/sendTx","https://testnet.zklighter.elliot.ai/api/v1/sendTx"]),ae=14,jt=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`lighter: bounded ${t} required`);return e};function X(e,t,r){if(!Number.isSafeInteger(e)||e!==t)throw new Error(`lighter: ${r} must be exact numeric ${t}`)}function Ve(e){let t=String(e||"").replace(/\/$/,"");if(!On.has(t))throw new Error("lighter: submitTo must be the official Lighter sendTx");return t}function Gt(e,t={}){if(e?.surface!=="lighter")throw new Error("lighter: surface lighter required");let r=e.artifact;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("lighter: structured artifact required");let n=jt(r.kind,"kind",48);if(n!=="lighter-order")throw new Error("lighter: unsupported Lighter kind");if(e.action!=="order")throw new Error("lighter: surface/action/kind mismatch");if(String(e.destination).toLowerCase()!=="lighter")throw new Error("lighter: destination must be lighter");let o=Ve(r.submitTo),i=r.marketIndex;if(typeof i!="number"||!Number.isSafeInteger(i)||i<0)throw new Error("lighter: marketIndex required");let s=Number(V(r.accountIndex,"lighter: accountIndex"));if(!Number.isSafeInteger(s)||s<0)throw new Error("lighter: accountIndex required");let a=Number(V(r.clientOrderIndex,"lighter: clientOrderIndex"));if(!Number.isSafeInteger(a)||a<0)throw new Error("lighter: clientOrderIndex required");X(r.orderType,0,"orderType"),X(r.timeInForce,1,"timeInForce"),X(r.reduceOnly,0,"reduceOnly"),X(r.triggerPrice,0,"triggerPrice"),X(r.orderExpiry,-1,"orderExpiry");let l=jt(r.symbol||r.coin,"symbol",32),c=Array.isArray(t.lighterMarkets)?t.lighterMarkets.map(String):[];if(c.length&&!c.includes(l)&&!c.includes(String(i))&&!c.includes("*"))throw new Error("lighter: market not allowed");if(r.side!=="buy"&&r.side!=="sell")throw new Error("lighter: side must be buy or sell");let u=Le(r.baseAmount,"lighter: baseAmount"),d=Le(r.price,"lighter: price");if(u>BigInt(Number.MAX_SAFE_INTEGER)||d>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("lighter: baseAmount and price must be safe integers");let p=Number(u),h=Number(d),f=Number(r.sizeDecimals??0),b=Number(r.priceDecimals??0);if(!Number.isInteger(f)||f<0||f>12)throw new Error("lighter: sizeDecimals required");if(!Number.isInteger(b)||b<0||b>12)throw new Error("lighter: priceDecimals required");let w=f+b,E=u*d,y=N(r.notionalUsd,w,"lighter: notionalUsd");if(y<=0n)throw new Error("lighter: notionalUsd required");if(E!==y)throw new Error("lighter: notionalUsd must match size and price");let x=N(t.maxNotionalUsd??Number.MAX_SAFE_INTEGER,w,"lighter: maxNotionalUsd");if(E>x)throw new Error("lighter: notional exceeds cap");let m=I(r.notionalUsd,"lighter: notionalUsd");return X(r.txType,ae,"txType"),Object.freeze({unit:"usd",value:String(m),notional:String(m),fee:"0",kind:n,symbol:l,marketIndex:i,side:r.side,baseAmount:p,price:h,submitTo:o,actionType:"create-order",amount:String(m)})}function Cn(e){let t=e.owner||e.user||e.from;if(!/^0x[0-9a-fA-F]{40}$/.test(String(t||"")))throw new Error("lighter: owner address required for local-signer envelope");return String(t).toLowerCase()}function Vt(e,t={},r={}){if(String(e?.kind)!=="lighter-order")throw new Error("lighter: prepared kind is not a local-signer surface");let n=Number(r.nowMs??Date.now()),o=Math.min(6e4,Math.max(1e3,Number(t.ttlMs??t.expiresInMs??3e4)||3e4)),i=Ve(e.submitTo),s={version:1,surface:"lighter",action:"order",owner:Cn(t),destination:"lighter",tradeId:String(t.tradeId||`lighter:${e.symbol}:${e.marketIndex}:${e.clientOrderIndex}`),expiresAtMs:n+o,slippageBps:Number(t.slippageBps??0),fee:{oracleFeeBps:0},provider:"lighter-delta-neutral",artifact:{kind:"lighter-order",symbol:e.symbol,marketIndex:e.marketIndex,side:e.side,baseAmount:e.baseAmount,price:e.price,notionalUsd:e.notionalUsd,sizeDecimals:e.sizeDecimals??0,priceDecimals:e.priceDecimals??0,clientOrderIndex:e.clientOrderIndex,txType:e.txType??ae,submitTo:i,accountIndex:e.accountIndex??t.accountIndex??null,orderType:e.orderType,timeInForce:e.timeInForce,reduceOnly:e.reduceOnly,triggerPrice:e.triggerPrice,orderExpiry:e.orderExpiry}};return Gt(s,{lighterMarkets:t.lighterMarkets||["*"],maxNotionalUsd:t.maxNotionalUsd??Number.MAX_SAFE_INTEGER}),s}var Jt="https://mainnet.zklighter.elliot.ai",Kt="https://testnet.zklighter.elliot.ai";function Rn(e={}){return e.testnet||process.env.LIGHTER_TESTNET==="1"?Kt:Jt}function z(e){let t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?t:null}function Fn(e,t){let r=e.toString().padStart(t+1,"0");if(t===0)return r;let n=r.slice(0,-t),o=r.slice(-t).replace(/0+$/,"");return o?`${n}.${o}`:n}function Xt(e){let t=z(e);if(t==null)throw new Error("lighter: funding rate required");return t*24*365*100}function Dn(e,t,r=4){let n=z(e),o=z(t),i=Number.isInteger(Number(r))?Number(r):4;if(!(n>0))throw new Error("lighter: notionalUsd must be > 0");if(!(o>0))throw new Error("lighter: markPx must be > 0");let s=10**i;return Math.floor(n/o*s+1e-12)}function Wt(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?e:null}function Yt(e,t){let r=Array.isArray(e?.funding_rates)?e.funding_rates:[],n=Array.isArray(t?.order_book_details)?t.order_book_details:[],o=new Map;for(let s of n){let a=Wt(s.market_id);a!=null&&o.set(a,s)}let i=[];for(let s of r){if(String(s.exchange||"")!=="lighter")continue;let a=Wt(s.market_id);if(a==null)continue;let l=o.get(a),c=z(l?.mark_price??l?.index_price),u=z(s.rate),d=String(s.symbol||l?.symbol||"").trim();!d||u==null||!(c>0)||i.push({coin:d,symbol:d,marketIndex:a,funding:u,markPx:c,openInterest:z(l?.open_interest)??0,sizeDecimals:Number(l?.supported_size_decimals??l?.size_decimals??4),priceDecimals:Number(l?.supported_price_decimals??l?.price_decimals??2),fundingAprPct:Xt(u)})}return i}function Qt(e,t){if(!e?.symbol&&!e?.coin)throw new Error("lighter: symbol required");let r=z(e.funding);if(r==null)throw new Error("lighter: funding required");let n=Xt(r),o=r>0,i={coin:e.symbol||e.coin,symbol:e.symbol||e.coin,marketIndex:e.marketIndex,notionalUsd:z(t),markPx:e.markPx,fundingHourly:r,fundingAprPct:n,targetDelta:0,spot:o?"hold-existing":"short-spot-not-in-light-path",perpSide:o?"sell":"buy",baseAmount:o?Dn(t,e.markPx,e.sizeDecimals):0,price:Math.round(Number(e.markPx)*10**Number(e.priceDecimals||0)),sizeDecimals:e.sizeDecimals,priceDecimals:e.priceDecimals,verdict:o?n>=5?"carry":"watch":"skip",posture:"light hold-spot / short-perp carry on Lighter. Armed via official sendTx. Not automated."};if(!(i.notionalUsd>0))throw new Error("lighter: notionalUsd must be > 0");return i}async function Zt(e={}){let t=Rn(e),r=e.fetchImpl,n=await H(`${t}/api/v1/funding-rates`,{fetchImpl:r,retries:0}),o=await H(`${t}/api/v1/orderBookDetails`,{fetchImpl:r,retries:0});return{funding:n,books:o}}async function We(e={},t={}){let r=Math.min(24,Math.max(1,Number(e.limit??8)||8)),{funding:n,books:o}=await Zt(t),i=Yt(n,o).filter(s=>s.funding>0).sort((s,a)=>a.funding-s.funding||a.openInterest-s.openInterest).slice(0,r);return{live:!0,source:"Lighter funding-rates + orderBookDetails",considered:Array.isArray(n?.funding_rates)?n.funding_rates.filter(s=>s.exchange==="lighter").length:0,candidates:i,posture:"read-only Lighter funding scan. Positive funding only. No signing."}}async function Je(e={},t={}){let r=String(e.coin||e.symbol||"").trim();if(!r)throw new Error("lighter: coin required");let n=Number(e.notionalUsd??e.notional??1e3),{funding:o,books:i}=await Zt(t),s=Yt(o,i).find(a=>a.symbol===r);if(!s)throw new Error(`lighter: ${r} not in Lighter funding`);return Qt(s,n)}async function Bn(e={},t={}){tr(e,t,"lighter");let r=rr(e.maxNotionalUsd??25e3,"lighter");if(typeof e.accountIndex!="number"||!Number.isSafeInteger(e.accountIndex)||e.accountIndex<0)throw new Error("lighter: accountIndex required");let n=e.accountIndex,o=await Je(e,t);if(o.verdict==="skip")return B({...o,prepared:!1,oraclePrepared:!1,surface:"lighter",reason:"negative funding is outside the light hold-spot path"},{provider:"lighter-delta-neutral",kind:"lighter-order"});let i=me(e,o.coin,"lighter");if(!er.test(String(e.owner||"")))throw new Error("lighter: prepare requires owner");if(o.baseAmount/10**Number(o.sizeDecimals||0)-i>1e-12)throw new Error("lighter: hedge cannot exceed held spot");let a=!!(t.testnet||process.env.LIGHTER_TESTNET==="1"),l=Number(o.sizeDecimals||0)+Number(o.priceDecimals||0),c=Fn(BigInt(o.baseAmount)*BigInt(o.price),l);if(e.clientOrderIndex!=null&&(typeof e.clientOrderIndex!="number"||!Number.isSafeInteger(e.clientOrderIndex)||e.clientOrderIndex<0))throw new Error("lighter: clientOrderIndex must be a safe integer");let u={...o,targetNotionalUsd:o.notionalUsd,notionalUsd:c,kind:"lighter-order",surface:"lighter",side:o.perpSide,clientOrderIndex:e.clientOrderIndex??Date.now()%1e9,accountIndex:n,orderType:0,timeInForce:1,reduceOnly:0,triggerPrice:0,orderExpiry:-1,txType:ae,submitTo:`${a?Kt:Jt}/api/v1/sendTx`,signed:!1,broadcast:!1},d=null,p=null;try{d=Vt(u,{...e,maxNotionalUsd:r},t)}catch(f){p=String(f?.message||f).slice(0,200)}return B({...u,prepared:!!d,signing:d?"awaiting-lighter-signer":"blocked",localSignerEnvelope:d,localSignerBlockedReason:p,oraclePrepared:!!d},{provider:"lighter-delta-neutral",kind:"lighter-order"})}var er=/^0x[0-9a-fA-F]{40}$/;function tr(e,t,r){if((t.hosted===!0||t.keyless===!0)&&(e.farming===!0||typeof t.signImpl=="function"))throw new Error(`${r}: hosted/keyless cannot sign`);if(e.farming===!0||typeof t.signImpl=="function"||typeof t.prepareImpl=="function")throw new Error(`${r}: farm cannot sign; use oracle signer`)}function Un(e,t,r){tr(e,t,r)}function zn(e={}){if(e.halted===!0)throw new Error("lighter: loop is halted");let t=e.mode==="live"?"live":"shadow",r=Array.isArray(e.coins||e.allowlist)?(e.coins||e.allowlist).map(String):[],n=e.maxCoins??1;if(typeof n!="number"&&!(typeof n=="string"&&/^(?:0|[1-9]\d*)$/.test(n)))throw new Error("lighter: maxCoins must be an integer");let o=Number(n);if(!Number.isSafeInteger(o))throw new Error("lighter: maxCoins must be an integer");if(o<1||o>8)throw new Error("lighter: maxCoins must be between 1 and 8");let i=rr(e.maxNotionalUsd??e.notionalUsd??e.notional??1e3,"lighter");if(t==="live"&&r.length===0)throw new Error("lighter: live loop requires a coin allowlist");if(t==="live"&&we(e,r,"lighter"),t==="live"&&!er.test(String(e.owner||"")))throw new Error("lighter: live loop requires owner");let s=e.accountIndex;if(t==="live"&&(typeof s!="number"||!Number.isSafeInteger(s)||s<0))throw new Error("lighter: live loop requires accountIndex");return{mode:t,allowlist:r,maxCoins:o,maxNotionalUsd:i,accountIndex:s}}function rr(e,t){let r=typeof e=="string"&&e===e.trim()&&/^(?:0\.\d+|[1-9]\d*(?:\.\d+)?)$/.test(e);if(typeof e!="number"&&!r)throw new Error(`${t}: maxNotionalUsd out of bounds`);let n=Number(e);if(!(n>0)||n>25e3)throw new Error(`${t}: maxNotionalUsd out of bounds`);return n}async function nr(e={},t={}){Un(e,t,"lighter");let r=zn(e),n=await We({limit:e.limit??16},t),o=new Set(r.allowlist),i=[],s=Math.floor(r.maxNotionalUsd/r.maxCoins);for(let a of n.candidates){if(o.size&&!o.has(a.symbol)&&!o.has(a.coin))continue;let l=Qt(a,s);if(l.verdict!=="carry")continue;if(i.length>=r.maxCoins)break;if(r.mode==="shadow"){i.push({...l,mode:"shadow",surface:"lighter",prepared:!1,signed:!1,broadcast:!1});continue}let c=await Bn({coin:l.symbol,notionalUsd:l.notionalUsd,maxNotionalUsd:s,owner:e.owner,accountIndex:r.accountIndex,spotSize:e.spotSize??e.spotHeldSize,spotSizes:e.spotSizes??e.spotHeldSizes},{fetchImpl:t.fetchImpl,nowMs:t.nowMs,testnet:t.testnet});i.push({...c,mode:"live",surface:"lighter"})}return{loop:!0,mode:r.mode,surface:"lighter",signer:"lighter",considered:n.considered,actions:i,signed:i.some(a=>a.signed===!0),broadcast:i.some(a=>a.broadcast===!0),posture:"one tick. Prepares an unsigned official sendTx for oracle signer. Armed, not automated. Farm loop never signs or broadcasts."}}var Ke=`oracle farm <methods|discover|airdrop|carry|loop|lighter> [options]
|
|
1
|
+
var sr=Object.defineProperty;var _=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var ar=(e,t)=>{for(var r in t)sr(e,r,{get:t[r],enumerable:!0})};import q from"node:net";import cr from"node:dns";function ue(e){let t=String(e).toLowerCase().split("%")[0];if((t.match(/::/g)||[]).length>1)return null;let r=u=>{if(!u)return[];let d=u.split(":"),p=d.at(-1);if(p?.includes(".")){let h=p.split(".").map(Number);if(h.length!==4||h.some(f=>!Number.isInteger(f)||f<0||f>255))return null;d.splice(d.length-1,1,(h[0]<<8|h[1]).toString(16),(h[2]<<8|h[3]).toString(16))}return d.some(h=>!/^[0-9a-f]{1,4}$/.test(h))?null:d.map(h=>Number.parseInt(h,16))},[n,o]=t.split("::"),i=r(n),s=r(o);if(!i||!s)return null;let a=t.includes("::"),l=8-i.length-s.length;if(!a&&l!==0||a&&l<1)return null;let c=[...i,...Array(Math.max(0,l)).fill(0),...s];return c.length!==8?null:Uint8Array.from(c.flatMap(u=>[u>>8,u&255]))}function Ee(e,t,r){let n=Math.floor(r/8),o=r%8;for(let s=0;s<n;s+=1)if(e[s]!==t[s])return!1;if(!o)return!0;let i=255<<8-o;return(e[n]&i)===(t[n]&i)}function Se(e){if(q.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(q.isIPv6(e)){let t=ue(e);if(!t)return!1;let r=ue("::ffff:0:0");return Ee(t,r,96)?Se([...t.slice(12)].join(".")):Ee(t,ue("2000::"),3)?![["2001::",23],["2001:db8::",32],["2001:10::",28],["2001:2::",48],["2002::",16],["3fff::",20]].some(([o,i])=>Ee(t,ue(o),i)):!1}return!1}function ur(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(lr.has(r)||r.endsWith(".localhost")||r.endsWith(".internal"))return{ok:!1,error:`refused internal host ${r}`};let n=q.isIP(r);return n!==0&&!Se(r)?{ok:!1,error:`refused private address ${r}`}:{ok:!0,url:t,host:r,isLiteralIp:n!==0}}async function Ie(e,{lookupFn:t=cr.promises.lookup}={}){let r=ur(e);if(!r.ok)return r;if(r.isLiteralIp)return{ok:!0,url:r.url,addresses:[{address:r.host,family:q.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=>!Se(o.address))?{ok:!1,error:`refused: ${r.host} resolves to a non-public address`}:{ok:!0,url:r.url,addresses:n}}async function ke({requireUndici:e=!1,importUndici:t=()=>import("undici")}={}){let r,n;try{let d=await t();r=d.Agent,n=d.fetch}catch(d){if(e)throw new Error(`egress-guard: untrustedUrl pinning requires the undici package, which failed to load: ${d?.message||d}`);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=d=>String(d).toLowerCase().replace(/^\[|\]$/g,"").replace(/\.+$/,""),i=new Map,s=d=>(Array.isArray(d)?d:[d]).map(p=>typeof p=="string"?{address:p}:p).filter(p=>p&&p.address).map(p=>({address:p.address,family:p.family||(q.isIPv6(p.address)?6:4)})),a=(d,p,h)=>{i.set(o(d),s(typeof p=="string"?[{address:p,family:h}]:p))},l=d=>{let p=o(d);if(q.isIP(p))return[{address:p,family:q.isIPv6(p)?6:4}];let h=i.get(p);if(!h||!h.length)throw new Error(`refused: unpinned host ${d} during pinned fetch`);return h},c=new r({connect:{lookup(d,p,h){let f;try{f=l(d)}catch(b){return h(b)}return p?.all?h(null,f):h(null,f[0].address,f[0].family)}}}),u=dr((d,p={})=>n(d,{...p,dispatcher:c}),a);return{dispatcher:c,fetch:u,pin:a,resolve:l,async close(){try{await c.destroy()}catch{}}}}function dr(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[Ae]=Object.freeze({pin:t}),e}function Ne(e){return typeof e=="function"&&typeof e[Ae]?.pin=="function"}function Xe(e,t,r){if(!Ne(e))throw new Error("pinFetchToAddresses: fetchImpl is not pin-capable");e[Ae].pin(t,r)}var lr,Ae,Ye=_(()=>{lr=new Set(["localhost","metadata.google.internal","metadata.goog"]);Ae=Symbol.for("oracle.egressGuard.pinCapableFetch")});import{createHash as pr}from"node:crypto";function gr(e){let t=String(e||"").toLowerCase();return nt.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function br(e){let t={};for(let[r,n]of Object.entries(e||{}))gr(r)||(t[r]=n);return t}function yr(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 xr(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Er(e,t,r,n={}){let o={};for(let[u,d]of Object.entries(r||{}))o[u.toLowerCase()]=d;let i=Object.keys(o).filter(u=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(u)),a=[...new Set([...nt,...i])].sort().map(u=>`${u}=${o[u]??""}`).join(`
|
|
2
|
+
`),l=pr("sha256").update(a).digest("hex").slice(0,32),c=`${n.untrustedUrl?"untrusted":"trusted"}:${n.maxResponseBytes??"unbounded"}`;return`${e} ${t} ${c} ${l}`}function Sr(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,Ze):Math.min(250*2**e,Ze)+Math.floor(Math.random()*100)}function Q(e,t={}){let r=new Error(e);return r.retryable=!1,Object.assign(r,t),r}function ve(e,t,r){return Q(`HTTP response from ${e} exceeded maxResponseBytes ${r} (${t})`,{oversize:!0})}function Z(e){try{let t=e?.body?.cancel?.();t&&typeof t.then=="function"&&t.catch(()=>{})}catch{}}function kr(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 i=Number(e.headers?.get?.("content-length"));if(Number.isFinite(i)&&i>t&&(Z(e),!n))throw ve(r,`content-length ${i}`,t);let s=e.body?.getReader?.();if(!s){let d=await e.text(),p=Buffer.byteLength(d,"utf8");if(p>t){if(!n)throw ve(r,`body ${p} bytes`,t);return Buffer.from(d,"utf8").subarray(0,t).toString("utf8")}return d}let a=[],l=0,c=!1;try{for(;;){let{value:d,done:p}=await s.read();if(p)break;if(d&&(a.push(Buffer.from(d)),l+=kr(d),l>t)){c=!0;break}}}finally{if(c)try{await s.cancel()}catch{}try{s.releaseLock?.()}catch{}}if(c&&(typeof o=="function"&&o(),!n))throw ve(r,`streamed ${l} bytes`,t);let u=Buffer.concat(a);return(c?u.subarray(0,t):u).toString("utf8")}function rt(e){if(!e)return null;try{return JSON.parse(e)}catch{return null}}async function Ar(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:i,lookupFn:s,realFetch:a,untrustedUrl:l=!1,maxResponseBytes:c=null,importUndici:u,validateResponse:d,signal:p}){let h=new AbortController,f=setTimeout(()=>h.abort(),i),b=p?typeof AbortSignal.any=="function"?AbortSignal.any([p,h.signal]):p:h.signal,w=null,E=t,y=s?{lookupFn:s}:{};if(l&&!a&&!Ne(E))throw Q(`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 x=async(m,{status:k=null}={})=>{let S=await Ie(m,y);if(!S.ok)throw Q(k==null?`HTTP refused ${m}: ${S.error}`:`HTTP redirect to ${m} ${S.error}`,k==null?{}:{status:k});let g=new URL(m).hostname;if(a){if(w&&(await w.close(),w=null),!w)try{w=await ke({requireUndici:!0,...u?{importUndici:u}:{}})}catch(P){throw Q(k==null?`HTTP refused ${m}: ${P?.message||P}`:`HTTP redirect to ${m} refused: ${P?.message||P}`,k==null?{}:{status:k})}w.pin(g,S.addresses),E=w.fetch}else Xe(E,g,S.addresses);return S};try{let m=String(e),k={...n||{}};l&&await x(m);for(let S=0;S<=et;S+=1){let g=await E(m,{method:r,headers:k,body:o,signal:b,redirect:"manual"});if(mr.has(g.status)){if(r!=="GET"&&r!=="HEAD"){let $=await tt(g,c??wr,{url:m,truncate:!0}),L=new Error(`HTTP ${g.status} ${r} ${m} redirected non-idempotent request`);throw L.status=g.status,L.body=rt($)??$.slice(0,300),L}if(S===et)throw Z(g),new Error(`HTTP redirect loop for ${e}`);let v=g.headers?.get?.("location"),B;try{B=yr(v,m)}catch($){throw Z(g),$}let Y=!xr(B,m);if(Z(g),Y&&(k=br(k)),l)await x(B,{status:g.status});else if(Y){let $=await Ie(B,y);if(!$.ok){let L=new Error(`HTTP redirect from ${m} ${$.error}`);throw L.status=g.status,L.retryable=!1,L}a&&$.addresses?.length&&(w||(w=await ke(u?{importUndici:u}:{})),w&&(w.pin(new URL(B).hostname,$.addresses),E=w.fetch))}m=B;continue}if(typeof d=="function")try{await d(g,{url:m})}catch(v){throw Z(g),Q(v?.message||String(v))}let P=await tt(g,c,{url:m,onOversize:()=>h.abort()}),le=rt(P);if(!g.ok){let v=new Error(`HTTP ${g.status} ${r} ${m}`);throw v.status=g.status,v.retryAfter=g.headers?.get?.("retry-after")??null,v.body=le??P.slice(0,300),v}return le??P}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(f),w&&await w.close()}}async function H(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,o=(t.method||"GET").toUpperCase(),i={Accept:"application/json",...t.headers||{}},s=t.body;s!=null&&typeof s!="string"&&(i["Content-Type"]=i["Content-Type"]||"application/json",s=JSON.stringify(s));let a=Number.isInteger(t.retries)?Math.max(t.retries,0):fr,l=t.lookupFn,c=!t.fetchImpl,u=t.untrustedUrl===!0,d=t.importUndici,p=t.validateResponse,h=t.signal,f=Number(t.maxResponseBytes),b=Number.isFinite(f)&&f>0?Math.floor(f):null,w=async()=>{let k;for(let S=0;S<=a;S++){h?.throwIfAborted?.();try{return await Ar(e,{fetchImpl:r,method:o,headers:i,body:s,timeoutMs:n,lookupFn:l,realFetch:c,untrustedUrl:u,maxResponseBytes:b,importUndici:d,validateResponse:p,signal:h})}catch(g){k=g;let P=g?.status,le=g?.name==="AbortError"||g?.name==="TimeoutError"||h?.aborted,v=new Set([408,425,429]),B=g?.retryable===!1?!1:P!=null?v.has(P)||hr.has(P)&&Qe.has(o):!le&&Qe.has(o);if(S===a||!B)throw g;let Y=Sr(S,g?.retryAfter);h?await new Promise(($,L)=>{let ir=setTimeout($,Y);h.addEventListener("abort",()=>{clearTimeout(ir),L(h.reason||new DOMException("Aborted","AbortError"))},{once:!0})}):await Ir(Y)}}throw k};if(!(t.dedupe!==!1&&!h&&o==="GET"&&s==null))return w();let y=Er(o,e,i,{untrustedUrl:u,maxResponseBytes:b}),x=Pe.get(y);if(x)return x;let m=w().finally(()=>Pe.delete(y));return Pe.set(y,m),m}var hr,Qe,fr,Ze,nt,mr,et,wr,Pe,Ir,de=_(()=>{Ye();hr=new Set([408,425,429,500,502,503,504]),Qe=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),fr=2,Ze=4e3,nt=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],mr=new Set([301,302,303,307,308]),et=3,wr=64*1024;Pe=new Map;Ir=e=>new Promise(t=>setTimeout(t,e))});function Cr({testnet:e,baseUrl:t}={}){if(t)return t.replace(/\/$/,"").endsWith("/info")?t:`${t.replace(/\/$/,"")}/info`;if(process.env.HL_INFO_URL)return process.env.HL_INFO_URL;if(process.env.HL_API_URL){let r=process.env.HL_API_URL.replace(/\/$/,"");return r.endsWith("/info")?r:`${r}/info`}return e||process.env.HL_TESTNET==="1"?Or:Lr}async function G(e,t={}){if(!e||!e.type)throw new Error("hlInfo requires body.type");let r=Cr(t);return H(r,{method:"POST",body:e,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function at(e={}){return G({type:"allMids"},e)}async function te(e={}){let t={type:"metaAndAssetCtxs"};return e.dex&&(t.dex=e.dex),G(t,e)}var Lr,Or,pe=_(()=>{de();Lr="https://api.hyperliquid.xyz/info",Or="https://api.hyperliquid-testnet.xyz/info"});import{createHash as Rr,createHmac as Fr,timingSafeEqual as co}from"node:crypto";function $e(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map($e).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${$e(e[r])}`).join(",")}}`}function ct(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function lt(e=process.env){return ct(process.env)||ct(e)}function zr(e){let{prepareHash:t,prepareMac:r,note:n,...o}=e||{};return o}function qr(e){let t=zr(e);return Rr("sha256").update($e(t)).digest("hex")}function Hr(e,t=lt()){return t?Fr("sha256",t).update(String(e)).digest("hex"):""}function C(e,{provider:t,kind:r,env:n=process.env,nowMs:o=Date.now(),expiresAtMs:i}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let s=Object.prototype.hasOwnProperty.call(e,"oraclePrepared");if(s&&typeof e.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let a={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:s?e.oraclePrepared:!0};if(!a.provider)throw new Error("stampPrepared: provider required");if(!a.kind)throw new Error("stampPrepared: kind required");let l=Number(o),c=i==null?l+Br:Number(i),u=c-l;if(!Number.isSafeInteger(l)||!Number.isSafeInteger(c)||u<=0||u>Ur)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let p={...a,preparedAt:l,expiresAt:c,prepareVersion:Dr},h=qr(p),f=lt(n),b=f?Hr(h,f):void 0,w={...p,prepareHash:h};return b&&(w.prepareMac=b),w}var Dr,Br,Ur,he=_(()=>{Dr=2,Br=300*1e3,Ur=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});async function pt(e={}){let t=Date.now();if(ne.dexs&&t-ne.at<6e4&&!e.fetchImpl)return ne.dexs;let r=await G({type:"perpDexs"},e);return ne={at:t,dexs:Array.isArray(r)?r:[]},ne.dexs}async function ht(e="",t={}){let r=e||"",n=Date.now(),o=dt.get(r);if(o&&n-o.at<3e4&&!t.fetchImpl)return o;let i=e?await G({type:"metaAndAssetCtxs",dex:e},t):await te(t),s=i?.[0]?.universe??i?.universe??[],a=Array.isArray(i?.[1])?i[1]:[],l={at:n,universe:s,ctxs:a};return dt.set(r,l),l}function ge(e){if(typeof e!="string"||!/^#(?:0|[1-9]\d*)$/.test(e))return null;let t=Number(e.slice(1));if(!Number.isSafeInteger(t)||t<0)return null;let r=t%10;if(r!==0&&r!==1)return null;let n=Math.floor(t/10),o=mt+t;return Number.isSafeInteger(o)?{encoding:t,outcome:n,side:r,coin:`#${t}`,assetId:o}:null}function ft(e,t){let r=Te(e),n=Te(t);if(r==null)throw new Error("hl-assets: outcome id must be a non-negative integer");if(n!==0&&n!==1)throw new Error("hl-assets: outcome side must be 0 or 1");let o=10*r+n;if(!Number.isSafeInteger(o))throw new Error("hl-assets: outcome encoding exceeds safe integer range");let i=mt+o;if(!Number.isSafeInteger(i))throw new Error("hl-assets: outcome asset id exceeds safe integer range");return{encoding:o,outcome:r,side:n,coin:`#${o}`,assetId:i}}function Te(e){if(typeof e=="number")return Number.isSafeInteger(e)&&e>=0?e:null;if(typeof e!="string"||!/^(?:0|[1-9]\d*)$/.test(e))return null;let t=Number(e);return Number.isSafeInteger(t)?t:null}async function Me(e={},t={}){if(e.outcome!=null||typeof e.coin=="string"&&e.coin.startsWith("#")){let c=e.coin==null?null:ge(e.coin);if(e.coin!=null&&!c)throw new Error(`hl-assets: invalid outcome coin ${e.coin}`);let u=e.outcome==null?null:ft(e.outcome,0).outcome;if(u!=null&&c&&c.outcome!==u)throw new Error("hl-assets: coin does not match outcome");let d=e.outcomeSide==null?null:Gr(e.outcomeSide,"outcomeSide"),p=u??c?.outcome;if(e.outcome!=null&&e.coin==null&&d==null)throw new Error("hl-assets: outcomeSide required");let h=d??c?.side;if(h==null)throw new Error("hl-assets: outcomeSide required");if(p==null)throw new Error("hl-assets: outcome identity required");let f=ft(p,h);if(c&&(c.outcome!==f.outcome||c.side!==f.side))throw new Error("hl-assets: coin does not match outcome side");let b=e.szDecimals!=null?Number(e.szDecimals):2;return{kind:"outcome",coin:f.coin,assetId:f.assetId,encoding:f.encoding,outcome:f.outcome,side:f.side,szDecimals:b,maxLeverage:1,dex:null,markPx:null}}let r=String(e.coin||e.symbol||e.name||"").trim();if(!r)throw new Error("hl-assets: coin required");if(r.includes(":")){let[c,...u]=r.split(":"),d=u.join(":");if(!c||!d)throw new Error(`hl-assets: bad builder coin ${r}`);let h=(await pt(t)).findIndex(m=>m&&m.name===c);if(h<1)throw new Error(`hl-assets: unknown builder dex "${c}"`);let{universe:f,ctxs:b}=await ht(c,t),w=f.findIndex(m=>m.name===r||m.name===`${c}:${d}`||m.name.endsWith(`:${d}`));if(w<0)throw new Error(`hl-assets: ${r} not in dex ${c} meta`);let E=f[w];if(E.isDelisted)throw new Error(`hl-assets: ${r} is delisted`);let y=jr+h*1e4+w,x=b[w]||{};return{kind:"hip3",coin:E.name||r,assetId:y,szDecimals:E.szDecimals??0,maxLeverage:E.maxLeverage??null,dex:c,dexIndex:h,indexInMeta:w,markPx:x.markPx??null}}let{universe:n,ctxs:o}=await ht("",t),i=r.toUpperCase(),s=n.findIndex(c=>c.name===i);if(s<0){if(t.allowBareBuilderLeaf===!0)try{let c=await pt(t);for(let u=1;u<c.length;u++){let d=c[u];if(!d?.name)continue;let p=`${d.name}:${i}`;try{return await Me({coin:p},t)}catch{}}}catch{}throw new Error(`hl-perps: ${i} is not a listed perp`)}let a=n[s];if(a.isDelisted)throw new Error(`hl-assets: ${i} is delisted`);let l=o[s]||{};return{kind:"main",coin:a.name,assetId:s,szDecimals:a.szDecimals??0,maxLeverage:a.maxLeverage??null,dex:"",markPx:l.markPx??null}}function Gr(e,t){let r=Te(e);if(r!==0&&r!==1)throw new Error(`hl-assets: ${t} must be 0 or 1`);return r}var mt,jr,ne,dt,Le=_(()=>{pe();mt=1e8,jr=1e5,ne={at:0,dexs:null},dt=new Map});function I(e,t="value"){if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`${t} must be a finite number`);if(Math.abs(e)>Number.MAX_SAFE_INTEGER)throw new Error(`${t} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);if(Number.isInteger(e)&&!Number.isSafeInteger(e))throw new Error(`${t} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return String(e)}if(typeof e=="string"){if(e!==e.trim())throw new Error(`${t} must be a number or decimal string`);return e}throw new Error(`${t} must be a number or decimal string`)}function wt(e,t="value"){if(typeof e!="string"||e==="")throw new Error(`${t} must be a string`);return e}function V(e,t="amount"){if(typeof e=="bigint")return e;if(typeof e=="number"){if(!Number.isInteger(e))throw new Error(`${t} must be an integer`);if(!Number.isSafeInteger(e))throw new Error(`${t} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return BigInt(e)}let r=I(e,t);if(r==="")throw new Error(`${t} is required`);if(!/^-?\d+$/.test(r)&&!/^0x[0-9a-fA-F]+$/.test(r))throw new Error(`${t} must be an integer in decimal or 0x-hex form, got ${JSON.stringify(r)}`);try{return BigInt(r)}catch{throw new Error(`${t} must be an integer, got ${JSON.stringify(r)}`)}}function Oe(e,t="amount"){let r=V(e,t);if(r<=0n)throw new Error(`${t} must be positive`);return r}function N(e,t,r="amount"){let n=I(e,r);if(!/^-?\d*(\.\d+)?$/.test(n)||n===""||n==="."||n==="-")throw new Error(`${r} must be a decimal number, got ${JSON.stringify(n)}`);let o=n.startsWith("-"),i=o?n.slice(1):n,[s="0",a=""]=i.split(".");if(a.length>t)throw new Error(`${r} has more than ${t} decimal places, which would lose precision`);let l=BigInt((s||"0")+a.padEnd(t,"0"));return o?-l:l}var be=_(()=>{});function Xr(e,t){let r=e.toString().padStart(t+1,"0");if(t===0)return r;let n=r.slice(0,-t),o=r.slice(-t).replace(/0+$/,"");return o?`${n}.${o}`:n}function gt(e,t){let r=I(e,`hl: ${t}`);if(!/^\d+(?:\.\d+)?$/.test(r))throw new Error(`hl: ${t} must be a positive decimal`);let[n,o=""]=r.split("."),i=BigInt(n+o);if(i<=0n)throw new Error(`hl: ${t} must be positive`);return{raw:i,decimals:o.length}}function M(e,t){if(e===null||typeof e=="string"||typeof e=="boolean")return JSON.stringify(e);if(typeof e=="number"){if(!Number.isFinite(e))throw new Error(`hl: ${t} must be finite JSON`);return JSON.stringify(e)}if(Array.isArray(e))return`[${e.map(n=>M(n,t)).join(",")}]`;if(!e||typeof e!="object")throw new Error(`hl: ${t} must be structured JSON`);return`{${Object.keys(e).sort().map(n=>`${JSON.stringify(n)}:${M(e[n],t)}`).join(",")}}`}function Yr(e){if(typeof e.orderType!="string"||!e.orderType)throw new Error("hl: order type must be a string");let t=e.orderType,r=e.orderWire;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("hl: declared order wire required");if(t==="limit"){let i=r.limit?.tif;if(!["Gtc","Ioc","Alo"].includes(i)||M(r,"declared order type")!==M({limit:{tif:i}},"expected order type"))throw new Error("hl: limit order type must match its wire shape");return}if(t==="market"){if(M(r,"declared order type")!==M({limit:{tif:"Ioc"}},"expected order type"))throw new Error("hl: market order type must match its IOC wire shape");return}let n={stopMarket:{isMarket:!0,tpsl:"sl"},stopLimit:{isMarket:!1,tpsl:"sl"},takeProfitMarket:{isMarket:!0,tpsl:"tp"},takeProfitLimit:{isMarket:!1,tpsl:"tp"}}[t];if(!n)throw new Error("hl: unsupported declared order type");let o=r.trigger?.triggerPx;if(o==null||M(r,"declared order type")!==M({trigger:{isMarket:n.isMarket,triggerPx:o,tpsl:n.tpsl}},"expected order type"))throw new Error("hl: trigger order type must match its wire shape")}function Qr(e,t,r){let n=gt(e.s,"signed size"),o=gt(e.p,"signed price"),i=n.decimals+o.decimals,s=n.raw*o.raw,a=N(t.notionalUsd,i,"hl: notionalUsd");if(a<=0n||s!==a)throw new Error("hl: signed notional must match");let l=N(r.maxNotionalUsd,i,"hl: maxNotionalUsd");if(s>l)throw new Error("hl: notional exceeds cap")}function Zr(e,t){let r=e.action.builder;if(r==null){if(e.builder!=null)throw new Error("hl: declared builder requires a signed builder");return}if(!r||typeof r!="object"||Array.isArray(r))throw new Error("hl: signed order builder must be structured");let n=U(r.b,"order builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(n))throw new Error("hl: order builder address required");if(wt(e.builder||"","hl: builder").toLowerCase()!==n)throw new Error("hl: signed order builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(a=>String(a).toLowerCase()):[]).includes(n))throw new Error("hl: order builder not allowed");let i=V(r.f,"hl: signed order builder fee");if(i<0n)throw new Error("hl: signed order builder fee must be non-negative");let s=N(t.maxBuilderFeeBps??0,1,"hl: maxBuilderFeeBps");if(i>s)throw new Error("hl: order builder fee exceeds cap")}function bt(e,t,r){if(!Number.isSafeInteger(e.a)||e.a!==r)throw new Error("hl: signed asset must match assetId");if(typeof e.b!="boolean"||e.b!==(t.side==="buy"))throw new Error("hl: signed side must match exactly");if(I(e.s,"hl: signed size")!==I(t.size,"hl: size"))throw new Error("hl: signed size must match");if(I(e.p,"hl: signed price")!==I(t.price,"hl: price"))throw new Error("hl: signed price must match");if(typeof t.reduceOnly!="boolean"||typeof e.r!="boolean"||e.r!==t.reduceOnly)throw new Error("hl: signed reduceOnly must match exactly");if(M(e.t,"signed order type")!==M(t.orderWire,"declared order type"))throw new Error("hl: signed order type must match declared order type");let n=Object.prototype.hasOwnProperty.call(e,"c");if(t.clientOrderId==null){if(n)throw new Error("hl: undeclared signed client order id")}else if(!n||typeof e.c!="string"||e.c!==t.clientOrderId)throw new Error("hl: signed client order id must match")}function yt(e,t,r,n,o){if(!Number.isSafeInteger(e.a)||e.a!==r)throw new Error("hl: bracket protection asset must match");if(typeof e.b!="boolean"||e.b===(t.side==="buy"))throw new Error("hl: bracket protection side must oppose entry");if(I(e.s,"hl: bracket protection size")!==I(t.size,"hl: size"))throw new Error("hl: bracket protection size must match");if(I(e.p,"hl: bracket protection price")!==I(n,"hl: protection price"))throw new Error("hl: bracket protection price must match");if(e.r!==!0)throw new Error("hl: bracket protection must be reduce-only");let i=e.t?.trigger;if(!i||i.isMarket!==!0||i.tpsl!==o)throw new Error("hl: bracket protection trigger must match");if(I(i.triggerPx,"hl: triggerPx")!==I(n,"hl: protection price"))throw new Error("hl: bracket protection trigger must match")}function en(e){let t=String(e||"").replace(/\/$/,"");if(!Vr.has(t))throw new Error("hl: submitTo must be the official Hyperliquid exchange");return t}function Ce(e){return ge(e)!=null}function tn(e,t){let r=String(e||""),n=Array.isArray(t.coins)?t.coins.map(String):[];if(Ce(r)){if(t.hip4!==!0)throw new Error("hl: HIP-4 outcome orders are disabled without explicit policy enablement");if(n.includes(r)||n.includes("#*")||n.includes("*")||n.length===0)return!0;throw new Error("hl: outcome coin not allowed")}if(n.length&&!n.includes(r)&&!n.includes("*"))throw new Error("hl: coin not allowed");return!0}function rn(e,t,r){let n=Array.isArray(r.hlMarkets)?r.hlMarkets:[];if(n.length){if(!n.some(s=>{if(typeof s=="string"){let[a,l]=String(s).split(":");return a===e&&Number(l)===t}return String(s?.coin)===e&&Number(s?.assetId)===t}))throw new Error("hl: coin/assetId pair not allowed");return!0}if(Ce(e)){let i=Array.isArray(r.coins)?r.coins.map(String):[];if(i.includes("#*")||i.includes("*")||i.length===0)return!0;throw new Error("hl: restricted coin policy requires hlMarkets pairs")}let o=Array.isArray(r.coins)?r.coins.map(String):[];if(o.length&&!o.includes("*"))throw new Error("hl: restricted coin policy requires hlMarkets pairs");return!0}function xt(e,t){if(e?.surface!=="hl")throw new Error("hl: surface hl required");let r=e.artifact;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("hl: structured artifact required");let n=U(r.kind,"kind",48),o=Jr[n];if(!o)throw new Error("hl: unsupported Hyperliquid kind");if(e.action!==o)throw new Error("hl: surface/action/kind mismatch");if(String(e.destination).toLowerCase()!=="hyperliquid")throw new Error("hl: destination must be hyperliquid");if(!/^0x[0-9a-fA-F]{40}$/.test(String(e.owner||"")))throw new Error("hl: owner required");let i=en(r.submitTo);if(Object.prototype.hasOwnProperty.call(r,"vaultAddress"))throw new Error("hl: vaultAddress is not public");if(Object.prototype.hasOwnProperty.call(r,"expiresAfter"))throw new Error("hl: expiresAfter is not public");let s=Number(r.nonce);if(!Number.isSafeInteger(s)||s<=0)throw new Error("hl: nonce must be a positive integer");if(!r.action||typeof r.action!="object")throw new Error("hl: signed action required");if(Object.prototype.hasOwnProperty.call(r.action,"vaultAddress"))throw new Error("hl: action vaultAddress is not public");if(Object.prototype.hasOwnProperty.call(r.action,"expiresAfter"))throw new Error("hl: action expiresAfter is not public");if(r.action.type!==Kr[n])throw new Error("hl: action type must match kind");let a=r.notionalUsd??0;if(Wr.has(n)||n==="perp-cancel"||n==="perp-leverage"||n==="perp-isolated-margin"){let l=U(r.coin,"coin",64),c=r.assetId??r.assetIndex;if(!Number.isSafeInteger(c)||c<0)throw new Error("hl: assetId required");if(n==="hip4-order"||c>=1e8){let u=ge(l);if(!u||u.coin!==l)throw new Error("hl: HIP-4 actions must use a canonical outcome coin");if(u.assetId!==c)throw new Error("hl: HIP-4 coin must bind to its canonical assetId")}if(tn(l,t),rn(l,c,t),n==="hip4-order"&&!Ce(l))throw new Error("hl: HIP-4 orders must use an outcome coin");if(n==="perp-order"||n==="hip3-order"||n==="hip4-order"||n==="perp-bracket"){if(r.side!=="buy"&&r.side!=="sell")throw new Error("hl: side must be buy or sell");if(r.action.type!=="order"||!Array.isArray(r.action.orders))throw new Error("hl: signed orders are required");Yr(r);let u=r.action.orders;if(n==="perp-bracket"){let d=r.takeProfitPx,p=r.stopLossPx,h=1+(d==null?0:1)+(p==null?0:1);if(h<2||u.length!==h||r.grouping!=="normalTpsl"||r.action.grouping!==r.grouping)throw new Error("hl: bracket must contain exactly the declared entry and protection legs");bt(u[0],r,c);let f=1;d!=null&&yt(u[f++],r,c,d,"tp"),p!=null&&yt(u[f],r,c,p,"sl")}else{if(u.length!==1)throw new Error("hl: exactly one signed order is required");if(r.grouping!=="na"||r.action.grouping!==r.grouping)throw new Error("hl: signed grouping must match declared grouping");bt(u[0],r,c)}Qr(u[0],r,t),Zr(r,t),a=I(r.notionalUsd,"hl: notionalUsd")}if(n==="perp-leverage"){let u=r.leverage;if(!Number.isSafeInteger(u)||u<1)throw new Error("hl: leverage must be a positive integer");let d=t.maxLeverage==null?50:t.maxLeverage;if(typeof d!="number"||!Number.isSafeInteger(d)||d<1)throw new Error("hl: maxLeverage must be a positive integer");if(u>d)throw new Error("hl: leverage exceeds cap")}if(n==="perp-cancel"){let u=r.action.cancels;if(!Array.isArray(u)||u.length!==1)throw new Error("hl: exactly one cancel is required");if(!Number.isSafeInteger(u[0].a)||u[0].a!==c)throw new Error("hl: signed cancel asset must match assetId");if(!Number.isSafeInteger(r.orderId)||r.orderId<0)throw new Error("hl: declared order id required");if(!Number.isSafeInteger(u[0].o)||u[0].o!==r.orderId)throw new Error("hl: signed cancel order id must match")}if(n==="perp-leverage"){if(!Number.isSafeInteger(r.action.asset)||r.action.asset!==c)throw new Error("hl: signed leverage asset must match assetId");if(!Number.isSafeInteger(r.action.leverage)||r.action.leverage!==r.leverage)throw new Error("hl: signed leverage must match");if(!["cross","isolated"].includes(r.marginMode))throw new Error("hl: declared margin mode required");let u=r.marginMode==="cross";if(typeof r.action.isCross!="boolean"||r.action.isCross!==u)throw new Error("hl: signed isCross must match declared margin mode")}if(n==="perp-isolated-margin"){if(!Number.isSafeInteger(r.action.asset)||r.action.asset!==c)throw new Error("hl: signed margin asset must match assetId");let u=U(r.usd,"margin usd",64),d=N(u,6,"hl: margin usd");if(V(r.action.ntli,"hl: signed margin ntli")!==d)throw new Error("hl: signed margin amount must match usd");if(typeof r.isBuy!="boolean"||r.action.isBuy!==r.isBuy)throw new Error("hl: signed margin isBuy must match");let h=N(t.maxNotionalUsd,6,"hl: maxNotionalUsd"),f=d<0n?-d:d;if(f>h)throw new Error("hl: margin notional exceeds cap");a=Xr(f,6)}}if(n==="builder-fee-approval"){let l=U(r.builder,"builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(l))throw new Error("hl: builder address required");if(U(r.action.builder,"signed builder",42).toLowerCase()!==l)throw new Error("hl: signed builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(f=>String(f).toLowerCase()):[]).includes(l))throw new Error("hl: builder not allowed");let u=U(r.maxFeeRate,"maxFeeRate",32);if(U(r.action.maxFeeRate,"signed maxFeeRate",32)!==u)throw new Error("hl: signed builder fee must match");if(!/^\d+(?:\.\d+)?%$/.test(u))throw new Error("hl: builder fee rate must be a percent");let d=N(u.slice(0,-1),12,"hl: builder fee percent"),p=N(t.maxBuilderFeeBps,12,"hl: maxBuilderFeeBps");if(p<0n||d*100n>p)throw new Error("hl: builder fee exceeds cap");if(Number(r.action.nonce)!==s)throw new Error("hl: signed builder nonce must match");let h=i.includes("testnet")?"Testnet":"Mainnet";if(r.hyperliquidChain!==h||r.action.hyperliquidChain!==r.hyperliquidChain)throw new Error("hl: signed Hyperliquid chain must match destination");if(r.signatureChainId!=="0x66eee"||r.action.signatureChainId!==r.signatureChainId)throw new Error("hl: signed signature chain id must match")}if(n.startsWith("hype-stake")||n==="hype-delegate"||n==="hype-undelegate"){if(n==="hype-delegate"||n==="hype-undelegate"){let l=n==="hype-undelegate";if(typeof r.action.isUndelegate!="boolean"||r.action.isUndelegate!==l)throw new Error("hl: signed isUndelegate must match delegate kind exactly")}if(t.maxHypeWei!=null&&BigInt(String(r.action.wei??r.caps?.amountHype??"0"))>BigInt(t.maxHypeWei))throw new Error("hl: stake amount exceeds cap")}return Object.freeze({unit:"usd",value:String(a??r.action.wei??0),notional:String(a??0),fee:"0",kind:n,actionType:r.action.type,amount:String(r.action.wei??a??0),coin:r.coin||null,submitTo:i})}var Vr,Wr,Jr,Kr,U,Et=_(()=>{be();Le();Vr=new Set(["https://api.hyperliquid.xyz/exchange","https://api.hyperliquid-testnet.xyz/exchange"]),Wr=new Set(["perp-order","hip3-order","hip4-order","perp-bracket"]),Jr=Object.freeze({"perp-order":"order","hip3-order":"order","hip4-order":"order","perp-bracket":"order","perp-cancel":"cancel","perp-leverage":"leverage","perp-isolated-margin":"margin","builder-fee-approval":"approveBuilder","hype-stake-deposit":"stake","hype-stake-withdraw":"unstake","hype-delegate":"delegate","hype-undelegate":"delegate"}),Kr=Object.freeze({"perp-order":"order","hip3-order":"order","hip4-order":"order","perp-bracket":"order","perp-cancel":"cancel","perp-leverage":"updateLeverage","perp-isolated-margin":"updateIsolatedMargin","builder-fee-approval":"approveBuilderFee","hype-stake-deposit":"cDeposit","hype-stake-withdraw":"cWithdraw","hype-delegate":"tokenDelegate","hype-undelegate":"tokenDelegate"}),U=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`hl: bounded ${t} required`);return e}});function on(e){let t=e.owner||e.user||e.from||e.recipient;if(!/^0x[0-9a-fA-F]{40}$/.test(String(t||"")))throw new Error("hl: owner/user address required for local-signer envelope");return String(t).toLowerCase()}function St(e,t={},r={}){let n=String(e?.kind||""),o=nn[n];if(!o)throw new Error("hl: prepared kind is not a local-signer surface");if(!e?.action||typeof e.action!="object")throw new Error("hl: prepared action required");let i=Number(r.nowMs??Date.now()),s=Math.min(6e4,Math.max(1e3,Number(t.ttlMs??t.expiresInMs??3e4)||3e4)),a=String(e.submitTo||"").replace(/\/$/,""),l={version:1,surface:"hl",action:o,owner:on(t),destination:"hyperliquid",tradeId:String(t.tradeId||`hl:${n}:${e.nonce}`),expiresAtMs:i+s,slippageBps:Number(t.slippageBps??0),fee:{oracleFeeBps:0},provider:e.provider,artifact:{kind:n,coin:e.coin??null,assetId:e.assetId??e.assetIndex??null,side:e.side??null,size:e.size??null,price:e.price??null,reduceOnly:e.reduceOnly??null,orderType:e.orderType??null,orderWire:e.action?.orders?.[0]?.t??null,clientOrderId:e.action?.orders?.[0]?.c??null,grouping:e.action?.grouping??null,orderId:e.orderId??null,leverage:e.leverage??null,marginMode:e.marginMode??null,notionalUsd:e.notionalUsd??0,usd:e.usd??null,isBuy:e.isBuy??null,takeProfitPx:e.takeProfitPx??null,stopLossPx:e.stopLossPx??null,builder:e.builderFee?.address??e.action?.builder??null,maxFeeRate:e.builderFee?.percent??e.action?.maxFeeRate??null,nonce:e.nonce,hyperliquidChain:e.action?.hyperliquidChain??null,signatureChainId:e.signatureChainId||e.action?.signatureChainId||"0xa4b1",submitTo:a,action:e.action,typedData:e.typedData||null,caps:e.caps||null}};return xt(l,{coins:t.coins||["*"],hip4:!0,maxNotionalUsd:t.maxNotionalUsd??Number.MAX_SAFE_INTEGER,maxLeverage:t.maxLeverage??50,hlBuilders:t.hlBuilders||(e.builderFee?.address?[e.builderFee.address]:[]),maxBuilderFeeBps:t.maxBuilderFeeBps??e.builderFee?.bps}),l}var nn,It=_(()=>{Et();nn=Object.freeze({"perp-order":"order","hip3-order":"order","hip4-order":"order","perp-bracket":"order","perp-cancel":"cancel","perp-leverage":"leverage","perp-isolated-margin":"margin","builder-fee-approval":"approveBuilder","hype-stake-deposit":"stake","hype-stake-withdraw":"unstake","hype-delegate":"delegate","hype-undelegate":"delegate"})});import{Contract as sn,JsonRpcProvider as an}from"ethers";function hn(e){return pn.test(String(e||""))}async function Re(e,{contract:t=cn,rpc:r=un,chainId:n=ln,balanceOf:o}={}){if(!hn(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let i=new an(r,n,{staticNetwork:!0}),s=new sn(t,dn,i);return BigInt(await s.balanceOf(e))}var cn,ln,un,dn,pn,Fe=_(()=>{cn="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",ln=999,un="https://rpc.hyperliquid.xyz/evm",dn=["function balanceOf(address owner) view returns (uint256)"],pn=/^0x[a-fA-F0-9]{40}$/});import{existsSync as fn,readFileSync as mn,lstatSync as wn}from"node:fs";import{homedir as kt}from"node:os";import{join as De}from"node:path";function gn(e=process.env){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){if(e[At])return String(e[At]);let t=e.ORACLE_CONFIG_DIR||De(kt(),".config","oracle");return De(t,"fee-recipient")}return De(kt(),".config","oracle","fee-recipient")}function Nt(e=process.env){try{let t=gn(e);if(!fn(t)||wn(t).isSymbolicLink())return"";let r=mn(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}var No,At,Pt=_(()=>{Fe();No=Object.freeze({swap:5,bridge:5,perps:0,nft:0}),At="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN"});var Ct={};ar(Ct,{HL_BUILDER_ADDRESS_ENV:()=>ye,HL_BUILDER_DEFAULT_FEE_BPS:()=>bn,HL_BUILDER_FEE_ENV:()=>Ue,HL_BUILDER_FEE_TIERS:()=>oe,HL_BUILDER_MAX_FEE_BPS:()=>Be,HL_PERP_MAX_SIG_FIGS:()=>vt,HL_PERP_PRICE_DECIMALS:()=>$t,HL_SIGNATURE_CHAIN_ID:()=>xe,MARGIN_MODE:()=>ie,ORDER_TYPES:()=>A,TIF:()=>se,formatPerpPrice:()=>R,formatPerpSize:()=>Lt,hlBuilderFeeBpsForKind:()=>Mt,hlPerpAssetInfo:()=>J,hlPrepareApproveAgent:()=>Nn,hlPrepareBracketOrder:()=>_n,hlPrepareBuilderApproval:()=>An,hlPrepareCancelOrder:()=>Pn,hlPreparePerpOrder:()=>Ot,hlPrepareUpdateIsolatedMargin:()=>$n,hlPrepareUpdateLeverage:()=>vn,resolveBuilderFee:()=>qe});function _t(e,t){if(typeof e=="number"){if(Number.isSafeInteger(e)&&e>=0)return e}else if(typeof e=="string"&&/^(?:0|[1-9]\d*)$/.test(e)){let r=Number(e);if(Number.isSafeInteger(r))return r}throw new Error(`hl-perps: ${t} must be a non-negative safe integer`)}function yn(e,t){let r=_t(e,t);if(r<1)throw new Error(`hl-perps: ${t} must be a positive integer`);return r}function xn(e={}){let t={...e};if(t.side==null)return t;if(t.side===0||t.side===1){if(t.outcomeSide!=null&&t.outcomeSide!==t.side)throw new Error("hl-perps: side conflict with outcomeSide");return t.outcomeSide=t.side,delete t.side,t}throw new Error("hl-assets: side must be 0 or 1")}function Tt(e,{defaultBuy:t=!1}={}){if(e.side!=null){if(typeof e.side!="string")throw new Error("hl-perps: side must be buy or sell");let r=e.side.toLowerCase();if(r!=="buy"&&r!=="sell")throw new Error("hl-perps: side must be buy or sell");let n=r==="buy";if(e.isBuy!=null&&(typeof e.isBuy!="boolean"||e.isBuy!==n))throw new Error("hl-perps: side and isBuy conflict");return n}if(e.isBuy==null&&t)return!0;if(typeof e.isBuy!="boolean")throw new Error("hl-perps: isBuy must be boolean when side is omitted");return e.isBuy}function Mt(e="perp"){if(e==="perp"||e==="main")return oe.perp;if(e==="spot")return oe.spot;if(e==="hip3")return oe.hip3;if(e==="outcome"||e==="hip4")return oe.hip4;throw new Error(`hl-perps: unknown builder fee kind ${e}`)}function qe({env:e=process.env,isHolder:t=!1,kind:r="perp"}={}){if(t)return null;let n=String(e?.[ye]||"").trim().toLowerCase();if(!n)return null;if(!/^0x[a-f0-9]{40}$/.test(n))throw new Error(`hl-perps: ${ye} must be an EVM address`);let o=Nt(e);if(!o||o!==n)return null;let i=e?.[Ue],s=Mt(r),a=i==null?s:Number(i);if(!Number.isFinite(a)||a<=0||Math.abs(a*10-Math.round(a*10))>1e-9)throw new Error(`hl-perps: ${Ue} must be a positive number in 0.1 bps increments`);if(a>Be)throw new Error(`hl-perps: builder fee ${a} bps exceeds the ${Be} bps cap`);if(a>s)throw new Error(`hl-perps: builder fee ${a} bps exceeds the ${s} bps product tier for ${r}`);let l=Math.round(a*10),c=(l/1e3).toFixed(3).replace(/0+$/,"").replace(/\.$/,"");return{wire:{b:n,f:l},disclosure:{address:n,bps:a,percent:`${c}%`}}}async function En(e,t={},r={}){if(!e)return{approved:!1,approvedFeeBps:0,status:"not-configured"};let n=String(t.user||r.user||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(n))return{approved:!1,approvedFeeBps:0,status:"wallet-required"};try{let o=Number(await G({type:"maxBuilderFee",user:n,builder:e.disclosure.address},r));return!Number.isInteger(o)||o<0?{approved:!1,approvedFeeBps:0,status:"invalid-response"}:{approved:o>=e.wire.f,approvedFeeBps:o/10,status:o>=e.wire.f?"approved":"insufficient"}}catch{return{approved:!1,approvedFeeBps:0,status:"unavailable"}}}async function Sn(e,t={},r={}){if(!e)return{exempt:!1,status:"not-configured"};let n=String(t.user||r.user||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(n))return{exempt:!1,status:"wallet-required"};try{let o=r.holderBalance||Re;return BigInt(await o(n))>0n?{exempt:!0,status:"holder"}:{exempt:!1,status:"non-holder"}}catch{return{exempt:!1,status:"unavailable"}}}function He(e,t,{roundDown:r=null}={}){let n=typeof e=="number"?e.toFixed(Math.min(20,t+8)):e;if(typeof n!="string"||!/^-?\d+(\.\d+)?$/.test(n))throw new Error(`hl-perps: "${e}" is not a decimal number`);let o=n.startsWith("-"),[i,s=""]=n.replace(/^-/,"").split(".");if(s.length<=t){let f=s.replace(/0+$/,"");return(o?"-":"")+(f?`${i}.${f}`:i)}let a=s.slice(0,t),l=Number(s[t]),c=BigInt(i+a),u=s.slice(t).replace(/0+$/,"")!=="";r===!0||(r===!1?u&&(c+=1n):l>=5&&(c+=1n));let d=c.toString().padStart(t+1,"0"),h=(t===0?d:`${d.slice(0,-t)}.${d.slice(-t)}`).replace(/(\.\d*?)0+$/,"$1").replace(/\.$/,"");return(o?"-":"")+h}function In(e,t,r={}){if(typeof e!="number"&&typeof e!="string")throw new Error(`hl-perps: "${e}" is not a decimal number`);let n=typeof e=="number"?String(e):e;if(!n.includes("."))return n;let o=Number(n);if(!Number.isFinite(o)||o===0)return n;let i=Math.floor(Math.log10(Math.abs(o))),s=Math.max(0,t-1-i);return He(n,s,r)}function R(e,t,r={}){let n=$t-Number(t??0);if(n<0)throw new Error("hl-perps: szDecimals out of range");return He(In(e,vt,r),n,r)}function Lt(e,t){let r=He(e,Number(t??0));if(BigInt(r.split(".")[0])<0n)throw new Error("hl-perps: size must be positive");if(Number(r)<=0)throw new Error("hl-perps: size rounds to zero at this asset's precision");return r}function kn(e,t){let r=(u,d)=>{let p=String(u).trim();if(!/^\d+(?:\.\d+)?$/.test(p))throw new Error(`hl-perps: ${d} must be a positive decimal`);let[h,f=""]=p.split(".");return{raw:BigInt(h+f),decimals:f.length}},n=r(e,"size"),o=r(t,"price"),i=n.raw*o.raw,s=n.decimals+o.decimals,a=i.toString().padStart(s+1,"0");if(s===0)return a;let l=a.slice(0,-s),c=a.slice(-s).replace(/0+$/,"");return c?`${l}.${c}`:l}async function J(e={},t={}){let r=await Me(e,t);return{coin:r.coin,assetId:r.assetId,szDecimals:r.szDecimals,maxLeverage:r.maxLeverage,markPx:r.markPx,kind:r.kind,dex:r.dex??null,outcome:r.outcome??null,side:r.side??null}}function ze(e,{tif:t=se.GTC,triggerPx:r,isMarket:n,szDecimals:o}={}){switch(e){case A.LIMIT:return{limit:{tif:t}};case A.MARKET:return{limit:{tif:se.IOC}};case A.STOP_MARKET:case A.TAKE_PROFIT_MARKET:return{trigger:{isMarket:!0,triggerPx:R(r,o),tpsl:e===A.STOP_MARKET?"sl":"tp"}};case A.STOP_LIMIT:case A.TAKE_PROFIT_LIMIT:return{trigger:{isMarket:!1,triggerPx:R(r,o),tpsl:e===A.STOP_LIMIT?"sl":"tp"}};default:throw new Error(`hl-perps: unknown order type ${e}`)}}function W(e,t,r={}){let n=r.testnet||process.env.HL_TESTNET==="1";return{action:e,nonce:t,signatureChainId:xe,submitTo:n?"https://api.hyperliquid-testnet.xyz/exchange":"https://api.hyperliquid.xyz/exchange",note:"Sign locally via Oracle local-signer or a wallet. Hosted Oracle does not submit."}}function K(e,t={},r={}){let n={...e};try{n.localSignerEnvelope=St(n,t,r),n.prepared=!0,n.signing="awaiting-hl-signer"}catch(o){n.prepared=!1,n.localSignerEnvelope=null,n.localSignerBlockedReason=String(o?.message||o).slice(0,200),n.signing="blocked"}return n.oraclePrepared=!!n.localSignerEnvelope,C(n,{provider:e.provider||"hl-perps",kind:e.kind})}function An(e={},t={}){let r=qe({env:t.env});if(!r)throw new Error(`hl-perps: ${ye} is required`);let n=Number(e.nonce??t.nonce??Date.now());if(!Number.isSafeInteger(n)||n<=0)throw new Error("hl-perps: nonce must be a positive integer");let o={type:"approveBuilderFee",hyperliquidChain:t.testnet||process.env.HL_TESTNET==="1"?"Testnet":"Mainnet",signatureChainId:xe,maxFeeRate:r.disclosure.percent,builder:r.disclosure.address,nonce:n};return K({provider:"hl-perps",venue:"hyperliquid",kind:"builder-fee-approval",builderFee:r.disclosure,...W(o,n,t)},e,t)}function Nn(e={},t={}){let r=String(e.agentAddress||e.agent||"").trim();if(!/^0x[0-9a-fA-F]{40}$/.test(r))throw new Error("hl-perps: agentAddress required");let n=Number(e.nonce??t.nonce??Date.now());if(!Number.isSafeInteger(n)||n<=0)throw new Error("hl-perps: nonce must be a positive integer");let o=String(e.agentName||"Oracle").slice(0,16),i={type:"approveAgent",hyperliquidChain:t.testnet||process.env.HL_TESTNET==="1"?"Testnet":"Mainnet",signatureChainId:xe,agentAddress:r.toLowerCase(),agentName:o,nonce:n};return C({provider:"hl-perps",venue:"hyperliquid",kind:"hl-approve-agent",unsigned:!0,broadcast:!1,agentAddress:r.toLowerCase(),agentName:o,...W(i,n,t)},{provider:"hl-perps",kind:"hl-approve-agent",env:t.env})}async function Ot(e={},t={}){let r=await J(e,t);if(e.type!=null&&(typeof e.type!="string"||!e.type))throw new Error("hl-perps: order type must be a string");let n=e.type??A.LIMIT;if(typeof n!="string"||!n)throw new Error("hl-perps: order type must be a string");let o=Tt(e);if(e.reduceOnly!=null&&typeof e.reduceOnly!="boolean")throw new Error("hl-perps: reduceOnly must be boolean");let i=e.reduceOnly===!0,s=Lt(e.size??e.sz,r.szDecimals),a;if(n===A.MARKET){let y=Number(r.markPx);if(!Number.isFinite(y)){let S=await at(t);y=Number(S?.[r.coin]??S?.[String(r.assetId)]??NaN)}if(!Number.isFinite(y))throw new Error("hl-perps: no mark price available for a market order");let x=Number(e.maxSlippageBps??50);if(!Number.isInteger(x)||x<0)throw new Error("hl-perps: maxSlippageBps must be a non-negative integer");if(x>100)throw new Error(`hl-perps: maxSlippageBps ${x} exceeds the hard 100 bps cap`);let m=o?y*(1+x/1e4):y*(1-x/1e4);a=R(m,r.szDecimals,{roundDown:o});let k=Math.abs(Number(a)/y-1)*1e4;if(k>x+1e-9)throw new Error(`hl-perps: tick rounding makes the limit ${k.toFixed(2)} bps from mark, above the ${x} bps cap`)}else{if(e.price==null&&e.limitPx==null)throw new Error("hl-perps: a limit order requires an explicit price");a=R(e.price??e.limitPx,r.szDecimals)}let l=ze(n,{tif:e.tif??(n===A.MARKET?se.IOC:se.GTC),triggerPx:e.triggerPx,szDecimals:r.szDecimals}),c={a:r.assetId,b:o,p:a,s,r:i,t:l};if(e.clientOrderId!=null){if(typeof e.clientOrderId!="string"||!e.clientOrderId)throw new Error("hl-perps: clientOrderId must be a string");c.c=e.clientOrderId}if(e.grouping!=null&&(typeof e.grouping!="string"||!e.grouping))throw new Error("hl-perps: grouping must be a string");let u={type:"order",orders:[c],grouping:e.grouping??"na"},d=qe({env:t.env,kind:r.kind}),p=await Sn(d,e,t),h=p.exempt?null:d,f=await En(h,e,t),b=f.approved?h:null;b&&(u.builder=b.wire);let w=Number(e.nonce??Date.now()),E=kn(s,a);return K({provider:"hl-perps",venue:"hyperliquid",kind:r.kind==="outcome"?"hip4-order":r.kind==="hip3"?"hip3-order":"perp-order",coin:r.coin,assetId:r.assetId,assetKind:r.kind,outcome:r.outcome??null,outcomeSide:r.side??null,dex:r.dex??null,side:o?"buy":"sell",orderType:n,price:a,size:s,reduceOnly:i,notionalUsd:E,maxLeverage:r.maxLeverage,markPx:r.markPx,builderFee:b?.disclosure??null,holderExempt:p.exempt,holderVerificationStatus:p.status,builderApprovalRequired:h&&!b?{...d.disclosure,...f}:null,...W(u,w,t)},e,t)}async function Pn(e={},t={}){let r=await J(xn(e),t),n=e.orderId??e.oid;if(n==null)throw new Error("hl-perps: orderId required");let o=_t(n,"orderId"),i={type:"cancel",cancels:[{a:r.assetId,o}]};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-cancel",coin:r.coin,assetId:r.assetId,orderId:o,...W(i,Number(e.nonce??Date.now()),t)},e,t)}async function vn(e={},t={}){let r=await J(e,t),n=yn(e.leverage,"leverage");if(r.maxLeverage!=null&&n>r.maxLeverage)throw new Error(`hl-perps: ${r.coin} allows at most ${r.maxLeverage}x, requested ${n}x`);if(e.marginMode!=null&&typeof e.marginMode!="string")throw new Error("hl-perps: marginMode must be a string");let o=(e.marginMode||ie.CROSS).toLowerCase();if(o!==ie.CROSS&&o!==ie.ISOLATED)throw new Error('hl-perps: marginMode must be "cross" or "isolated"');let i={type:"updateLeverage",asset:r.assetId,isCross:o===ie.CROSS,leverage:n};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-leverage",coin:r.coin,assetId:r.assetId,leverage:n,marginMode:o,maxLeverage:r.maxLeverage,liquidationWarning:n>=20?`${n}x liquidates on roughly a ${(100/n).toFixed(2)}% adverse move before fees`:null,...W(i,Number(e.nonce??Date.now()),t)},e,t)}async function $n(e={},t={}){let r=await J(e,t),n=e.usd??e.amountUsd;if(n==null)throw new Error("hl-perps: usd amount required");if(typeof n!="number"&&typeof n!="string")throw new Error("hl-perps: usd must be a decimal number");let o=typeof n=="number"?String(n):n;if(!/^-?\d+(\.\d+)?$/.test(o))throw new Error("hl-perps: usd must be a decimal number");let i=N(o,6,"hl-perps: usd"),s=Tt(e,{defaultBuy:!0}),a={type:"updateIsolatedMargin",asset:r.assetId,isBuy:s,ntli:i<=BigInt(Number.MAX_SAFE_INTEGER)?Number(i):i.toString()};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-isolated-margin",coin:r.coin,assetId:r.assetId,isBuy:s,usd:o,...W(a,Number(e.nonce??Date.now()),t)},e,t)}async function _n(e={},t={}){let r=await Ot(e,t),n=await J(e,t),o=r.side==="buy",i=[r.action.orders[0]];if(e.takeProfitPx!=null&&i.push({a:n.assetId,b:!o,p:R(e.takeProfitPx,n.szDecimals),s:r.size,r:!0,t:ze(A.TAKE_PROFIT_MARKET,{triggerPx:e.takeProfitPx,szDecimals:n.szDecimals})}),e.stopLossPx!=null&&i.push({a:n.assetId,b:!o,p:R(e.stopLossPx,n.szDecimals),s:r.size,r:!0,t:ze(A.STOP_MARKET,{triggerPx:e.stopLossPx,szDecimals:n.szDecimals})}),i.length===1)throw new Error("hl-perps: a bracket needs takeProfitPx and/or stopLossPx");let s={type:"order",orders:i,grouping:"normalTpsl",...r.action.builder?{builder:r.action.builder}:{}};return K({provider:"hl-perps",venue:"hyperliquid",kind:"perp-bracket",coin:n.coin,assetId:n.assetId,side:r.side,price:r.price,size:r.size,reduceOnly:r.reduceOnly,orderType:r.orderType,notionalUsd:r.notionalUsd,legs:i.length,entry:{side:r.side,price:r.price,size:r.size},takeProfitPx:e.takeProfitPx==null?null:R(e.takeProfitPx,n.szDecimals),stopLossPx:e.stopLossPx==null?null:R(e.stopLossPx,n.szDecimals),builderFee:r.builderFee,...W(s,Number(e.nonce??Date.now()),t)},e,t)}var vt,$t,xe,bn,Be,ye,Ue,oe,A,se,ie,Rt=_(()=>{pe();Le();be();he();It();Fe();Pt();vt=5,$t=6,xe="0x66eee",bn=2,Be=10,ye="ORACLE_HL_BUILDER_ADDRESS",Ue="ORACLE_HL_BUILDER_FEE_BPS",oe=Object.freeze({perp:2,spot:1,hip3:1,hip4:1}),A=Object.freeze({LIMIT:"limit",MARKET:"market",STOP_MARKET:"stopMarket",STOP_LIMIT:"stopLimit",TAKE_PROFIT_MARKET:"takeProfitMarket",TAKE_PROFIT_LIMIT:"takeProfitLimit"}),se=Object.freeze({GTC:"Gtc",IOC:"Ioc",ALO:"Alo"}),ie=Object.freeze({CROSS:"cross",ISOLATED:"isolated"})});de();var Nr="https://yields.llama.fi";async function ot(e={},t={}){let r=(t.yieldsBaseUrl||process.env.DEFILLAMA_YIELDS_URL||Nr).replace(/\/$/,""),n=await H(`${r}/pools`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??3e4}),o=Array.isArray(n?.data)?n.data:[];e.chain&&(o=o.filter(s=>String(s.chain).toLowerCase()===String(e.chain).toLowerCase())),e.project&&(o=o.filter(s=>String(s.project).toLowerCase()===String(e.project).toLowerCase())),e.stablecoin!=null&&(o=o.filter(s=>!!s.stablecoin==!!e.stablecoin)),o.sort((s,a)=>Number(a.tvlUsd||0)-Number(s.tvlUsd||0));let i=Math.min(5e3,Math.max(1,Number(e.limit||o.length||1)));return{...n,data:o.slice(0,i)}}var ee=Object.freeze([{id:"stable-loop",label:"Stablecoin loop",risk:"Conservative",targetDelta:"0.00",setup:"Supply USDC, borrow a second major stable, redeposit inside the same protocol or campaign.",exposure:"Borrow APR spike, depeg, collateral-factor change, protocol cap change.",hedge:"No perp hedge by default. Cap leverage, diversify stables, and keep unwind triggers explicit.",monitor:"Borrow APR, utilization, oracle health, depeg distance, reward dilution.",exit:"Unwind if borrow APR exceeds reward-adjusted APR or any stable trades outside the defined band."},{id:"collateral-hedge",label:"Collateral plus perp hedge",risk:"Balanced",targetDelta:"~0.00",setup:"Supply a volatile asset as collateral, borrow stables, and short the collateral notional on a liquid perp venue.",exposure:"Liquidation risk, funding cost, hedge slippage, borrow APR drift.",hedge:"Short collateral notional on a liquid perp venue; rebalance when delta drifts past the band.",monitor:"Health factor, funding, mark price, borrow APR, hedge margin.",exit:"Cut when funding turns persistently negative against the position or health factor nears the floor."},{id:"lp-hedge",label:"LP incentive hedge",risk:"Aggressive",targetDelta:"range-dependent",setup:"Provide concentrated liquidity for incentives and short the estimated volatile-token delta.",exposure:"Impermanent loss, range breaks, reward dilution, exit slippage.",hedge:"Short the estimated volatile-token delta and recompute after material price or range moves.",monitor:"Position delta, range utilization, fee APR, rewards, funding, exit slippage.",exit:"Withdraw when incentives dilute, liquidity caps fill, or expected reward no longer beats IL plus opportunity cost."},{id:"quest-farming",label:"Testnet and quest farming",risk:"Conservative",targetDelta:"n/a",setup:"Complete real protocol tasks with consistent, genuine usage from wallets you actually control.",exposure:"Eligibility rules change, sybil filters, unpaid effort, opportunity cost.",hedge:"No financial hedge. Diversify across campaigns so no single ruleset dominates the outcome.",monitor:"Campaign rules, snapshot windows, task eligibility evidence, wallet hygiene.",exit:"Stop once snapshot risk rises, campaign rules change, or the probability-adjusted expected value turns negative."},{id:"liquidity-usage",label:"Liquidity and route usage",risk:"Balanced",targetDelta:"varies",setup:"Route genuine volume and provide liquidity where usage is a stated eligibility signal.",exposure:"IL, slippage, gas burn, bridge fees, lockup discount.",hedge:"Size positions so IL and fees stay inside the modelled reward, and hedge volatile legs when material.",monitor:"Volume attribution, fee drag, reward accrual, lockup terms.",exit:"Withdraw when incentives dilute or expected reward no longer beats IL plus opportunity cost."},{id:"governance-usage",label:"Governance and ecosystem usage",risk:"Conservative",targetDelta:"n/a",setup:"Participate in governance and ecosystem surfaces where real contribution is the eligibility signal.",exposure:"Vanity activity with no eligibility weight, lock-up of governance assets.",hedge:"No financial hedge. Weight effort toward actions with documented eligibility evidence.",monitor:"Proposal participation, delegation terms, lock durations, published criteria.",exit:"Stop contributing effort once criteria change or the probability-adjusted value turns negative."}]),Pr={"stable-loop":"No default perp hedge. Bound leverage and monitor depeg plus borrow APR.","collateral-hedge":"Short the collateral notional on a liquid perp venue and rebalance when delta drifts.","lp-hedge":"Short the estimated volatile-token delta and recompute after material price or range moves."},vr={"stable-loop":"Borrow APR, utilization, stable peg, reward dilution, health factor.","collateral-hedge":"Health factor, funding, mark price, borrow APR, hedge margin.","lp-hedge":"Position delta, range utilization, fee APR, rewards, funding, exit slippage."},$r={"stable-loop":["Prepare supply for the stable collateral leg.","Prepare borrow only after health factor and borrow APR pass the method limits.","Prepare redeposit or unwind steps as separate wallet-signed actions."],"collateral-hedge":["Prepare collateral supply after sizing liquidation buffer.","Prepare stable borrow if borrow APR remains inside the method limit.","Open or adjust the perp short on the selected hedge venue, then record hedge size."],"lp-hedge":["Prepare LP add only after checking pool depth, range, and expected position delta.","Short the estimated volatile-token delta on the selected hedge venue.","Prepare LP remove if the range breaks or net APR turns negative."]};function j(e){let t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?t:null}function O(e,t="unknown"){if(typeof e!="string")return t;let r=e.trim();return r===""?t:r.slice(0,96)}function _r(e){let t=O(e.symbol,"").toUpperCase(),r=O(e.exposure,"").toLowerCase(),n=j(e.apy)??0,o=j(e.tvlUsd)??0;return n<=0||o<=0?null:e.stablecoin===!0?"stable-loop":t.includes("-")||r.includes("multi")?"lp-hedge":/ETH|BTC|SOL|HYPE|BNB|AVAX|MATIC|OP|ARB/.test(t)?"collateral-hedge":null}function Tr(e,t){let r=j(e.tvlUsd)??0,n=O(e.ilRisk,"").toLowerCase(),o=O(e.predictions?.predictedClass,"").toLowerCase(),i=t==="stable-loop"?3:t==="collateral-hedge"?6:9;return r<1e6?i+=6:r<1e7&&(i+=3),(n.includes("yes")||n.includes("high"))&&(i+=3),o.includes("down")&&(i+=2),Math.min(35,Math.max(0,i))}function Mr(e){let t=_r(e);if(!t)return null;let r=j(e.apy)??0,n=j(e.apyBase)??0,o=Math.max(0,j(e.apyReward)??Math.max(0,r-n)),i=Math.max(0,j(e.tvlUsd)??0),s=Tr(e,t),a=t==="stable-loop"?4:t==="collateral-hedge"?6:0,l=t==="stable-loop"?0:t==="collateral-hedge"?4:5,c=i<5e6?1.2:.5,u=r-a-l-c-s,d=u<1?"Avoid":r>80||i<1e7?"Watchlist":u>=8?"Farmable":"Watchlist",p=O(e.project),h=O(e.symbol),f=O(e.chain);return{id:O(e.pool,`${f}:${p}:${h}`),recipe:t,label:`${p} ${h}`,chain:f,project:p,symbol:h,tvlUsd:i,rewardApr:o,nativeApr:n,estimatedBorrowApr:a,estimatedFundingApr:l,gasApr:c,riskHaircut:s,netApr:u,verdict:d,exposure:O(e.exposure,t==="stable-loop"?"stablecoin":t==="lp-hedge"?"multi-asset LP":"single-asset collateral"),hedge:Pr[t],monitor:vr[t],prepareSteps:[`Verify ${p} contracts and reward terms on ${f}.`,"Set wallet grant with chain, protocol, max value, slippage, and TTL before preparing any transaction.",...$r[t]],source:"DeFiLlama yields"}}async function it(e={},t={}){let r=Math.min(24,Math.max(3,Number(e.limit??12)||12)),n=Number(e.minTvl??2e6),o=new Date().toISOString(),i="read-only discovery and prepare-plan design; no signing or broadcast";try{let s=await ot({chain:e.chain&&e.chain!=="all"?e.chain:void 0,limit:5e3},t),a=Array.isArray(s?.data)?s.data:[],l=a.map(Mr).filter(c=>c!==null).filter(c=>c.tvlUsd>=n).filter(c=>c.rewardApr+c.nativeApr<=300).sort((c,u)=>u.netApr-c.netApr||u.tvlUsd-c.tvlUsd).slice(0,r);return{configured:!0,live:!0,source:"DeFiLlama yields",generatedAt:o,chain:e.chain??"all",considered:a.length,consideredNote:"deepest pools by TVL from the DeFiLlama yields feed",candidates:l,posture:i}}catch(s){return{configured:!1,live:!1,source:"DeFiLlama yields",generatedAt:o,chain:e.chain??"all",considered:0,consideredNote:"deepest pools by TVL from the DeFiLlama yields feed",error:String(s?.message||s),candidates:[],posture:i}}}function T(e,t,r,n){let o=typeof e=="number"?e:Number(e);return Number.isFinite(o)?Math.min(n,Math.max(r,o)):t}function st(e={}){let t=T(e.wallets,5,1,500),r=T(e.tasksWeekly,6,0,500),n=T(e.hoursWeekly,4,0,168),o=T(e.hourlyCost,25,0,1e4),i=T(e.gasPerTask,.4,0,1e4),s=T(e.bridgeMonthly,12,0,1e5),a=T(e.expectedReward,900,0,1e7),l=T(e.probability,22,0,100)/100,c=T(e.sybilHaircut,25,0,100)/100,u=T(e.lockupMonths,6,0,120),d=r*t*4.33,p=d*i,h=n*4.33*o,f=p+h+s,b=Math.max(0,1-u*.015),w=t*a*l,E=w*(1-c)*b,y=E-f,x=f>0?y/f*100:null,m=t*a>0?f/(t*a*(1-c)*(b||1))*100:null;return{inputs:{wallets:t,tasksWeekly:r,hoursWeekly:n,hourlyCost:o,gasPerTask:i,bridgeMonthly:s,expectedReward:a,probabilityPct:l*100,sybilHaircutPct:c*100,lockupMonths:u},monthlyTasks:d,monthlyGas:p,laborMonthly:h,monthlyCost:f,lockupDiscount:b,grossExpectedValue:w,adjustedExpectedValue:E,netExpectedValue:y,roiPct:x,breakevenProbabilityPct:m,verdict:y>0?"positive-ev":"negative-ev",posture:"estimate on your own inputs; not a payout promise and not financial advice"}}pe();he();function ut(e={}){let t=e.spotSizes??e.spotHeldSizes;return t&&typeof t=="object"&&!Array.isArray(t)?t:null}function me(e={},t,r){let n=String(t||""),o=ut(e);if(o){let s=re(o[n]);if(s==null)throw new Error(`${r}: held spot required for ${n}`);return s}let i=re(e.spotSize??e.spotHeldSize);if(i==null)throw new Error(`${r}: prepare requires spotSize of held spot`);return i}function we(e={},t=[],r){let n=ut(e);if(t.length>1){if(!n)throw new Error(`${r}: multi-coin live loop requires spotSizes map`);for(let o of t)if(re(n[o])==null)throw new Error(`${r}: held spot required for ${o}`);return}if(n){let o=t[0];if(o&&re(n[o])==null)throw new Error(`${r}: held spot required for ${o}`);return}if(re(e.spotSize??e.spotHeldSize)==null)throw new Error(`${r}: live loop requires spotSize of held spot`)}var _e=Number.MAX_SAFE_INTEGER,fe=String(_e);function re(e){if(typeof e=="number")return Number.isFinite(e)&&e>0&&e<=_e?e:null;if(typeof e!="string"||!/^(?:0|[1-9]\d*)(?:\.\d+)?$/.test(e))return null;let[t,r=""]=e.split(".");if(t.length>fe.length||t.length===fe.length&&t>fe||t===fe&&/[1-9]/.test(r))return null;let n=Number(e);return Number.isFinite(n)&&n>0&&n<=_e?n:null}function F(e){let t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?t:null}function Ft(e){let t=F(e);if(t==null)throw new Error("hl-delta-neutral: funding rate required");return t*24*365*100}function Tn(e,t,r=4){let n=F(e),o=F(t),i=Number.isInteger(Number(r))?Number(r):4;if(!(n>0))throw new Error("hl-delta-neutral: notionalUsd must be > 0");if(!(o>0))throw new Error("hl-delta-neutral: markPx must be > 0");let s=10**i;return String(Math.floor(n/o*s+1e-12)/s)}function Dt(e){let t=Array.isArray(e?.[0]?.universe)?e[0].universe:[],r=Array.isArray(e?.[1])?e[1]:[],n=[];for(let o=0;o<t.length;o+=1){let i=t[o]||{},s=r[o]||{},a=String(i.name||"").trim(),l=F(s.funding),c=F(s.markPx??s.oraclePx),u=F(s.openInterest)??0;!a||l==null||!(c>0)||n.push({coin:a,szDecimals:Number.isInteger(Number(i.szDecimals))?Number(i.szDecimals):4,funding:l,markPx:c,oraclePx:F(s.oraclePx),openInterest:u,fundingAprPct:Ft(l)})}return n}function Bt(e,t){if(!e?.coin)throw new Error("hl-delta-neutral: coin required");let r=F(e.funding);if(r==null)throw new Error("hl-delta-neutral: funding required");let n=Ft(r),o=r>0,i={coin:e.coin,notionalUsd:F(t),markPx:e.markPx,fundingHourly:r,fundingAprPct:n,targetDelta:0,spot:o?"hold-existing":"short-spot-not-in-light-path",perpSide:o?"sell":"buy",perpSize:o?Tn(t,e.markPx,e.szDecimals):"0",verdict:o?n>=5?"carry":"watch":"skip",posture:"light hold-spot / short-perp carry. A farm tick may prepare the perp hedge unsigned. Hosted stays prepare-only."};if(!(i.notionalUsd>0))throw new Error("hl-delta-neutral: notionalUsd must be > 0");return i}async function je(e={},t={}){let r=Math.min(24,Math.max(1,Number(e.limit??8)||8)),n=Number(e.minOpenInterest??0),o=await te(t),i=Dt(o).filter(s=>s.funding>0&&s.openInterest>=n).sort((s,a)=>a.funding-s.funding||a.openInterest-s.openInterest).slice(0,r);return{live:!0,source:"Hyperliquid metaAndAssetCtxs",considered:Array.isArray(o?.[0]?.universe)?o[0].universe.length:0,candidates:i,posture:"read-only funding scan. Positive funding only. No signing."}}async function Ge(e={},t={}){let r=String(e.coin||"").trim();if(!r)throw new Error("hl-delta-neutral: coin required");let n=Number(e.notionalUsd??e.notional??1e3),o=await te(t),i=Dt(o).find(s=>s.coin===r);if(!i)throw new Error(`hl-delta-neutral: ${r} not in Hyperliquid meta`);return Bt(i,n)}async function Mn(e={},t={}){zt(e,t,"hl-delta-neutral");let r=qt(e.maxNotionalUsd??25e3,"hl-delta-neutral"),n=await Ge(e,t);if(n.verdict==="skip")return C({...n,prepared:!1,oraclePrepared:!1,surface:"hl",reason:"negative funding is outside the light hold-spot path"},{provider:"hl-delta-neutral",kind:"hl-carry-hedge"});let o=me(e,n.coin,"hl-delta-neutral");if(!Ut.test(String(e.owner||"")))throw new Error("hl-delta-neutral: prepare requires owner");if(Number(n.perpSize)-o>1e-12)throw new Error("hl-delta-neutral: hedge cannot exceed held spot");let{hlPreparePerpOrder:i}=await Promise.resolve().then(()=>(Rt(),Ct)),s=await i({coin:n.coin,side:n.perpSide,size:n.perpSize,type:e.orderType||"limit",price:e.price??n.markPx,owner:e.owner,maxNotionalUsd:r},{fetchImpl:t.fetchImpl,nowMs:t.nowMs});if(s?.signed===!0||s?.broadcast===!0)throw new Error("hl-delta-neutral: prepare cannot sign or broadcast");let a=s?.localSignerEnvelope||null,l=s?.localSignerBlockedReason||null;return C({...n,prepared:!!a,surface:"hl",hedge:s,localSignerEnvelope:a,localSignerBlockedReason:l,signed:!1,broadcast:!1,signing:a?"awaiting-hl-signer":"blocked",oraclePrepared:!!a},{provider:"hl-delta-neutral",kind:"hl-carry-hedge"})}var Ut=/^0x[0-9a-fA-F]{40}$/;function zt(e,t,r){if((t.hosted===!0||t.keyless===!0)&&(e.farming===!0||typeof t.signImpl=="function"))throw new Error(`${r}: hosted/keyless cannot sign`);if(e.farming===!0||typeof t.signImpl=="function"||typeof t.prepareImpl=="function")throw new Error(`${r}: farm cannot sign; use oracle signer`)}function Ln(e,t,r){zt(e,t,r)}function On(e={}){if(e.halted===!0)throw new Error("hl-delta-neutral: loop is halted");let t=e.mode==="live"?"live":"shadow",r=Array.isArray(e.coins||e.allowlist)?(e.coins||e.allowlist).map(String):[],n=e.maxCoins??1;if(typeof n!="number"&&!(typeof n=="string"&&/^(?:0|[1-9]\d*)$/.test(n)))throw new Error("hl-delta-neutral: maxCoins must be an integer");let o=Number(n);if(!Number.isSafeInteger(o))throw new Error("hl-delta-neutral: maxCoins must be an integer");if(o<1||o>8)throw new Error("hl-delta-neutral: maxCoins must be between 1 and 8");let i=qt(e.maxNotionalUsd??e.notionalUsd??e.notional??1e3,"hl-delta-neutral");if(t==="live"&&r.length===0)throw new Error("hl-delta-neutral: live loop requires a coin allowlist");if(t==="live"&&we(e,r,"hl-delta-neutral"),t==="live"&&!Ut.test(String(e.owner||"")))throw new Error("hl-delta-neutral: live loop requires owner");return{mode:t,allowlist:r,maxCoins:o,maxNotionalUsd:i,intervalMs:Math.max(3e4,Number(e.intervalMs??3e5)||3e5)}}function qt(e,t){let r=typeof e=="string"&&e===e.trim()&&/^(?:0\.\d+|[1-9]\d*(?:\.\d+)?)$/.test(e);if(typeof e!="number"&&!r)throw new Error(`${t}: maxNotionalUsd out of bounds`);let n=Number(e);if(!(n>0)||n>25e3)throw new Error(`${t}: maxNotionalUsd out of bounds`);return n}async function Ht(e={},t={}){Ln(e,t,"hl-delta-neutral");let r=On(e),n=await je({limit:e.limit??16,minOpenInterest:e.minOpenInterest},t),o=new Set(r.allowlist),i=[],s=Math.floor(r.maxNotionalUsd/r.maxCoins);for(let a of n.candidates){if(o.size&&!o.has(a.coin))continue;let l=Bt(a,s);if(l.verdict!=="carry")continue;if(i.length>=r.maxCoins)break;if(r.mode==="shadow"){i.push({...l,mode:"shadow",surface:"hl",prepared:!1,signed:!1,broadcast:!1});continue}let c=await Mn({coin:l.coin,notionalUsd:l.notionalUsd,owner:e.owner,orderType:e.orderType,price:e.price,maxNotionalUsd:s,spotSize:e.spotSize??e.spotHeldSize,spotSizes:e.spotSizes??e.spotHeldSizes},{fetchImpl:t.fetchImpl,nowMs:t.nowMs});i.push({...c,mode:"live",surface:"hl"})}return{loop:!0,mode:r.mode,surface:"hl",signer:"hl",considered:n.considered,actions:i,nextWaitMs:r.intervalMs,signed:i.some(a=>a.signed===!0),broadcast:i.some(a=>a.broadcast===!0),posture:"one tick. Prepares an unsigned hedge for oracle signer. Armed, not automated. Farm loop never signs or broadcasts."}}de();he();be();var Cn=new Set(["https://mainnet.zklighter.elliot.ai/api/v1/sendTx","https://testnet.zklighter.elliot.ai/api/v1/sendTx"]),ae=14,jt=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`lighter: bounded ${t} required`);return e};function X(e,t,r){if(!Number.isSafeInteger(e)||e!==t)throw new Error(`lighter: ${r} must be exact numeric ${t}`)}function Ve(e){let t=String(e||"").replace(/\/$/,"");if(!Cn.has(t))throw new Error("lighter: submitTo must be the official Lighter sendTx");return t}function Gt(e,t={}){if(e?.surface!=="lighter")throw new Error("lighter: surface lighter required");let r=e.artifact;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("lighter: structured artifact required");let n=jt(r.kind,"kind",48);if(n!=="lighter-order")throw new Error("lighter: unsupported Lighter kind");if(e.action!=="order")throw new Error("lighter: surface/action/kind mismatch");if(String(e.destination).toLowerCase()!=="lighter")throw new Error("lighter: destination must be lighter");let o=Ve(r.submitTo),i=r.marketIndex;if(typeof i!="number"||!Number.isSafeInteger(i)||i<0)throw new Error("lighter: marketIndex required");let s=Number(V(r.accountIndex,"lighter: accountIndex"));if(!Number.isSafeInteger(s)||s<0)throw new Error("lighter: accountIndex required");let a=Number(V(r.clientOrderIndex,"lighter: clientOrderIndex"));if(!Number.isSafeInteger(a)||a<0)throw new Error("lighter: clientOrderIndex required");X(r.orderType,0,"orderType"),X(r.timeInForce,1,"timeInForce"),X(r.reduceOnly,0,"reduceOnly"),X(r.triggerPrice,0,"triggerPrice"),X(r.orderExpiry,-1,"orderExpiry");let l=jt(r.symbol||r.coin,"symbol",32),c=Array.isArray(t.lighterMarkets)?t.lighterMarkets.map(String):[];if(c.length&&!c.includes(l)&&!c.includes(String(i))&&!c.includes("*"))throw new Error("lighter: market not allowed");if(r.side!=="buy"&&r.side!=="sell")throw new Error("lighter: side must be buy or sell");let u=Oe(r.baseAmount,"lighter: baseAmount"),d=Oe(r.price,"lighter: price");if(u>BigInt(Number.MAX_SAFE_INTEGER)||d>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("lighter: baseAmount and price must be safe integers");let p=Number(u),h=Number(d),f=Number(r.sizeDecimals??0),b=Number(r.priceDecimals??0);if(!Number.isInteger(f)||f<0||f>12)throw new Error("lighter: sizeDecimals required");if(!Number.isInteger(b)||b<0||b>12)throw new Error("lighter: priceDecimals required");let w=f+b,E=u*d,y=N(r.notionalUsd,w,"lighter: notionalUsd");if(y<=0n)throw new Error("lighter: notionalUsd required");if(E!==y)throw new Error("lighter: notionalUsd must match size and price");let x=N(t.maxNotionalUsd??Number.MAX_SAFE_INTEGER,w,"lighter: maxNotionalUsd");if(E>x)throw new Error("lighter: notional exceeds cap");let m=I(r.notionalUsd,"lighter: notionalUsd");return X(r.txType,ae,"txType"),Object.freeze({unit:"usd",value:String(m),notional:String(m),fee:"0",kind:n,symbol:l,marketIndex:i,side:r.side,baseAmount:p,price:h,submitTo:o,actionType:"create-order",amount:String(m)})}function Rn(e){let t=e.owner||e.user||e.from;if(!/^0x[0-9a-fA-F]{40}$/.test(String(t||"")))throw new Error("lighter: owner address required for local-signer envelope");return String(t).toLowerCase()}function Vt(e,t={},r={}){if(String(e?.kind)!=="lighter-order")throw new Error("lighter: prepared kind is not a local-signer surface");let n=Number(r.nowMs??Date.now()),o=Math.min(6e4,Math.max(1e3,Number(t.ttlMs??t.expiresInMs??3e4)||3e4)),i=Ve(e.submitTo),s={version:1,surface:"lighter",action:"order",owner:Rn(t),destination:"lighter",tradeId:String(t.tradeId||`lighter:${e.symbol}:${e.marketIndex}:${e.clientOrderIndex}`),expiresAtMs:n+o,slippageBps:Number(t.slippageBps??0),fee:{oracleFeeBps:0},provider:"lighter-delta-neutral",artifact:{kind:"lighter-order",symbol:e.symbol,marketIndex:e.marketIndex,side:e.side,baseAmount:e.baseAmount,price:e.price,notionalUsd:e.notionalUsd,sizeDecimals:e.sizeDecimals??0,priceDecimals:e.priceDecimals??0,clientOrderIndex:e.clientOrderIndex,txType:e.txType??ae,submitTo:i,accountIndex:e.accountIndex??t.accountIndex??null,orderType:e.orderType,timeInForce:e.timeInForce,reduceOnly:e.reduceOnly,triggerPrice:e.triggerPrice,orderExpiry:e.orderExpiry}};return Gt(s,{lighterMarkets:t.lighterMarkets||["*"],maxNotionalUsd:t.maxNotionalUsd??Number.MAX_SAFE_INTEGER}),s}var Jt="https://mainnet.zklighter.elliot.ai",Kt="https://testnet.zklighter.elliot.ai";function Fn(e={}){return e.testnet||process.env.LIGHTER_TESTNET==="1"?Kt:Jt}function z(e){let t=typeof e=="number"?e:Number(e);return Number.isFinite(t)?t:null}function Dn(e,t){let r=e.toString().padStart(t+1,"0");if(t===0)return r;let n=r.slice(0,-t),o=r.slice(-t).replace(/0+$/,"");return o?`${n}.${o}`:n}function Xt(e){let t=z(e);if(t==null)throw new Error("lighter: funding rate required");return t*24*365*100}function Bn(e,t,r=4){let n=z(e),o=z(t),i=Number.isInteger(Number(r))?Number(r):4;if(!(n>0))throw new Error("lighter: notionalUsd must be > 0");if(!(o>0))throw new Error("lighter: markPx must be > 0");let s=10**i;return Math.floor(n/o*s+1e-12)}function Wt(e){return typeof e=="number"&&Number.isSafeInteger(e)&&e>=0?e:null}function Yt(e,t){let r=Array.isArray(e?.funding_rates)?e.funding_rates:[],n=Array.isArray(t?.order_book_details)?t.order_book_details:[],o=new Map;for(let s of n){let a=Wt(s.market_id);a!=null&&o.set(a,s)}let i=[];for(let s of r){if(String(s.exchange||"")!=="lighter")continue;let a=Wt(s.market_id);if(a==null)continue;let l=o.get(a),c=z(l?.mark_price??l?.index_price),u=z(s.rate),d=String(s.symbol||l?.symbol||"").trim();!d||u==null||!(c>0)||i.push({coin:d,symbol:d,marketIndex:a,funding:u,markPx:c,openInterest:z(l?.open_interest)??0,sizeDecimals:Number(l?.supported_size_decimals??l?.size_decimals??4),priceDecimals:Number(l?.supported_price_decimals??l?.price_decimals??2),fundingAprPct:Xt(u)})}return i}function Qt(e,t){if(!e?.symbol&&!e?.coin)throw new Error("lighter: symbol required");let r=z(e.funding);if(r==null)throw new Error("lighter: funding required");let n=Xt(r),o=r>0,i={coin:e.symbol||e.coin,symbol:e.symbol||e.coin,marketIndex:e.marketIndex,notionalUsd:z(t),markPx:e.markPx,fundingHourly:r,fundingAprPct:n,targetDelta:0,spot:o?"hold-existing":"short-spot-not-in-light-path",perpSide:o?"sell":"buy",baseAmount:o?Bn(t,e.markPx,e.sizeDecimals):0,price:Math.round(Number(e.markPx)*10**Number(e.priceDecimals||0)),sizeDecimals:e.sizeDecimals,priceDecimals:e.priceDecimals,verdict:o?n>=5?"carry":"watch":"skip",posture:"light hold-spot / short-perp carry on Lighter. Armed via official sendTx. Not automated."};if(!(i.notionalUsd>0))throw new Error("lighter: notionalUsd must be > 0");return i}async function Zt(e={}){let t=Fn(e),r=e.fetchImpl,n=await H(`${t}/api/v1/funding-rates`,{fetchImpl:r,retries:0}),o=await H(`${t}/api/v1/orderBookDetails`,{fetchImpl:r,retries:0});return{funding:n,books:o}}async function We(e={},t={}){let r=Math.min(24,Math.max(1,Number(e.limit??8)||8)),{funding:n,books:o}=await Zt(t),i=Yt(n,o).filter(s=>s.funding>0).sort((s,a)=>a.funding-s.funding||a.openInterest-s.openInterest).slice(0,r);return{live:!0,source:"Lighter funding-rates + orderBookDetails",considered:Array.isArray(n?.funding_rates)?n.funding_rates.filter(s=>s.exchange==="lighter").length:0,candidates:i,posture:"read-only Lighter funding scan. Positive funding only. No signing."}}async function Je(e={},t={}){let r=String(e.coin||e.symbol||"").trim();if(!r)throw new Error("lighter: coin required");let n=Number(e.notionalUsd??e.notional??1e3),{funding:o,books:i}=await Zt(t),s=Yt(o,i).find(a=>a.symbol===r);if(!s)throw new Error(`lighter: ${r} not in Lighter funding`);return Qt(s,n)}async function Un(e={},t={}){tr(e,t,"lighter");let r=rr(e.maxNotionalUsd??25e3,"lighter");if(typeof e.accountIndex!="number"||!Number.isSafeInteger(e.accountIndex)||e.accountIndex<0)throw new Error("lighter: accountIndex required");let n=e.accountIndex,o=await Je(e,t);if(o.verdict==="skip")return C({...o,prepared:!1,oraclePrepared:!1,surface:"lighter",reason:"negative funding is outside the light hold-spot path"},{provider:"lighter-delta-neutral",kind:"lighter-order"});let i=me(e,o.coin,"lighter");if(!er.test(String(e.owner||"")))throw new Error("lighter: prepare requires owner");if(o.baseAmount/10**Number(o.sizeDecimals||0)-i>1e-12)throw new Error("lighter: hedge cannot exceed held spot");let a=!!(t.testnet||process.env.LIGHTER_TESTNET==="1"),l=Number(o.sizeDecimals||0)+Number(o.priceDecimals||0),c=Dn(BigInt(o.baseAmount)*BigInt(o.price),l);if(e.clientOrderIndex!=null&&(typeof e.clientOrderIndex!="number"||!Number.isSafeInteger(e.clientOrderIndex)||e.clientOrderIndex<0))throw new Error("lighter: clientOrderIndex must be a safe integer");let u={...o,targetNotionalUsd:o.notionalUsd,notionalUsd:c,kind:"lighter-order",surface:"lighter",side:o.perpSide,clientOrderIndex:e.clientOrderIndex??Date.now()%1e9,accountIndex:n,orderType:0,timeInForce:1,reduceOnly:0,triggerPrice:0,orderExpiry:-1,txType:ae,submitTo:`${a?Kt:Jt}/api/v1/sendTx`,signed:!1,broadcast:!1},d=null,p=null;try{d=Vt(u,{...e,maxNotionalUsd:r},t)}catch(f){p=String(f?.message||f).slice(0,200)}return C({...u,prepared:!!d,signing:d?"awaiting-lighter-signer":"blocked",localSignerEnvelope:d,localSignerBlockedReason:p,oraclePrepared:!!d},{provider:"lighter-delta-neutral",kind:"lighter-order"})}var er=/^0x[0-9a-fA-F]{40}$/;function tr(e,t,r){if((t.hosted===!0||t.keyless===!0)&&(e.farming===!0||typeof t.signImpl=="function"))throw new Error(`${r}: hosted/keyless cannot sign`);if(e.farming===!0||typeof t.signImpl=="function"||typeof t.prepareImpl=="function")throw new Error(`${r}: farm cannot sign; use oracle signer`)}function zn(e,t,r){tr(e,t,r)}function qn(e={}){if(e.halted===!0)throw new Error("lighter: loop is halted");let t=e.mode==="live"?"live":"shadow",r=Array.isArray(e.coins||e.allowlist)?(e.coins||e.allowlist).map(String):[],n=e.maxCoins??1;if(typeof n!="number"&&!(typeof n=="string"&&/^(?:0|[1-9]\d*)$/.test(n)))throw new Error("lighter: maxCoins must be an integer");let o=Number(n);if(!Number.isSafeInteger(o))throw new Error("lighter: maxCoins must be an integer");if(o<1||o>8)throw new Error("lighter: maxCoins must be between 1 and 8");let i=rr(e.maxNotionalUsd??e.notionalUsd??e.notional??1e3,"lighter");if(t==="live"&&r.length===0)throw new Error("lighter: live loop requires a coin allowlist");if(t==="live"&&we(e,r,"lighter"),t==="live"&&!er.test(String(e.owner||"")))throw new Error("lighter: live loop requires owner");let s=e.accountIndex;if(t==="live"&&(typeof s!="number"||!Number.isSafeInteger(s)||s<0))throw new Error("lighter: live loop requires accountIndex");return{mode:t,allowlist:r,maxCoins:o,maxNotionalUsd:i,accountIndex:s}}function rr(e,t){let r=typeof e=="string"&&e===e.trim()&&/^(?:0\.\d+|[1-9]\d*(?:\.\d+)?)$/.test(e);if(typeof e!="number"&&!r)throw new Error(`${t}: maxNotionalUsd out of bounds`);let n=Number(e);if(!(n>0)||n>25e3)throw new Error(`${t}: maxNotionalUsd out of bounds`);return n}async function nr(e={},t={}){zn(e,t,"lighter");let r=qn(e),n=await We({limit:e.limit??16},t),o=new Set(r.allowlist),i=[],s=Math.floor(r.maxNotionalUsd/r.maxCoins);for(let a of n.candidates){if(o.size&&!o.has(a.symbol)&&!o.has(a.coin))continue;let l=Qt(a,s);if(l.verdict!=="carry")continue;if(i.length>=r.maxCoins)break;if(r.mode==="shadow"){i.push({...l,mode:"shadow",surface:"lighter",prepared:!1,signed:!1,broadcast:!1});continue}let c=await Un({coin:l.symbol,notionalUsd:l.notionalUsd,maxNotionalUsd:s,owner:e.owner,accountIndex:r.accountIndex,spotSize:e.spotSize??e.spotHeldSize,spotSizes:e.spotSizes??e.spotHeldSizes},{fetchImpl:t.fetchImpl,nowMs:t.nowMs,testnet:t.testnet});i.push({...c,mode:"live",surface:"lighter"})}return{loop:!0,mode:r.mode,surface:"lighter",signer:"lighter",considered:n.considered,actions:i,signed:i.some(a=>a.signed===!0),broadcast:i.some(a=>a.broadcast===!0),posture:"one tick. Prepares an unsigned official sendTx for oracle signer. Armed, not automated. Farm loop never signs or broadcasts."}}var Ke=`oracle farm <methods|discover|airdrop|carry|loop|lighter> [options]
|
|
3
3
|
|
|
4
4
|
oracle farm methods list the delta-aware farming playbooks
|
|
5
5
|
oracle farm methods --id stable-loop full setup/exposure/hedge/monitor/exit for one method
|
|
@@ -13,7 +13,7 @@ var sr=Object.defineProperty;var _=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(
|
|
|
13
13
|
oracle farm loop [--venue hl|lighter] [--mode shadow|live] [--coin BTC] [--notional 1000] [--spot-size 0.01] [--owner 0x...] [--json]
|
|
14
14
|
oracle farm lighter [--coin BTC] [--notional 1000] [--json]
|
|
15
15
|
|
|
16
|
-
Owner-operated. Carry/loop only prepare unsigned hedges. Signing is oracle signer after exact confirm. Farm loop never signs or broadcasts.`;function
|
|
16
|
+
Owner-operated. Carry/loop only prepare unsigned hedges. Signing is oracle signer after exact confirm. Farm loop never signs or broadcasts.`;function Hn(e){let t={_:[]};for(let r=0;r<e.length;r+=1){let n=e[r];if(n==="--json"){t.json=!0;continue}if(n.startsWith("--")){let o=n.slice(2),i=e[r+1];if(i===void 0||i.startsWith("--")){t[o]=!0;continue}t[o]=i,r+=1;continue}t._.push(n)}return t}var D=e=>`$${Math.round(Number(e)||0).toLocaleString("en-US")}`,ce=e=>`${(Number(e)||0).toFixed(1)}%`;function jn(e){let t=typeof e.id=="string"?e.id:null;if(t){let r=ee.find(n=>n.id===t);if(!r)return process.stderr.write(`oracle farm: unknown method '${t}'. Known: ${ee.map(n=>n.id).join(", ")}
|
|
17
17
|
`),1;if(e.json)return process.stdout.write(JSON.stringify(r,null,2)+`
|
|
18
18
|
`),0;process.stdout.write(`
|
|
19
19
|
${r.label} [${r.risk}] target delta ${r.targetDelta}
|
|
@@ -28,28 +28,28 @@ Owner-operated. Carry/loop only prepare unsigned hedges. Signing is oracle signe
|
|
|
28
28
|
`);return process.stdout.write(`
|
|
29
29
|
oracle farm methods --id <id> for setup, exposure, hedge, monitor, and exit rules.
|
|
30
30
|
|
|
31
|
-
`),0}async function
|
|
31
|
+
`),0}async function Gn(e){let t=await it({chain:typeof e.chain=="string"?e.chain:null,limit:e.limit,minTvl:e["min-tvl"]});if(e.json)return process.stdout.write(JSON.stringify(t,null,2)+`
|
|
32
32
|
`),0;if(!t.live)return process.stderr.write(`oracle farm: discovery unavailable \u2014 ${t.error}
|
|
33
33
|
`),1;process.stdout.write(`
|
|
34
34
|
live farm discovery \u2014 ${t.source}, ${t.considered.toLocaleString("en-US")} pools considered (${t.consideredNote}), chain=${t.chain}
|
|
35
35
|
|
|
36
36
|
`),process.stdout.write(` ${"verdict".padEnd(10)}${"net apr".padStart(9)} ${"tvl".padStart(12)} ${"chain".padEnd(12)}${"recipe".padEnd(18)}pool
|
|
37
|
-
`);for(let r of t.candidates)process.stdout.write(` ${r.verdict.padEnd(10)}${ce(r.netApr).padStart(9)} ${
|
|
37
|
+
`);for(let r of t.candidates)process.stdout.write(` ${r.verdict.padEnd(10)}${ce(r.netApr).padStart(9)} ${D(r.tvlUsd).padStart(12)} ${r.chain.slice(0,11).padEnd(12)}${r.recipe.padEnd(18)}${r.label}
|
|
38
38
|
`);return process.stdout.write(`
|
|
39
39
|
net apr = apy \u2212 borrow \u2212 funding \u2212 gas \u2212 risk haircut.
|
|
40
40
|
${t.posture}.
|
|
41
41
|
|
|
42
|
-
`),0}function
|
|
42
|
+
`),0}function Vn(e){let t=st({wallets:e.wallets,tasksWeekly:e["tasks-weekly"],hoursWeekly:e["hours-weekly"],hourlyCost:e["hourly-cost"],gasPerTask:e["gas-per-task"],bridgeMonthly:e["bridge-monthly"],expectedReward:e["expected-reward"],probability:e.probability,sybilHaircut:e["sybil-haircut"],lockupMonths:e["lockup-months"]});if(e.json)return process.stdout.write(JSON.stringify(t,null,2)+`
|
|
43
43
|
`),0;let r=t.inputs;return process.stdout.write(`
|
|
44
44
|
airdrop expected value
|
|
45
45
|
|
|
46
|
-
`),process.stdout.write(` ${r.wallets} wallets \xB7 ${r.tasksWeekly} tasks/wk \xB7 ${r.hoursWeekly} hrs/wk @ ${
|
|
46
|
+
`),process.stdout.write(` ${r.wallets} wallets \xB7 ${r.tasksWeekly} tasks/wk \xB7 ${r.hoursWeekly} hrs/wk @ ${D(r.hourlyCost)}/hr
|
|
47
47
|
`),process.stdout.write(` ${ce(r.probabilityPct)} eligibility \xB7 ${ce(r.sybilHaircutPct)} sybil haircut \xB7 ${r.lockupMonths}mo lockup
|
|
48
48
|
|
|
49
|
-
`),process.stdout.write(` monthly cost ${
|
|
50
|
-
`),process.stdout.write(` gross EV ${
|
|
51
|
-
`),process.stdout.write(` after haircuts ${
|
|
52
|
-
`),process.stdout.write(` net EV ${
|
|
49
|
+
`),process.stdout.write(` monthly cost ${D(t.monthlyCost).padStart(12)} (gas ${D(t.monthlyGas)} + labor ${D(t.laborMonthly)} + bridges ${D(r.bridgeMonthly)})
|
|
50
|
+
`),process.stdout.write(` gross EV ${D(t.grossExpectedValue).padStart(12)}
|
|
51
|
+
`),process.stdout.write(` after haircuts ${D(t.adjustedExpectedValue).padStart(12)} (lockup discount ${(t.lockupDiscount*100).toFixed(0)}%)
|
|
52
|
+
`),process.stdout.write(` net EV ${D(t.netExpectedValue).padStart(12)} ${t.verdict}
|
|
53
53
|
`),t.roiPct!=null&&process.stdout.write(` ROI ${ce(t.roiPct).padStart(12)}
|
|
54
54
|
`),t.breakevenProbabilityPct!=null&&process.stdout.write(` breakeven odds ${ce(t.breakevenProbabilityPct).padStart(12)} campaign must clear this to profit
|
|
55
55
|
`),process.stdout.write(`
|
|
@@ -58,15 +58,15 @@ Owner-operated. Carry/loop only prepare unsigned hedges. Signing is oracle signe
|
|
|
58
58
|
`),0}async function or(e,t={}){let r=t.fetchImpl?{fetchImpl:t.fetchImpl}:{},n=typeof e.coin=="string"?e.coin:null,i=(e.venue==="lighter"?"lighter":"hl")==="lighter"?n?await Je({coin:n,notionalUsd:e.notional},r):await We({limit:e.limit},r):n?await Ge({coin:n,notionalUsd:e.notional},r):await je({limit:e.limit},r);return e.json?(process.stdout.write(JSON.stringify(i,null,2)+`
|
|
59
59
|
`),0):(process.stdout.write(`
|
|
60
60
|
${JSON.stringify(i)}
|
|
61
|
-
`),0)}async function
|
|
61
|
+
`),0)}async function Wn(e,t={}){let r=t.fetchImpl?{fetchImpl:t.fetchImpl}:{},n=typeof e.coin=="string"?[e.coin]:[],o=e.venue==="lighter"?"lighter":"hl",i={mode:e.mode==="live"?"live":"shadow",coins:n,notionalUsd:e.notional,limit:e.limit,spotSize:e["spot-size"],owner:e.owner},s=o==="lighter"?await nr(i,r):await Ht(i,r);if(e.json)return process.stdout.write(JSON.stringify(s,null,2)+`
|
|
62
62
|
`),0;process.stdout.write(`
|
|
63
63
|
farm loop ${s.mode} via ${s.signer}, ${s.actions.length} action(s)
|
|
64
64
|
`);for(let a of s.actions)process.stdout.write(` ${a.coin||a.symbol} ${a.perpSide} ${a.perpSize||a.baseAmount} ${a.verdict} ${a.mode}
|
|
65
65
|
`);return process.stdout.write(`
|
|
66
66
|
${s.posture}
|
|
67
67
|
|
|
68
|
-
`),0}var
|
|
69
|
-
`),0):r==="methods"?
|
|
68
|
+
`),0}var Zo={name:"farm",summary:"farming methods, live farm discovery, HL carry loop, airdrop EV",group:"read",usage:Ke,async run(e){let t=Hn(e.argv),r=t._[0];return!r||r==="help"?(process.stdout.write(Ke+`
|
|
69
|
+
`),0):r==="methods"?jn(t):r==="discover"?Gn(t):r==="airdrop"?Vn(t):r==="carry"?or(t,e):r==="loop"?Wn(t,e):r==="lighter"?or({...t,venue:"lighter"},e):(process.stderr.write(`oracle farm: unknown subcommand '${r}'
|
|
70
70
|
|
|
71
71
|
${Ke}
|
|
72
|
-
`),1)}};export{
|
|
72
|
+
`),1)}};export{Zo as default};
|