@oracle-agent/oracle 0.25.2 → 0.25.3
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 +33 -1
- package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
- package/dist/bin/desk-server.mjs +53 -53
- package/dist/bin/oracle-data-mcp.mjs +12 -12
- package/dist/bin/oracle-public-server.mjs +15 -15
- package/dist/bin/oracle-route.mjs +14 -14
- package/dist/cli/commands/chat.mjs +96 -96
- package/dist/cli/commands/doctor.mjs +3 -3
- package/dist/cli/commands/eval.mjs +414 -85
- package/dist/cli/commands/farm.mjs +21 -21
- package/dist/cli/commands/model.mjs +101 -101
- package/dist/cli/commands/receipt.mjs +2 -2
- package/dist/cli/commands/sign.mjs +9 -9
- package/dist/cli/commands/signer.mjs +12 -12
- package/dist/cli/commands/strategy.mjs +11 -11
- package/dist/cli/commands/swap.mjs +10 -10
- package/dist/cli/commands/venues.mjs +2 -2
- package/dist/data/desk-data.mjs +51 -51
- package/dist/data/providers/universal-evm-nft-transfer.mjs +1 -0
- package/dist/data/providers/universal-ordinals-transfer.mjs +1 -0
- package/dist/data/providers/universal-solana-nft-transfer.mjs +1 -0
- package/dist/index.mjs +55 -55
- package/dist/local-signer/index.mjs +3 -3
- package/dist/nft/index.mjs +1 -1
- package/dist/nft/universal-mint-router.mjs +47 -0
- package/dist/nft/universal-nft-lifecycle.mjs +1 -0
- package/dist/prepare-envelope.mjs +1 -1
- package/dist/router/index.mjs +9 -9
- package/dist/router/prepare-bridge.mjs +18 -18
- package/dist/strategy/index.mjs +11 -11
- package/package.json +6 -1
- package/public/oracle-splash/downloads/index.html +4 -4
- package/public/oracle-splash/index.html +1 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{createHash as _n,randomBytes as Cn,timingSafeEqual as Pn}from"node:crypto";import{base58 as Ir}from"@scure/base";import{Interface as Vr,MaxUint256 as zr,isAddress as Gr,keccak256 as Co,toUtf8Bytes as Po}from"ethers";import{Interface as Jr,isAddress as mo}from"ethers";import{isAddress as so}from"ethers";import{createHash as Mr,createHmac as $r,timingSafeEqual as Fr}from"node:crypto";import{readFileSync as Br}from"node:fs";import{homedir as _r}from"node:os";import{join as ae}from"node:path";function Cr(){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){let r=(process.env.ORACLE_EXEC_ENV_FILE||"").trim();return r?[r]:[]}let e=(process.env.ORACLE_EXEC_ENV_FILE||process.env.MAD_EXEC_ENV_FILE||"").trim(),t=_r();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||ae(t,".config","oracle")).trim();return[e,ae(r,"exec.env")].filter(Boolean)}return[e,ae(t,".config","oracle","exec.env"),ae(t,".config","mad-desk","exec.env")].filter(Boolean)}function Z(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of Cr())try{let i=Br(o,"utf8"),a=i.match(new RegExp(`^${t}=(.*)$`,"m"))||i.match(new RegExp(`^${r}=(.*)$`,"m"));if(a&&(n=a[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}function K(e,t,r="guard"){let n=Number(t);if(t==null||!Number.isFinite(n))throw new Error(`${r}: current time must be a finite number (got ${Pr(t)})`);let o=Number(e?.issuedAtMs),i=Number(e?.expiresAtMs);if(!Number.isFinite(i))throw new Error(`${r}: expiresAtMs is required and must be a finite number`);if(n>i)throw new Error(`${r} expired at ${i}, now ${n}`);if(e?.issuedAtMs!=null){if(!Number.isFinite(o))throw new Error(`${r}: issuedAtMs must be a finite number when present`);if(i<=o)throw new Error(`${r}: expiry must be after issuance`)}return{now:n,issuedAtMs:o,expiresAtMs:i}}function Pr(e){return e===null?"null":e===void 0?"undefined":typeof e=="number"?String(e):`${typeof e} ${JSON.stringify(String(e)).slice(0,24)}`}var Be=100;function he(e){return Array.isArray(e)?`[${e.map(he).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${he(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function qr(e,{required:t=!1}={}){try{return Z(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function Rr(e){let{signature:t,...r}=e;return r}function Dr(e){let t=String(e||"").toLowerCase();if(!/^0x[0-9a-f]+$/.test(t)||t.length<10||t.length%2!==0)throw new Error("auto-slippage calldata must be even-length hex with a selector");return Mr("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function Ur(e,t){let r=Buffer.from(String(e??""),"utf8"),n=Buffer.from(String(t??""),"utf8");return r.length!==n.length||r.length===0?!1:Fr(r,n)}function Wr(e){let t=String(e||"");if(!/^0x[0-9a-fA-F]+$/.test(t)||t.length<10||t.length%2!==0)return null;let r=t.slice(0,10).toLowerCase(),n=[];for(let i=10;i+64<=t.length;i+=64)n.push(t.slice(i,i+64));let o=i=>n[i]==null?null:BigInt("0x"+n[i]);switch(r){case"0x414bf389":return o(6);case"0x04e45aaf":return o(5);case"0xc04b8d59":{let i=o(0);if(i==null)return null;let a=Number(i)/32;return!Number.isInteger(a)||a<0?null:o(a+4)}case"0xb858183f":{let i=o(0);if(i==null)return null;let a=Number(i)/32;return!Number.isInteger(a)||a<0?null:o(a+3)}case"0xa026383e":return o(6);case"0x38ed1739":case"0x5c11d795":return o(1);case"0x7ff36ab5":case"0xb6f9de95":return o(0);case"0x18cbafe5":case"0x791ac947":return o(1);default:return null}}function we(e,{nowMs:t=Date.now(),chainId:r,venue:n,secret:o,tx:i,requireSigned:a=!1}={}){if(!e||e.mode!=="auto")throw new Error("bounded auto-slippage guard required");let c=qr(o,{required:a});if(a&&!c)throw new Error("auto-slippage attestation secret required for signing or broadcast");if(c){let p=$r("sha256",c).update(he(Rr(e))).digest("hex");if(!Ur(e.signature,p))throw new Error("auto-slippage guard signature mismatch \u2014 the guard was not issued by this Oracle")}else if(e.signature)throw new Error("auto-slippage guard carries a signature but no attestation secret is configured");let u=Number(e.selectedBps),s=Number(e.capBps);if(!Number.isInteger(u)||u<0||u>Be)throw new Error("auto-slippage selected tolerance exceeds hard 100 bps cap");if(!Number.isInteger(s)||s<0||s>Be||u>s)throw new Error("auto-slippage cap exceeds hard 100 bps cap");try{K({expiresAtMs:e.expiresAtMs,issuedAtMs:e.quotedAtMs},t,"auto-slippage quote")}catch(p){throw new Error(`${p.message}; re-quote before signing`)}if(r!=null&&Number(e.chainId)!==Number(r))throw new Error("auto-slippage guard chain mismatch");if(n&&String(e.venue).toLowerCase()!==String(n).toLowerCase())throw new Error("auto-slippage guard venue mismatch");let f=BigInt(e.quoteAmountOut??0),l=BigInt(e.minAmountOut??0);if(f<=0n||l<=0n)throw new Error("auto-slippage guard amounts must be positive");let d=f*BigInt(1e4-u),m=d/10000n;if(d%10000n!==0n&&(m+=1n),l<m)throw new Error("auto-slippage guard is under-protected relative to its fresh quote");if(i?.data&&e.minAmountOut!=null){let p=Wr(i.data);if(e.calldataHash!=null){if(String(e.calldataHash)!==Dr(i.data))throw new Error("auto-slippage guard is not bound to this call: calldata hash mismatch");if(p!=null&&p!==BigInt(e.minAmountOut))throw new Error(`auto-slippage guard is hash-bound but the calldata encodes ${p}, not the guard floor ${e.minAmountOut}`)}else{if(p==null){let w=String(i.data).slice(0,10);throw new Error(`auto-slippage: cannot verify the output floor encoded by selector ${w}; refusing rather than trusting unbound calldata at an allowlisted venue`)}if(p!==BigInt(e.minAmountOut))throw new Error(`auto-slippage guard is not bound to this call: guard minAmountOut ${e.minAmountOut} but calldata encodes ${p}`)}}return!0}var Eo=new Jr(["function approve(address spender,uint256 amount) returns (bool)"]);import{Interface as jr,isAddress as yo}from"ethers";var Io=new jr(["function approve(address spender,uint256 amount) returns (bool)"]),To=Object.freeze({42161:"0x1c3fa76e6e1088bce750f23a5bfcffa1efef6a41",43114:"0x8f550e53dfe96c055d5bdb267c21f268fcaf63b2"});function x(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 T(e,t="value"){if(typeof e!="string"||e==="")throw new Error(`${t} must be a string`);return e}function q(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=x(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 ge(e,t="amount"){let r=q(e,t);if(r<=0n)throw new Error(`${t} must be positive`);return r}function b(e,t,r="amount"){let n=x(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,[a="0",c=""]=i.split(".");if(c.length>t)throw new Error(`${r} has more than ${t} decimal places, which would lose precision`);let u=BigInt((a||"0")+c.padEnd(t,"0"));return o?-u:u}var Do=new Vr(["function approve(address spender,uint256 amount) returns (bool)"]);function _e(e,t){let r=String(e||"").trim();if(!Gr(r))throw new Error(`${t} must be an address`);return r.toLowerCase()}function Kr(e,t="approval amount",{allowZero:r=!1}={}){let n=q(e,t);if(r?n<0n:n<=0n)throw new Error(`${t} must be positive`);if(n>=zr)throw new Error("unlimited approvals are refused; use an exact bounded amount");return n.toString()}var Ce=new Set(["0x095ea7b3","0x39509351","0x61f49ed6","0xeb5625d9","0xf9255c1f","0x87517c45","0xd505accf","0x8fcbaf0c","0x2b67b570","0x2a2d80d1"]),Yr=new Set(["0x39509351","0xf9255c1f"]);function j(e){let t=String(e||"").toLowerCase();return t.length<10?!1:Ce.has(t.slice(0,10))}function Pe(e){if(!j(e))throw new Error("approval calldata required");let t=String(e||"").toLowerCase(),r=t.slice(0,10),n=t.slice(10).match(/.{1,64}/g)||[],o=s=>n[s]?"0x"+n[s].slice(24):null,i=s=>n[s]?BigInt("0x"+n[s]):null,a=null,c=null,u=null;switch(r){case"0x095ea7b3":case"0x39509351":a=o(0),c=i(1);break;case"0x61f49ed6":case"0xeb5625d9":case"0xf9255c1f":u=o(0),a=o(1),c=i(2);break;case"0xd505accf":a=o(1),c=i(2);break;case"0x8fcbaf0c":{a=o(1),c=i(4)===0n?0n:(1n<<256n)-1n;break}case"0x87517c45":u=o(0),a=o(1),c=i(2);break;default:throw new Error(`approval selector ${r} is recognised but not decodable; refusing to bound it`)}if(a==null||c==null)throw new Error("invalid approve calldata");return{spender:_e(a,"approval spender"),token:u==null?null:_e(u,"approval token"),amount:Kr(c,"approval amount",{allowZero:!0}),selector:r,additive:Yr.has(r)}}import{createHash as Xr,createHmac as Ho,timingSafeEqual as Jo}from"node:crypto";var Zr=2,Ee=300*1e3,Me=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})();function Qr(e){let t=e==null||e===""?Ee:Number(e);return!Number.isFinite(t)||t<0?Ee:Math.min(t,Me)}function xe(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(xe).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${xe(e[r])}`).join(",")}}`}function et(e){let{prepareHash:t,prepareMac:r,note:n,...o}=e||{};return o}function rt(e){let t=et(e);return Xr("sha256").update(xe(t)).digest("hex")}function $e(e,{maxAgeMs:t=Ee,nowMs:r=Date.now(),providers:n=null,kinds:o=null,label:i="operator"}={}){if(!e||typeof e!="object")throw new Error(`${i}: prepared envelope object required`);if(e.oraclePrepared!==!0)throw new Error(`${i}: prepared integrity envelope missing \u2014 use an @oracle-agent/oracle prepare result`);if(Number(e.prepareVersion)!==Zr)throw new Error(`${i}: unsupported prepareVersion ${e.prepareVersion}`);let a=rt(e);if(String(e.prepareHash||"")!==a)throw new Error(`${i}: prepareHash mismatch \u2014 payload was altered after prepare`);let c=Number(e.preparedAt),u=Number(e.expiresAt),s=Qr(t),f=r-c,l=u-c;if(!Number.isFinite(f)||!Number.isFinite(u)||!Number.isFinite(l)||f<0||l<=0||l>Me||f>s||r>u)throw new Error(`${i}: prepare envelope expired or clock-skewed (ageMs=${f}, max=${s})`);if(n&&!new Set(n).has(e.provider))throw new Error(`${i}: provider ${e.provider} not allowed here`);if(o&&!new Set(o).has(e.kind))throw new Error(`${i}: kind ${e.kind} not allowed here`);return!0}var se=e=>String(e||"").toLowerCase(),tt=new Set(["chainId","from","to","data","value","gasLimit","gasPrice","maxFeePerGas","maxPriorityFeePerGas","l1FeeWei","operatorFeeWei","nonce","type","accessList","slippageBps","expiresAtMs"]),nt=new Set([10n,8453n,84532n,42161n,421614n,11155420n,7777777n]);function W(e){try{return nt.has(BigInt(e))}catch{return!1}}var B=(e,t)=>{if(e==null||e==="")throw new Error(`policy: ${t} required`);try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`policy: ${t} must be a non-negative integer`)}},Fe=(e,t)=>{let r=Number(e);if(!Number.isFinite(r))throw new Error(`policy: ${t} must be finite`);return r},Q=(e,t,r,n=String)=>{if(!Array.isArray(t)||t.length===0)throw new Error(`policy: ${r} allowlist is empty`);if(!t.map(n).includes(n(e)))throw new Error(`policy: ${r} not allowed`)};function ce(e,t,{nowMs:r=Date.now(),networkFees:n,requireNetworkFees:o=!1}={}){if(!e||!t)throw new Error("policy: artifact and policy required");if(Object.keys(e).some(m=>!tt.has(m)))throw new Error("policy: unexpected EVM artifact field");if(e.gasPrice!=null&&(e.maxFeePerGas!=null||e.maxPriorityFeePerGas!=null))throw new Error("policy: ambiguous EVM fee fields");if(e.type!=null&&![0,1,2].includes(Number(e.type)))throw new Error("policy: unsupported EVM transaction type");let i=(m,p)=>{try{return BigInt(m)===BigInt(p)}catch{return String(m)===String(p)}};if(!Array.isArray(t.chains)||t.chains.length===0)throw new Error("policy: chain allowlist is empty");if(!t.chains.some(m=>i(m,e.chainId)))throw new Error("policy: chain not allowed");if(Q(e.to,t.destinations,"destination",se),Q(String(e.data||"0x").slice(0,10),t.selectors,"selector",m=>String(m).toLowerCase()),Q(e.from,t.owners,"owner",se),j(e.data)){let m;try{m=Pe(e.data)}catch(w){throw new Error(`policy: malformed approval calldata: ${w?.message||w}`)}Q(m.spender,t.spenders,"spender",se),Q(m.token||e.to,t.erc20Tokens,"ERC-20 token",se);let p=B(t.maxApproval,"maxApproval");if(BigInt(m.amount)>p)throw new Error("policy: approval exceeds cap");if(m.additive)throw new Error("policy: additive approval cannot be bounded; use approve() with an absolute amount")}if(B(e.value,"value")>B(t.maxValueWei,"maxValueWei"))throw new Error("policy: value exceeds cap");let a=B(e.gasLimit,"gasLimit");if(a>B(t.maxGasLimit,"maxGasLimit"))throw new Error("policy: gas exceeds cap");let c=e.maxFeePerGas??e.gasPrice,u=B(c,"feePerGas")*a,s=0n;try{if(W(e.chainId)&&(e.l1FeeWei===void 0||e.operatorFeeWei===void 0))throw new Error("missing")}catch{throw new Error("policy: rollup EVM artifacts require l1FeeWei and operatorFeeWei")}if(e.l1FeeWei!==void 0&&(s+=B(e.l1FeeWei,"l1FeeWei")),e.operatorFeeWei!==void 0&&(s+=B(e.operatorFeeWei,"operatorFeeWei")),W(e.chainId)&&(o||n!=null)){if(!n||n.l1FeeWei===void 0||n.operatorFeeWei===void 0)throw new Error("policy: rollup fee estimate required");let m=B(n.l1FeeWei,"estimated l1FeeWei")+B(n.operatorFeeWei,"estimated operatorFeeWei");if(s<m)throw new Error("policy: rollup fee attestation understates estimate")}if(u+s>B(t.maxFeeWei,"maxFeeWei"))throw new Error("policy: fee exceeds cap");let l=Fe(t.maxSlippageBps,"maxSlippageBps");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>l)throw new Error("policy: slippage attestation exceeds cap");if(!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=r)throw new Error("policy: artifact expired");let d=Fe(t.maxTtlMs??12e4,"maxTtlMs");if(d<=0||e.expiresAtMs-r>d)throw new Error("policy: artifact TTL exceeds cap");return!0}import{createHash as qe}from"node:crypto";import{Address as ot,NETWORK as it,OutScript as Re,RawTx as at,SigHash as De,TEST_NETWORK as st,Transaction as ct}from"@scure/btc-signer";var Ue=(e,t)=>{if(e==null||e==="")throw new Error(`policy: ${t} required`);try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`policy: ${t} must be a non-negative integer`)}},ut=(e,t)=>{if(typeof e!="string"||e.length===0||e.length>131072||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e))throw new Error(`envelope: invalid ${t}`);let r=Buffer.from(e,"base64");if(r.toString("base64")!==e)throw new Error(`envelope: invalid ${t}`);return r},lt=e=>Array.isArray(e)||e instanceof Uint8Array?e.length>0:e!=null,ft=e=>/^(bc1|tb1|bcrt1)/i.test(String(e)),V=e=>ft(e)?String(e).toLowerCase():String(e),be=(e,t)=>Array.isArray(t)&&t.some(r=>V(r)===V(e)),dt=(e,t)=>Buffer.from(e||[]).equals(Buffer.from(t||[]));function pt(e){let t=Buffer.from(at.encode(e)),r=qe("sha256").update(t).digest();return Buffer.from(qe("sha256").update(r).digest()).reverse().toString("hex")}function mt(e){if(!e.nonWitnessUtxo)throw new Error("envelope: PSBT input nonWitnessUtxo required");if(pt(e.nonWitnessUtxo)!==Buffer.from(e.txid||[]).toString("hex"))throw new Error("envelope: Bitcoin prevout txid mismatch");let t=e.nonWitnessUtxo.outputs?.[e.index];if(!t)throw new Error("envelope: Bitcoin prevout output missing");if(!e.witnessUtxo)throw new Error("envelope: PSBT input witness UTXO required");if(BigInt(e.witnessUtxo.amount)!==BigInt(t.amount)||!dt(e.witnessUtxo.script,t.script))throw new Error("envelope: Bitcoin witness UTXO mismatch");return t}function ht(e,t){if(e.action!=="transfer")throw new Error("envelope: BTC decoder requires transfer action");let r=e?.artifact;if(Object.keys(r).some(l=>!["network","psbt"].includes(l)))throw new Error("envelope: unexpected BTC artifact field");if(!be(r.network,t.chains))throw new Error("policy: chain not allowed");let n=["bitcoin","mainnet"].includes(String(r.network).toLowerCase())?it:["testnet","signet","regtest"].includes(String(r.network).toLowerCase())?st:null;if(!n)throw new Error("envelope: unsupported Bitcoin network");let o;try{o=ct.fromPSBT(ut(r.psbt,"PSBT"))}catch(l){throw new Error(`envelope: invalid PSBT: ${l?.message||l}`)}if(o.inputsLength===0||o.outputsLength===0)throw new Error("envelope: PSBT inputs and outputs required");let i=ot(n);for(let l=0;l<o.inputsLength;l++){let d=o.getInput(l);for(let w of["partialSig","tapKeySig","tapScriptSig","finalScriptSig","finalScriptWitness"])if(lt(d[w]))throw new Error("envelope: signed or finalized PSBT refused");if(d.sighashType!==void 0&&d.sighashType!==De.DEFAULT&&d.sighashType!==De.ALL)throw new Error("envelope: Bitcoin sighash must bind all inputs and outputs");let m=mt(d),p;try{let w=Re.decode(m.script);if(!["wpkh"].includes(w.type))throw new Error("unsupported input");p=i.encode(w)}catch{throw new Error("envelope: unsupported Bitcoin input script")}if(!be(p,t.owners)||V(p)!==V(e.owner))throw new Error("envelope: Bitcoin input owner mismatch")}let a=new Set([e.owner,...t.changeAddresses||[]].map(l=>V(l))),c=0n,u=!1,s=[];for(let l=0;l<o.outputsLength;l++){let d=o.getOutput(l),m;try{m=i.encode(Re.decode(d.script))}catch{throw new Error("envelope: unsupported Bitcoin output script")}let p=V(m);if(s.push(`${m}:${d.amount}`),p===V(e.destination)){u=!0,c+=d.amount;continue}if(be(m,t.destinations)){c+=d.amount;continue}if(!a.has(p))throw new Error("policy: Bitcoin output destination not allowed")}if(!u)throw new Error("envelope: Bitcoin destination mismatch");let f;try{f=o.fee}catch{throw new Error("envelope: PSBT fee cannot be decoded")}if(f<0n||f>Ue(t.maxFeeSats,"maxFeeSats"))throw new Error("policy: Bitcoin fee exceeds cap");if(c>Ue(t.maxValueSats,"maxValueSats"))throw new Error("policy: Bitcoin value exceeds cap");return Object.freeze({unit:"sats",value:c.toString(),notional:(c+f).toString(),fee:f.toString(),outputs:Object.freeze(s)})}function We(e,t){let{unit:r,value:n,notional:o,fee:i}=ht(e,t);return Object.freeze({unit:r,value:n,notional:o,fee:i})}import{createHash as Se}from"node:crypto";import{base58 as Ge}from"@scure/base";import{getCompiledTransactionMessageDecoder as wt}from"@solana/transaction-messages";var Ae="11111111111111111111111111111111",gt="ComputeBudget111111111111111111111111111111",Et="So11111111111111111111111111111111111111112",Ke="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";var Ye="ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",xt=5000n,bt=2039280n,yt=37095705934669439343138083508754565189542113879843219016388785533085940283555n,y=57896044618658097711785492504343953926634992332820282019728792003956564819949n,He=19681161376707505956807079304988542015446066515923890162744021073123829784752n,Je=e=>Se("sha256").update(`global:${e}`).digest().subarray(0,8).toString("hex"),St=new Map([[Je("route"),{name:"route",prefixBytes:0}],[Je("shared_accounts_route"),{name:"shared_accounts_route",prefixBytes:1}]]),N=(e,t)=>{if(e==null||e==="")throw new Error(`policy: ${t} required`);try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`policy: ${t} must be a non-negative integer`)}},At=(e,t)=>{if(typeof e!="string"||e.length===0||e.length>131072||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e))throw new Error(`envelope: invalid ${t}`);let r=Buffer.from(e,"base64");if(r.toString("base64")!==e)throw new Error(`envelope: invalid ${t}`);return r},R=(e,t)=>Array.isArray(t)&&t.some(r=>String(r)===String(e)),_=e=>String(e||""),vt=e=>Array.isArray(e.solMints)&&e.solMints.length?e.solMints:e.tokens,le=e=>Se("sha256").update(e).digest("hex");function ue(e,t){try{let r=Buffer.from(Ge.decode(String(e||"")));if(r.length!==32)throw new Error("wrong length");return r}catch{throw new Error(`envelope: invalid Solana ${t}`)}}function k(e){let t=e%y;return t>=0n?t:y+t}function M(e,t){let r=e;for(;t-- >0n;)r=r*r%y;return r}function It(e){let r=e*e%y*e%y,n=M(r,2n)*r%y,o=M(n,1n)*e%y,i=M(o,5n)*o%y,a=M(i,10n)*i%y,c=M(a,20n)*a%y,u=M(c,40n)*c%y,s=M(u,80n)*u%y,f=M(s,80n)*u%y,l=M(f,10n)*i%y;return M(l,2n)*e%y}function Tt(e,t){let r=k(t*t*t),n=k(r*r*t),o=It(e*n),i=k(e*r*o),a=k(t*i*i),c=i,u=k(i*He),s=a===e,f=a===k(-e),l=a===k(-e*He);return s&&(i=c),(f||l)&&(i=u),(k(i)&1n)===1n&&(i=k(-i)),!s&&!f?null:i}function kt(e){if(!e||e.length!==32)return!1;let t=0n;for(let o=31;o>=0;o--)t=(t<<8n)+BigInt(o===31?e[o]&127:e[o]);let r=k(t*t),n=Tt(k(r-1n),k(yt*r+1n));return n===null?!1:!(n===0n&&(e[31]&128)!==0)}function Nt(e,t){let r=Buffer.concat([...e,ue(t,"program id"),Buffer.from("ProgramDerivedAddress")]),n=Se("sha256").update(r).digest();if(kt(n))throw new Error("envelope: derived Solana program address is on curve");return Ge.encode(n)}function ve(e,t,r=Ke){let n=[ue(e,"owner"),ue(r,"token program"),ue(t,"mint")];for(let o=255;o>=0;o--)try{return Nt([...n,Buffer.from([o])],Ye)}catch(i){if(!/on curve/.test(String(i?.message||i)))throw i}throw new Error("envelope: unable to derive associated token account")}function Ot(e,t){return(t.accountIndices||[]).map(r=>_(e.staticAccounts[r]))}function ee(e){return Buffer.from(e.data||[])}function Lt(e,t){return _(e.staticAccounts[t.programAddressIndex])}function Xe(e,t){return Number(t)<e.header.numSignerAccounts}function Bt(e,t){let r=e.header.numSignerAccounts,n=e.header.numReadonlySignerAccounts,o=e.header.numReadonlyNonSignerAccounts,i=e.staticAccounts.length;return Number(t)<r?Number(t)<r-n:Number(t)<i-o}function re(e){return e.accountIndices||[]}function ye(e,t){if(!Array.isArray(e)||!e.length)throw new Error(`policy: ${t} allowlist required`);return e.map(String)}function je(e,t){let r=re(t).map(n=>{let o=Xe(e,n)?"s":"n",i=Bt(e,n)?"w":"r";return`${n}:${_(e.staticAccounts[n])}:${o}:${i}`});return le(Buffer.from(r.join(`
|
|
2
|
-
`)))}function Ve(e,t,r){if(t+8>e.length)throw new Error(`envelope: malformed Jupiter ${r}`);return e.readBigUInt64LE(t)}function _t(e,t,r){if(t+2>e.length)throw new Error(`envelope: malformed Jupiter ${r}`);return e.readUInt16LE(t)}function Ct(e,t,r){if(t+4>e.length)throw new Error(`envelope: malformed Jupiter ${r}`);return e.readUInt32LE(t)}function Pt(e,t,r){let n=r.maxJupiterRoutePlanSteps===void 0?1:Number(r.maxJupiterRoutePlanSteps);if(!Number.isSafeInteger(n)||n<1)throw new Error("policy: maxJupiterRoutePlanSteps must be a positive integer");if(t<1||t>n)throw new Error("policy: Jupiter route-plan step count exceeds reviewed cap");let o=Array.isArray(r.jupiterRouteVariants)?r.jupiterRouteVariants.map(Number):[];if(!o.length)throw new Error("policy: Jupiter route variant allowlist required");let i=r.jupiterRouteVariantPayloadBytes||{},a=0,c=0,u=[];for(let s=0;s<t;s++){if(a>=e.length)throw new Error("envelope: opaque or unsupported Jupiter route-plan payload");let f=e[a++];if(!o.includes(f))throw new Error("policy: Jupiter route variant not allowed");if(!Object.hasOwn(i,String(f)))throw new Error("policy: Jupiter route variant payload size required");let l=Number(i[String(f)]);if(!Number.isSafeInteger(l)||l<0||l>16)throw new Error("policy: Jupiter route variant payload size invalid");if(a+l+3>e.length)throw new Error("envelope: opaque or unsupported Jupiter route-plan payload");let d=e.subarray(a,a+l);a+=l;let m=d.toString("hex"),p=r.jupiterRouteVariantPayloads?.[String(f)];if(!Array.isArray(p)||!p.map(String).includes(m))throw new Error("policy: Jupiter route variant payload not allowed");let w=e[a++],h=e[a++],E=e[a++];if(w<1||w>100)throw new Error("envelope: Jupiter route-plan percent invalid");if(h!==s||E!==s+1)throw new Error("envelope: unsupported Jupiter route-plan token index");c+=w,u.push(Object.freeze({swapVariant:f,variantPayloadHex:m,percent:w,inputIndex:h,outputIndex:E}))}if(a!==e.length)throw new Error("envelope: opaque or unsupported Jupiter route-plan payload");if(c!==100*t)throw new Error("envelope: Jupiter route-plan percent total mismatch");return Object.freeze(u)}function Mt(e,t){let r=ee({data:e}),n=r.subarray(0,8).toString("hex"),o=St.get(n);if(!o)throw new Error("envelope: unsupported Jupiter instruction discriminator");let i=19,a=o.prefixBytes===1?r[8]:null;if(o.prefixBytes===1&&r.length<9)throw new Error("envelope: malformed Jupiter shared route payload");let c=8+o.prefixBytes,u=c+4,s=r.length-i;if(s<=u)throw new Error("envelope: malformed Jupiter route payload");let f=Ct(r,c,"route plan length"),l=r.subarray(u,s),d=Pt(l,f,t);return Object.freeze({instruction:o.name,routeId:a,routePlanSteps:f,routePlan:d,routePlanHash:le(l),inAmount:Ve(r,s,"in_amount"),quotedOutAmount:Ve(r,s+8,"quoted_out_amount"),slippageBps:_t(r,s+16,"slippage_bps"),platformFeeBps:r[s+18],instructionHash:le(r)})}function $t(e,t,r){let n=Ot(e,t),o=(i,a)=>{let c=n[i];if(!c)throw new Error(`envelope: Jupiter ${a} account missing`);return c};if(r.instruction==="route"){if(n.length<9)throw new Error("envelope: Jupiter route account layout incomplete");return{tokenProgram:o(0,"tokenProgram"),userTransferAuthority:o(1,"userTransferAuthority"),userSourceTokenAccount:o(2,"userSourceTokenAccount"),userDestinationTokenAccount:o(3,"userDestinationTokenAccount"),destinationTokenAccount:o(4,"destinationTokenAccount"),destinationMint:o(5,"destinationMint"),platformFeeAccount:o(6,"platformFeeAccount"),eventAuthority:o(7,"eventAuthority"),program:o(8,"program")}}if(r.instruction==="shared_accounts_route"){if(n.length<13)throw new Error("envelope: Jupiter shared route account layout incomplete");return{tokenProgram:o(0,"tokenProgram"),programAuthority:o(1,"programAuthority"),userTransferAuthority:o(2,"userTransferAuthority"),userSourceTokenAccount:o(3,"sourceTokenAccount"),programSourceTokenAccount:o(4,"programSourceTokenAccount"),programDestinationTokenAccount:o(5,"programDestinationTokenAccount"),userDestinationTokenAccount:o(6,"destinationTokenAccount"),sourceMint:o(7,"sourceMint"),destinationMint:o(8,"destinationMint"),platformFeeAccount:o(9,"platformFeeAccount"),token2022Program:o(10,"token2022Program"),eventAuthority:o(11,"eventAuthority"),program:o(12,"program")}}throw new Error("envelope: unsupported Jupiter account layout")}function ze(e,t){return e&&e!==t?e:null}function O(e,t,r){let n=_(e.staticAccounts[t]);if(!n)throw new Error(`envelope: Jupiter ${r} missing`);return n}function Ft(e,t){let r=ee(e);if(r.length===5&&r[0]===2){let n=r.readUInt32LE(1),o=t.maxComputeUnits===void 0?14e5:Number(t.maxComputeUnits);if(!Number.isSafeInteger(o)||o<=0)throw new Error("policy: maxComputeUnits must be positive");if(n>o)throw new Error("policy: Jupiter compute unit limit exceeds cap");return 0n}throw r.length===9&&r[0]===3?new Error("policy: Jupiter priority fee not allowed"):new Error("envelope: unsupported Jupiter compute-budget helper")}function qt(e,t,r,n,o,i){let a=ee(t);if(a.length!==1||a[0]!==1)throw new Error("envelope: unsupported Jupiter ATA helper");let c=re(t);if(c.length!==6)throw new Error("envelope: malformed Jupiter ATA helper");let u=O(e,c[0],"ATA payer"),s=O(e,c[1],"ATA account"),f=O(e,c[2],"ATA owner"),l=O(e,c[3],"ATA mint"),d=O(e,c[4],"ATA system program"),m=O(e,c[5],"ATA token program");if(u!==r.owner)throw new Error("envelope: Jupiter ATA payer must equal owner");if(f!==r.owner)throw new Error("envelope: Jupiter ATA owner must equal owner");if(d!==Ae)throw new Error("envelope: Jupiter ATA system program mismatch");if(m!==o)throw new Error("envelope: Jupiter ATA token program mismatch");if(l!==n.inputMint&&l!==n.outputMint)throw new Error("envelope: Jupiter ATA mint mismatch");if(s!==ve(r.owner,l,o))throw new Error("envelope: Jupiter ATA account mismatch");return{ata:s,debit:i}}function Rt(e,t,r,n,o){let i=re(t),a=ee(t);if(i.length!==2||a.length!==12||a.readUInt32LE(0)!==2)throw new Error("envelope: unsupported Jupiter system helper");let c=O(e,i[0],"wrap payer"),u=O(e,i[1],"wrap target"),s=a.readBigUInt64LE(4);if(c!==r.owner||u!==n)throw new Error("envelope: unsupported Jupiter wrap transfer");if(s!==o)throw new Error("envelope: Jupiter wrap transfer amount mismatch");return s}function Dt(e,t,r,n){let o=re(t),i=ee(t);if(i.length!==1)throw new Error("envelope: unsupported Jupiter token helper");if(i[0]===17){if(o.length!==1||O(e,o[0],"syncNative account")!==n)throw new Error("envelope: Jupiter syncNative account mismatch");return{kind:"syncNative"}}if(i[0]===9){if(o.length!==3)throw new Error("envelope: malformed Jupiter closeAccount helper");let a=O(e,o[0],"closeAccount source"),c=O(e,o[1],"closeAccount destination"),u=O(e,o[2],"closeAccount authority");if(a!==n||c!==r.owner||u!==r.owner)throw new Error("envelope: Jupiter closeAccount must return to owner");return{kind:"closeAccount"}}throw new Error("envelope: unsupported Jupiter token helper")}function Ut(e,t,r,n,o,i,a){let c=ve(t.owner,t.artifact.inputMint,a);if(o.userSourceTokenAccount!==c)throw new Error("envelope: Jupiter source token account is not owner ATA");let u=N(r.jupiterAtaRentLamports,"jupiterAtaRentLamports");if(u<bt)throw new Error("policy: Jupiter ATA rent below the token-account rent-exempt minimum");let s=new Map,f=0n,l=!1,d=!1;for(let m of e.instructions){if(m===n)continue;let p=Lt(e,m);if(p===gt)Ft(m,r);else if(p===Ye){let{ata:w,debit:h}=qt(e,m,t,t.artifact,a,u);s.set(w,h)}else if(p===Ae)f+=Rt(e,m,t,c,i);else if(p===a){let w=Dt(e,m,t,c);w.kind==="syncNative"&&(l=!0),w.kind==="closeAccount"&&(d=!0)}else throw new Error("envelope: unsupported Jupiter helper instruction")}if(f>0n&&(!l||!d))throw new Error("envelope: Jupiter native wrap helpers incomplete");if(f!==0n&&f!==i)throw new Error("envelope: Jupiter native wrap amount mismatch");return[...s.values()].reduce((m,p)=>m+p,0n)}function Wt(e){let t;try{t=wt().decode(At(e.messageBase64,"Solana message"))}catch(r){throw new Error(`envelope: invalid Solana message: ${r?.message||r}`)}if(t.version!=="legacy"&&Array.isArray(t.addressTableLookups)&&t.addressTableLookups.length)throw new Error("envelope: unresolved Solana address tables refused");return t}function Ht(e,t,r){if(e.header.numSignerAccounts!==1||_(e.staticAccounts[0])!==t.owner||!R(t.owner,r.owners))throw new Error("envelope: Solana owner mismatch");if(!Array.isArray(e.instructions)||e.instructions.length===0)throw new Error("envelope: Solana instructions required");let n=[];for(let o of e.instructions){let i=_(e.staticAccounts[o.programAddressIndex]);if(!i||!R(i,r.programs))throw new Error("policy: Solana program not allowed");n.push(i)}return n}function Jt(e,t,r){let n=N(r.lamportsPerSignature,"lamportsPerSignature");if(n<xt)throw new Error("policy: Solana per-signature fee is below the network minimum");let o=r.maxLamportsPerSignature===void 0?n:N(r.maxLamportsPerSignature,"maxLamportsPerSignature");if(n>o)throw new Error("policy: Solana per-signature fee exceeds cap");let i=BigInt(e.header.numSignerAccounts),a=i*n,c=i*o;if(t.exactFeeLamports!==void 0){let s=N(t.exactFeeLamports,"exactFeeLamports");if(s<a)throw new Error("policy: Solana exact fee below the base signature fee");if(s>c)throw new Error("policy: Solana exact fee exceeds the per-signature bound")}let u=c;if(u>N(r.maxFeeLamports,"maxFeeLamports"))throw new Error("policy: Solana fee exceeds cap");return u}function jt(e,t,r,n){let o=0n,i=!1;for(let a of e.instructions){if(_(e.staticAccounts[a.programAddressIndex])!==Ae)throw new Error("envelope: unsupported Solana program decoder");let u=a.accountIndices||[];if(u.length!==2||_(e.staticAccounts[u[0]])!==t.owner)throw new Error("envelope: Solana transfer owner mismatch");let s=_(e.staticAccounts[u[1]]);if(s!==t.destination||!R(s,r.destinations))throw new Error("envelope: Solana destination mismatch");let f=Buffer.from(a.data||[]);if(f.length!==12||f.readUInt32LE(0)!==2)throw new Error("envelope: unsupported Solana system instruction");o+=f.readBigUInt64LE(4),i=!0}if(!i)throw new Error("envelope: Solana destination mismatch");if(o>N(r.maxValueLamports,"maxValueLamports"))throw new Error("policy: Solana value exceeds cap");return{value:o,programs:n}}function Vt(e,t,r,n){let o=t.artifact;if(o.provider!=="jupiter")throw new Error("envelope: Solana swap provider must be jupiter");if(o.inputMint!==Et)throw new Error("envelope: Jupiter local signer requires native SOL input");if(o.outputMint!==t.destination||!R(o.outputMint,r.destinations))throw new Error("envelope: Jupiter output mint destination mismatch");let i=vt(r);if(!R(o.inputMint,i)||!R(o.outputMint,i))throw new Error("policy: Solana token not allowed");let a=N(o.inAmount,"inAmount"),c=N(o.outAmount,"outAmount"),u=N(o.otherAmountThreshold,"otherAmountThreshold");if(a<=0n||a>N(r.maxPerTradeLamports,"maxPerTradeLamports"))throw new Error("policy: Solana swap amount exceeds per-trade cap");if(a>N(r.maxValueLamports,"maxValueLamports"))throw new Error("policy: Solana value exceeds cap");if(c<=0n||u<=0n||u>c)throw new Error("envelope: Jupiter quote floor invalid");if(Number(o.slippageBps)!==Number(t.slippageBps))throw new Error("policy: Solana slippage mismatch");let s=_(o.jupiterProgram);if(!s||!R(s,r.programs)||!n.includes(s))throw new Error("policy: Jupiter program not allowed or absent");let f=e.instructions.filter(F=>_(e.staticAccounts[F.programAddressIndex])===s);if(f.length!==1)throw new Error("envelope: exactly one Jupiter swap instruction required");let l=f[0],d=Mt(l.data,r);if(d.instruction==="shared_accounts_route"){let F=Array.isArray(r.jupiterSharedRouteIds)?r.jupiterSharedRouteIds.map(Number):[];if(!F.length)throw new Error("policy: Jupiter shared route id allowlist required");if(!F.includes(Number(d.routeId)))throw new Error("policy: Jupiter shared route id not allowed")}else if(d.routeId!=null)throw new Error("envelope: unexpected Jupiter shared route id");if(!ye(r.jupiterRoutePlanHashes,"Jupiter route-plan hash").includes(d.routePlanHash))throw new Error("policy: Jupiter route-plan hash not allowed");if(d.inAmount!==a)throw new Error("envelope: Jupiter route in_amount mismatch");if(d.quotedOutAmount!==c)throw new Error("envelope: Jupiter route quoted_out_amount mismatch");if(d.slippageBps!==Number(o.slippageBps))throw new Error("envelope: Jupiter route slippage mismatch");let m=d.quotedOutAmount-d.quotedOutAmount*BigInt(d.slippageBps)/10000n;if(u!==m)throw new Error("envelope: Jupiter otherAmountThreshold does not match serialized min-out");if(d.platformFeeBps!==0)throw new Error("policy: Jupiter platform fee not allowed");let p=$t(e,l,d),w=re(l),h=d.instruction==="shared_accounts_route"?2:1;if(!Xe(e,w[h]))throw new Error("envelope: Jupiter transfer authority must be signer");if(p.program!==s)throw new Error("envelope: Jupiter program account mismatch");if(p.userTransferAuthority!==t.owner)throw new Error("envelope: Jupiter transfer authority must equal owner");if(p.destinationMint!==o.outputMint)throw new Error("envelope: Jupiter destination mint mismatch");if(p.sourceMint!==void 0&&p.sourceMint!==o.inputMint)throw new Error("envelope: Jupiter source mint mismatch");let E=Array.isArray(r.tokenPrograms)&&r.tokenPrograms.length?r.tokenPrograms:[Ke];if(!R(p.tokenProgram,E))throw new Error("policy: Solana token program not allowed");let L=ve(t.owner,o.outputMint,p.tokenProgram);if(p.userDestinationTokenAccount!==L)throw new Error("envelope: Jupiter destination token account is not owner ATA");let P=ze(p.destinationTokenAccount,s);if(P&&P!==L)throw new Error("envelope: Jupiter optional destination account redirects proceeds");if(ze(p.platformFeeAccount,s))throw new Error("policy: Jupiter platform fee account not allowed");if(!ye(r.jupiterRouteAccountHashes,"Jupiter route account hash").includes(je(e,l)))throw new Error("policy: Jupiter route account hash not allowed");let I=le(Buffer.from([d.instruction,d.routeId??"",d.routePlanHash,je(e,l)].join(`
|
|
3
|
-
`)));if(!ye(r.jupiterRouteReviewHashes,"Jupiter route review hash").includes(I))throw new Error("policy: Jupiter route review hash not allowed");let G=Ut(e,t,r,l,p,a,p.tokenProgram),U=a+G;if(U>N(r.maxValueLamports,"maxValueLamports"))throw new Error("policy: Solana value exceeds cap");return{value:U,programs:n}}function zt(e,t){if(e.action!=="transfer"&&e.action!=="swap")throw new Error("envelope: Solana decoder requires transfer or swap action");let r=e?.artifact,n=e.action==="transfer"?["cluster","messageBase64","exactFeeLamports"]:["cluster","provider","messageBase64","exactFeeLamports","inputMint","outputMint","inAmount","outAmount","otherAmountThreshold","slippageBps","jupiterProgram"];if(Object.keys(r||{}).some(u=>!n.includes(u)))throw new Error("envelope: unexpected Solana artifact field");if(!R(r.cluster,t.chains))throw new Error("policy: chain not allowed");let o=Wt(r),i=Ht(o,e,t),a=e.action==="transfer"?jt(o,e,t,i):Vt(o,e,t,i),c=Jt(o,r,t);return Object.freeze({unit:"lamports",value:a.value.toString(),notional:(a.value+c).toString(),fee:c.toString(),programs:Object.freeze(a.programs)})}function Ze(e,t){let{unit:r,value:n,notional:o,fee:i}=zt(e,t);return Object.freeze({unit:r,value:n,notional:o,fee:i})}var Gt=1e8;function Ie(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=Gt+t;return Number.isSafeInteger(o)?{encoding:t,outcome:n,side:r,coin:`#${t}`,assetId:o}:null}var Kt=new Set(["https://api.hyperliquid.xyz/exchange","https://api.hyperliquid-testnet.xyz/exchange"]),Yt=new Set(["perp-order","hip3-order","hip4-order","perp-bracket"]),Xt=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"}),Zt=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"}),H=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`hl: bounded ${t} required`);return e};function Qt(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 Qe(e,t){let r=x(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 $(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=>$(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)}:${$(e[n],t)}`).join(",")}}`}function en(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)||$(r,"declared order type")!==$({limit:{tif:i}},"expected order type"))throw new Error("hl: limit order type must match its wire shape");return}if(t==="market"){if($(r,"declared order type")!==$({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||$(r,"declared order type")!==$({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 rn(e,t,r){let n=Qe(e.s,"signed size"),o=Qe(e.p,"signed price"),i=n.decimals+o.decimals,a=n.raw*o.raw,c=b(t.notionalUsd,i,"hl: notionalUsd");if(c<=0n||a!==c)throw new Error("hl: signed notional must match");let u=b(r.maxNotionalUsd,i,"hl: maxNotionalUsd");if(a>u)throw new Error("hl: notional exceeds cap")}function tn(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=H(r.b,"order builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(n))throw new Error("hl: order builder address required");if(T(e.builder||"","hl: builder").toLowerCase()!==n)throw new Error("hl: signed order builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(c=>String(c).toLowerCase()):[]).includes(n))throw new Error("hl: order builder not allowed");let i=q(r.f,"hl: signed order builder fee");if(i<0n)throw new Error("hl: signed order builder fee must be non-negative");let a=b(t.maxBuilderFeeBps??0,1,"hl: maxBuilderFeeBps");if(i>a)throw new Error("hl: order builder fee exceeds cap")}function er(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(x(e.s,"hl: signed size")!==x(t.size,"hl: size"))throw new Error("hl: signed size must match");if(x(e.p,"hl: signed price")!==x(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($(e.t,"signed order type")!==$(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 rr(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(x(e.s,"hl: bracket protection size")!==x(t.size,"hl: size"))throw new Error("hl: bracket protection size must match");if(x(e.p,"hl: bracket protection price")!==x(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(x(i.triggerPx,"hl: triggerPx")!==x(n,"hl: protection price"))throw new Error("hl: bracket protection trigger must match")}function nn(e){let t=String(e||"").replace(/\/$/,"");if(!Kt.has(t))throw new Error("hl: submitTo must be the official Hyperliquid exchange");return t}function Te(e){return Ie(e)!=null}function on(e,t){let r=String(e||""),n=Array.isArray(t.coins)?t.coins.map(String):[];if(Te(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 an(e,t,r){let n=Array.isArray(r.hlMarkets)?r.hlMarkets:[];if(n.length){if(!n.some(a=>{if(typeof a=="string"){let[c,u]=String(a).split(":");return c===e&&Number(u)===t}return String(a?.coin)===e&&Number(a?.assetId)===t}))throw new Error("hl: coin/assetId pair not allowed");return!0}if(Te(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 tr(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=H(r.kind,"kind",48),o=Xt[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=nn(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 a=Number(r.nonce);if(!Number.isSafeInteger(a)||a<=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!==Zt[n])throw new Error("hl: action type must match kind");let c=r.notionalUsd??0;if(Yt.has(n)||n==="perp-cancel"||n==="perp-leverage"||n==="perp-isolated-margin"){let u=H(r.coin,"coin",64),s=r.assetId??r.assetIndex;if(!Number.isSafeInteger(s)||s<0)throw new Error("hl: assetId required");if(n==="hip4-order"||s>=1e8){let f=Ie(u);if(!f||f.coin!==u)throw new Error("hl: HIP-4 actions must use a canonical outcome coin");if(f.assetId!==s)throw new Error("hl: HIP-4 coin must bind to its canonical assetId")}if(on(u,t),an(u,s,t),n==="hip4-order"&&!Te(u))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");en(r);let f=r.action.orders;if(n==="perp-bracket"){let l=r.takeProfitPx,d=r.stopLossPx,m=1+(l==null?0:1)+(d==null?0:1);if(m<2||f.length!==m||r.grouping!=="normalTpsl"||r.action.grouping!==r.grouping)throw new Error("hl: bracket must contain exactly the declared entry and protection legs");er(f[0],r,s);let p=1;l!=null&&rr(f[p++],r,s,l,"tp"),d!=null&&rr(f[p],r,s,d,"sl")}else{if(f.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");er(f[0],r,s)}rn(f[0],r,t),tn(r,t),c=x(r.notionalUsd,"hl: notionalUsd")}if(n==="perp-leverage"){let f=r.leverage;if(!Number.isSafeInteger(f)||f<1)throw new Error("hl: leverage must be a positive integer");let l=t.maxLeverage==null?50:t.maxLeverage;if(typeof l!="number"||!Number.isSafeInteger(l)||l<1)throw new Error("hl: maxLeverage must be a positive integer");if(f>l)throw new Error("hl: leverage exceeds cap")}if(n==="perp-cancel"){let f=r.action.cancels;if(!Array.isArray(f)||f.length!==1)throw new Error("hl: exactly one cancel is required");if(!Number.isSafeInteger(f[0].a)||f[0].a!==s)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(f[0].o)||f[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!==s)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 f=r.marginMode==="cross";if(typeof r.action.isCross!="boolean"||r.action.isCross!==f)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!==s)throw new Error("hl: signed margin asset must match assetId");let f=H(r.usd,"margin usd",64),l=b(f,6,"hl: margin usd");if(q(r.action.ntli,"hl: signed margin ntli")!==l)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 m=b(t.maxNotionalUsd,6,"hl: maxNotionalUsd"),p=l<0n?-l:l;if(p>m)throw new Error("hl: margin notional exceeds cap");c=Qt(p,6)}}if(n==="builder-fee-approval"){let u=H(r.builder,"builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(u))throw new Error("hl: builder address required");if(H(r.action.builder,"signed builder",42).toLowerCase()!==u)throw new Error("hl: signed builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(p=>String(p).toLowerCase()):[]).includes(u))throw new Error("hl: builder not allowed");let f=H(r.maxFeeRate,"maxFeeRate",32);if(H(r.action.maxFeeRate,"signed maxFeeRate",32)!==f)throw new Error("hl: signed builder fee must match");if(!/^\d+(?:\.\d+)?%$/.test(f))throw new Error("hl: builder fee rate must be a percent");let l=b(f.slice(0,-1),12,"hl: builder fee percent"),d=b(t.maxBuilderFeeBps,12,"hl: maxBuilderFeeBps");if(d<0n||l*100n>d)throw new Error("hl: builder fee exceeds cap");if(Number(r.action.nonce)!==a)throw new Error("hl: signed builder nonce must match");let m=i.includes("testnet")?"Testnet":"Mainnet";if(r.hyperliquidChain!==m||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 u=n==="hype-undelegate";if(typeof r.action.isUndelegate!="boolean"||r.action.isUndelegate!==u)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(c??r.action.wei??0),notional:String(c??0),fee:"0",kind:n,actionType:r.action.type,amount:String(r.action.wei??c??0),coin:r.coin||null,submitTo:i})}var gi="0x"+"00".repeat(32);function nr(e,t){let r=BigInt(x(e.makerAmount,"poly: makerAmount")),n=BigInt(x(e.takerAmount,"poly: takerAmount"));if(r<=0n||n<=0n)throw new Error("poly: order amounts must be positive integer micro-units");return Number(t==="BUY"?r:n)/1e6}var sn=new Set(["https://clob.polymarket.com/order"]),te=Object.freeze([["salt","uint256"],["maker","address"],["signer","address"],["tokenId","uint256"],["makerAmount","uint256"],["takerAmount","uint256"],["side","uint8"],["signatureType","uint8"],["timestamp","uint256"],["metadata","bytes32"],["builder","bytes32"]]),yi=Object.freeze(te.map(e=>e[0])),cn=new Set(["0xe111180000d2663c0091e4f400237545b87b996b","0xe2222d279d744050d28e00520010520000310f59"]),un="0xe111180000d2663c0091e4f400237545b87b996b",ln="0xe2222d279d744050d28e00520010520000310f59",or=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`poly: bounded ${t} required`);return e};function ir(e){let t=String(e||"").replace(/\/$/,"");if(!sn.has(t))throw new Error("poly: submitTo must be the official Polymarket CLOB");return t}function ar(e){let t=T(e,"poly: exchange").toLowerCase();if(!cn.has(t))throw new Error("poly: verifyingContract must be an official CTF Exchange");return t}function sr(e,t){if(e?.surface!=="poly")throw new Error("poly: surface poly required");let r=e.artifact;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("poly: structured artifact required");let n=or(r.kind,"kind",48);if(n!=="poly-order")throw new Error("poly: unsupported Polymarket kind");if(e.action!=="order")throw new Error("poly: surface/action/kind mismatch");if(T(e.destination,"poly: destination").toLowerCase()!=="polymarket")throw new Error("poly: destination must be polymarket");if(ir(r.submitTo),r.chainId!==137)throw new Error("poly: chainId must be Polygon 137");let o=r.domain;if(!o||typeof o!="object")throw new Error("poly: EIP-712 domain required");if(o.name!=="Polymarket CTF Exchange"||o.version!=="2"||o.chainId!==137)throw new Error("poly: EIP-712 domain must be official CTF Exchange v2 on Polygon");if(ar(o.verifyingContract),ar(r.exchange),T(o.verifyingContract,"poly: verifyingContract").toLowerCase()!==T(r.exchange,"poly: exchange").toLowerCase())throw new Error("poly: exchange/domain mismatch");if(typeof r.negRisk!="boolean")throw new Error("poly: negRisk must be a boolean");let i=r.negRisk?ln:un;if(T(r.exchange,"poly: exchange").toLowerCase()!==i)throw new Error("poly: negRisk/exchange mismatch");let a=r.message||r.value;if(!a||typeof a!="object")throw new Error("poly: signed order message required");let c=r.types?.Order;if(!Array.isArray(c)||c.length!==te.length)throw new Error("poly: EIP-712 Order type must be official CLOB v2");for(let h=0;h<te.length;h+=1)if(c[h]?.name!==te[h][0]||c[h]?.type!==te[h][1])throw new Error("poly: EIP-712 Order type must be official CLOB v2");if((r.orderType||"GTC")!=="GTC")throw new Error("poly: only GTC is public");let u=String(e.owner||"").toLowerCase();if(T(a.maker,"poly: maker").toLowerCase()!==u)throw new Error("poly: maker must equal owner");if(T(a.signer,"poly: signer").toLowerCase()!==u)throw new Error("poly: signer must equal owner");if(a.signatureType!==0)throw new Error("poly: only EOA signatureType 0 is public");if(typeof a.builder!="string"||a.builder.toLowerCase()!==`0x${"00".repeat(32)}`)throw new Error("poly: builder must be zero");if(a.side!==0&&a.side!==1)throw new Error("poly: side must be BUY or SELL");let s=or(r.tokenId,"tokenId",80);if(T(a.tokenId,"poly: tokenId")!==s)throw new Error("poly: tokenId mismatch");let f=Array.isArray(t.polyTokens)?t.polyTokens.map(String):[];if(f.length&&!f.includes(s)&&!f.includes("*"))throw new Error("poly: tokenId not allowed");let l=Number(a.side)===0?"BUY":"SELL";if(r.side&&r.side!==l)throw new Error("poly: side mismatch");let d=nr(a,l),m=b(r.notionalUsdc,6,"poly: notionalUsdc"),p=b(d,6,"poly: computed notional");if(m!==p)throw new Error("poly: notionalUsdc must match CLOB v2 amounts");let w=t.maxNotionalUsd??t.maxNotionalUsdc;if(w!=null){let h=b(w,6,"poly: maxNotionalUsd");if(p>h)throw new Error("poly: notional exceeds cap")}return Object.freeze({unit:"usdc",value:String(d),notional:String(d),fee:"0",kind:n,tokenId:s,side:l,submitTo:ir(r.submitTo)})}var fn=new Set(["https://mainnet.zklighter.elliot.ai/api/v1/sendTx","https://testnet.zklighter.elliot.ai/api/v1/sendTx"]),ur=14,cr=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`lighter: bounded ${t} required`);return e};function Y(e,t,r){if(!Number.isSafeInteger(e)||e!==t)throw new Error(`lighter: ${r} must be exact numeric ${t}`)}function lr(e){let t=String(e||"").replace(/\/$/,"");if(!fn.has(t))throw new Error("lighter: submitTo must be the official Lighter sendTx");return t}function fr(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=cr(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=lr(r.submitTo),i=r.marketIndex;if(typeof i!="number"||!Number.isSafeInteger(i)||i<0)throw new Error("lighter: marketIndex required");let a=Number(q(r.accountIndex,"lighter: accountIndex"));if(!Number.isSafeInteger(a)||a<0)throw new Error("lighter: accountIndex required");let c=Number(q(r.clientOrderIndex,"lighter: clientOrderIndex"));if(!Number.isSafeInteger(c)||c<0)throw new Error("lighter: clientOrderIndex required");Y(r.orderType,0,"orderType"),Y(r.timeInForce,1,"timeInForce"),Y(r.reduceOnly,0,"reduceOnly"),Y(r.triggerPrice,0,"triggerPrice"),Y(r.orderExpiry,-1,"orderExpiry");let u=cr(r.symbol||r.coin,"symbol",32),s=Array.isArray(t.lighterMarkets)?t.lighterMarkets.map(String):[];if(s.length&&!s.includes(u)&&!s.includes(String(i))&&!s.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 f=ge(r.baseAmount,"lighter: baseAmount"),l=ge(r.price,"lighter: price");if(f>BigInt(Number.MAX_SAFE_INTEGER)||l>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("lighter: baseAmount and price must be safe integers");let d=Number(f),m=Number(l),p=Number(r.sizeDecimals??0),w=Number(r.priceDecimals??0);if(!Number.isInteger(p)||p<0||p>12)throw new Error("lighter: sizeDecimals required");if(!Number.isInteger(w)||w<0||w>12)throw new Error("lighter: priceDecimals required");let h=p+w,E=f*l,L=b(r.notionalUsd,h,"lighter: notionalUsd");if(L<=0n)throw new Error("lighter: notionalUsd required");if(E!==L)throw new Error("lighter: notionalUsd must match size and price");let P=b(t.maxNotionalUsd??Number.MAX_SAFE_INTEGER,h,"lighter: maxNotionalUsd");if(E>P)throw new Error("lighter: notional exceeds cap");let I=x(r.notionalUsd,"lighter: notionalUsd");return Y(r.txType,ur,"txType"),Object.freeze({unit:"usd",value:String(I),notional:String(I),fee:"0",kind:n,symbol:u,marketIndex:i,side:r.side,baseAmount:d,price:m,submitTo:o,actionType:"create-order",amount:String(I)})}var mr=new Set(["evm","evm-swap","evm-bridge","evm-nft","btc","sol","hl","poly","lighter"]);var Ne=Object.freeze({swap:5,bridge:5,perps:0,nft:0,mint:0,transfer:0,approve:0,order:0,cancel:0,leverage:0,margin:0,approveBuilder:0,stake:0,unstake:0,delegate:0}),dn=new Set(["0x0000000000000000000000000000000000000000","0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"]),hr=Object.freeze({"0x04e45aaf":{provider:"uniswap-v3",action:"swap",layout:"router02-exact-input-single"},"0x414bf389":{provider:"uniswap-v3",action:"swap",layout:"swap-router-exact-input-single"},"0xc04b8d59":{provider:"uniswap-v3",action:"swap",layout:"exact-input-deadline"},"0xb858183f":{provider:"uniswap-v3",action:"swap",layout:"exact-input"},"0x5ae401dc":{provider:"uniswap-v3",action:"swap",layout:"multicall-deadline"},"0xa026383e":{provider:"aerodrome",action:"swap",layout:"aerodrome-exact-input-single"},"0x7b939232":{provider:"across-v3",action:"bridge",layout:"across-deposit-v3"}}),pn=Object.freeze({"0x161ac21f":{provider:"opensea-nft",action:"mint",layout:"seadrop-mint-public"}}),mn=Object.freeze({"0xa0712d68":{provider:"nft-mint",action:"mint",layout:"mint-quantity"},"0x1249c58b":{provider:"nft-mint",action:"mint",layout:"mint-no-args"},"0x2db11544":{provider:"nft-mint",action:"mint",layout:"mint-quantity"},"0xefef39a1":{provider:"nft-mint",action:"mint",layout:"mint-quantity"},"0xa6f2ae3a":{provider:"nft-mint",action:"mint",layout:"mint-no-args"}});var fe=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`envelope: bounded ${t} required`);return e},g=(e,t)=>{try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`envelope: ${t} must be a non-negative integer`)}},dr=(e,t)=>{let r=Number(e);if(!Number.isFinite(r))throw new Error(`policy: ${t} must be finite`);return r},hn=(e,t)=>{if(!Array.isArray(e)||e.length===0)throw new Error(`policy: ${t} allowlist is empty`);return e},S=(e,t,r)=>{if(!hn(t,r).map(n=>String(n).toLowerCase()).includes(String(e).toLowerCase()))throw new Error(`policy: ${r} not allowed`)},ke=(e,t,r)=>{Array.isArray(t)&&t.length&&S(e,t,r)},D=(e,t)=>{let r=String(e||"").toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(r))throw new Error(`envelope: ${t} must be a 20-byte address`);return r},z=e=>String(e||"0x").slice(0,10).toLowerCase(),wr=e=>g(e.gasLimit,"gasLimit")*g(e.maxFeePerGas??e.gasPrice,"feePerGas")+g(e.l1FeeWei??0,"l1FeeWei")+g(e.operatorFeeWei??0,"operatorFeeWei");function X(e,t,r,{dynamicTail:n=!1}={}){let o=String(e||"").toLowerCase();if(!/^0x[0-9a-f]*$/.test(o)||o.length<10+t*64)throw new Error(`envelope: malformed ${r} calldata`);if(!n&&o.length!==10+t*64)throw new Error(`envelope: malformed ${r} calldata`);return{hex:o,word:i=>o.slice(10+i*64,10+(i+1)*64)}}function A(e,t){if(!/^0{24}[0-9a-f]{40}$/.test(e))throw new Error(`envelope: malformed ${t} address`);return`0x${e.slice(24)}`}function C(e,t){try{return BigInt(`0x${e}`)}catch{throw new Error(`envelope: malformed ${t} integer`)}}function wn(e){if(z(e)!=="0x095ea7b3")return null;let t=X(e,2,"approval");return{kind:"approval",spender:A(t.word(0),"approval spender"),amount:C(t.word(1),"approval amount")}}function gr(e,t){let r=t==="router02-exact-input-single"?7:8,n=X(e,r,"Uniswap v3 exactInputSingle"),o=r===7?4:5;return{kind:"action",action:"swap",inputToken:A(n.word(0),"input token"),outputToken:A(n.word(1),"output token"),recipient:A(n.word(3),"recipient"),amountIn:C(n.word(o),"amountIn"),minimumOut:C(n.word(o+1),"amountOutMinimum")}}function gn(e){let t=X(e,12,"Across depositV3",{dynamicTail:!0}),r=C(t.word(11),"message offset");if(r!==384n)throw new Error("envelope: malformed Across depositV3 message offset");let n=10+Number(r)*2;if(t.hex.length<n+64)throw new Error("envelope: malformed Across depositV3 message");let o=Number(BigInt(`0x${t.hex.slice(n,n+64)}`));if(!Number.isSafeInteger(o))throw new Error("envelope: malformed Across depositV3 message length");let i=Math.ceil(o/32)*64;if(t.hex.length!==n+64+i)throw new Error("envelope: malformed Across depositV3 trailing bytes");return{kind:"action",action:"bridge",depositor:A(t.word(0),"depositor"),recipient:A(t.word(1),"recipient"),inputToken:A(t.word(2),"input token"),outputToken:A(t.word(3),"output token"),amountIn:C(t.word(4),"inputAmount"),minimumOut:C(t.word(5),"outputAmount"),destinationChainId:C(t.word(6),"destinationChainId")}}function En(e){let t=String(e||"").replace(/^0x/i,"").toLowerCase();if(t.length<86||t.length%2!==0)throw new Error("envelope: malformed Uniswap path");let r=`0x${t.slice(0,40)}`,n=`0x${t.slice(t.length-40)}`;if(!/^0x[0-9a-f]{40}$/.test(r)||!/^0x[0-9a-f]{40}$/.test(n))throw new Error("envelope: malformed Uniswap path tokens");return{inputToken:r,outputToken:n}}function pr(e,{hasDeadline:t}){let r=String(e||"").toLowerCase();if(!/^0x[0-9a-f]+$/.test(r)||r.length<74)throw new Error("envelope: malformed exactInput calldata");let n=[];for(let h=10;h+64<=r.length;h+=64)n.push(r.slice(h,h+64));let o=(h,E)=>{if(!n[h])throw new Error(`envelope: malformed ${E}`);return BigInt(`0x${n[h]}`)},i=Number(o(0,"exactInput struct offset"));if(i%32!==0)throw new Error("envelope: malformed exactInput struct offset");let a=i/32,c=Number(o(a,"path offset")),u=n[a+1],s=o(a+(t?3:2),"amountIn"),f=o(a+(t?4:3),"amountOutMinimum"),l=a+c/32;if(!Number.isInteger(l)||!n[l])throw new Error("envelope: malformed exactInput path");let d=Number(o(l,"path length")),m=r.slice(10+(l+1)*64,10+(l+1)*64+d*2),{inputToken:p,outputToken:w}=En(`0x${m}`);return{kind:"action",action:"swap",inputToken:p,outputToken:w,recipient:A(u,"recipient"),amountIn:s,minimumOut:f}}function xn(e){let t=X(e,8,"Aerodrome exactInputSingle");return{kind:"action",action:"swap",inputToken:A(t.word(0),"input token"),outputToken:A(t.word(1),"output token"),recipient:A(t.word(3),"recipient"),amountIn:C(t.word(5),"amountIn"),minimumOut:C(t.word(6),"amountOutMinimum")}}function bn(e){let t=String(e||"").toLowerCase();if(!t.startsWith("0x5ae401dc"))throw new Error("envelope: malformed Uniswap multicall");let r=[];for(let d=10;d+64<=t.length;d+=64)r.push(t.slice(d,d+64));let n=Number(BigInt(`0x${r[1]}`));if(n%32!==0)throw new Error("envelope: malformed multicall data offset");let o=n/32;if(Number(BigInt(`0x${r[o]}`))!==1)throw new Error("envelope: multicall must wrap exactly one swap");let a=Number(BigInt(`0x${r[o+1]}`)),c=o+1+a/32,u=Number(BigInt(`0x${r[c]}`)),f=`0x${t.slice(10+(c+1)*64,10+(c+1)*64+u*2)}`,l=z(f);if(l!=="0x04e45aaf"&&l!=="0x414bf389")throw new Error("envelope: multicall inner call must be exactInputSingle");return gr(f,l==="0x04e45aaf"?"router02-exact-input-single":"swap-router-exact-input-single")}function yn(e,t){let r=z(e),n=hr[r];if(!n)throw new Error("envelope: opaque or unsupported EVM swap/bridge calldata");if(String(t).toLowerCase()!==n.provider)throw new Error("envelope: provider does not match reviewed selector");if(n.layout==="router02-exact-input-single"||n.layout==="swap-router-exact-input-single")return{...gr(e,n.layout),selector:r,provider:n.provider};if(n.layout==="exact-input-deadline")return{...pr(e,{hasDeadline:!0}),selector:r,provider:n.provider};if(n.layout==="exact-input")return{...pr(e,{hasDeadline:!1}),selector:r,provider:n.provider};if(n.layout==="multicall-deadline")return{...bn(e),selector:r,provider:n.provider};if(n.layout==="aerodrome-exact-input-single")return{...xn(e),selector:r,provider:n.provider};if(n.action==="bridge")return{...gn(e),selector:r,provider:n.provider};throw new Error("envelope: unsupported reviewed EVM action")}function Sn(e){let t=X(e,4,"SeaDrop mintPublic");return{kind:"mint",action:"mint",contract:A(t.word(0),"mint NFT contract"),feeRecipient:A(t.word(1),"mint fee recipient"),recipient:A(t.word(2),"mint recipient"),quantity:C(t.word(3),"mint quantity")}}function An(e,t){let r=z(e);if(String(t).toLowerCase()==="nft-mint")return vn(e);let n=pn[r];if(!n)throw new Error("envelope: opaque or unsupported NFT mint calldata");if(String(t).toLowerCase()!==n.provider)throw new Error("envelope: provider does not match reviewed NFT selector");if(n.layout==="seadrop-mint-public")return{...Sn(e),selector:r,provider:n.provider};throw new Error("envelope: unsupported reviewed NFT action")}function vn(e){let t=z(e);if(t==="0x40c10f19")throw new Error("envelope: ambiguous mint(address,uint256) calldata is not a built-in signer surface");let r=mn[t];if(!r)throw new Error("envelope: opaque or unsupported NFT mint calldata");if(r.layout==="mint-no-args")return{kind:"mint",action:"mint",selector:t,provider:"nft-mint",quantity:1n};if(r.layout==="mint-quantity"){let n=X(e,1,"generic NFT mint");return{kind:"mint",action:"mint",selector:t,provider:"nft-mint",quantity:C(n.word(0),"mint quantity")}}throw new Error("envelope: unsupported generic NFT mint calldata")}function ne(e){let t=e?.artifact;if(Array.isArray(t?.transactions))return t.transactions;if(t?.transaction&&typeof t.transaction=="object")return[t.transaction];if(t?.data)return[t];throw new Error("envelope: ordered EVM transaction batch required")}function Er(e,t,r,{nowMs:n=Date.now(),networkFees:o,requireNetworkFees:i=!1}={}){let a=D(e.owner,"owner"),c=e.artifact,u=Number(c?.chainId??ne(e)[0]?.chainId);if(!Number.isSafeInteger(u)||u<=0)throw new Error("envelope: explicit batch chainId required");if(S(u,t.chains,"chain"),c?.owner!==void 0&&D(c.owner,"batch owner")!==a)throw new Error("envelope: explicit batch owner mismatch");let s=ne(e);if(!s.length||s.length>8)throw new Error("envelope: bounded EVM transaction batch required");let f=0n,l=0n,d=0n;for(let m of s){if(!m||typeof m!="object"||Array.isArray(m))throw new Error("envelope: structured EVM transaction required");if(Number(m.chainId)!==u)throw new Error("envelope: every batch leg must use the same chain");if(D(m.from,"transaction owner")!==a)throw new Error("envelope: every batch leg must use the same owner");if(S(z(m.data),t.selectors,"selector"),f+=g(m.value??0,"value"),l+=g(m.gasLimit,"gasLimit"),d+=wr(m),W(u)&&(m.l1FeeWei===void 0||m.operatorFeeWei===void 0))throw new Error("policy: rollup EVM artifacts require l1FeeWei and operatorFeeWei")}if(f>g(t.maxValueWei,"maxValueWei"))throw new Error("policy: aggregate value exceeds cap");if(l>g(t.maxGasLimit,"maxGasLimit"))throw new Error("policy: aggregate gas exceeds cap");if(d>g(t.maxFeeWei,"maxFeeWei"))throw new Error("policy: aggregate fee exceeds cap");return{transactions:s,chainId:u,owner:a,totalValue:f,totalGas:l,totalFee:d}}function xr(e,t,{nowMs:r=Date.now(),routeAttestationSecret:n}={}){let o=String(e?.surface||"");if(o!=="evm-swap"&&o!=="evm-bridge")throw new Error("envelope: strict EVM swap/bridge surface required");let i=fe(e.provider,"provider",64).toLowerCase();S(i,t.providers,"provider");let a=Er(e,t,o,{nowMs:r}),c=[],u=-1;for(let p=0;p<a.transactions.length;p++){let w=a.transactions[p],h=wn(w.data),E;if(h){if(u!==-1)throw new Error("envelope: approval must be before action");if(g(w.value??0,"value")!==0n)throw new Error("envelope: approval cannot transfer native value");let I=D(w.to,"approval token");if(S(I,t.tokens,"token"),S(h.spender,t.spenders,"spender"),h.amount>g(t.maxApproval,"maxApproval"))throw new Error("policy: approval exceeds cap");E={...h,token:I,index:p}}else{if(u!==-1)throw new Error("envelope: exactly one swap/bridge action is supported per batch");S(w.to,t.destinations,"destination"),E={...yn(w.data,i),target:D(w.to,"action target"),index:p},u=p}let L=g(w.value??0,"value"),P=g(w.gasLimit,"gasLimit");c.push({...E,value:L,gas:P,fee:wr(w)})}if(u<0)throw new Error("envelope: reviewed swap/bridge action required");let s=c[u],f=o==="evm-swap"?"swap":"bridge";if(s.action!==f||e.action!==f)throw new Error("envelope: surface/action/calldata mismatch");if(D(e.destination,"destination")!==s.target)throw new Error("envelope: destination must equal decoded action target");if(s.recipient!==a.owner)throw new Error("envelope: decoded recipient must equal owner");if(s.depositor&&s.depositor!==a.owner)throw new Error("envelope: decoded bridge depositor must equal owner");if(S(s.inputToken,t.tokens,"input token"),S(s.outputToken,t.tokens,"output token"),s.amountIn<=0n||s.amountIn>g(t.maxPerTrade,"maxPerTrade"))throw new Error("policy: decoded amount exceeds per-trade cap");if(s.minimumOut<=0n)throw new Error("policy: decoded minimum output must be positive");if(we(e.autoSlippage,{nowMs:r,chainId:a.chainId,venue:i,tx:a.transactions[u],secret:n,requireSigned:!0}),Number(e.slippageBps)!==Number(e.autoSlippage.selectedBps))throw new Error("policy: slippageBps must equal the authenticated quote selectedBps");if(s.minimumOut!==g(e.autoSlippage.minAmountOut,"authenticated quote minAmountOut"))throw new Error("policy: decoded minimum output does not match authenticated quote");if(s.action==="bridge"&&g(e.toChainId,"toChainId")!==s.destinationChainId)throw new Error("envelope: decoded bridge destination chain mismatch");let l=c.filter(p=>p.kind==="approval");if(!new Set([...dn,...Array.isArray(t.nativeInputTokens)?t.nativeInputTokens.map(p=>String(p).toLowerCase()):[]]).has(s.inputToken))throw new Error("envelope: strict local signer swap/bridge requires native input token; use wallet signing for token-unit rails");if(l.length)throw new Error("envelope: native-value action must not include token approval");if(s.value!==s.amountIn)throw new Error("envelope: native value must exactly match decoded amountIn");let m=Object.freeze({quoteAmountOut:g(e.autoSlippage.quoteAmountOut,"authenticated quote amountOut"),minAmountOut:g(e.autoSlippage.minAmountOut,"authenticated quote minAmountOut"),selectedBps:Number(e.autoSlippage.selectedBps),quotedAtMs:Number(e.autoSlippage.quotedAtMs),expiresAtMs:Number(e.autoSlippage.expiresAtMs)});return{...a,decoded:c,action:s,provider:i,authenticatedQuote:m}}function br(e,t,{nowMs:r=Date.now()}={}){if(e?.surface!=="evm-nft")throw new Error("envelope: evm-nft surface required");if(!["mint","nft"].includes(e.action))throw new Error("envelope: evm-nft requires mint action");let n=fe(e.provider||e.artifact?.provider||"opensea-nft","provider",64).toLowerCase();ke(n,t.providers,"provider");let o=e.artifact?.oraclePrepared===!0?e.artifact:e.prepared;o?.oraclePrepared===!0&&$e(o,{nowMs:r,providers:Array.isArray(t.providers)&&t.providers.length?t.providers:null,kinds:["nft-mint"],label:"local-signer"});let i=Er(e,t,"evm-nft",{nowMs:r});if(i.transactions.length!==1)throw new Error("envelope: mint supports exactly one transaction");let a=i.transactions[0],c=z(a.data);S(c,t.selectors,"selector"),S(a.to,t.destinations,"destination");let u=An(a.data,n),s=D(e.contract??e.artifact?.contract,"NFT contract");if(ke(s,t.nftContracts,"NFT contract"),(u.contract||D(a.to,"NFT contract"))!==s)throw new Error("envelope: mint calldata NFT contract mismatch");if(u.recipient&&u.recipient!==i.owner)throw new Error("envelope: mint calldata recipient mismatch");u.feeRecipient&&ke(u.feeRecipient,t.nftFeeRecipients,"mint fee recipient");let l=g(e.quantity??e.artifact?.quantity,"quantity");if(l<=0n||l>g(t.maxMintQuantity??1,"maxMintQuantity"))throw new Error("policy: mint quantity exceeds cap");if(u.quantity!==l)throw new Error("envelope: mint calldata quantity mismatch");let d=g(e.totalWei??e.artifact?.totalWei,"totalWei");if(i.totalValue!==d)throw new Error("envelope: mint value does not match declared totalWei");if((e.priceWei!==void 0||e.artifact?.priceWei!==void 0)&&g(e.priceWei??e.artifact.priceWei,"priceWei")*l!==d)throw new Error("envelope: mint price does not match declared totalWei");if(d>g(t.maxMintTotalWei??t.maxValueWei,"maxMintTotalWei"))throw new Error("policy: mint total exceeds cap");return{...i,provider:n,decoded:[{...u,target:D(a.to,"mint target"),value:i.totalValue,gas:i.totalGas,fee:i.totalFee}]}}function yr(e,{localsWaiver:t=!1}={}){if(!(e in Ne))throw new Error("fee: unknown action");return t?0:Ne[e]}function oe(e,t,{nowMs:r=Date.now(),verifyFeeWaiver:n,routeAttestationSecret:o,networkFees:i,requireNetworkFees:a=!1}={}){if(!e||e.version!==1)throw new Error("envelope: version 1 required");let c=fe(e.surface,"surface",16);if(!mr.has(c))throw new Error("envelope: unsupported public surface");let u=fe(e.action,"action",32);S(c,t.surfaces,"surface"),S(u,t.actions,"action"),S(e.owner,t.owners,"owner"),S(e.destination,t.destinations,"destination");let s=dr(t.maxTtlMs,"maxTtlMs"),f=dr(t.maxSlippageBps,"maxSlippageBps");if(!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=r||e.expiresAtMs-r>s)throw new Error("policy: TTL outside bounds");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>f)throw new Error("policy: slippage exceeds cap");let l=e.artifact;if(!l||typeof l!="object"||Array.isArray(l))throw new Error("envelope: structured artifact required");if(c==="evm-swap"||c==="evm-bridge")xr(e,t,{nowMs:r,routeAttestationSecret:o});else if(c==="evm-nft")br(e,t,{nowMs:r});else if(c==="evm"){if(!["transfer","approve"].includes(u))throw new Error("envelope: generic evm requires transfer or approve; use strict evm-nft for mint action");if(u==="swap"||u==="bridge")throw new Error("envelope: surface/action mismatch; use strict decoded surface");if(String(l.to).toLowerCase()!==String(e.destination).toLowerCase())throw new Error("envelope: destination mismatch");if(String(l.from).toLowerCase()!==String(e.owner).toLowerCase())throw new Error("envelope: artifact from mismatch with owner");ce({...l,slippageBps:e.slippageBps,expiresAtMs:e.expiresAtMs},t,{nowMs:r,networkFees:i,requireNetworkFees:a});let p=String(l.data||"0x").toLowerCase(),w=g(l.value,"EVM value");if(p==="0x"){if(w===0n)throw new Error("envelope: native EVM transfer value required")}else if(j(p)){if(w!==0n)throw new Error("envelope: EVM approval cannot transfer native value")}else throw new Error("envelope: unsupported generic EVM calldata")}else c==="btc"?We(e,t):c==="sol"?Ze(e,t):c==="hl"?tr(e,t):c==="poly"?sr(e,t):c==="lighter"&&fr(e,t);let d=Number(e.fee?.oracleFeeBps)===0&&Ne[u]!==0;if(e.fee?.waiver||d&&!e.fee?.waiverAttestation)throw new Error("fee: verified waiver attestation required");if(d&&(typeof n!="function"||n(e.fee.waiverAttestation,e)!==!0))throw new Error("fee: waiver attestation invalid");let m=yr(u,{localsWaiver:d});if(Number(e.fee?.oracleFeeBps)!==m)throw new Error("fee: final artifact fee mismatch");return!0}var de=Object.freeze([...mr]),In=Object.freeze({...hr});function Tn(e={}){let t={};for(let r of de){let n=e[r];if(n){if(typeof n.simulate!="function"||typeof n.sign!="function"||typeof n.broadcast!="function")throw new Error(`adapter: ${r} requires simulate, sign, and broadcast functions`);t[r]=Object.freeze({simulate:(o,i)=>n.simulate(structuredClone(o),structuredClone(i)),sign:(o,i)=>n.sign(structuredClone(o),structuredClone(i)),broadcast:(o,i,a)=>n.broadcast(o,structuredClone(i),structuredClone(a))})}}return Object.freeze(t)}function kn(e,t){let r=e?.surface||"evm",n=t?.[r];if(!n)throw new Error(`adapter: ${r} is not configured on this self-host`);return n}import{ed25519 as Gi}from"@noble/curves/ed25519.js";import{base58 as Nn}from"@scure/base";import{RawTx as Xi,SigHash as Zi,Transaction as On}from"@scure/btc-signer";import{Transaction as Ln,keccak256 as Sr,verifyTypedData as ea}from"ethers";import{encode as $i}from"@msgpack/msgpack";import{keccak256 as qi,verifyTypedData as Ri}from"ethers";var Di=Object.freeze({name:"Exchange",version:"1",chainId:1337,verifyingContract:"0x0000000000000000000000000000000000000000"}),Ui=Object.freeze({Agent:[{name:"source",type:"string"},{name:"connectionId",type:"bytes32"}]});var Ar=e=>{if(typeof e!="string"||e.length===0||e.length>262144||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e))return null;let t=Buffer.from(e,"base64");return t.toString("base64")===e?t:null};function Bn(e){let t=0,r=0,n=0;for(;n<e.length&&n<3;){let o=e[n++];if(t|=(o&127)<<r,(o&128)===0)return{value:t,offset:n};r+=7}return null}function vr(e,t){try{if(String(e).startsWith("evm"))return Ln.from(t).hash;if(e==="btc"){let r=Ar(t);if(!r)return null;let n=On.fromPSBT(r);return n.finalize(),n.extract(),n.id}if(e==="sol"){let r=Ar(t);if(!r)return null;let n=Bn(r);if(!n||n.value!==1)return null;let o=r.subarray(n.offset,n.offset+64);return o.length===64?Nn.encode(o):null}if(e==="hl"&&typeof t=="string"&&t.startsWith("0x"))return Sr(t);if(e==="poly"&&typeof t=="string"&&t.startsWith("0x"))return Sr(t)}catch{}return null}var Mn=e=>String(e||"").toLowerCase();function J(e){return _n("sha256").update(JSON.stringify(e)).digest("hex")}function me(e,t,r={}){return ce(e,t,r)}async function $n(e,t={}){if(!W(e?.chainId))return{l1FeeWei:"0",operatorFeeWei:"0"};if(typeof t.estimateNetworkFees!="function")throw new Error("policy: rollup fee estimate required");let r=await t.estimateNetworkFees(e);if(!r||r.l1FeeWei===void 0||r.operatorFeeWei===void 0)throw new Error("policy: rollup fee estimate required");return{l1FeeWei:String(r.l1FeeWei),operatorFeeWei:String(r.operatorFeeWei)}}function Tr(e,t,r=!1){if(!W(e?.chainId))return!0;if(e.l1FeeWei===void 0||e.operatorFeeWei===void 0)throw new Error("policy: rollup EVM artifacts require l1FeeWei and operatorFeeWei");if(r||t!=null){if(!t||t.l1FeeWei===void 0||t.operatorFeeWei===void 0)throw new Error("policy: rollup fee estimate required");let n=BigInt(e.l1FeeWei)+BigInt(e.operatorFeeWei),o=BigInt(t.l1FeeWei)+BigInt(t.operatorFeeWei);if(n<o)throw new Error("policy: rollup fee attestation understates estimate")}return!0}function Fn(e,t={}){return renderConfirmationArtifact(e,J(e),t)}var ie=class{#e=new Map;constructor({now:t=Date.now}={}){this.now=t}issue({artifact:t,owner:r,ttlMs:n=6e4}){if(!Number.isFinite(n)||!Number.isInteger(n)||n<=0||n>12e4)throw new Error("confirmation: ttl out of range");let o=Cn(32).toString("hex");return this.#e.set(o,{digest:J(t),owner:Mn(r),expiresAtMs:this.now()+n}),o}consume(t,r){let n=this.#e.get(String(t));if(!n)throw new Error("confirmation: used or unknown nonce");if(n.expiresAtMs<=this.now())throw this.#e.delete(String(t)),new Error("confirmation: expired nonce");let o=Buffer.from(n.digest,"hex"),i=Buffer.from(J(r),"hex");if(!Pn(o,i))throw new Error("confirmation: artifact mismatch");return this.#e.delete(String(t)),n}clear(){this.#e.clear()}};function qn(e){let t=String(e?.data||"0x").toLowerCase(),r=BigInt(e?.value??0);if(t==="0x"){if(r<=0n)throw new Error("signer: native EVM transfer value required");return!0}if(j(t)){if(r!==0n)throw new Error("signer: EVM approval cannot transfer native value");return!0}throw new Error("signer: unsupported EVM calldata; use a versioned envelope")}function Rn(e={},t={}){let r={};for(let n of new Set([...Object.keys(e||{}),...Object.keys(t||{})]))r[n]=(BigInt(t?.[n]??0)-BigInt(e?.[n]??0)).toString();return r}function pe(e,t){let r=String(t||"");if(String(e).startsWith("evm"))return/^0x[0-9a-fA-F]{64}$/.test(r);if(e==="btc")return/^[0-9a-fA-F]{64}$/.test(r);if(e==="sol")try{let n=Ir.decode(r);return n.length===64&&Ir.encode(n)===r}catch{return!1}return e==="hl"?/^0x[0-9a-fA-F]{64}$/.test(r):e==="poly"?/^0x[0-9a-fA-F]{64}$/.test(r):!1}function kr(e,t,r){return!pe(e,t)||!pe(e,r)?!1:e==="sol"?String(t)===String(r):String(t).toLowerCase()===String(r).toLowerCase()}function Dn(e){let t=e?.confirmationMode;if(t!=="exact-human"&&t!=="auto-within-rails")throw new Error("signer: confirmationMode must be exact-human or auto-within-rails");return t}async function Oe({artifact:e,envelope:t,nonce:r,deps:n,policy:o,confirmation:i,consumeNonce:a,nowMs:c}){let u=Dn(o);if(n.autonomous===!0){if(n.env?.ORACLE_AUTONOMOUS_TRADING!=="1")throw new Error("signer: autonomous execution requires ORACLE_AUTONOMOUS_TRADING=1");if(u!=="auto-within-rails")throw new Error("signer: autonomous execution requires auto-within-rails policy");if(typeof n.verifyTriggerAttestation!="function"||await n.verifyTriggerAttestation(t?.triggerAttestation,e,c())!==!0)throw new Error("signer: autonomous trigger attestation required");return i}if(u!=="exact-human")throw new Error("signer: non-autonomous execution requires exact-human exact confirmation policy");if(!n.confirmations)throw new Error("signer: exact-human confirmation store required");if(a)return n.confirmations.consume(r,e);if(!i||!Number.isFinite(i.expiresAtMs)||i.expiresAtMs<=c())throw new Error("confirmation: expired nonce");return i}function Un(e){return e==="evm-swap"||e==="evm-bridge"||e==="evm-nft"}function Wn(e,t){return e&&Un(e.surface)?ne(e):[t]}function Hn(e,t){let r=e?.hash??null,n=e?.transactionHash??null;if(r!=null&&n!=null&&!kr(t,r,n))throw new Error("signer: receipt reports conflicting transaction hashes");return r||n||null}function Jn(e,t){let r=e?.verifiedBefore??e?.before,n=e?.verifiedAfter??e?.after;return{transactionHash:t,status:e?.status,balanceDeltaVerified:!!(e?.verifiedBefore&&e?.verifiedAfter),delta:Rn(r,n)}}async function Le(e,t,r){if(!r.isArmed())throw new Error("signer: disarmed");let n=e?.version===1&&e?.surface?e:null,o=n?n.artifact:(()=>{let{tradeId:h,...E}=e||{};return E})(),i=Wn(n,o),a=typeof r.readPolicy=="function"?r.readPolicy():r.policy,c=()=>typeof r.nowMs=="function"?r.nowMs():r.nowMs??Date.now(),u=await Oe({artifact:e,envelope:n,nonce:t,deps:r,policy:a,confirmation:null,consumeNonce:!0,nowMs:c}),s=J(e),f=(h={})=>{n?oe(n,a,h):(me(o,a,{nowMs:h.nowMs,networkFees:h.networkFees,requireNetworkFees:h.requireNetworkFees}),qn(o))},l=async h=>{let E=n&&!String(n.surface||"").startsWith("evm")?void 0:await $n(h,r);return{nowMs:c(),verifyFeeWaiver:r.verifyFeeWaiver,routeAttestationSecret:r.routeAttestationSecret,networkFees:E,requireNetworkFees:W(h?.chainId)}};f({nowMs:c(),verifyFeeWaiver:r.verifyFeeWaiver,routeAttestationSecret:r.routeAttestationSecret});for(let h of["reserveLedger","validateReservation","commitLedger","releaseLedger","settleFailedLedger"])if(typeof r[h]!="function")throw new Error(`signer: ${h} is required`);let d=r.reserveLedger(n||e,a);if(!d)throw new Error("signer: ledger reservation required");let m=!1,p=[];try{for(let h of i){if(typeof r.simulate!="function"||await r.simulate(h,n)!==!0)throw new Error("signer: strict affirmative simulation required");let E=await l(h);if(Tr(h,E.networkFees,E.requireNetworkFees),!r.isArmed())throw new Error("signer: disarmed before signing");a=typeof r.readPolicy=="function"?r.readPolicy():r.policy,u=await Oe({artifact:e,envelope:n,nonce:t,deps:r,policy:a,confirmation:u,consumeNonce:!1,nowMs:c}),f(E),r.validateReservation(d,a,n&&typeof r.decodeEconomics=="function"?r.decodeEconomics(n,a):void 0),m=!0;let L=await r.sign(h,n);if(typeof r.verifySigned!="function"||await r.verifySigned(L,h,n)!==!0)throw new Error("signer: signed bytes do not match confirmed artifact");if(!r.isArmed())throw new Error("signer: disarmed before broadcast");if(J(e)!==s)throw new Error("signer: artifact mutated after signing");a=typeof r.readPolicy=="function"?r.readPolicy():r.policy,u=await Oe({artifact:e,envelope:n,nonce:t,deps:r,policy:a,confirmation:u,consumeNonce:!1,nowMs:c});let P=await l(h);Tr(h,P.networkFees,P.requireNetworkFees),f(P),r.validateReservation(d,a,n&&typeof r.decodeEconomics=="function"?r.decodeEconomics(n,a):void 0);let I=await r.broadcast(L,h,n),G=I?.status,U=n?.surface||"evm",F=Hn(I,U),Lr=vr(U,L);if(!kr(U,F,Lr))throw new Error("signer: receipt transaction hash does not match signed bytes");if(G===0||G==="0x0")throw pe(U,F)?(r.settleFailedLedger(d),new Error("signer: broadcast did not return a successful receipt")):new Error("signer: failed broadcast requires a valid transaction hash");if(G!==1&&G!=="0x1")throw new Error("signer: broadcast did not return a successful receipt");if(!pe(U,F))throw new Error("signer: successful broadcast requires a valid transaction hash");p.push(Jn(I,F))}}catch(h){throw m||r.releaseLedger(d),h}if(r.commitLedger(d),p.length===1){let h={receipt:p[0]};return n?.surface==="evm-bridge"&&(h.originStatus="success",h.destinationStatus="unverified",h.destinationSuccess=!1,h.note="Origin-chain receipts do not prove destination-chain settlement."),h}let w={receipts:p,status:"success"};return n?.surface==="evm-bridge"&&(w.originStatus="success",w.destinationStatus="unverified",w.destinationSuccess=!1,w.note="Origin-chain receipts do not prove destination-chain settlement."),w}import jn from"node:http";import{timingSafeEqual as Vn}from"node:crypto";var Nr=new Set(["127.0.0.1","::1","localhost"]),zn=(e,t)=>{let r=Buffer.from(String(e)),n=Buffer.from(String(t));return r.length===n.length&&Vn(r,n)},v=(e,t,r)=>{let n=JSON.stringify(r);e.writeHead(t,{"content-type":"application/json","cache-control":"no-store","content-length":Buffer.byteLength(n)}),e.end(n)};function Gn(e){let t=String(e||"");if(t.startsWith("[")){let r=t.indexOf("]");if(r>1)return t.slice(1,r)}return t.split(":")[0]}var Or=e=>new Promise((t,r)=>{let n=0,o=[],i=!1;e.on("data",a=>{n+=a.length,n>64*1024&&!i?(i=!0,r(new Error("request refused")),e.resume()):i||o.push(a)}),e.on("end",()=>{if(!i)try{t(JSON.parse(Buffer.concat(o).toString()||"{}"))}catch{r(new Error("request refused"))}}),e.on("error",r)});function Kn(e={}){let t=e.host||"127.0.0.1";if(!Nr.has(t))throw new Error("signer: loopback bind required");if(String(e.token||"").length<32)throw new Error("signer: strong auth token required");for(let i of["reserveLedger","validateReservation","commitLedger","releaseLedger","settleFailedLedger"])if(typeof e[i]!="function")throw new Error(`signer: ${i} is required`);if(typeof e.disarm!="function")throw new Error("signer: disarm callback is required");let r=e.confirmations||new ie,n=e.origin||`http://${t}`;return jn.createServer(async(i,a)=>{try{let c=String(i.headers.authorization||"").replace(/^Bearer /i,"");if(!zn(c,e.token))return v(a,401,{error:"unauthorized"});let u=Gn(i.headers.host);if(!Nr.has(u))return v(a,403,{error:"host refused"});if(i.headers.origin&&i.headers.origin!==n)return v(a,403,{error:"origin refused"});if(i.method==="GET"&&i.url==="/status"){let s=typeof e.readPolicy=="function"?e.readPolicy():e.policy,f=new Set(de),l=Array.isArray(s?.surfaces)?s.surfaces.filter(d=>typeof d=="string"&&f.has(d)):[];return v(a,200,{ok:!0,service:"oracle-signer",armed:e.isArmed?.()===!0,surfaces:l,sessionExpiresAtMs:e.sessionExpiresAtMs||null})}if(i.method==="POST"&&i.url==="/disarm")return e.disarm(),r.clear(),v(a,200,{ok:!0,armed:!1});if(!["GET","POST"].includes(i.method))return v(a,405,{error:"request refused"});if(i.method==="POST"&&String(i.headers["content-type"]||"").split(";",1)[0].trim().toLowerCase()!=="application/json")return v(a,415,{error:"request refused"});if(i.method==="POST"&&i.url==="/confirm"){if(e.autonomous===!0)return v(a,403,{error:"autonomous signer does not issue human confirmation nonces"});let s=await Or(i),f=J(s.artifact),l=typeof e.readPolicy=="function"?e.readPolicy():e.policy;if(l?.confirmationMode!=="exact-human")return v(a,403,{error:"exact-human policy required"});let d=typeof e.nowMs=="function"?e.nowMs():Date.now();if(s.artifact?.version===1&&s.artifact?.surface)oe(s.artifact,l,{nowMs:d,verifyFeeWaiver:e.verifyFeeWaiver});else{let{tradeId:m,...p}=s.artifact||{};me(p,l,{nowMs:d})}return typeof e.confirmArtifact!="function"?v(a,403,{error:"local human confirmation unavailable"}):await e.confirmArtifact(s.artifact,f,l)!==!0?v(a,400,{error:"exact human confirmation refused"}):v(a,200,{confirmationNonce:r.issue({artifact:s.artifact,owner:s.artifact?.owner??s.artifact?.from,ttlMs:s.ttlMs})})}if(i.method==="POST"&&i.url==="/execute"){let s=await Or(i),f=await Le(s.artifact,s.confirmationNonce,{...e,confirmations:r});return v(a,200,f)}return v(a,404,{error:"not found"})}catch(c){return e.onError?.(String(c?.message||c)),v(a,400,{error:"request refused"})}})}export{ie as ConfirmationStore,de as PUBLIC_SIGNER_SURFACES,In as REVIEWED_EVM_SELECTORS,J as artifactDigest,me as assertExactPolicy,Kn as createSignerServer,Tn as createSurfaceAdapters,ne as evmTransactions,Le as executeConfirmedArtifact,Fn as inspectArtifactForConfirmation,xr as inspectEvmBatch,br as inspectEvmNft,yr as publicFeeBps,kn as surfaceAdapterFor,oe as validateSurfaceEnvelope};
|
|
1
|
+
import{createHash as Mn,randomBytes as Fn,timingSafeEqual as $n}from"node:crypto";import{base58 as Tr}from"@scure/base";import{Interface as pn}from"ethers";import{Interface as zr,MaxUint256 as Gr,isAddress as Kr,keccak256 as Fo,toUtf8Bytes as $o}from"ethers";import{Interface as jr,isAddress as go}from"ethers";import{isAddress as lo}from"ethers";import{createHash as Fr,createHmac as $r,timingSafeEqual as qr}from"node:crypto";import{readFileSync as _r}from"node:fs";import{homedir as Cr}from"node:os";import{join as ae}from"node:path";function Pr(){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){let r=(process.env.ORACLE_EXEC_ENV_FILE||"").trim();return r?[r]:[]}let e=(process.env.ORACLE_EXEC_ENV_FILE||process.env.MAD_EXEC_ENV_FILE||"").trim(),t=Cr();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||ae(t,".config","oracle")).trim();return[e,ae(r,"exec.env")].filter(Boolean)}return[e,ae(t,".config","oracle","exec.env"),ae(t,".config","mad-desk","exec.env")].filter(Boolean)}function Z(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of Pr())try{let i=_r(o,"utf8"),a=i.match(new RegExp(`^${t}=(.*)$`,"m"))||i.match(new RegExp(`^${r}=(.*)$`,"m"));if(a&&(n=a[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}function K(e,t,r="guard"){let n=Number(t);if(t==null||!Number.isFinite(n))throw new Error(`${r}: current time must be a finite number (got ${Mr(t)})`);let o=Number(e?.issuedAtMs),i=Number(e?.expiresAtMs);if(!Number.isFinite(i))throw new Error(`${r}: expiresAtMs is required and must be a finite number`);if(n>i)throw new Error(`${r} expired at ${i}, now ${n}`);if(e?.issuedAtMs!=null){if(!Number.isFinite(o))throw new Error(`${r}: issuedAtMs must be a finite number when present`);if(i<=o)throw new Error(`${r}: expiry must be after issuance`)}return{now:n,issuedAtMs:o,expiresAtMs:i}}function Mr(e){return e===null?"null":e===void 0?"undefined":typeof e=="number"?String(e):`${typeof e} ${JSON.stringify(String(e)).slice(0,24)}`}var Be=100;function he(e){return Array.isArray(e)?`[${e.map(he).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${he(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Rr(e,{required:t=!1}={}){try{return Z(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function Dr(e){let{signature:t,...r}=e;return r}function Ur(e){let t=String(e||"").toLowerCase();if(!/^0x[0-9a-f]+$/.test(t)||t.length<10||t.length%2!==0)throw new Error("auto-slippage calldata must be even-length hex with a selector");return Fr("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function Wr(e,t){let r=Buffer.from(String(e??""),"utf8"),n=Buffer.from(String(t??""),"utf8");return r.length!==n.length||r.length===0?!1:qr(r,n)}function Hr(e){let t=String(e||"");if(!/^0x[0-9a-fA-F]+$/.test(t)||t.length<10||t.length%2!==0)return null;let r=t.slice(0,10).toLowerCase(),n=[];for(let i=10;i+64<=t.length;i+=64)n.push(t.slice(i,i+64));let o=i=>n[i]==null?null:BigInt("0x"+n[i]);switch(r){case"0x414bf389":return o(6);case"0x04e45aaf":return o(5);case"0xc04b8d59":{let i=o(0);if(i==null)return null;let a=Number(i)/32;return!Number.isInteger(a)||a<0?null:o(a+4)}case"0xb858183f":{let i=o(0);if(i==null)return null;let a=Number(i)/32;return!Number.isInteger(a)||a<0?null:o(a+3)}case"0xa026383e":return o(6);case"0x38ed1739":case"0x5c11d795":return o(1);case"0x7ff36ab5":case"0xb6f9de95":return o(0);case"0x18cbafe5":case"0x791ac947":return o(1);default:return null}}function we(e,{nowMs:t=Date.now(),chainId:r,venue:n,secret:o,tx:i,requireSigned:a=!1}={}){if(!e||e.mode!=="auto")throw new Error("bounded auto-slippage guard required");let c=Rr(o,{required:a});if(a&&!c)throw new Error("auto-slippage attestation secret required for signing or broadcast");if(c){let p=$r("sha256",c).update(he(Dr(e))).digest("hex");if(!Wr(e.signature,p))throw new Error("auto-slippage guard signature mismatch \u2014 the guard was not issued by this Oracle")}else if(e.signature)throw new Error("auto-slippage guard carries a signature but no attestation secret is configured");let u=Number(e.selectedBps),s=Number(e.capBps);if(!Number.isInteger(u)||u<0||u>Be)throw new Error("auto-slippage selected tolerance exceeds hard 100 bps cap");if(!Number.isInteger(s)||s<0||s>Be||u>s)throw new Error("auto-slippage cap exceeds hard 100 bps cap");try{K({expiresAtMs:e.expiresAtMs,issuedAtMs:e.quotedAtMs},t,"auto-slippage quote")}catch(p){throw new Error(`${p.message}; re-quote before signing`)}if(r!=null&&Number(e.chainId)!==Number(r))throw new Error("auto-slippage guard chain mismatch");if(n&&String(e.venue).toLowerCase()!==String(n).toLowerCase())throw new Error("auto-slippage guard venue mismatch");let f=BigInt(e.quoteAmountOut??0),l=BigInt(e.minAmountOut??0);if(f<=0n||l<=0n)throw new Error("auto-slippage guard amounts must be positive");let d=f*BigInt(1e4-u),m=d/10000n;if(d%10000n!==0n&&(m+=1n),l<m)throw new Error("auto-slippage guard is under-protected relative to its fresh quote");if(i?.data&&e.minAmountOut!=null){let p=Hr(i.data);if(e.calldataHash!=null){if(String(e.calldataHash)!==Ur(i.data))throw new Error("auto-slippage guard is not bound to this call: calldata hash mismatch");if(p!=null&&p!==BigInt(e.minAmountOut))throw new Error(`auto-slippage guard is hash-bound but the calldata encodes ${p}, not the guard floor ${e.minAmountOut}`)}else{if(p==null){let w=String(i.data).slice(0,10);throw new Error(`auto-slippage: cannot verify the output floor encoded by selector ${w}; refusing rather than trusting unbound calldata at an allowlisted venue`)}if(p!==BigInt(e.minAmountOut))throw new Error(`auto-slippage guard is not bound to this call: guard minAmountOut ${e.minAmountOut} but calldata encodes ${p}`)}}return!0}var yo=new jr(["function approve(address spender,uint256 amount) returns (bool)"]);import{Interface as Vr,isAddress as vo}from"ethers";var No=new Vr(["function approve(address spender,uint256 amount) returns (bool)"]),Oo=Object.freeze({42161:"0x1c3fa76e6e1088bce750f23a5bfcffa1efef6a41",43114:"0x8f550e53dfe96c055d5bdb267c21f268fcaf63b2"});function x(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 T(e,t="value"){if(typeof e!="string"||e==="")throw new Error(`${t} must be a string`);return e}function R(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=x(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 ge(e,t="amount"){let r=R(e,t);if(r<=0n)throw new Error(`${t} must be positive`);return r}function b(e,t,r="amount"){let n=x(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,[a="0",c=""]=i.split(".");if(c.length>t)throw new Error(`${r} has more than ${t} decimal places, which would lose precision`);let u=BigInt((a||"0")+c.padEnd(t,"0"));return o?-u:u}var Ho=new zr(["function approve(address spender,uint256 amount) returns (bool)"]);function _e(e,t){let r=String(e||"").trim();if(!Kr(r))throw new Error(`${t} must be an address`);return r.toLowerCase()}function Yr(e,t="approval amount",{allowZero:r=!1}={}){let n=R(e,t);if(r?n<0n:n<=0n)throw new Error(`${t} must be positive`);if(n>=Gr)throw new Error("unlimited approvals are refused; use an exact bounded amount");return n.toString()}var Ce=new Set(["0x095ea7b3","0x39509351","0x61f49ed6","0xeb5625d9","0xf9255c1f","0x87517c45","0xd505accf","0x8fcbaf0c","0x2b67b570","0x2a2d80d1"]),Xr=new Set(["0x39509351","0xf9255c1f"]);function j(e){let t=String(e||"").toLowerCase();return t.length<10?!1:Ce.has(t.slice(0,10))}function Pe(e){if(!j(e))throw new Error("approval calldata required");let t=String(e||"").toLowerCase(),r=t.slice(0,10),n=t.slice(10).match(/.{1,64}/g)||[],o=s=>n[s]?"0x"+n[s].slice(24):null,i=s=>n[s]?BigInt("0x"+n[s]):null,a=null,c=null,u=null;switch(r){case"0x095ea7b3":case"0x39509351":a=o(0),c=i(1);break;case"0x61f49ed6":case"0xeb5625d9":case"0xf9255c1f":u=o(0),a=o(1),c=i(2);break;case"0xd505accf":a=o(1),c=i(2);break;case"0x8fcbaf0c":{a=o(1),c=i(4)===0n?0n:(1n<<256n)-1n;break}case"0x87517c45":u=o(0),a=o(1),c=i(2);break;default:throw new Error(`approval selector ${r} is recognised but not decodable; refusing to bound it`)}if(a==null||c==null)throw new Error("invalid approve calldata");return{spender:_e(a,"approval spender"),token:u==null?null:_e(u,"approval token"),amount:Yr(c,"approval amount",{allowZero:!0}),selector:r,additive:Xr.has(r)}}import{createHash as Zr,createHmac as Vo,timingSafeEqual as zo}from"node:crypto";var Qr=2,Ee=300*1e3,Me=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})();function et(e){let t=e==null||e===""?Ee:Number(e);return!Number.isFinite(t)||t<0?Ee:Math.min(t,Me)}function xe(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(xe).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${xe(e[r])}`).join(",")}}`}function rt(e){let{prepareHash:t,prepareMac:r,note:n,...o}=e||{};return o}function tt(e){let t=rt(e);return Zr("sha256").update(xe(t)).digest("hex")}function Fe(e,{maxAgeMs:t=Ee,nowMs:r=Date.now(),providers:n=null,kinds:o=null,label:i="operator"}={}){if(!e||typeof e!="object")throw new Error(`${i}: prepared envelope object required`);if(e.oraclePrepared!==!0)throw new Error(`${i}: prepared integrity envelope missing \u2014 use an @oracle-agent/oracle prepare result`);if(Number(e.prepareVersion)!==Qr)throw new Error(`${i}: unsupported prepareVersion ${e.prepareVersion}`);let a=tt(e);if(String(e.prepareHash||"")!==a)throw new Error(`${i}: prepareHash mismatch \u2014 payload was altered after prepare`);let c=Number(e.preparedAt),u=Number(e.expiresAt),s=et(t),f=r-c,l=u-c;if(!Number.isFinite(f)||!Number.isFinite(u)||!Number.isFinite(l)||f<0||l<=0||l>Me||f>s||r>=u)throw new Error(`${i}: prepare envelope expired or clock-skewed (ageMs=${f}, max=${s})`);if(n&&!new Set(n).has(e.provider))throw new Error(`${i}: provider ${e.provider} not allowed here`);if(o&&!new Set(o).has(e.kind))throw new Error(`${i}: kind ${e.kind} not allowed here`);return!0}var se=e=>String(e||"").toLowerCase(),nt=new Set(["chainId","from","to","data","value","gasLimit","gasPrice","maxFeePerGas","maxPriorityFeePerGas","l1FeeWei","operatorFeeWei","nonce","type","accessList","slippageBps","expiresAtMs"]),ot=new Set([10n,8453n,84532n,42161n,421614n,11155420n,7777777n]);function W(e){try{return ot.has(BigInt(e))}catch{return!1}}var _=(e,t)=>{if(e==null||e==="")throw new Error(`policy: ${t} required`);try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`policy: ${t} must be a non-negative integer`)}},$e=(e,t)=>{let r=Number(e);if(!Number.isFinite(r))throw new Error(`policy: ${t} must be finite`);return r},Q=(e,t,r,n=String)=>{if(!Array.isArray(t)||t.length===0)throw new Error(`policy: ${r} allowlist is empty`);if(!t.map(n).includes(n(e)))throw new Error(`policy: ${r} not allowed`)};function ce(e,t,{nowMs:r=Date.now(),networkFees:n,requireNetworkFees:o=!1}={}){if(!e||!t)throw new Error("policy: artifact and policy required");if(Object.keys(e).some(m=>!nt.has(m)))throw new Error("policy: unexpected EVM artifact field");if(e.gasPrice!=null&&(e.maxFeePerGas!=null||e.maxPriorityFeePerGas!=null))throw new Error("policy: ambiguous EVM fee fields");if(e.type!=null&&![0,1,2].includes(Number(e.type)))throw new Error("policy: unsupported EVM transaction type");let i=(m,p)=>{try{return BigInt(m)===BigInt(p)}catch{return String(m)===String(p)}};if(!Array.isArray(t.chains)||t.chains.length===0)throw new Error("policy: chain allowlist is empty");if(!t.chains.some(m=>i(m,e.chainId)))throw new Error("policy: chain not allowed");if(Q(e.to,t.destinations,"destination",se),Q(String(e.data||"0x").slice(0,10),t.selectors,"selector",m=>String(m).toLowerCase()),Q(e.from,t.owners,"owner",se),j(e.data)){let m;try{m=Pe(e.data)}catch(w){throw new Error(`policy: malformed approval calldata: ${w?.message||w}`)}Q(m.spender,t.spenders,"spender",se),Q(m.token||e.to,t.erc20Tokens,"ERC-20 token",se);let p=_(t.maxApproval,"maxApproval");if(BigInt(m.amount)>p)throw new Error("policy: approval exceeds cap");if(m.additive)throw new Error("policy: additive approval cannot be bounded; use approve() with an absolute amount")}if(_(e.value,"value")>_(t.maxValueWei,"maxValueWei"))throw new Error("policy: value exceeds cap");let a=_(e.gasLimit,"gasLimit");if(a>_(t.maxGasLimit,"maxGasLimit"))throw new Error("policy: gas exceeds cap");let c=e.maxFeePerGas??e.gasPrice,u=_(c,"feePerGas")*a,s=0n;try{if(W(e.chainId)&&(e.l1FeeWei===void 0||e.operatorFeeWei===void 0))throw new Error("missing")}catch{throw new Error("policy: rollup EVM artifacts require l1FeeWei and operatorFeeWei")}if(e.l1FeeWei!==void 0&&(s+=_(e.l1FeeWei,"l1FeeWei")),e.operatorFeeWei!==void 0&&(s+=_(e.operatorFeeWei,"operatorFeeWei")),W(e.chainId)&&(o||n!=null)){if(!n||n.l1FeeWei===void 0||n.operatorFeeWei===void 0)throw new Error("policy: rollup fee estimate required");let m=_(n.l1FeeWei,"estimated l1FeeWei")+_(n.operatorFeeWei,"estimated operatorFeeWei");if(s<m)throw new Error("policy: rollup fee attestation understates estimate")}if(u+s>_(t.maxFeeWei,"maxFeeWei"))throw new Error("policy: fee exceeds cap");let l=$e(t.maxSlippageBps,"maxSlippageBps");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>l)throw new Error("policy: slippage attestation exceeds cap");if(!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=r)throw new Error("policy: artifact expired");let d=$e(t.maxTtlMs??12e4,"maxTtlMs");if(d<=0||e.expiresAtMs-r>d)throw new Error("policy: artifact TTL exceeds cap");return!0}import{createHash as qe}from"node:crypto";import{Address as it,NETWORK as at,OutScript as Re,RawTx as st,SigHash as De,TEST_NETWORK as ct,Transaction as ut}from"@scure/btc-signer";var Ue=(e,t)=>{if(e==null||e==="")throw new Error(`policy: ${t} required`);try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`policy: ${t} must be a non-negative integer`)}},lt=(e,t)=>{if(typeof e!="string"||e.length===0||e.length>131072||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e))throw new Error(`envelope: invalid ${t}`);let r=Buffer.from(e,"base64");if(r.toString("base64")!==e)throw new Error(`envelope: invalid ${t}`);return r},ft=e=>Array.isArray(e)||e instanceof Uint8Array?e.length>0:e!=null,dt=e=>/^(bc1|tb1|bcrt1)/i.test(String(e)),V=e=>dt(e)?String(e).toLowerCase():String(e),be=(e,t)=>Array.isArray(t)&&t.some(r=>V(r)===V(e)),pt=(e,t)=>Buffer.from(e||[]).equals(Buffer.from(t||[]));function mt(e){let t=Buffer.from(st.encode(e)),r=qe("sha256").update(t).digest();return Buffer.from(qe("sha256").update(r).digest()).reverse().toString("hex")}function ht(e){if(!e.nonWitnessUtxo)throw new Error("envelope: PSBT input nonWitnessUtxo required");if(mt(e.nonWitnessUtxo)!==Buffer.from(e.txid||[]).toString("hex"))throw new Error("envelope: Bitcoin prevout txid mismatch");let t=e.nonWitnessUtxo.outputs?.[e.index];if(!t)throw new Error("envelope: Bitcoin prevout output missing");if(!e.witnessUtxo)throw new Error("envelope: PSBT input witness UTXO required");if(BigInt(e.witnessUtxo.amount)!==BigInt(t.amount)||!pt(e.witnessUtxo.script,t.script))throw new Error("envelope: Bitcoin witness UTXO mismatch");return t}function wt(e,t){if(e.action!=="transfer")throw new Error("envelope: BTC decoder requires transfer action");let r=e?.artifact;if(Object.keys(r).some(l=>!["network","psbt"].includes(l)))throw new Error("envelope: unexpected BTC artifact field");if(!be(r.network,t.chains))throw new Error("policy: chain not allowed");let n=["bitcoin","mainnet"].includes(String(r.network).toLowerCase())?at:["testnet","signet","regtest"].includes(String(r.network).toLowerCase())?ct:null;if(!n)throw new Error("envelope: unsupported Bitcoin network");let o;try{o=ut.fromPSBT(lt(r.psbt,"PSBT"))}catch(l){throw new Error(`envelope: invalid PSBT: ${l?.message||l}`)}if(o.inputsLength===0||o.outputsLength===0)throw new Error("envelope: PSBT inputs and outputs required");let i=it(n);for(let l=0;l<o.inputsLength;l++){let d=o.getInput(l);for(let w of["partialSig","tapKeySig","tapScriptSig","finalScriptSig","finalScriptWitness"])if(ft(d[w]))throw new Error("envelope: signed or finalized PSBT refused");if(d.sighashType!==void 0&&d.sighashType!==De.DEFAULT&&d.sighashType!==De.ALL)throw new Error("envelope: Bitcoin sighash must bind all inputs and outputs");let m=ht(d),p;try{let w=Re.decode(m.script);if(!["wpkh"].includes(w.type))throw new Error("unsupported input");p=i.encode(w)}catch{throw new Error("envelope: unsupported Bitcoin input script")}if(!be(p,t.owners)||V(p)!==V(e.owner))throw new Error("envelope: Bitcoin input owner mismatch")}let a=new Set([e.owner,...t.changeAddresses||[]].map(l=>V(l))),c=0n,u=!1,s=[];for(let l=0;l<o.outputsLength;l++){let d=o.getOutput(l),m;try{m=i.encode(Re.decode(d.script))}catch{throw new Error("envelope: unsupported Bitcoin output script")}let p=V(m);if(s.push(`${m}:${d.amount}`),p===V(e.destination)){u=!0,c+=d.amount;continue}if(be(m,t.destinations)){c+=d.amount;continue}if(!a.has(p))throw new Error("policy: Bitcoin output destination not allowed")}if(!u)throw new Error("envelope: Bitcoin destination mismatch");let f;try{f=o.fee}catch{throw new Error("envelope: PSBT fee cannot be decoded")}if(f<0n||f>Ue(t.maxFeeSats,"maxFeeSats"))throw new Error("policy: Bitcoin fee exceeds cap");if(c>Ue(t.maxValueSats,"maxValueSats"))throw new Error("policy: Bitcoin value exceeds cap");return Object.freeze({unit:"sats",value:c.toString(),notional:(c+f).toString(),fee:f.toString(),outputs:Object.freeze(s)})}function We(e,t){let{unit:r,value:n,notional:o,fee:i}=wt(e,t);return Object.freeze({unit:r,value:n,notional:o,fee:i})}import{createHash as Se}from"node:crypto";import{base58 as Ge}from"@scure/base";import{getCompiledTransactionMessageDecoder as gt}from"@solana/transaction-messages";var Ae="11111111111111111111111111111111",Et="ComputeBudget111111111111111111111111111111",xt="So11111111111111111111111111111111111111112",Ke="TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";var Ye="ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL",bt=5000n,yt=2039280n,St=37095705934669439343138083508754565189542113879843219016388785533085940283555n,y=57896044618658097711785492504343953926634992332820282019728792003956564819949n,He=19681161376707505956807079304988542015446066515923890162744021073123829784752n,Je=e=>Se("sha256").update(`global:${e}`).digest().subarray(0,8).toString("hex"),At=new Map([[Je("route"),{name:"route",prefixBytes:0}],[Je("shared_accounts_route"),{name:"shared_accounts_route",prefixBytes:1}]]),N=(e,t)=>{if(e==null||e==="")throw new Error(`policy: ${t} required`);try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`policy: ${t} must be a non-negative integer`)}},vt=(e,t)=>{if(typeof e!="string"||e.length===0||e.length>131072||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e))throw new Error(`envelope: invalid ${t}`);let r=Buffer.from(e,"base64");if(r.toString("base64")!==e)throw new Error(`envelope: invalid ${t}`);return r},D=(e,t)=>Array.isArray(t)&&t.some(r=>String(r)===String(e)),C=e=>String(e||""),It=e=>Array.isArray(e.solMints)&&e.solMints.length?e.solMints:e.tokens,le=e=>Se("sha256").update(e).digest("hex");function ue(e,t){try{let r=Buffer.from(Ge.decode(String(e||"")));if(r.length!==32)throw new Error("wrong length");return r}catch{throw new Error(`envelope: invalid Solana ${t}`)}}function k(e){let t=e%y;return t>=0n?t:y+t}function F(e,t){let r=e;for(;t-- >0n;)r=r*r%y;return r}function Tt(e){let r=e*e%y*e%y,n=F(r,2n)*r%y,o=F(n,1n)*e%y,i=F(o,5n)*o%y,a=F(i,10n)*i%y,c=F(a,20n)*a%y,u=F(c,40n)*c%y,s=F(u,80n)*u%y,f=F(s,80n)*u%y,l=F(f,10n)*i%y;return F(l,2n)*e%y}function kt(e,t){let r=k(t*t*t),n=k(r*r*t),o=Tt(e*n),i=k(e*r*o),a=k(t*i*i),c=i,u=k(i*He),s=a===e,f=a===k(-e),l=a===k(-e*He);return s&&(i=c),(f||l)&&(i=u),(k(i)&1n)===1n&&(i=k(-i)),!s&&!f?null:i}function Nt(e){if(!e||e.length!==32)return!1;let t=0n;for(let o=31;o>=0;o--)t=(t<<8n)+BigInt(o===31?e[o]&127:e[o]);let r=k(t*t),n=kt(k(r-1n),k(St*r+1n));return n===null?!1:!(n===0n&&(e[31]&128)!==0)}function Ot(e,t){let r=Buffer.concat([...e,ue(t,"program id"),Buffer.from("ProgramDerivedAddress")]),n=Se("sha256").update(r).digest();if(Nt(n))throw new Error("envelope: derived Solana program address is on curve");return Ge.encode(n)}function ve(e,t,r=Ke){let n=[ue(e,"owner"),ue(r,"token program"),ue(t,"mint")];for(let o=255;o>=0;o--)try{return Ot([...n,Buffer.from([o])],Ye)}catch(i){if(!/on curve/.test(String(i?.message||i)))throw i}throw new Error("envelope: unable to derive associated token account")}function Lt(e,t){return(t.accountIndices||[]).map(r=>C(e.staticAccounts[r]))}function ee(e){return Buffer.from(e.data||[])}function Bt(e,t){return C(e.staticAccounts[t.programAddressIndex])}function Xe(e,t){return Number(t)<e.header.numSignerAccounts}function _t(e,t){let r=e.header.numSignerAccounts,n=e.header.numReadonlySignerAccounts,o=e.header.numReadonlyNonSignerAccounts,i=e.staticAccounts.length;return Number(t)<r?Number(t)<r-n:Number(t)<i-o}function re(e){return e.accountIndices||[]}function ye(e,t){if(!Array.isArray(e)||!e.length)throw new Error(`policy: ${t} allowlist required`);return e.map(String)}function je(e,t){let r=re(t).map(n=>{let o=Xe(e,n)?"s":"n",i=_t(e,n)?"w":"r";return`${n}:${C(e.staticAccounts[n])}:${o}:${i}`});return le(Buffer.from(r.join(`
|
|
2
|
+
`)))}function Ve(e,t,r){if(t+8>e.length)throw new Error(`envelope: malformed Jupiter ${r}`);return e.readBigUInt64LE(t)}function Ct(e,t,r){if(t+2>e.length)throw new Error(`envelope: malformed Jupiter ${r}`);return e.readUInt16LE(t)}function Pt(e,t,r){if(t+4>e.length)throw new Error(`envelope: malformed Jupiter ${r}`);return e.readUInt32LE(t)}function Mt(e,t,r){let n=r.maxJupiterRoutePlanSteps===void 0?1:Number(r.maxJupiterRoutePlanSteps);if(!Number.isSafeInteger(n)||n<1)throw new Error("policy: maxJupiterRoutePlanSteps must be a positive integer");if(t<1||t>n)throw new Error("policy: Jupiter route-plan step count exceeds reviewed cap");let o=Array.isArray(r.jupiterRouteVariants)?r.jupiterRouteVariants.map(Number):[];if(!o.length)throw new Error("policy: Jupiter route variant allowlist required");let i=r.jupiterRouteVariantPayloadBytes||{},a=0,c=0,u=[];for(let s=0;s<t;s++){if(a>=e.length)throw new Error("envelope: opaque or unsupported Jupiter route-plan payload");let f=e[a++];if(!o.includes(f))throw new Error("policy: Jupiter route variant not allowed");if(!Object.hasOwn(i,String(f)))throw new Error("policy: Jupiter route variant payload size required");let l=Number(i[String(f)]);if(!Number.isSafeInteger(l)||l<0||l>16)throw new Error("policy: Jupiter route variant payload size invalid");if(a+l+3>e.length)throw new Error("envelope: opaque or unsupported Jupiter route-plan payload");let d=e.subarray(a,a+l);a+=l;let m=d.toString("hex"),p=r.jupiterRouteVariantPayloads?.[String(f)];if(!Array.isArray(p)||!p.map(String).includes(m))throw new Error("policy: Jupiter route variant payload not allowed");let w=e[a++],h=e[a++],E=e[a++];if(w<1||w>100)throw new Error("envelope: Jupiter route-plan percent invalid");if(h!==s||E!==s+1)throw new Error("envelope: unsupported Jupiter route-plan token index");c+=w,u.push(Object.freeze({swapVariant:f,variantPayloadHex:m,percent:w,inputIndex:h,outputIndex:E}))}if(a!==e.length)throw new Error("envelope: opaque or unsupported Jupiter route-plan payload");if(c!==100*t)throw new Error("envelope: Jupiter route-plan percent total mismatch");return Object.freeze(u)}function Ft(e,t){let r=ee({data:e}),n=r.subarray(0,8).toString("hex"),o=At.get(n);if(!o)throw new Error("envelope: unsupported Jupiter instruction discriminator");let i=19,a=o.prefixBytes===1?r[8]:null;if(o.prefixBytes===1&&r.length<9)throw new Error("envelope: malformed Jupiter shared route payload");let c=8+o.prefixBytes,u=c+4,s=r.length-i;if(s<=u)throw new Error("envelope: malformed Jupiter route payload");let f=Pt(r,c,"route plan length"),l=r.subarray(u,s),d=Mt(l,f,t);return Object.freeze({instruction:o.name,routeId:a,routePlanSteps:f,routePlan:d,routePlanHash:le(l),inAmount:Ve(r,s,"in_amount"),quotedOutAmount:Ve(r,s+8,"quoted_out_amount"),slippageBps:Ct(r,s+16,"slippage_bps"),platformFeeBps:r[s+18],instructionHash:le(r)})}function $t(e,t,r){let n=Lt(e,t),o=(i,a)=>{let c=n[i];if(!c)throw new Error(`envelope: Jupiter ${a} account missing`);return c};if(r.instruction==="route"){if(n.length<9)throw new Error("envelope: Jupiter route account layout incomplete");return{tokenProgram:o(0,"tokenProgram"),userTransferAuthority:o(1,"userTransferAuthority"),userSourceTokenAccount:o(2,"userSourceTokenAccount"),userDestinationTokenAccount:o(3,"userDestinationTokenAccount"),destinationTokenAccount:o(4,"destinationTokenAccount"),destinationMint:o(5,"destinationMint"),platformFeeAccount:o(6,"platformFeeAccount"),eventAuthority:o(7,"eventAuthority"),program:o(8,"program")}}if(r.instruction==="shared_accounts_route"){if(n.length<13)throw new Error("envelope: Jupiter shared route account layout incomplete");return{tokenProgram:o(0,"tokenProgram"),programAuthority:o(1,"programAuthority"),userTransferAuthority:o(2,"userTransferAuthority"),userSourceTokenAccount:o(3,"sourceTokenAccount"),programSourceTokenAccount:o(4,"programSourceTokenAccount"),programDestinationTokenAccount:o(5,"programDestinationTokenAccount"),userDestinationTokenAccount:o(6,"destinationTokenAccount"),sourceMint:o(7,"sourceMint"),destinationMint:o(8,"destinationMint"),platformFeeAccount:o(9,"platformFeeAccount"),token2022Program:o(10,"token2022Program"),eventAuthority:o(11,"eventAuthority"),program:o(12,"program")}}throw new Error("envelope: unsupported Jupiter account layout")}function ze(e,t){return e&&e!==t?e:null}function O(e,t,r){let n=C(e.staticAccounts[t]);if(!n)throw new Error(`envelope: Jupiter ${r} missing`);return n}function qt(e,t){let r=ee(e);if(r.length===5&&r[0]===2){let n=r.readUInt32LE(1),o=t.maxComputeUnits===void 0?14e5:Number(t.maxComputeUnits);if(!Number.isSafeInteger(o)||o<=0)throw new Error("policy: maxComputeUnits must be positive");if(n>o)throw new Error("policy: Jupiter compute unit limit exceeds cap");return 0n}throw r.length===9&&r[0]===3?new Error("policy: Jupiter priority fee not allowed"):new Error("envelope: unsupported Jupiter compute-budget helper")}function Rt(e,t,r,n,o,i){let a=ee(t);if(a.length!==1||a[0]!==1)throw new Error("envelope: unsupported Jupiter ATA helper");let c=re(t);if(c.length!==6)throw new Error("envelope: malformed Jupiter ATA helper");let u=O(e,c[0],"ATA payer"),s=O(e,c[1],"ATA account"),f=O(e,c[2],"ATA owner"),l=O(e,c[3],"ATA mint"),d=O(e,c[4],"ATA system program"),m=O(e,c[5],"ATA token program");if(u!==r.owner)throw new Error("envelope: Jupiter ATA payer must equal owner");if(f!==r.owner)throw new Error("envelope: Jupiter ATA owner must equal owner");if(d!==Ae)throw new Error("envelope: Jupiter ATA system program mismatch");if(m!==o)throw new Error("envelope: Jupiter ATA token program mismatch");if(l!==n.inputMint&&l!==n.outputMint)throw new Error("envelope: Jupiter ATA mint mismatch");if(s!==ve(r.owner,l,o))throw new Error("envelope: Jupiter ATA account mismatch");return{ata:s,debit:i}}function Dt(e,t,r,n,o){let i=re(t),a=ee(t);if(i.length!==2||a.length!==12||a.readUInt32LE(0)!==2)throw new Error("envelope: unsupported Jupiter system helper");let c=O(e,i[0],"wrap payer"),u=O(e,i[1],"wrap target"),s=a.readBigUInt64LE(4);if(c!==r.owner||u!==n)throw new Error("envelope: unsupported Jupiter wrap transfer");if(s!==o)throw new Error("envelope: Jupiter wrap transfer amount mismatch");return s}function Ut(e,t,r,n){let o=re(t),i=ee(t);if(i.length!==1)throw new Error("envelope: unsupported Jupiter token helper");if(i[0]===17){if(o.length!==1||O(e,o[0],"syncNative account")!==n)throw new Error("envelope: Jupiter syncNative account mismatch");return{kind:"syncNative"}}if(i[0]===9){if(o.length!==3)throw new Error("envelope: malformed Jupiter closeAccount helper");let a=O(e,o[0],"closeAccount source"),c=O(e,o[1],"closeAccount destination"),u=O(e,o[2],"closeAccount authority");if(a!==n||c!==r.owner||u!==r.owner)throw new Error("envelope: Jupiter closeAccount must return to owner");return{kind:"closeAccount"}}throw new Error("envelope: unsupported Jupiter token helper")}function Wt(e,t,r,n,o,i,a){let c=ve(t.owner,t.artifact.inputMint,a);if(o.userSourceTokenAccount!==c)throw new Error("envelope: Jupiter source token account is not owner ATA");let u=N(r.jupiterAtaRentLamports,"jupiterAtaRentLamports");if(u<yt)throw new Error("policy: Jupiter ATA rent below the token-account rent-exempt minimum");let s=new Map,f=0n,l=!1,d=!1;for(let m of e.instructions){if(m===n)continue;let p=Bt(e,m);if(p===Et)qt(m,r);else if(p===Ye){let{ata:w,debit:h}=Rt(e,m,t,t.artifact,a,u);s.set(w,h)}else if(p===Ae)f+=Dt(e,m,t,c,i);else if(p===a){let w=Ut(e,m,t,c);w.kind==="syncNative"&&(l=!0),w.kind==="closeAccount"&&(d=!0)}else throw new Error("envelope: unsupported Jupiter helper instruction")}if(f>0n&&(!l||!d))throw new Error("envelope: Jupiter native wrap helpers incomplete");if(f!==0n&&f!==i)throw new Error("envelope: Jupiter native wrap amount mismatch");return[...s.values()].reduce((m,p)=>m+p,0n)}function Ht(e){let t;try{t=gt().decode(vt(e.messageBase64,"Solana message"))}catch(r){throw new Error(`envelope: invalid Solana message: ${r?.message||r}`)}if(t.version!=="legacy"&&Array.isArray(t.addressTableLookups)&&t.addressTableLookups.length)throw new Error("envelope: unresolved Solana address tables refused");return t}function Jt(e,t,r){if(e.header.numSignerAccounts!==1||C(e.staticAccounts[0])!==t.owner||!D(t.owner,r.owners))throw new Error("envelope: Solana owner mismatch");if(!Array.isArray(e.instructions)||e.instructions.length===0)throw new Error("envelope: Solana instructions required");let n=[];for(let o of e.instructions){let i=C(e.staticAccounts[o.programAddressIndex]);if(!i||!D(i,r.programs))throw new Error("policy: Solana program not allowed");n.push(i)}return n}function jt(e,t,r){let n=N(r.lamportsPerSignature,"lamportsPerSignature");if(n<bt)throw new Error("policy: Solana per-signature fee is below the network minimum");let o=r.maxLamportsPerSignature===void 0?n:N(r.maxLamportsPerSignature,"maxLamportsPerSignature");if(n>o)throw new Error("policy: Solana per-signature fee exceeds cap");let i=BigInt(e.header.numSignerAccounts),a=i*n,c=i*o;if(t.exactFeeLamports!==void 0){let s=N(t.exactFeeLamports,"exactFeeLamports");if(s<a)throw new Error("policy: Solana exact fee below the base signature fee");if(s>c)throw new Error("policy: Solana exact fee exceeds the per-signature bound")}let u=c;if(u>N(r.maxFeeLamports,"maxFeeLamports"))throw new Error("policy: Solana fee exceeds cap");return u}function Vt(e,t,r,n){let o=0n,i=!1;for(let a of e.instructions){if(C(e.staticAccounts[a.programAddressIndex])!==Ae)throw new Error("envelope: unsupported Solana program decoder");let u=a.accountIndices||[];if(u.length!==2||C(e.staticAccounts[u[0]])!==t.owner)throw new Error("envelope: Solana transfer owner mismatch");let s=C(e.staticAccounts[u[1]]);if(s!==t.destination||!D(s,r.destinations))throw new Error("envelope: Solana destination mismatch");let f=Buffer.from(a.data||[]);if(f.length!==12||f.readUInt32LE(0)!==2)throw new Error("envelope: unsupported Solana system instruction");o+=f.readBigUInt64LE(4),i=!0}if(!i)throw new Error("envelope: Solana destination mismatch");if(o>N(r.maxValueLamports,"maxValueLamports"))throw new Error("policy: Solana value exceeds cap");return{value:o,programs:n}}function zt(e,t,r,n){let o=t.artifact;if(o.provider!=="jupiter")throw new Error("envelope: Solana swap provider must be jupiter");if(o.inputMint!==xt)throw new Error("envelope: Jupiter local signer requires native SOL input");if(o.outputMint!==t.destination||!D(o.outputMint,r.destinations))throw new Error("envelope: Jupiter output mint destination mismatch");let i=It(r);if(!D(o.inputMint,i)||!D(o.outputMint,i))throw new Error("policy: Solana token not allowed");let a=N(o.inAmount,"inAmount"),c=N(o.outAmount,"outAmount"),u=N(o.otherAmountThreshold,"otherAmountThreshold");if(a<=0n||a>N(r.maxPerTradeLamports,"maxPerTradeLamports"))throw new Error("policy: Solana swap amount exceeds per-trade cap");if(a>N(r.maxValueLamports,"maxValueLamports"))throw new Error("policy: Solana value exceeds cap");if(c<=0n||u<=0n||u>c)throw new Error("envelope: Jupiter quote floor invalid");if(Number(o.slippageBps)!==Number(t.slippageBps))throw new Error("policy: Solana slippage mismatch");let s=C(o.jupiterProgram);if(!s||!D(s,r.programs)||!n.includes(s))throw new Error("policy: Jupiter program not allowed or absent");let f=e.instructions.filter(q=>C(e.staticAccounts[q.programAddressIndex])===s);if(f.length!==1)throw new Error("envelope: exactly one Jupiter swap instruction required");let l=f[0],d=Ft(l.data,r);if(d.instruction==="shared_accounts_route"){let q=Array.isArray(r.jupiterSharedRouteIds)?r.jupiterSharedRouteIds.map(Number):[];if(!q.length)throw new Error("policy: Jupiter shared route id allowlist required");if(!q.includes(Number(d.routeId)))throw new Error("policy: Jupiter shared route id not allowed")}else if(d.routeId!=null)throw new Error("envelope: unexpected Jupiter shared route id");if(!ye(r.jupiterRoutePlanHashes,"Jupiter route-plan hash").includes(d.routePlanHash))throw new Error("policy: Jupiter route-plan hash not allowed");if(d.inAmount!==a)throw new Error("envelope: Jupiter route in_amount mismatch");if(d.quotedOutAmount!==c)throw new Error("envelope: Jupiter route quoted_out_amount mismatch");if(d.slippageBps!==Number(o.slippageBps))throw new Error("envelope: Jupiter route slippage mismatch");let m=d.quotedOutAmount-d.quotedOutAmount*BigInt(d.slippageBps)/10000n;if(u!==m)throw new Error("envelope: Jupiter otherAmountThreshold does not match serialized min-out");if(d.platformFeeBps!==0)throw new Error("policy: Jupiter platform fee not allowed");let p=$t(e,l,d),w=re(l),h=d.instruction==="shared_accounts_route"?2:1;if(!Xe(e,w[h]))throw new Error("envelope: Jupiter transfer authority must be signer");if(p.program!==s)throw new Error("envelope: Jupiter program account mismatch");if(p.userTransferAuthority!==t.owner)throw new Error("envelope: Jupiter transfer authority must equal owner");if(p.destinationMint!==o.outputMint)throw new Error("envelope: Jupiter destination mint mismatch");if(p.sourceMint!==void 0&&p.sourceMint!==o.inputMint)throw new Error("envelope: Jupiter source mint mismatch");let E=Array.isArray(r.tokenPrograms)&&r.tokenPrograms.length?r.tokenPrograms:[Ke];if(!D(p.tokenProgram,E))throw new Error("policy: Solana token program not allowed");let B=ve(t.owner,o.outputMint,p.tokenProgram);if(p.userDestinationTokenAccount!==B)throw new Error("envelope: Jupiter destination token account is not owner ATA");let M=ze(p.destinationTokenAccount,s);if(M&&M!==B)throw new Error("envelope: Jupiter optional destination account redirects proceeds");if(ze(p.platformFeeAccount,s))throw new Error("policy: Jupiter platform fee account not allowed");if(!ye(r.jupiterRouteAccountHashes,"Jupiter route account hash").includes(je(e,l)))throw new Error("policy: Jupiter route account hash not allowed");let I=le(Buffer.from([d.instruction,d.routeId??"",d.routePlanHash,je(e,l)].join(`
|
|
3
|
+
`)));if(!ye(r.jupiterRouteReviewHashes,"Jupiter route review hash").includes(I))throw new Error("policy: Jupiter route review hash not allowed");let G=Wt(e,t,r,l,p,a,p.tokenProgram),U=a+G;if(U>N(r.maxValueLamports,"maxValueLamports"))throw new Error("policy: Solana value exceeds cap");return{value:U,programs:n}}function Gt(e,t){if(e.action!=="transfer"&&e.action!=="swap")throw new Error("envelope: Solana decoder requires transfer or swap action");let r=e?.artifact,n=e.action==="transfer"?["cluster","messageBase64","exactFeeLamports"]:["cluster","provider","messageBase64","exactFeeLamports","inputMint","outputMint","inAmount","outAmount","otherAmountThreshold","slippageBps","jupiterProgram"];if(Object.keys(r||{}).some(u=>!n.includes(u)))throw new Error("envelope: unexpected Solana artifact field");if(!D(r.cluster,t.chains))throw new Error("policy: chain not allowed");let o=Ht(r),i=Jt(o,e,t),a=e.action==="transfer"?Vt(o,e,t,i):zt(o,e,t,i),c=jt(o,r,t);return Object.freeze({unit:"lamports",value:a.value.toString(),notional:(a.value+c).toString(),fee:c.toString(),programs:Object.freeze(a.programs)})}function Ze(e,t){let{unit:r,value:n,notional:o,fee:i}=Gt(e,t);return Object.freeze({unit:r,value:n,notional:o,fee:i})}var Kt=1e8;function Ie(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=Kt+t;return Number.isSafeInteger(o)?{encoding:t,outcome:n,side:r,coin:`#${t}`,assetId:o}:null}var Yt=new Set(["https://api.hyperliquid.xyz/exchange","https://api.hyperliquid-testnet.xyz/exchange"]),Xt=new Set(["perp-order","hip3-order","hip4-order","perp-bracket"]),Zt=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"}),Qt=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"}),H=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`hl: bounded ${t} required`);return e};function en(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 Qe(e,t){let r=x(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 $(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=>$(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)}:${$(e[n],t)}`).join(",")}}`}function rn(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)||$(r,"declared order type")!==$({limit:{tif:i}},"expected order type"))throw new Error("hl: limit order type must match its wire shape");return}if(t==="market"){if($(r,"declared order type")!==$({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||$(r,"declared order type")!==$({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 tn(e,t,r){let n=Qe(e.s,"signed size"),o=Qe(e.p,"signed price"),i=n.decimals+o.decimals,a=n.raw*o.raw,c=b(t.notionalUsd,i,"hl: notionalUsd");if(c<=0n||a!==c)throw new Error("hl: signed notional must match");let u=b(r.maxNotionalUsd,i,"hl: maxNotionalUsd");if(a>u)throw new Error("hl: notional exceeds cap")}function nn(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=H(r.b,"order builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(n))throw new Error("hl: order builder address required");if(T(e.builder||"","hl: builder").toLowerCase()!==n)throw new Error("hl: signed order builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(c=>String(c).toLowerCase()):[]).includes(n))throw new Error("hl: order builder not allowed");let i=R(r.f,"hl: signed order builder fee");if(i<0n)throw new Error("hl: signed order builder fee must be non-negative");let a=b(t.maxBuilderFeeBps??0,1,"hl: maxBuilderFeeBps");if(i>a)throw new Error("hl: order builder fee exceeds cap")}function er(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(x(e.s,"hl: signed size")!==x(t.size,"hl: size"))throw new Error("hl: signed size must match");if(x(e.p,"hl: signed price")!==x(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($(e.t,"signed order type")!==$(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 rr(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(x(e.s,"hl: bracket protection size")!==x(t.size,"hl: size"))throw new Error("hl: bracket protection size must match");if(x(e.p,"hl: bracket protection price")!==x(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(x(i.triggerPx,"hl: triggerPx")!==x(n,"hl: protection price"))throw new Error("hl: bracket protection trigger must match")}function on(e){let t=String(e||"").replace(/\/$/,"");if(!Yt.has(t))throw new Error("hl: submitTo must be the official Hyperliquid exchange");return t}function Te(e){return Ie(e)!=null}function an(e,t){let r=String(e||""),n=Array.isArray(t.coins)?t.coins.map(String):[];if(Te(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 sn(e,t,r){let n=Array.isArray(r.hlMarkets)?r.hlMarkets:[];if(n.length){if(!n.some(a=>{if(typeof a=="string"){let[c,u]=String(a).split(":");return c===e&&Number(u)===t}return String(a?.coin)===e&&Number(a?.assetId)===t}))throw new Error("hl: coin/assetId pair not allowed");return!0}if(Te(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 tr(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=H(r.kind,"kind",48),o=Zt[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=on(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 a=Number(r.nonce);if(!Number.isSafeInteger(a)||a<=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!==Qt[n])throw new Error("hl: action type must match kind");let c=r.notionalUsd??0;if(Xt.has(n)||n==="perp-cancel"||n==="perp-leverage"||n==="perp-isolated-margin"){let u=H(r.coin,"coin",64),s=r.assetId??r.assetIndex;if(!Number.isSafeInteger(s)||s<0)throw new Error("hl: assetId required");if(n==="hip4-order"||s>=1e8){let f=Ie(u);if(!f||f.coin!==u)throw new Error("hl: HIP-4 actions must use a canonical outcome coin");if(f.assetId!==s)throw new Error("hl: HIP-4 coin must bind to its canonical assetId")}if(an(u,t),sn(u,s,t),n==="hip4-order"&&!Te(u))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");rn(r);let f=r.action.orders;if(n==="perp-bracket"){let l=r.takeProfitPx,d=r.stopLossPx,m=1+(l==null?0:1)+(d==null?0:1);if(m<2||f.length!==m||r.grouping!=="normalTpsl"||r.action.grouping!==r.grouping)throw new Error("hl: bracket must contain exactly the declared entry and protection legs");er(f[0],r,s);let p=1;l!=null&&rr(f[p++],r,s,l,"tp"),d!=null&&rr(f[p],r,s,d,"sl")}else{if(f.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");er(f[0],r,s)}tn(f[0],r,t),nn(r,t),c=x(r.notionalUsd,"hl: notionalUsd")}if(n==="perp-leverage"){let f=r.leverage;if(!Number.isSafeInteger(f)||f<1)throw new Error("hl: leverage must be a positive integer");let l=t.maxLeverage==null?50:t.maxLeverage;if(typeof l!="number"||!Number.isSafeInteger(l)||l<1)throw new Error("hl: maxLeverage must be a positive integer");if(f>l)throw new Error("hl: leverage exceeds cap")}if(n==="perp-cancel"){let f=r.action.cancels;if(!Array.isArray(f)||f.length!==1)throw new Error("hl: exactly one cancel is required");if(!Number.isSafeInteger(f[0].a)||f[0].a!==s)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(f[0].o)||f[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!==s)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 f=r.marginMode==="cross";if(typeof r.action.isCross!="boolean"||r.action.isCross!==f)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!==s)throw new Error("hl: signed margin asset must match assetId");let f=H(r.usd,"margin usd",64),l=b(f,6,"hl: margin usd");if(R(r.action.ntli,"hl: signed margin ntli")!==l)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 m=b(t.maxNotionalUsd,6,"hl: maxNotionalUsd"),p=l<0n?-l:l;if(p>m)throw new Error("hl: margin notional exceeds cap");c=en(p,6)}}if(n==="builder-fee-approval"){let u=H(r.builder,"builder",42).toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(u))throw new Error("hl: builder address required");if(H(r.action.builder,"signed builder",42).toLowerCase()!==u)throw new Error("hl: signed builder must match");if(!(Array.isArray(t.hlBuilders)?t.hlBuilders.map(p=>String(p).toLowerCase()):[]).includes(u))throw new Error("hl: builder not allowed");let f=H(r.maxFeeRate,"maxFeeRate",32);if(H(r.action.maxFeeRate,"signed maxFeeRate",32)!==f)throw new Error("hl: signed builder fee must match");if(!/^\d+(?:\.\d+)?%$/.test(f))throw new Error("hl: builder fee rate must be a percent");let l=b(f.slice(0,-1),12,"hl: builder fee percent"),d=b(t.maxBuilderFeeBps,12,"hl: maxBuilderFeeBps");if(d<0n||l*100n>d)throw new Error("hl: builder fee exceeds cap");if(Number(r.action.nonce)!==a)throw new Error("hl: signed builder nonce must match");let m=i.includes("testnet")?"Testnet":"Mainnet";if(r.hyperliquidChain!==m||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 u=n==="hype-undelegate";if(typeof r.action.isUndelegate!="boolean"||r.action.isUndelegate!==u)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(c??r.action.wei??0),notional:String(c??0),fee:"0",kind:n,actionType:r.action.type,amount:String(r.action.wei??c??0),coin:r.coin||null,submitTo:i})}var bi="0x"+"00".repeat(32);function nr(e,t){let r=BigInt(x(e.makerAmount,"poly: makerAmount")),n=BigInt(x(e.takerAmount,"poly: takerAmount"));if(r<=0n||n<=0n)throw new Error("poly: order amounts must be positive integer micro-units");return Number(t==="BUY"?r:n)/1e6}var cn=new Set(["https://clob.polymarket.com/order"]),te=Object.freeze([["salt","uint256"],["maker","address"],["signer","address"],["tokenId","uint256"],["makerAmount","uint256"],["takerAmount","uint256"],["side","uint8"],["signatureType","uint8"],["timestamp","uint256"],["metadata","bytes32"],["builder","bytes32"]]),vi=Object.freeze(te.map(e=>e[0])),un=new Set(["0xe111180000d2663c0091e4f400237545b87b996b","0xe2222d279d744050d28e00520010520000310f59"]),ln="0xe111180000d2663c0091e4f400237545b87b996b",fn="0xe2222d279d744050d28e00520010520000310f59",or=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`poly: bounded ${t} required`);return e};function ir(e){let t=String(e||"").replace(/\/$/,"");if(!cn.has(t))throw new Error("poly: submitTo must be the official Polymarket CLOB");return t}function ar(e){let t=T(e,"poly: exchange").toLowerCase();if(!un.has(t))throw new Error("poly: verifyingContract must be an official CTF Exchange");return t}function sr(e,t){if(e?.surface!=="poly")throw new Error("poly: surface poly required");let r=e.artifact;if(!r||typeof r!="object"||Array.isArray(r))throw new Error("poly: structured artifact required");let n=or(r.kind,"kind",48);if(n!=="poly-order")throw new Error("poly: unsupported Polymarket kind");if(e.action!=="order")throw new Error("poly: surface/action/kind mismatch");if(T(e.destination,"poly: destination").toLowerCase()!=="polymarket")throw new Error("poly: destination must be polymarket");if(ir(r.submitTo),r.chainId!==137)throw new Error("poly: chainId must be Polygon 137");let o=r.domain;if(!o||typeof o!="object")throw new Error("poly: EIP-712 domain required");if(o.name!=="Polymarket CTF Exchange"||o.version!=="2"||o.chainId!==137)throw new Error("poly: EIP-712 domain must be official CTF Exchange v2 on Polygon");if(ar(o.verifyingContract),ar(r.exchange),T(o.verifyingContract,"poly: verifyingContract").toLowerCase()!==T(r.exchange,"poly: exchange").toLowerCase())throw new Error("poly: exchange/domain mismatch");if(typeof r.negRisk!="boolean")throw new Error("poly: negRisk must be a boolean");let i=r.negRisk?fn:ln;if(T(r.exchange,"poly: exchange").toLowerCase()!==i)throw new Error("poly: negRisk/exchange mismatch");let a=r.message||r.value;if(!a||typeof a!="object")throw new Error("poly: signed order message required");let c=r.types?.Order;if(!Array.isArray(c)||c.length!==te.length)throw new Error("poly: EIP-712 Order type must be official CLOB v2");for(let h=0;h<te.length;h+=1)if(c[h]?.name!==te[h][0]||c[h]?.type!==te[h][1])throw new Error("poly: EIP-712 Order type must be official CLOB v2");if((r.orderType||"GTC")!=="GTC")throw new Error("poly: only GTC is public");let u=String(e.owner||"").toLowerCase();if(T(a.maker,"poly: maker").toLowerCase()!==u)throw new Error("poly: maker must equal owner");if(T(a.signer,"poly: signer").toLowerCase()!==u)throw new Error("poly: signer must equal owner");if(a.signatureType!==0)throw new Error("poly: only EOA signatureType 0 is public");if(typeof a.builder!="string"||a.builder.toLowerCase()!==`0x${"00".repeat(32)}`)throw new Error("poly: builder must be zero");if(a.side!==0&&a.side!==1)throw new Error("poly: side must be BUY or SELL");let s=or(r.tokenId,"tokenId",80);if(T(a.tokenId,"poly: tokenId")!==s)throw new Error("poly: tokenId mismatch");let f=Array.isArray(t.polyTokens)?t.polyTokens.map(String):[];if(f.length&&!f.includes(s)&&!f.includes("*"))throw new Error("poly: tokenId not allowed");let l=Number(a.side)===0?"BUY":"SELL";if(r.side&&r.side!==l)throw new Error("poly: side mismatch");let d=nr(a,l),m=b(r.notionalUsdc,6,"poly: notionalUsdc"),p=b(d,6,"poly: computed notional");if(m!==p)throw new Error("poly: notionalUsdc must match CLOB v2 amounts");let w=t.maxNotionalUsd??t.maxNotionalUsdc;if(w!=null){let h=b(w,6,"poly: maxNotionalUsd");if(p>h)throw new Error("poly: notional exceeds cap")}return Object.freeze({unit:"usdc",value:String(d),notional:String(d),fee:"0",kind:n,tokenId:s,side:l,submitTo:ir(r.submitTo)})}var dn=new Set(["https://mainnet.zklighter.elliot.ai/api/v1/sendTx","https://testnet.zklighter.elliot.ai/api/v1/sendTx"]),ur=14,cr=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`lighter: bounded ${t} required`);return e};function Y(e,t,r){if(!Number.isSafeInteger(e)||e!==t)throw new Error(`lighter: ${r} must be exact numeric ${t}`)}function lr(e){let t=String(e||"").replace(/\/$/,"");if(!dn.has(t))throw new Error("lighter: submitTo must be the official Lighter sendTx");return t}function fr(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=cr(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=lr(r.submitTo),i=r.marketIndex;if(typeof i!="number"||!Number.isSafeInteger(i)||i<0)throw new Error("lighter: marketIndex required");let a=Number(R(r.accountIndex,"lighter: accountIndex"));if(!Number.isSafeInteger(a)||a<0)throw new Error("lighter: accountIndex required");let c=Number(R(r.clientOrderIndex,"lighter: clientOrderIndex"));if(!Number.isSafeInteger(c)||c<0)throw new Error("lighter: clientOrderIndex required");Y(r.orderType,0,"orderType"),Y(r.timeInForce,1,"timeInForce"),Y(r.reduceOnly,0,"reduceOnly"),Y(r.triggerPrice,0,"triggerPrice"),Y(r.orderExpiry,-1,"orderExpiry");let u=cr(r.symbol||r.coin,"symbol",32),s=Array.isArray(t.lighterMarkets)?t.lighterMarkets.map(String):[];if(s.length&&!s.includes(u)&&!s.includes(String(i))&&!s.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 f=ge(r.baseAmount,"lighter: baseAmount"),l=ge(r.price,"lighter: price");if(f>BigInt(Number.MAX_SAFE_INTEGER)||l>BigInt(Number.MAX_SAFE_INTEGER))throw new Error("lighter: baseAmount and price must be safe integers");let d=Number(f),m=Number(l),p=Number(r.sizeDecimals??0),w=Number(r.priceDecimals??0);if(!Number.isInteger(p)||p<0||p>12)throw new Error("lighter: sizeDecimals required");if(!Number.isInteger(w)||w<0||w>12)throw new Error("lighter: priceDecimals required");let h=p+w,E=f*l,B=b(r.notionalUsd,h,"lighter: notionalUsd");if(B<=0n)throw new Error("lighter: notionalUsd required");if(E!==B)throw new Error("lighter: notionalUsd must match size and price");let M=b(t.maxNotionalUsd??Number.MAX_SAFE_INTEGER,h,"lighter: maxNotionalUsd");if(E>M)throw new Error("lighter: notional exceeds cap");let I=x(r.notionalUsd,"lighter: notionalUsd");return Y(r.txType,ur,"txType"),Object.freeze({unit:"usd",value:String(I),notional:String(I),fee:"0",kind:n,symbol:u,marketIndex:i,side:r.side,baseAmount:d,price:m,submitTo:o,actionType:"create-order",amount:String(I)})}var hr=new Set(["evm","evm-swap","evm-bridge","evm-nft","btc","sol","hl","poly","lighter"]);var Ne=Object.freeze({swap:5,bridge:5,perps:0,nft:0,mint:0,transfer:0,approve:0,order:0,cancel:0,leverage:0,margin:0,approveBuilder:0,stake:0,unstake:0,delegate:0}),mn=new Set(["0x0000000000000000000000000000000000000000","0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"]),wr=Object.freeze({"0x04e45aaf":{provider:"uniswap-v3",action:"swap",layout:"router02-exact-input-single"},"0x414bf389":{provider:"uniswap-v3",action:"swap",layout:"swap-router-exact-input-single"},"0xc04b8d59":{provider:"uniswap-v3",action:"swap",layout:"exact-input-deadline"},"0xb858183f":{provider:"uniswap-v3",action:"swap",layout:"exact-input"},"0x5ae401dc":{provider:"uniswap-v3",action:"swap",layout:"multicall-deadline"},"0xa026383e":{provider:"aerodrome",action:"swap",layout:"aerodrome-exact-input-single"},"0x7b939232":{provider:"across-v3",action:"bridge",layout:"across-deposit-v3"}}),hn=Object.freeze({"0x161ac21f":{provider:"opensea-nft",action:"mint",layout:"seadrop-mint-public"},"0xc2f6663a":{provider:"opensea-nft",action:"mint",layout:"seadrop-mint-allowlist"}}),dr=new pn(["function mintAllowList(address nftContract,address feeRecipient,address minterIfNotPayer,uint256 quantity,(uint80 mintPrice,uint48 maxTotalMintableByWallet,uint48 startTime,uint48 endTime,uint48 dropStageIndex,uint32 maxTokenSupplyForStage,uint16 feeBps,bool restrictFeeRecipients) mintParams,bytes32[] proof) payable"]),wn=Object.freeze({"0xa0712d68":{provider:"nft-mint",action:"mint",layout:"mint-quantity"},"0x1249c58b":{provider:"nft-mint",action:"mint",layout:"mint-no-args"},"0x2db11544":{provider:"nft-mint",action:"mint",layout:"mint-quantity"},"0xefef39a1":{provider:"nft-mint",action:"mint",layout:"mint-quantity"},"0xa6f2ae3a":{provider:"nft-mint",action:"mint",layout:"mint-no-args"}});var fe=(e,t,r=256)=>{if(typeof e!="string"||!e||e.length>r)throw new Error(`envelope: bounded ${t} required`);return e},g=(e,t)=>{try{let r=BigInt(e);if(r<0n)throw 0;return r}catch{throw new Error(`envelope: ${t} must be a non-negative integer`)}},pr=(e,t)=>{let r=Number(e);if(!Number.isFinite(r))throw new Error(`policy: ${t} must be finite`);return r},gn=(e,t)=>{if(!Array.isArray(e)||e.length===0)throw new Error(`policy: ${t} allowlist is empty`);return e},S=(e,t,r)=>{if(!gn(t,r).map(n=>String(n).toLowerCase()).includes(String(e).toLowerCase()))throw new Error(`policy: ${r} not allowed`)},ke=(e,t,r)=>{Array.isArray(t)&&t.length&&S(e,t,r)},L=(e,t)=>{let r=String(e||"").toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(r))throw new Error(`envelope: ${t} must be a 20-byte address`);return r},z=e=>String(e||"0x").slice(0,10).toLowerCase(),gr=e=>g(e.gasLimit,"gasLimit")*g(e.maxFeePerGas??e.gasPrice,"feePerGas")+g(e.l1FeeWei??0,"l1FeeWei")+g(e.operatorFeeWei??0,"operatorFeeWei");function X(e,t,r,{dynamicTail:n=!1}={}){let o=String(e||"").toLowerCase();if(!/^0x[0-9a-f]*$/.test(o)||o.length<10+t*64)throw new Error(`envelope: malformed ${r} calldata`);if(!n&&o.length!==10+t*64)throw new Error(`envelope: malformed ${r} calldata`);return{hex:o,word:i=>o.slice(10+i*64,10+(i+1)*64)}}function A(e,t){if(!/^0{24}[0-9a-f]{40}$/.test(e))throw new Error(`envelope: malformed ${t} address`);return`0x${e.slice(24)}`}function P(e,t){try{return BigInt(`0x${e}`)}catch{throw new Error(`envelope: malformed ${t} integer`)}}function En(e){if(z(e)!=="0x095ea7b3")return null;let t=X(e,2,"approval");return{kind:"approval",spender:A(t.word(0),"approval spender"),amount:P(t.word(1),"approval amount")}}function Er(e,t){let r=t==="router02-exact-input-single"?7:8,n=X(e,r,"Uniswap v3 exactInputSingle"),o=r===7?4:5;return{kind:"action",action:"swap",inputToken:A(n.word(0),"input token"),outputToken:A(n.word(1),"output token"),recipient:A(n.word(3),"recipient"),amountIn:P(n.word(o),"amountIn"),minimumOut:P(n.word(o+1),"amountOutMinimum")}}function xn(e){let t=X(e,12,"Across depositV3",{dynamicTail:!0}),r=P(t.word(11),"message offset");if(r!==384n)throw new Error("envelope: malformed Across depositV3 message offset");let n=10+Number(r)*2;if(t.hex.length<n+64)throw new Error("envelope: malformed Across depositV3 message");let o=Number(BigInt(`0x${t.hex.slice(n,n+64)}`));if(!Number.isSafeInteger(o))throw new Error("envelope: malformed Across depositV3 message length");let i=Math.ceil(o/32)*64;if(t.hex.length!==n+64+i)throw new Error("envelope: malformed Across depositV3 trailing bytes");return{kind:"action",action:"bridge",depositor:A(t.word(0),"depositor"),recipient:A(t.word(1),"recipient"),inputToken:A(t.word(2),"input token"),outputToken:A(t.word(3),"output token"),amountIn:P(t.word(4),"inputAmount"),minimumOut:P(t.word(5),"outputAmount"),destinationChainId:P(t.word(6),"destinationChainId")}}function bn(e){let t=String(e||"").replace(/^0x/i,"").toLowerCase();if(t.length<86||t.length%2!==0)throw new Error("envelope: malformed Uniswap path");let r=`0x${t.slice(0,40)}`,n=`0x${t.slice(t.length-40)}`;if(!/^0x[0-9a-f]{40}$/.test(r)||!/^0x[0-9a-f]{40}$/.test(n))throw new Error("envelope: malformed Uniswap path tokens");return{inputToken:r,outputToken:n}}function mr(e,{hasDeadline:t}){let r=String(e||"").toLowerCase();if(!/^0x[0-9a-f]+$/.test(r)||r.length<74)throw new Error("envelope: malformed exactInput calldata");let n=[];for(let h=10;h+64<=r.length;h+=64)n.push(r.slice(h,h+64));let o=(h,E)=>{if(!n[h])throw new Error(`envelope: malformed ${E}`);return BigInt(`0x${n[h]}`)},i=Number(o(0,"exactInput struct offset"));if(i%32!==0)throw new Error("envelope: malformed exactInput struct offset");let a=i/32,c=Number(o(a,"path offset")),u=n[a+1],s=o(a+(t?3:2),"amountIn"),f=o(a+(t?4:3),"amountOutMinimum"),l=a+c/32;if(!Number.isInteger(l)||!n[l])throw new Error("envelope: malformed exactInput path");let d=Number(o(l,"path length")),m=r.slice(10+(l+1)*64,10+(l+1)*64+d*2),{inputToken:p,outputToken:w}=bn(`0x${m}`);return{kind:"action",action:"swap",inputToken:p,outputToken:w,recipient:A(u,"recipient"),amountIn:s,minimumOut:f}}function yn(e){let t=X(e,8,"Aerodrome exactInputSingle");return{kind:"action",action:"swap",inputToken:A(t.word(0),"input token"),outputToken:A(t.word(1),"output token"),recipient:A(t.word(3),"recipient"),amountIn:P(t.word(5),"amountIn"),minimumOut:P(t.word(6),"amountOutMinimum")}}function Sn(e){let t=String(e||"").toLowerCase();if(!t.startsWith("0x5ae401dc"))throw new Error("envelope: malformed Uniswap multicall");let r=[];for(let d=10;d+64<=t.length;d+=64)r.push(t.slice(d,d+64));let n=Number(BigInt(`0x${r[1]}`));if(n%32!==0)throw new Error("envelope: malformed multicall data offset");let o=n/32;if(Number(BigInt(`0x${r[o]}`))!==1)throw new Error("envelope: multicall must wrap exactly one swap");let a=Number(BigInt(`0x${r[o+1]}`)),c=o+1+a/32,u=Number(BigInt(`0x${r[c]}`)),f=`0x${t.slice(10+(c+1)*64,10+(c+1)*64+u*2)}`,l=z(f);if(l!=="0x04e45aaf"&&l!=="0x414bf389")throw new Error("envelope: multicall inner call must be exactInputSingle");return Er(f,l==="0x04e45aaf"?"router02-exact-input-single":"swap-router-exact-input-single")}function An(e,t){let r=z(e),n=wr[r];if(!n)throw new Error("envelope: opaque or unsupported EVM swap/bridge calldata");if(String(t).toLowerCase()!==n.provider)throw new Error("envelope: provider does not match reviewed selector");if(n.layout==="router02-exact-input-single"||n.layout==="swap-router-exact-input-single")return{...Er(e,n.layout),selector:r,provider:n.provider};if(n.layout==="exact-input-deadline")return{...mr(e,{hasDeadline:!0}),selector:r,provider:n.provider};if(n.layout==="exact-input")return{...mr(e,{hasDeadline:!1}),selector:r,provider:n.provider};if(n.layout==="multicall-deadline")return{...Sn(e),selector:r,provider:n.provider};if(n.layout==="aerodrome-exact-input-single")return{...yn(e),selector:r,provider:n.provider};if(n.action==="bridge")return{...xn(e),selector:r,provider:n.provider};throw new Error("envelope: unsupported reviewed EVM action")}function vn(e){let t=X(e,4,"SeaDrop mintPublic");return{kind:"mint",action:"mint",mintType:"public",contract:A(t.word(0),"mint NFT contract"),feeRecipient:A(t.word(1),"mint fee recipient"),recipient:A(t.word(2),"mint recipient"),quantity:P(t.word(3),"mint quantity")}}function In(e){let t;try{t=dr.decodeFunctionData("mintAllowList",e)}catch{throw new Error("envelope: malformed SeaDrop mintAllowList calldata")}let r=t[4],n=[...t[5]].map(String);if(n.length<1||n.length>64||n.some(u=>!/^0x[0-9a-fA-F]{64}$/.test(u)))throw new Error("envelope: bounded canonical SeaDrop allowlist proof required");if(dr.encodeFunctionData("mintAllowList",[t[0],t[1],t[2],t[3],r,n]).toLowerCase()!==String(e).toLowerCase())throw new Error("envelope: SeaDrop allowlist calldata must be canonical");let i=BigInt(r.startTime),a=BigInt(r.endTime);if(a<=i)throw new Error("envelope: SeaDrop allowlist stage time range is invalid");let c=BigInt(t[3]);if(BigInt(r.maxTotalMintableByWallet)<c)throw new Error("envelope: SeaDrop allowlist wallet cap is below quantity");return{kind:"mint",action:"mint",mintType:"allowlist",contract:L(t[0],"mint NFT contract"),feeRecipient:L(t[1],"mint fee recipient"),recipient:L(t[2],"mint recipient"),quantity:c,mintPrice:BigInt(r.mintPrice),startTime:i,endTime:a,dropStageIndex:BigInt(r.dropStageIndex),proof:n}}function Tn(e,t){let r=z(e);if(String(t).toLowerCase()==="nft-mint")return kn(e);let n=hn[r];if(!n)throw new Error("envelope: opaque or unsupported NFT mint calldata");if(String(t).toLowerCase()!==n.provider)throw new Error("envelope: provider does not match reviewed NFT selector");if(n.layout==="seadrop-mint-public")return{...vn(e),selector:r,provider:n.provider};if(n.layout==="seadrop-mint-allowlist")return{...In(e),selector:r,provider:n.provider};throw new Error("envelope: unsupported reviewed NFT action")}function kn(e){let t=z(e);if(t==="0x40c10f19")throw new Error("envelope: ambiguous mint(address,uint256) calldata is not a built-in signer surface");let r=wn[t];if(!r)throw new Error("envelope: opaque or unsupported NFT mint calldata");if(r.layout==="mint-no-args")return{kind:"mint",action:"mint",selector:t,provider:"nft-mint",quantity:1n};if(r.layout==="mint-quantity"){let n=X(e,1,"generic NFT mint");return{kind:"mint",action:"mint",selector:t,provider:"nft-mint",quantity:P(n.word(0),"mint quantity")}}throw new Error("envelope: unsupported generic NFT mint calldata")}function ne(e){let t=e?.artifact;if(Array.isArray(t?.transactions))return t.transactions;if(t?.transaction&&typeof t.transaction=="object")return[t.transaction];if(t?.data)return[t];throw new Error("envelope: ordered EVM transaction batch required")}function xr(e,t,r,{nowMs:n=Date.now(),networkFees:o,requireNetworkFees:i=!1}={}){let a=L(e.owner,"owner"),c=e.artifact,u=Number(c?.chainId??ne(e)[0]?.chainId);if(!Number.isSafeInteger(u)||u<=0)throw new Error("envelope: explicit batch chainId required");if(S(u,t.chains,"chain"),c?.owner!==void 0&&L(c.owner,"batch owner")!==a)throw new Error("envelope: explicit batch owner mismatch");let s=ne(e);if(!s.length||s.length>8)throw new Error("envelope: bounded EVM transaction batch required");let f=0n,l=0n,d=0n;for(let m of s){if(!m||typeof m!="object"||Array.isArray(m))throw new Error("envelope: structured EVM transaction required");if(Number(m.chainId)!==u)throw new Error("envelope: every batch leg must use the same chain");if(L(m.from,"transaction owner")!==a)throw new Error("envelope: every batch leg must use the same owner");if(S(z(m.data),t.selectors,"selector"),f+=g(m.value??0,"value"),l+=g(m.gasLimit,"gasLimit"),d+=gr(m),W(u)&&(m.l1FeeWei===void 0||m.operatorFeeWei===void 0))throw new Error("policy: rollup EVM artifacts require l1FeeWei and operatorFeeWei")}if(f>g(t.maxValueWei,"maxValueWei"))throw new Error("policy: aggregate value exceeds cap");if(l>g(t.maxGasLimit,"maxGasLimit"))throw new Error("policy: aggregate gas exceeds cap");if(d>g(t.maxFeeWei,"maxFeeWei"))throw new Error("policy: aggregate fee exceeds cap");return{transactions:s,chainId:u,owner:a,totalValue:f,totalGas:l,totalFee:d}}function br(e,t,{nowMs:r=Date.now(),routeAttestationSecret:n}={}){let o=String(e?.surface||"");if(o!=="evm-swap"&&o!=="evm-bridge")throw new Error("envelope: strict EVM swap/bridge surface required");let i=fe(e.provider,"provider",64).toLowerCase();S(i,t.providers,"provider");let a=xr(e,t,o,{nowMs:r}),c=[],u=-1;for(let p=0;p<a.transactions.length;p++){let w=a.transactions[p],h=En(w.data),E;if(h){if(u!==-1)throw new Error("envelope: approval must be before action");if(g(w.value??0,"value")!==0n)throw new Error("envelope: approval cannot transfer native value");let I=L(w.to,"approval token");if(S(I,t.tokens,"token"),S(h.spender,t.spenders,"spender"),h.amount>g(t.maxApproval,"maxApproval"))throw new Error("policy: approval exceeds cap");E={...h,token:I,index:p}}else{if(u!==-1)throw new Error("envelope: exactly one swap/bridge action is supported per batch");S(w.to,t.destinations,"destination"),E={...An(w.data,i),target:L(w.to,"action target"),index:p},u=p}let B=g(w.value??0,"value"),M=g(w.gasLimit,"gasLimit");c.push({...E,value:B,gas:M,fee:gr(w)})}if(u<0)throw new Error("envelope: reviewed swap/bridge action required");let s=c[u],f=o==="evm-swap"?"swap":"bridge";if(s.action!==f||e.action!==f)throw new Error("envelope: surface/action/calldata mismatch");if(L(e.destination,"destination")!==s.target)throw new Error("envelope: destination must equal decoded action target");if(s.recipient!==a.owner)throw new Error("envelope: decoded recipient must equal owner");if(s.depositor&&s.depositor!==a.owner)throw new Error("envelope: decoded bridge depositor must equal owner");if(S(s.inputToken,t.tokens,"input token"),S(s.outputToken,t.tokens,"output token"),s.amountIn<=0n||s.amountIn>g(t.maxPerTrade,"maxPerTrade"))throw new Error("policy: decoded amount exceeds per-trade cap");if(s.minimumOut<=0n)throw new Error("policy: decoded minimum output must be positive");if(we(e.autoSlippage,{nowMs:r,chainId:a.chainId,venue:i,tx:a.transactions[u],secret:n,requireSigned:!0}),Number(e.slippageBps)!==Number(e.autoSlippage.selectedBps))throw new Error("policy: slippageBps must equal the authenticated quote selectedBps");if(s.minimumOut!==g(e.autoSlippage.minAmountOut,"authenticated quote minAmountOut"))throw new Error("policy: decoded minimum output does not match authenticated quote");if(s.action==="bridge"&&g(e.toChainId,"toChainId")!==s.destinationChainId)throw new Error("envelope: decoded bridge destination chain mismatch");let l=c.filter(p=>p.kind==="approval");if(!new Set([...mn,...Array.isArray(t.nativeInputTokens)?t.nativeInputTokens.map(p=>String(p).toLowerCase()):[]]).has(s.inputToken))throw new Error("envelope: strict local signer swap/bridge requires native input token; use wallet signing for token-unit rails");if(l.length)throw new Error("envelope: native-value action must not include token approval");if(s.value!==s.amountIn)throw new Error("envelope: native value must exactly match decoded amountIn");let m=Object.freeze({quoteAmountOut:g(e.autoSlippage.quoteAmountOut,"authenticated quote amountOut"),minAmountOut:g(e.autoSlippage.minAmountOut,"authenticated quote minAmountOut"),selectedBps:Number(e.autoSlippage.selectedBps),quotedAtMs:Number(e.autoSlippage.quotedAtMs),expiresAtMs:Number(e.autoSlippage.expiresAtMs)});return{...a,decoded:c,action:s,provider:i,authenticatedQuote:m}}function yr(e,t,{nowMs:r=Date.now()}={}){if(e?.surface!=="evm-nft")throw new Error("envelope: evm-nft surface required");if(!["mint","nft"].includes(e.action))throw new Error("envelope: evm-nft requires mint action");let n=fe(e.provider||e.artifact?.provider||"opensea-nft","provider",64).toLowerCase();ke(n,t.providers,"provider");let o=e.artifact?.oraclePrepared===!0?e.artifact:e.prepared;o?.oraclePrepared===!0&&Fe(o,{nowMs:r,providers:Array.isArray(t.providers)&&t.providers.length?t.providers:null,kinds:["nft-mint"],label:"local-signer"});let i=xr(e,t,"evm-nft",{nowMs:r});if(i.transactions.length!==1)throw new Error("envelope: mint supports exactly one transaction");let a=i.transactions[0],c=z(a.data);S(c,t.selectors,"selector"),S(a.to,t.destinations,"destination");let u=Tn(a.data,n),s=L(e.contract??e.artifact?.contract,"NFT contract");if(ke(s,t.nftContracts,"NFT contract"),(u.contract||L(a.to,"NFT contract"))!==s)throw new Error("envelope: mint calldata NFT contract mismatch");if(u.recipient&&u.recipient!==i.owner)throw new Error("envelope: mint calldata recipient mismatch");u.feeRecipient&&ke(u.feeRecipient,t.nftFeeRecipients,"mint fee recipient");let l=g(e.quantity??e.artifact?.quantity,"quantity");if(l<=0n||l>g(t.maxMintQuantity??1,"maxMintQuantity"))throw new Error("policy: mint quantity exceeds cap");if(u.quantity!==l)throw new Error("envelope: mint calldata quantity mismatch");let d=g(e.totalWei??e.artifact?.totalWei,"totalWei");if(i.totalValue!==d)throw new Error("envelope: mint value does not match declared totalWei");if(u.mintType==="allowlist"){let m=BigInt(Math.floor(r/1e3));if(u.startTime>m||u.endTime<=m)throw new Error("policy: SeaDrop allowlist stage is not open");if(u.mintPrice*l!==d)throw new Error("envelope: SeaDrop allowlist price does not match declared totalWei")}if((e.priceWei!==void 0||e.artifact?.priceWei!==void 0)&&g(e.priceWei??e.artifact.priceWei,"priceWei")*l!==d)throw new Error("envelope: mint price does not match declared totalWei");if(d>g(t.maxMintTotalWei??t.maxValueWei,"maxMintTotalWei"))throw new Error("policy: mint total exceeds cap");return{...i,provider:n,decoded:[{...u,target:L(a.to,"mint target"),value:i.totalValue,gas:i.totalGas,fee:i.totalFee}]}}function Sr(e,{localsWaiver:t=!1}={}){if(!(e in Ne))throw new Error("fee: unknown action");return t?0:Ne[e]}function oe(e,t,{nowMs:r=Date.now(),verifyFeeWaiver:n,routeAttestationSecret:o,networkFees:i,requireNetworkFees:a=!1}={}){if(!e||e.version!==1)throw new Error("envelope: version 1 required");let c=fe(e.surface,"surface",16);if(!hr.has(c))throw new Error("envelope: unsupported public surface");let u=fe(e.action,"action",32);S(c,t.surfaces,"surface"),S(u,t.actions,"action"),S(e.owner,t.owners,"owner"),S(e.destination,t.destinations,"destination");let s=pr(t.maxTtlMs,"maxTtlMs"),f=pr(t.maxSlippageBps,"maxSlippageBps");if(!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=r||e.expiresAtMs-r>s)throw new Error("policy: TTL outside bounds");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>f)throw new Error("policy: slippage exceeds cap");let l=e.artifact;if(!l||typeof l!="object"||Array.isArray(l))throw new Error("envelope: structured artifact required");if(c==="evm-swap"||c==="evm-bridge")br(e,t,{nowMs:r,routeAttestationSecret:o});else if(c==="evm-nft")yr(e,t,{nowMs:r});else if(c==="evm"){if(!["transfer","approve"].includes(u))throw new Error("envelope: generic evm requires transfer or approve; use strict evm-nft for mint action");if(u==="swap"||u==="bridge")throw new Error("envelope: surface/action mismatch; use strict decoded surface");if(String(l.to).toLowerCase()!==String(e.destination).toLowerCase())throw new Error("envelope: destination mismatch");if(String(l.from).toLowerCase()!==String(e.owner).toLowerCase())throw new Error("envelope: artifact from mismatch with owner");ce({...l,slippageBps:e.slippageBps,expiresAtMs:e.expiresAtMs},t,{nowMs:r,networkFees:i,requireNetworkFees:a});let p=String(l.data||"0x").toLowerCase(),w=g(l.value,"EVM value");if(p==="0x"){if(w===0n)throw new Error("envelope: native EVM transfer value required")}else if(j(p)){if(w!==0n)throw new Error("envelope: EVM approval cannot transfer native value")}else throw new Error("envelope: unsupported generic EVM calldata")}else c==="btc"?We(e,t):c==="sol"?Ze(e,t):c==="hl"?tr(e,t):c==="poly"?sr(e,t):c==="lighter"&&fr(e,t);let d=Number(e.fee?.oracleFeeBps)===0&&Ne[u]!==0;if(e.fee?.waiver||d&&!e.fee?.waiverAttestation)throw new Error("fee: verified waiver attestation required");if(d&&(typeof n!="function"||n(e.fee.waiverAttestation,e)!==!0))throw new Error("fee: waiver attestation invalid");let m=Sr(u,{localsWaiver:d});if(Number(e.fee?.oracleFeeBps)!==m)throw new Error("fee: final artifact fee mismatch");return!0}var de=Object.freeze([...hr]),Nn=Object.freeze({...wr});function On(e={}){let t={};for(let r of de){let n=e[r];if(n){if(typeof n.simulate!="function"||typeof n.sign!="function"||typeof n.broadcast!="function")throw new Error(`adapter: ${r} requires simulate, sign, and broadcast functions`);t[r]=Object.freeze({simulate:(o,i)=>n.simulate(structuredClone(o),structuredClone(i)),sign:(o,i)=>n.sign(structuredClone(o),structuredClone(i)),broadcast:(o,i,a)=>n.broadcast(o,structuredClone(i),structuredClone(a))})}}return Object.freeze(t)}function Ln(e,t){let r=e?.surface||"evm",n=t?.[r];if(!n)throw new Error(`adapter: ${r} is not configured on this self-host`);return n}import{ed25519 as Zi}from"@noble/curves/ed25519.js";import{base58 as Bn}from"@scure/base";import{RawTx as ra,SigHash as ta,Transaction as _n}from"@scure/btc-signer";import{Transaction as Cn,keccak256 as Ar,verifyTypedData as oa}from"ethers";import{encode as Di}from"@msgpack/msgpack";import{keccak256 as Wi,verifyTypedData as Hi}from"ethers";var Ji=Object.freeze({name:"Exchange",version:"1",chainId:1337,verifyingContract:"0x0000000000000000000000000000000000000000"}),ji=Object.freeze({Agent:[{name:"source",type:"string"},{name:"connectionId",type:"bytes32"}]});var vr=e=>{if(typeof e!="string"||e.length===0||e.length>262144||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e))return null;let t=Buffer.from(e,"base64");return t.toString("base64")===e?t:null};function Pn(e){let t=0,r=0,n=0;for(;n<e.length&&n<3;){let o=e[n++];if(t|=(o&127)<<r,(o&128)===0)return{value:t,offset:n};r+=7}return null}function Ir(e,t){try{if(String(e).startsWith("evm"))return Cn.from(t).hash;if(e==="btc"){let r=vr(t);if(!r)return null;let n=_n.fromPSBT(r);return n.finalize(),n.extract(),n.id}if(e==="sol"){let r=vr(t);if(!r)return null;let n=Pn(r);if(!n||n.value!==1)return null;let o=r.subarray(n.offset,n.offset+64);return o.length===64?Bn.encode(o):null}if(e==="hl"&&typeof t=="string"&&t.startsWith("0x"))return Ar(t);if(e==="poly"&&typeof t=="string"&&t.startsWith("0x"))return Ar(t)}catch{}return null}var qn=e=>String(e||"").toLowerCase();function J(e){return Mn("sha256").update(JSON.stringify(e)).digest("hex")}function me(e,t,r={}){return ce(e,t,r)}async function Rn(e,t={}){if(!W(e?.chainId))return{l1FeeWei:"0",operatorFeeWei:"0"};if(typeof t.estimateNetworkFees!="function")throw new Error("policy: rollup fee estimate required");let r=await t.estimateNetworkFees(e);if(!r||r.l1FeeWei===void 0||r.operatorFeeWei===void 0)throw new Error("policy: rollup fee estimate required");return{l1FeeWei:String(r.l1FeeWei),operatorFeeWei:String(r.operatorFeeWei)}}function kr(e,t,r=!1){if(!W(e?.chainId))return!0;if(e.l1FeeWei===void 0||e.operatorFeeWei===void 0)throw new Error("policy: rollup EVM artifacts require l1FeeWei and operatorFeeWei");if(r||t!=null){if(!t||t.l1FeeWei===void 0||t.operatorFeeWei===void 0)throw new Error("policy: rollup fee estimate required");let n=BigInt(e.l1FeeWei)+BigInt(e.operatorFeeWei),o=BigInt(t.l1FeeWei)+BigInt(t.operatorFeeWei);if(n<o)throw new Error("policy: rollup fee attestation understates estimate")}return!0}function Dn(e,t={}){return renderConfirmationArtifact(e,J(e),t)}var ie=class{#e=new Map;constructor({now:t=Date.now}={}){this.now=t}issue({artifact:t,owner:r,ttlMs:n=6e4}){if(!Number.isFinite(n)||!Number.isInteger(n)||n<=0||n>12e4)throw new Error("confirmation: ttl out of range");let o=Fn(32).toString("hex");return this.#e.set(o,{digest:J(t),owner:qn(r),expiresAtMs:this.now()+n}),o}consume(t,r){let n=this.#e.get(String(t));if(!n)throw new Error("confirmation: used or unknown nonce");if(n.expiresAtMs<=this.now())throw this.#e.delete(String(t)),new Error("confirmation: expired nonce");let o=Buffer.from(n.digest,"hex"),i=Buffer.from(J(r),"hex");if(!$n(o,i))throw new Error("confirmation: artifact mismatch");return this.#e.delete(String(t)),n}clear(){this.#e.clear()}};function Un(e){let t=String(e?.data||"0x").toLowerCase(),r=BigInt(e?.value??0);if(t==="0x"){if(r<=0n)throw new Error("signer: native EVM transfer value required");return!0}if(j(t)){if(r!==0n)throw new Error("signer: EVM approval cannot transfer native value");return!0}throw new Error("signer: unsupported EVM calldata; use a versioned envelope")}function Wn(e={},t={}){let r={};for(let n of new Set([...Object.keys(e||{}),...Object.keys(t||{})]))r[n]=(BigInt(t?.[n]??0)-BigInt(e?.[n]??0)).toString();return r}function pe(e,t){let r=String(t||"");if(String(e).startsWith("evm"))return/^0x[0-9a-fA-F]{64}$/.test(r);if(e==="btc")return/^[0-9a-fA-F]{64}$/.test(r);if(e==="sol")try{let n=Tr.decode(r);return n.length===64&&Tr.encode(n)===r}catch{return!1}return e==="hl"?/^0x[0-9a-fA-F]{64}$/.test(r):e==="poly"?/^0x[0-9a-fA-F]{64}$/.test(r):!1}function Nr(e,t,r){return!pe(e,t)||!pe(e,r)?!1:e==="sol"?String(t)===String(r):String(t).toLowerCase()===String(r).toLowerCase()}function Hn(e){let t=e?.confirmationMode;if(t!=="exact-human"&&t!=="auto-within-rails")throw new Error("signer: confirmationMode must be exact-human or auto-within-rails");return t}async function Oe({artifact:e,envelope:t,nonce:r,deps:n,policy:o,confirmation:i,consumeNonce:a,nowMs:c}){let u=Hn(o);if(n.autonomous===!0){if(n.env?.ORACLE_AUTONOMOUS_TRADING!=="1")throw new Error("signer: autonomous execution requires ORACLE_AUTONOMOUS_TRADING=1");if(u!=="auto-within-rails")throw new Error("signer: autonomous execution requires auto-within-rails policy");if(typeof n.verifyTriggerAttestation!="function"||await n.verifyTriggerAttestation(t?.triggerAttestation,e,c())!==!0)throw new Error("signer: autonomous trigger attestation required");return i}if(u!=="exact-human")throw new Error("signer: non-autonomous execution requires exact-human exact confirmation policy");if(!n.confirmations)throw new Error("signer: exact-human confirmation store required");if(a)return n.confirmations.consume(r,e);if(!i||!Number.isFinite(i.expiresAtMs)||i.expiresAtMs<=c())throw new Error("confirmation: expired nonce");return i}function Jn(e){return e==="evm-swap"||e==="evm-bridge"||e==="evm-nft"}function jn(e,t){return e&&Jn(e.surface)?ne(e):[t]}function Vn(e,t){let r=e?.hash??null,n=e?.transactionHash??null;if(r!=null&&n!=null&&!Nr(t,r,n))throw new Error("signer: receipt reports conflicting transaction hashes");return r||n||null}function zn(e,t){let r=e?.verifiedBefore??e?.before,n=e?.verifiedAfter??e?.after;return{transactionHash:t,status:e?.status,balanceDeltaVerified:!!(e?.verifiedBefore&&e?.verifiedAfter),delta:Wn(r,n)}}async function Le(e,t,r){if(!r.isArmed())throw new Error("signer: disarmed");let n=e?.version===1&&e?.surface?e:null,o=n?n.artifact:(()=>{let{tradeId:h,...E}=e||{};return E})(),i=jn(n,o),a=typeof r.readPolicy=="function"?r.readPolicy():r.policy,c=()=>typeof r.nowMs=="function"?r.nowMs():r.nowMs??Date.now(),u=await Oe({artifact:e,envelope:n,nonce:t,deps:r,policy:a,confirmation:null,consumeNonce:!0,nowMs:c}),s=J(e),f=(h={})=>{n?oe(n,a,h):(me(o,a,{nowMs:h.nowMs,networkFees:h.networkFees,requireNetworkFees:h.requireNetworkFees}),Un(o))},l=async h=>{let E=n&&!String(n.surface||"").startsWith("evm")?void 0:await Rn(h,r);return{nowMs:c(),verifyFeeWaiver:r.verifyFeeWaiver,routeAttestationSecret:r.routeAttestationSecret,networkFees:E,requireNetworkFees:W(h?.chainId)}};f({nowMs:c(),verifyFeeWaiver:r.verifyFeeWaiver,routeAttestationSecret:r.routeAttestationSecret});for(let h of["reserveLedger","validateReservation","commitLedger","releaseLedger","settleFailedLedger"])if(typeof r[h]!="function")throw new Error(`signer: ${h} is required`);let d=r.reserveLedger(n||e,a);if(!d)throw new Error("signer: ledger reservation required");let m=!1,p=[];try{for(let h of i){if(typeof r.simulate!="function"||await r.simulate(h,n)!==!0)throw new Error("signer: strict affirmative simulation required");let E=await l(h);if(kr(h,E.networkFees,E.requireNetworkFees),!r.isArmed())throw new Error("signer: disarmed before signing");a=typeof r.readPolicy=="function"?r.readPolicy():r.policy,u=await Oe({artifact:e,envelope:n,nonce:t,deps:r,policy:a,confirmation:u,consumeNonce:!1,nowMs:c}),f(E),r.validateReservation(d,a,n&&typeof r.decodeEconomics=="function"?r.decodeEconomics(n,a):void 0),m=!0;let B=await r.sign(h,n);if(typeof r.verifySigned!="function"||await r.verifySigned(B,h,n)!==!0)throw new Error("signer: signed bytes do not match confirmed artifact");if(!r.isArmed())throw new Error("signer: disarmed before broadcast");if(J(e)!==s)throw new Error("signer: artifact mutated after signing");a=typeof r.readPolicy=="function"?r.readPolicy():r.policy,u=await Oe({artifact:e,envelope:n,nonce:t,deps:r,policy:a,confirmation:u,consumeNonce:!1,nowMs:c});let M=await l(h);kr(h,M.networkFees,M.requireNetworkFees),f(M),r.validateReservation(d,a,n&&typeof r.decodeEconomics=="function"?r.decodeEconomics(n,a):void 0);let I=await r.broadcast(B,h,n),G=I?.status,U=n?.surface||"evm",q=Vn(I,U),Br=Ir(U,B);if(!Nr(U,q,Br))throw new Error("signer: receipt transaction hash does not match signed bytes");if(G===0||G==="0x0")throw pe(U,q)?(r.settleFailedLedger(d),new Error("signer: broadcast did not return a successful receipt")):new Error("signer: failed broadcast requires a valid transaction hash");if(G!==1&&G!=="0x1")throw new Error("signer: broadcast did not return a successful receipt");if(!pe(U,q))throw new Error("signer: successful broadcast requires a valid transaction hash");p.push(zn(I,q))}}catch(h){throw m||r.releaseLedger(d),h}if(r.commitLedger(d),p.length===1){let h={receipt:p[0]};return n?.surface==="evm-bridge"&&(h.originStatus="success",h.destinationStatus="unverified",h.destinationSuccess=!1,h.note="Origin-chain receipts do not prove destination-chain settlement."),h}let w={receipts:p,status:"success"};return n?.surface==="evm-bridge"&&(w.originStatus="success",w.destinationStatus="unverified",w.destinationSuccess=!1,w.note="Origin-chain receipts do not prove destination-chain settlement."),w}import Gn from"node:http";import{timingSafeEqual as Kn}from"node:crypto";var Or=new Set(["127.0.0.1","::1","localhost"]),Yn=(e,t)=>{let r=Buffer.from(String(e)),n=Buffer.from(String(t));return r.length===n.length&&Kn(r,n)},v=(e,t,r)=>{let n=JSON.stringify(r);e.writeHead(t,{"content-type":"application/json","cache-control":"no-store","content-length":Buffer.byteLength(n)}),e.end(n)};function Xn(e){let t=String(e||"");if(t.startsWith("[")){let r=t.indexOf("]");if(r>1)return t.slice(1,r)}return t.split(":")[0]}var Lr=e=>new Promise((t,r)=>{let n=0,o=[],i=!1;e.on("data",a=>{n+=a.length,n>64*1024&&!i?(i=!0,r(new Error("request refused")),e.resume()):i||o.push(a)}),e.on("end",()=>{if(!i)try{t(JSON.parse(Buffer.concat(o).toString()||"{}"))}catch{r(new Error("request refused"))}}),e.on("error",r)});function Zn(e={}){let t=e.host||"127.0.0.1";if(!Or.has(t))throw new Error("signer: loopback bind required");if(String(e.token||"").length<32)throw new Error("signer: strong auth token required");for(let i of["reserveLedger","validateReservation","commitLedger","releaseLedger","settleFailedLedger"])if(typeof e[i]!="function")throw new Error(`signer: ${i} is required`);if(typeof e.disarm!="function")throw new Error("signer: disarm callback is required");let r=e.confirmations||new ie,n=e.origin||`http://${t}`;return Gn.createServer(async(i,a)=>{try{let c=String(i.headers.authorization||"").replace(/^Bearer /i,"");if(!Yn(c,e.token))return v(a,401,{error:"unauthorized"});let u=Xn(i.headers.host);if(!Or.has(u))return v(a,403,{error:"host refused"});if(i.headers.origin&&i.headers.origin!==n)return v(a,403,{error:"origin refused"});if(i.method==="GET"&&i.url==="/status"){let s=typeof e.readPolicy=="function"?e.readPolicy():e.policy,f=new Set(de),l=Array.isArray(s?.surfaces)?s.surfaces.filter(d=>typeof d=="string"&&f.has(d)):[];return v(a,200,{ok:!0,service:"oracle-signer",armed:e.isArmed?.()===!0,surfaces:l,sessionExpiresAtMs:e.sessionExpiresAtMs||null})}if(i.method==="POST"&&i.url==="/disarm")return e.disarm(),r.clear(),v(a,200,{ok:!0,armed:!1});if(!["GET","POST"].includes(i.method))return v(a,405,{error:"request refused"});if(i.method==="POST"&&String(i.headers["content-type"]||"").split(";",1)[0].trim().toLowerCase()!=="application/json")return v(a,415,{error:"request refused"});if(i.method==="POST"&&i.url==="/confirm"){if(e.autonomous===!0)return v(a,403,{error:"autonomous signer does not issue human confirmation nonces"});let s=await Lr(i),f=J(s.artifact),l=typeof e.readPolicy=="function"?e.readPolicy():e.policy;if(l?.confirmationMode!=="exact-human")return v(a,403,{error:"exact-human policy required"});let d=typeof e.nowMs=="function"?e.nowMs():Date.now();if(s.artifact?.version===1&&s.artifact?.surface)oe(s.artifact,l,{nowMs:d,verifyFeeWaiver:e.verifyFeeWaiver});else{let{tradeId:m,...p}=s.artifact||{};me(p,l,{nowMs:d})}return typeof e.confirmArtifact!="function"?v(a,403,{error:"local human confirmation unavailable"}):await e.confirmArtifact(s.artifact,f,l)!==!0?v(a,400,{error:"exact human confirmation refused"}):v(a,200,{confirmationNonce:r.issue({artifact:s.artifact,owner:s.artifact?.owner??s.artifact?.from,ttlMs:s.ttlMs})})}if(i.method==="POST"&&i.url==="/execute"){let s=await Lr(i),f=await Le(s.artifact,s.confirmationNonce,{...e,confirmations:r});return v(a,200,f)}return v(a,404,{error:"not found"})}catch(c){return e.onError?.(String(c?.message||c)),v(a,400,{error:"request refused"})}})}export{ie as ConfirmationStore,de as PUBLIC_SIGNER_SURFACES,Nn as REVIEWED_EVM_SELECTORS,J as artifactDigest,me as assertExactPolicy,Zn as createSignerServer,On as createSurfaceAdapters,ne as evmTransactions,Le as executeConfirmedArtifact,Dn as inspectArtifactForConfirmation,br as inspectEvmBatch,yr as inspectEvmNft,Sr as publicFeeBps,Ln as surfaceAdapterFor,oe as validateSurfaceEnvelope};
|
package/dist/nft/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function re(t,e="value"){if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`${e} must be a finite number`);if(Math.abs(t)>Number.MAX_SAFE_INTEGER)throw new Error(`${e} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);if(Number.isInteger(t)&&!Number.isSafeInteger(t))throw new Error(`${e} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return String(t)}if(typeof t=="string"){if(t!==t.trim())throw new Error(`${e} must be a number or decimal string`);return t}throw new Error(`${e} must be a number or decimal string`)}function $(t,e="amount"){if(typeof t=="bigint")return t;if(typeof t=="number"){if(!Number.isInteger(t))throw new Error(`${e} must be an integer`);if(!Number.isSafeInteger(t))throw new Error(`${e} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return BigInt(t)}let r=re(t,e);if(r==="")throw new Error(`${e} is required`);if(!/^-?\d+$/.test(r)&&!/^0x[0-9a-fA-F]+$/.test(r))throw new Error(`${e} must be an integer in decimal or 0x-hex form, got ${JSON.stringify(r)}`);try{return BigInt(r)}catch{throw new Error(`${e} must be an integer, got ${JSON.stringify(r)}`)}}var P=1,o=Object.freeze({BUY:"BUY",PASS:"PASS",NO_TRADE:"NO_TRADE"}),j=Object.freeze(["reveal","repriced","reprice","price_drop","relisted"]),C=10000n,G=Object.freeze({minTraitSales:3,minTraitVolumeWei:"1000000000000000000",minVolumeCoverage:3,minEdgeBps:1200,minEdgeBpsWithoutEvent:2e3,maxPremiumOverCollectionFloorBps:5e3,maxListingAgeMs:900*1e3,maxEventAgeMs:1800*1e3,maxMarketDataAgeMs:3600*1e3,maxTraitWindowHours:72,marketplaceFeeBps:250,royaltyBps:500,maxSpendWei:null});function N(t,e,r,{positive:i=!0,allowZero:s=!1}={}){if(t==null||t==="")return r.push(`${e}: missing`),null;let n;try{n=$(t,e)}catch(a){return r.push(`${e}: ${String(a?.message||a)}`),null}return n<0n?(r.push(`${e}: must not be negative`),null):i&&!s&&n===0n?(r.push(`${e}: must be positive`),null):n}function ie(t,e,r){if(t==null||t==="")return r.push(`${e}: missing`),null;let i=Number(t);return!Number.isInteger(i)||i<0?(r.push(`${e}: must be a non-negative integer`),null):i}function y(t){let e=Number(t);return Number.isFinite(e)?e:null}function l(...t){for(let e of t)if(e!=null&&e!=="")return e;return null}function q(t,e){return e==null||e===0n?null:Number(t*C/e)}function ne(t){let e=y(l(t?.rarityPct,t?.rarity_pct));if(e!=null&&e>0)return Math.round(e*100);let r=y(l(t?.traitSupply,t?.supply,t?.count)),i=y(l(t?.collectionSupply,t?.totalSupply));return r!=null&&i!=null&&r>0&&i>0?Math.round(r/i*1e4):null}function oe(t={}){let e={...G,...t||{}},r=Number(e.marketplaceFeeBps)||0,i=Number(e.royaltyBps)||0;if(r<0||i<0||r+i>=1e4)throw new Error("trait sniper: marketplaceFeeBps + royaltyBps must be >= 0 and < 10000");return e}function p(t,e,r,i={}){return{ok:t===o.BUY,decision:t,failureKind:e,reasons:r,version:P,executed:!1,signed:!1,broadcast:!1,requiresUserSignature:!0,...i}}function U(t={}){let e;try{e=oe(t.policy)}catch(w){return p(o.NO_TRADE,"bad-policy",[String(w?.message||w)])}let r=Number.isFinite(Number(t.nowMs))?Number(t.nowMs):Date.now(),i=t.listing||{},s=t.trait||{},n=t.traitMarket||t.traitStats||{},a=t.collectionMarket||t.collection||{},u={chainId:y(l(t.chainId,i.chainId))??null,contract:String(l(t.contract,t.collectionAddress,i.contract,"")||"")||null,tokenId:String(l(i.tokenId,t.tokenId,"")||"")||null,marketplace:String(l(i.marketplace,i.source,"")||"")||null,trait:{type:String(l(s.type,s.traitType,"")||"")||null,value:String(l(s.value,s.traitValue,"")||"")||null,rarityBps:ne(s)}},d=[],c=N(l(i.priceWei,i.price),"listing.priceWei",d),h=N(l(n.floorPriceWei,n.floorWei),"traitMarket.floorPriceWei",d),g=N(l(n.volumeWei,n.volume),"traitMarket.volumeWei",d,{allowZero:!0}),b=N(l(a.floorPriceWei,a.floorWei),"collectionMarket.floorPriceWei",d),E=ie(l(n.sales,n.salesCount),"traitMarket.sales",d),x=y(l(n.windowHours,n.window_hours));if((x==null||x<=0)&&d.push("traitMarket.windowHours: missing"),d.length)return p(o.NO_TRADE,"insufficient-data",[`missing or unusable market data \u2014 ${d.join("; ")}`],{identity:u,dataGaps:d,liquidity:null,edge:null});if(x>e.maxTraitWindowHours)return p(o.NO_TRADE,"window-too-wide",[`trait stats aggregate ${x}h > maxTraitWindowHours ${e.maxTraitWindowHours}h \u2014 not recent liquidity`],{identity:u,dataGaps:[],liquidity:null,edge:null});let D=y(l(n.observedAtMs,n.asOfMs,a.observedAtMs));if(D==null)return p(o.NO_TRADE,"insufficient-data",["missing or unusable market data \u2014 traitMarket.observedAtMs: missing"],{identity:u,dataGaps:["traitMarket.observedAtMs: missing"],liquidity:null,edge:null});let M=r-D;if(M>e.maxMarketDataAgeMs)return p(o.NO_TRADE,"stale-market-data",[`market snapshot is ${M}ms old > maxMarketDataAgeMs ${e.maxMarketDataAgeMs}ms`],{identity:u,marketAgeMs:M,liquidity:null,edge:null});if(i.flagged===!0||i.reported===!0)return p(o.NO_TRADE,"listing-flagged",["listing is flagged/reported by the marketplace \u2014 a cheap flagged token is cheap for a reason"],{identity:u,liquidity:null,edge:null});let z=g>=c*BigInt(Math.max(0,Math.trunc(e.minVolumeCoverage))),_=$(e.minTraitVolumeWei??0,"policy.minTraitVolumeWei"),R={sales:E,minSales:e.minTraitSales,volumeWei:g.toString(),minVolumeWei:_.toString(),windowHours:x,coverageX:c===0n?null:Number(g/c),minCoverageX:e.minVolumeCoverage,illiquid:!1},A=[];if(E<e.minTraitSales&&A.push(`only ${E} trait sale(s) in ${x}h, need ${e.minTraitSales}`),g<_&&A.push(`trait volume ${g} wei below minTraitVolumeWei ${_} wei`),z||A.push(`trait volume ${g} wei does not cover ${e.minVolumeCoverage}x the ${c} wei listing \u2014 no exit depth`),A.length){R.illiquid=!0;let w=u.trait.rarityBps;return w!=null&&w<=100&&A.push(`trait is rare (${w} bps of supply) but rarity is ranking-only \u2014 an unsold rare trait is an illiquid bag, not an edge`),p(o.NO_TRADE,"illiquid-trait",A,{identity:u,liquidity:R,edge:null,marketAgeMs:M})}let W=String(l(t.event?.kind,t.event?.type,i.eventKind,"")||"").toLowerCase(),V=y(l(t.event?.atMs,i.eventAtMs)),T=V==null?null:r-V,k=j.includes(W)&&T!=null&&T>=0&&T<=e.maxEventAgeMs,B=k?e.minEdgeBps:e.minEdgeBpsWithoutEvent,Z=BigInt(Math.trunc(e.marketplaceFeeBps)),Q=BigInt(Math.trunc(e.royaltyBps)),H=h*(C-Z-Q)/C,O=H-c,ee=q(h-c,h),I=q(c-b,b),v=q(O,c),te={listingPriceWei:c.toString(),traitFloorWei:h.toString(),collectionFloorWei:b.toString(),netExitWei:H.toString(),edgeWei:O.toString(),edgeBps:v,requiredEdgeBps:B,discountToTraitFloorBps:ee,premiumToCollectionFloorBps:I,feeBps:e.marketplaceFeeBps,royaltyBps:e.royaltyBps,triggered:k,eventKind:W||null,eventAgeMs:T},S={identity:u,liquidity:R,edge:te,marketAgeMs:M},L=y(l(i.listedAtMs,i.listedAt)),m=L==null?null:r-L;if(i.stale===!0)return p(o.PASS,"listing-stale",["listing is marked stale by the caller"],S);if(m==null)return p(o.NO_TRADE,"insufficient-data",["missing or unusable market data \u2014 listing.listedAtMs: missing"],{...S,dataGaps:["listing.listedAtMs: missing"]});if(m<0)return p(o.NO_TRADE,"listing-in-future",[`listing.listedAtMs is ${-m}ms in the future`],S);if(m>e.maxListingAgeMs)return p(o.PASS,"listing-stale",[`listing is ${m}ms old > maxListingAgeMs ${e.maxListingAgeMs}ms \u2014 the mispricing is not live`],{...S,listingAgeMs:m});if(e.maxSpendWei!=null&&e.maxSpendWei!==""){let w=$(e.maxSpendWei,"policy.maxSpendWei");if(c>w)return p(o.PASS,"spend-cap",[`listing ${c} wei exceeds maxSpendWei ${w} wei`],{...S,listingAgeMs:m})}return c>=h?p(o.PASS,"no-discount",[`listing ${c} wei is at or above the trait floor ${h} wei`],{...S,listingAgeMs:m}):I!=null&&I>e.maxPremiumOverCollectionFloorBps?p(o.PASS,"collection-floor-premium",[`listing sits ${I} bps over the collection floor > maxPremiumOverCollectionFloorBps ${e.maxPremiumOverCollectionFloorBps} bps`],{...S,listingAgeMs:m}):O<=0n||v==null||v<B?p(o.PASS,"edge-below-threshold",[`net edge ${v??0} bps after ${e.marketplaceFeeBps}+${e.royaltyBps} bps costs is below the ${B} bps required${k?"":" without a reveal/reprice trigger"}`],{...S,listingAgeMs:m}):p(o.BUY,null,[`${E} trait sale(s) and ${g} wei of volume in ${x}h clear the liquidity gate`,`net edge ${v} bps vs trait floor after ${e.marketplaceFeeBps}+${e.royaltyBps} bps costs, required ${B} bps`,k?`${W} event ${T}ms ago explains the mispricing`:"no trigger event \u2014 cleared the higher untriggered bar"],{...S,listingAgeMs:m})}function se(t=[],e={}){if(!Array.isArray(t))throw new TypeError("scanTraitListings: listings array required");let r=t.map((n,a)=>{let u={...e,...n,policy:{...e.policy||{},...n?.policy||{}}},d=U(u);return{index:a,...d}}),i=r.filter(n=>n.decision===o.BUY),s=[...i].sort((n,a)=>{let u=(a.edge?.edgeBps??0)-(n.edge?.edgeBps??0);if(u!==0)return u;let d=n.identity?.trait?.rarityBps??Number.MAX_SAFE_INTEGER,c=a.identity?.trait?.rarityBps??Number.MAX_SAFE_INTEGER;return d!==c?d-c:n.index-a.index});return{evaluated:r,ranked:s,counts:{total:r.length,buy:i.length,pass:r.filter(n=>n.decision===o.PASS).length,noTrade:r.filter(n=>n.decision===o.NO_TRADE).length},executed:!1,signed:!1,broadcast:!1}}import{createHash as ae,createHmac as ce,timingSafeEqual as xe}from"node:crypto";var le=2,ue=300*1e3,be=(()=>{let t=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(t)&&t>0?t:1800*1e3})();function F(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(F).join(",")}]`:`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${F(t[r])}`).join(",")}}`}function Y(t){let e=String(t?.ORACLE_STAMP_HMAC_SECRET||"").trim();return e.length>=16?e:""}function X(t=process.env){return Y(process.env)||Y(t)}function pe(t){let{prepareHash:e,prepareMac:r,note:i,...s}=t||{};return s}function de(t){let e=pe(t);return ae("sha256").update(F(e)).digest("hex")}function me(t,e=X()){return e?ce("sha256",e).update(String(t)).digest("hex"):""}function J(t,{provider:e,kind:r,env:i=process.env}={}){if(!t||typeof t!="object")throw new Error("stampPrepared: payload object required");let s=Object.prototype.hasOwnProperty.call(t,"oraclePrepared");if(s&&typeof t.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let n={...t,provider:t.provider||e,kind:t.kind||r,requiresUserSignature:t.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:s?t.oraclePrepared:!0};if(!n.provider)throw new Error("stampPrepared: provider required");if(!n.kind)throw new Error("stampPrepared: kind required");let a=Date.now(),u=a+ue,c={...n,preparedAt:a,expiresAt:u,prepareVersion:le},h=de(c),g=X(i),b=g?me(h,g):void 0,E={...c,prepareHash:h};return b&&(E.prepareMac=b),E}var ge=/^0x[0-9a-fA-F]{40}$/,fe=10000n,f=class extends Error{constructor(e,r){super(e),this.name="TraitSnipePrepareError",this.failureKind=r}};function K(t={}){let e=t.verdict;if(!e||typeof e!="object")throw new f("prepareTraitSnipeCandidate: verdict object required","verdict-required");if(e.decision!==o.BUY||e.ok!==!0)throw new f(`prepareTraitSnipeCandidate: refusing to prepare a ${e.decision||"unknown"} verdict \u2014 only BUY is preparable`,"not-a-buy");if(!e.edge||!e.liquidity||e.liquidity.illiquid===!0)throw new f("prepareTraitSnipeCandidate: verdict is missing its edge/liquidity evidence","evidence-required");let r=String(t.buyer||"").trim();if(!ge.test(r))throw new f("prepareTraitSnipeCandidate: buyer must be a 0x EVM address \u2014 Oracle never derives it from a key","buyer-required");let i=e.identity||{};if(!i.contract||!i.tokenId)throw new f("prepareTraitSnipeCandidate: verdict identity needs contract and tokenId","identity-required");let s=Number(i.chainId);if(!Number.isInteger(s)||s<=0)throw new f("prepareTraitSnipeCandidate: chainId required","chain-required");let n=$(e.edge.listingPriceWei,"listingPriceWei"),a=BigInt(Math.max(0,Math.trunc(Number(t.maxSlippageBps??0))));if(a>1000n)throw new f("prepareTraitSnipeCandidate: maxSlippageBps is capped at 1000","slippage-cap");let u=n+n*a/fe;return J({provider:"nft-trait-sniper",kind:"nft-trait-snipe-intent",traitSniperVersion:P,chainId:s,contract:i.contract,tokenId:i.tokenId,marketplace:i.marketplace,trait:i.trait,buyer:r,intent:{action:"nft-buy-listing",chainId:s,contract:i.contract,tokenId:i.tokenId,marketplace:i.marketplace,listingPriceWei:n.toString(),maxPriceWei:u.toString(),maxSlippageBps:Number(a),buyer:r},transaction:null,calldata:null,decision:e.decision,reasons:e.reasons,liquidity:e.liquidity,edge:e.edge,requiresUserSignature:!0,requiresExternalFillRoute:!0,marketplaceContacted:!1,orderSubmitted:!1,note:"Unsigned intent metadata only. Oracle did not contact a marketplace, build fill calldata, sign, or broadcast. A user-controlled client must source the order and the user must sign it."},{provider:"nft-trait-sniper",kind:"nft-trait-snipe-intent"})}function he(t={},e={}){let r=Array.isArray(t.ranked)?t.ranked[0]:null;return r?{candidate:K({...e,verdict:r}),verdict:r}:{candidate:null,verdict:null}}export{G as DEFAULT_TRAIT_SNIPE_POLICY,o as TRAIT_DECISIONS,P as TRAIT_SNIPER_VERSION,j as TRIGGER_EVENTS,f as TraitSnipePrepareError,U as evaluateTraitListing,he as prepareTopTraitSnipe,K as prepareTraitSnipeCandidate,se as scanTraitListings};
|
|
1
|
+
function re(t,e="value"){if(typeof t=="number"){if(!Number.isFinite(t))throw new Error(`${e} must be a finite number`);if(Math.abs(t)>Number.MAX_SAFE_INTEGER)throw new Error(`${e} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);if(Number.isInteger(t)&&!Number.isSafeInteger(t))throw new Error(`${e} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return String(t)}if(typeof t=="string"){if(t!==t.trim())throw new Error(`${e} must be a number or decimal string`);return t}throw new Error(`${e} must be a number or decimal string`)}function M(t,e="amount"){if(typeof t=="bigint")return t;if(typeof t=="number"){if(!Number.isInteger(t))throw new Error(`${e} must be an integer`);if(!Number.isSafeInteger(t))throw new Error(`${e} exceeds safe integer precision \u2014 pass it as a decimal string or BigInt so the exact value is preserved`);return BigInt(t)}let r=re(t,e);if(r==="")throw new Error(`${e} is required`);if(!/^-?\d+$/.test(r)&&!/^0x[0-9a-fA-F]+$/.test(r))throw new Error(`${e} must be an integer in decimal or 0x-hex form, got ${JSON.stringify(r)}`);try{return BigInt(r)}catch{throw new Error(`${e} must be an integer, got ${JSON.stringify(r)}`)}}var _=1,o=Object.freeze({BUY:"BUY",PASS:"PASS",NO_TRADE:"NO_TRADE"}),j=Object.freeze(["reveal","repriced","reprice","price_drop","relisted"]),F=10000n,G=Object.freeze({minTraitSales:3,minTraitVolumeWei:"1000000000000000000",minVolumeCoverage:3,minEdgeBps:1200,minEdgeBpsWithoutEvent:2e3,maxPremiumOverCollectionFloorBps:5e3,maxListingAgeMs:900*1e3,maxEventAgeMs:1800*1e3,maxMarketDataAgeMs:3600*1e3,maxTraitWindowHours:72,marketplaceFeeBps:250,royaltyBps:500,maxSpendWei:null});function P(t,e,r,{positive:i=!0,allowZero:p=!1}={}){if(t==null||t==="")return r.push(`${e}: missing`),null;let n;try{n=M(t,e)}catch(a){return r.push(`${e}: ${String(a?.message||a)}`),null}return n<0n?(r.push(`${e}: must not be negative`),null):i&&!p&&n===0n?(r.push(`${e}: must be positive`),null):n}function ie(t,e,r){if(t==null||t==="")return r.push(`${e}: missing`),null;let i=Number(t);return!Number.isInteger(i)||i<0?(r.push(`${e}: must be a non-negative integer`),null):i}function x(t){let e=Number(t);return Number.isFinite(e)?e:null}function u(...t){for(let e of t)if(e!=null&&e!=="")return e;return null}function C(t,e){return e==null||e===0n?null:Number(t*F/e)}function ne(t){let e=x(u(t?.rarityPct,t?.rarity_pct));if(e!=null&&e>0)return Math.round(e*100);let r=x(u(t?.traitSupply,t?.supply,t?.count)),i=x(u(t?.collectionSupply,t?.totalSupply));return r!=null&&i!=null&&r>0&&i>0?Math.round(r/i*1e4):null}function oe(t={}){let e={...G,...t||{}},r=Number(e.marketplaceFeeBps)||0,i=Number(e.royaltyBps)||0;if(r<0||i<0||r+i>=1e4)throw new Error("trait sniper: marketplaceFeeBps + royaltyBps must be >= 0 and < 10000");return e}function d(t,e,r,i={}){return{ok:t===o.BUY,decision:t,failureKind:e,reasons:r,version:_,executed:!1,signed:!1,broadcast:!1,requiresUserSignature:!0,...i}}function U(t={}){let e;try{e=oe(t.policy)}catch(w){return d(o.NO_TRADE,"bad-policy",[String(w?.message||w)])}let r=Number.isFinite(Number(t.nowMs))?Number(t.nowMs):Date.now(),i=t.listing||{},p=t.trait||{},n=t.traitMarket||t.traitStats||{},a=t.collectionMarket||t.collection||{},c={chainId:x(u(t.chainId,i.chainId))??null,contract:String(u(t.contract,t.collectionAddress,i.contract,"")||"")||null,tokenId:String(u(i.tokenId,t.tokenId,"")||"")||null,marketplace:String(u(i.marketplace,i.source,"")||"")||null,trait:{type:String(u(p.type,p.traitType,"")||"")||null,value:String(u(p.value,p.traitValue,"")||"")||null,rarityBps:ne(p)}},l=[],s=P(u(i.priceWei,i.price),"listing.priceWei",l),h=P(u(n.floorPriceWei,n.floorWei),"traitMarket.floorPriceWei",l),y=P(u(n.volumeWei,n.volume),"traitMarket.volumeWei",l,{allowZero:!0}),A=P(u(a.floorPriceWei,a.floorWei),"collectionMarket.floorPriceWei",l),b=ie(u(n.sales,n.salesCount),"traitMarket.sales",l),g=x(u(n.windowHours,n.window_hours));if((g==null||g<=0)&&l.push("traitMarket.windowHours: missing"),l.length)return d(o.NO_TRADE,"insufficient-data",[`missing or unusable market data \u2014 ${l.join("; ")}`],{identity:c,dataGaps:l,liquidity:null,edge:null});if(g>e.maxTraitWindowHours)return d(o.NO_TRADE,"window-too-wide",[`trait stats aggregate ${g}h > maxTraitWindowHours ${e.maxTraitWindowHours}h \u2014 not recent liquidity`],{identity:c,dataGaps:[],liquidity:null,edge:null});let T=x(u(n.observedAtMs,n.asOfMs,a.observedAtMs));if(T==null)return d(o.NO_TRADE,"insufficient-data",["missing or unusable market data \u2014 traitMarket.observedAtMs: missing"],{identity:c,dataGaps:["traitMarket.observedAtMs: missing"],liquidity:null,edge:null});let E=r-T;if(E>e.maxMarketDataAgeMs)return d(o.NO_TRADE,"stale-market-data",[`market snapshot is ${E}ms old > maxMarketDataAgeMs ${e.maxMarketDataAgeMs}ms`],{identity:c,marketAgeMs:E,liquidity:null,edge:null});if(i.flagged===!0||i.reported===!0)return d(o.NO_TRADE,"listing-flagged",["listing is flagged/reported by the marketplace \u2014 a cheap flagged token is cheap for a reason"],{identity:c,liquidity:null,edge:null});let z=y>=s*BigInt(Math.max(0,Math.trunc(e.minVolumeCoverage))),R=M(e.minTraitVolumeWei??0,"policy.minTraitVolumeWei"),W={sales:b,minSales:e.minTraitSales,volumeWei:y.toString(),minVolumeWei:R.toString(),windowHours:g,coverageX:s===0n?null:Number(y/s),minCoverageX:e.minVolumeCoverage,illiquid:!1},$=[];if(b<e.minTraitSales&&$.push(`only ${b} trait sale(s) in ${g}h, need ${e.minTraitSales}`),y<R&&$.push(`trait volume ${y} wei below minTraitVolumeWei ${R} wei`),z||$.push(`trait volume ${y} wei does not cover ${e.minVolumeCoverage}x the ${s} wei listing \u2014 no exit depth`),$.length){W.illiquid=!0;let w=c.trait.rarityBps;return w!=null&&w<=100&&$.push(`trait is rare (${w} bps of supply) but rarity is ranking-only \u2014 an unsold rare trait is an illiquid bag, not an edge`),d(o.NO_TRADE,"illiquid-trait",$,{identity:c,liquidity:W,edge:null,marketAgeMs:E})}let O=String(u(t.event?.kind,t.event?.type,i.eventKind,"")||"").toLowerCase(),V=x(u(t.event?.atMs,i.eventAtMs)),v=V==null?null:r-V,N=j.includes(O)&&v!=null&&v>=0&&v<=e.maxEventAgeMs,B=N?e.minEdgeBps:e.minEdgeBpsWithoutEvent,Z=BigInt(Math.trunc(e.marketplaceFeeBps)),Q=BigInt(Math.trunc(e.royaltyBps)),H=h*(F-Z-Q)/F,q=H-s,ee=C(h-s,h),I=C(s-A,A),k=C(q,s),te={listingPriceWei:s.toString(),traitFloorWei:h.toString(),collectionFloorWei:A.toString(),netExitWei:H.toString(),edgeWei:q.toString(),edgeBps:k,requiredEdgeBps:B,discountToTraitFloorBps:ee,premiumToCollectionFloorBps:I,feeBps:e.marketplaceFeeBps,royaltyBps:e.royaltyBps,triggered:N,eventKind:O||null,eventAgeMs:v},S={identity:c,liquidity:W,edge:te,marketAgeMs:E},L=x(u(i.listedAtMs,i.listedAt)),m=L==null?null:r-L;if(i.stale===!0)return d(o.PASS,"listing-stale",["listing is marked stale by the caller"],S);if(m==null)return d(o.NO_TRADE,"insufficient-data",["missing or unusable market data \u2014 listing.listedAtMs: missing"],{...S,dataGaps:["listing.listedAtMs: missing"]});if(m<0)return d(o.NO_TRADE,"listing-in-future",[`listing.listedAtMs is ${-m}ms in the future`],S);if(m>e.maxListingAgeMs)return d(o.PASS,"listing-stale",[`listing is ${m}ms old > maxListingAgeMs ${e.maxListingAgeMs}ms \u2014 the mispricing is not live`],{...S,listingAgeMs:m});if(e.maxSpendWei!=null&&e.maxSpendWei!==""){let w=M(e.maxSpendWei,"policy.maxSpendWei");if(s>w)return d(o.PASS,"spend-cap",[`listing ${s} wei exceeds maxSpendWei ${w} wei`],{...S,listingAgeMs:m})}return s>=h?d(o.PASS,"no-discount",[`listing ${s} wei is at or above the trait floor ${h} wei`],{...S,listingAgeMs:m}):I!=null&&I>e.maxPremiumOverCollectionFloorBps?d(o.PASS,"collection-floor-premium",[`listing sits ${I} bps over the collection floor > maxPremiumOverCollectionFloorBps ${e.maxPremiumOverCollectionFloorBps} bps`],{...S,listingAgeMs:m}):q<=0n||k==null||k<B?d(o.PASS,"edge-below-threshold",[`net edge ${k??0} bps after ${e.marketplaceFeeBps}+${e.royaltyBps} bps costs is below the ${B} bps required${N?"":" without a reveal/reprice trigger"}`],{...S,listingAgeMs:m}):d(o.BUY,null,[`${b} trait sale(s) and ${y} wei of volume in ${g}h clear the liquidity gate`,`net edge ${k} bps vs trait floor after ${e.marketplaceFeeBps}+${e.royaltyBps} bps costs, required ${B} bps`,N?`${O} event ${v}ms ago explains the mispricing`:"no trigger event \u2014 cleared the higher untriggered bar"],{...S,listingAgeMs:m})}function se(t=[],e={}){if(!Array.isArray(t))throw new TypeError("scanTraitListings: listings array required");let r=t.map((n,a)=>{let c={...e,...n,policy:{...e.policy||{},...n?.policy||{}}},l=U(c);return{index:a,...l}}),i=r.filter(n=>n.decision===o.BUY),p=[...i].sort((n,a)=>{let c=(a.edge?.edgeBps??0)-(n.edge?.edgeBps??0);if(c!==0)return c;let l=n.identity?.trait?.rarityBps??Number.MAX_SAFE_INTEGER,s=a.identity?.trait?.rarityBps??Number.MAX_SAFE_INTEGER;return l!==s?l-s:n.index-a.index});return{evaluated:r,ranked:p,counts:{total:r.length,buy:i.length,pass:r.filter(n=>n.decision===o.PASS).length,noTrade:r.filter(n=>n.decision===o.NO_TRADE).length},executed:!1,signed:!1,broadcast:!1}}import{createHash as ae,createHmac as ce,timingSafeEqual as be}from"node:crypto";var le=2,ue=300*1e3,pe=(()=>{let t=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(t)&&t>0?t:1800*1e3})();function D(t){return t===null||typeof t!="object"?JSON.stringify(t):Array.isArray(t)?`[${t.map(D).join(",")}]`:`{${Object.keys(t).sort().map(r=>`${JSON.stringify(r)}:${D(t[r])}`).join(",")}}`}function Y(t){let e=String(t?.ORACLE_STAMP_HMAC_SECRET||"").trim();return e.length>=16?e:""}function X(t=process.env){return Y(process.env)||Y(t)}function de(t){let{prepareHash:e,prepareMac:r,note:i,...p}=t||{};return p}function me(t){let e=de(t);return ae("sha256").update(D(e)).digest("hex")}function ge(t,e=X()){return e?ce("sha256",e).update(String(t)).digest("hex"):""}function J(t,{provider:e,kind:r,env:i=process.env,nowMs:p=Date.now(),expiresAtMs:n}={}){if(!t||typeof t!="object")throw new Error("stampPrepared: payload object required");let a=Object.prototype.hasOwnProperty.call(t,"oraclePrepared");if(a&&typeof t.oraclePrepared!="boolean")throw new Error("stampPrepared: oraclePrepared must be boolean");let c={...t,provider:t.provider||e,kind:t.kind||r,requiresUserSignature:t.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1,oraclePrepared:a?t.oraclePrepared:!0};if(!c.provider)throw new Error("stampPrepared: provider required");if(!c.kind)throw new Error("stampPrepared: kind required");let l=Number(p),s=n==null?l+ue:Number(n),h=s-l;if(!Number.isSafeInteger(l)||!Number.isSafeInteger(s)||h<=0||h>pe)throw new Error("stampPrepared: bounded preparedAt/expiresAt required");let A={...c,preparedAt:l,expiresAt:s,prepareVersion:le},b=me(A),g=X(i),T=g?ge(b,g):void 0,E={...A,prepareHash:b};return T&&(E.prepareMac=T),E}var fe=/^0x[0-9a-fA-F]{40}$/,he=10000n,f=class extends Error{constructor(e,r){super(e),this.name="TraitSnipePrepareError",this.failureKind=r}};function K(t={}){let e=t.verdict;if(!e||typeof e!="object")throw new f("prepareTraitSnipeCandidate: verdict object required","verdict-required");if(e.decision!==o.BUY||e.ok!==!0)throw new f(`prepareTraitSnipeCandidate: refusing to prepare a ${e.decision||"unknown"} verdict \u2014 only BUY is preparable`,"not-a-buy");if(!e.edge||!e.liquidity||e.liquidity.illiquid===!0)throw new f("prepareTraitSnipeCandidate: verdict is missing its edge/liquidity evidence","evidence-required");let r=String(t.buyer||"").trim();if(!fe.test(r))throw new f("prepareTraitSnipeCandidate: buyer must be a 0x EVM address \u2014 Oracle never derives it from a key","buyer-required");let i=e.identity||{};if(!i.contract||!i.tokenId)throw new f("prepareTraitSnipeCandidate: verdict identity needs contract and tokenId","identity-required");let p=Number(i.chainId);if(!Number.isInteger(p)||p<=0)throw new f("prepareTraitSnipeCandidate: chainId required","chain-required");let n=M(e.edge.listingPriceWei,"listingPriceWei"),a=BigInt(Math.max(0,Math.trunc(Number(t.maxSlippageBps??0))));if(a>1000n)throw new f("prepareTraitSnipeCandidate: maxSlippageBps is capped at 1000","slippage-cap");let c=n+n*a/he;return J({provider:"nft-trait-sniper",kind:"nft-trait-snipe-intent",traitSniperVersion:_,chainId:p,contract:i.contract,tokenId:i.tokenId,marketplace:i.marketplace,trait:i.trait,buyer:r,intent:{action:"nft-buy-listing",chainId:p,contract:i.contract,tokenId:i.tokenId,marketplace:i.marketplace,listingPriceWei:n.toString(),maxPriceWei:c.toString(),maxSlippageBps:Number(a),buyer:r},transaction:null,calldata:null,decision:e.decision,reasons:e.reasons,liquidity:e.liquidity,edge:e.edge,requiresUserSignature:!0,requiresExternalFillRoute:!0,marketplaceContacted:!1,orderSubmitted:!1,note:"Unsigned intent metadata only. Oracle did not contact a marketplace, build fill calldata, sign, or broadcast. A user-controlled client must source the order and the user must sign it."},{provider:"nft-trait-sniper",kind:"nft-trait-snipe-intent"})}function Se(t={},e={}){let r=Array.isArray(t.ranked)?t.ranked[0]:null;return r?{candidate:K({...e,verdict:r}),verdict:r}:{candidate:null,verdict:null}}export{G as DEFAULT_TRAIT_SNIPE_POLICY,o as TRAIT_DECISIONS,_ as TRAIT_SNIPER_VERSION,j as TRIGGER_EVENTS,f as TraitSnipePrepareError,U as evaluateTraitListing,Se as prepareTopTraitSnipe,K as prepareTraitSnipeCandidate,se as scanTraitListings};
|