@oracle-agent/oracle 0.24.4 → 0.24.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -30
- package/SETUP.md +23 -2
- package/dist/assets/profiles/protocol-builder/SOUL.md +6 -1
- package/dist/assets/profiles/protocol-builder/profile.json +1 -1
- package/dist/assets/skills/oracle-desk-product/SKILL.md +1 -1
- package/dist/assets/skills/oracle-multichain-nft-launch/SKILL.md +2 -2
- package/dist/assets/skills/oracle-multichain-token-launch/SKILL.md +2 -2
- package/dist/assets/skills/oracle-protocol-builder/SKILL.md +44 -8
- package/dist/bin/desk-server.mjs +147 -17
- package/dist/bin/oracle-data-mcp.mjs +7 -7
- package/dist/bin/oracle-route.mjs +3 -3
- package/dist/cli/commands/chat.mjs +89 -89
- package/dist/cli/commands/doctor.mjs +5 -5
- package/dist/cli/commands/harness.mjs +5 -5
- package/dist/cli/commands/model.mjs +96 -96
- package/dist/cli/commands/receipt.mjs +3 -3
- package/dist/cli/commands/sign.mjs +12 -12
- package/dist/cli/commands/signer.mjs +14 -8
- package/dist/cli/commands/swap.mjs +2 -2
- package/dist/cli/commands/venues.mjs +3 -3
- package/dist/data/desk-data.mjs +145 -15
- package/dist/index.mjs +150 -20
- package/dist/local-signer/index.mjs +1 -4
- package/dist/router/index.mjs +2 -2
- package/package.json +1 -1
|
@@ -1,4 +1 @@
|
|
|
1
|
-
import{createCipheriv as X,createDecipheriv as Z,randomBytes as v,scryptSync as K}from"node:crypto";import s from"node:fs";import m from"node:path";var R="ORACLE-LOCAL-VAULT",F=1,x=Object.freeze({N:1<<17,r:8,p:1}),Q=256*1024*1024,ee=16*1024;function O(e,r,n,{max:t=r}={}){if(typeof e!="string"||!/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(e))throw new Error(`local-vault: invalid ${n} encoding`);let i=Buffer.from(e,"base64");if(i.toString("base64")!==e||i.length<r||i.length>t)throw new Error(`local-vault: invalid ${n} length`);return i}function j(e,r,n=x){let t=String(e??"");if(t.length<12)throw new Error("local-vault: passphrase must be at least 12 characters");return K(t,r,32,{...n,maxmem:Q})}function Oe(e,r,n={}){let t=Buffer.isBuffer(e)?Buffer.from(e):Buffer.from(String(e));if(!t.length)throw new Error("local-vault: refusing empty key material");let i=v(32),o=v(12),a={magic:R,version:F,kdf:{name:"scrypt",...x,salt:i.toString("base64")},cipher:{name:"aes-256-gcm",iv:o.toString("base64")},meta:{address:n.address?String(n.address).toLowerCase():null,kind:n.kind||"evm",createdAt:new Date().toISOString()}},c=j(r,i);try{let u=X("aes-256-gcm",c,o);u.setAAD(Buffer.from(JSON.stringify(a)));let f=Buffer.concat([u.update(t),u.final()]);return{...a,ciphertext:f.toString("base64"),tag:u.getAuthTag().toString("base64")}}finally{c.fill(0),t.fill(0)}}function ve(e,r){if(e?.magic!==R||e?.version!==F)throw new Error("local-vault: unsupported vault file");if(e?.kdf?.name!=="scrypt"||e?.cipher?.name!=="aes-256-gcm")throw new Error("local-vault: unsupported cryptography");if(e.kdf.N!==x.N||e.kdf.r!==x.r||e.kdf.p!==x.p)throw new Error("local-vault: unsupported KDF parameters");if(Object.keys(e.kdf).sort().join(",")!=="N,name,p,r,salt"||Object.keys(e.cipher).sort().join(",")!=="iv,name")throw new Error("local-vault: unexpected cryptography field");if(!e.meta||Object.keys(e.meta).some(d=>!["address","kind","createdAt"].includes(d))||String(e.meta.kind||"").length>16||String(e.meta.address||"").length>128||!Number.isFinite(Date.parse(e.meta.createdAt)))throw new Error("local-vault: invalid metadata");let n=["magic","version","kdf","cipher","meta","ciphertext","tag"];if(Object.keys(e).some(d=>!n.includes(d)))throw new Error("local-vault: unexpected vault field");let t=O(e.kdf.salt,32,"salt"),i=O(e.cipher.iv,12,"iv"),o=O(e.tag,16,"tag"),a=O(e.ciphertext,1,"ciphertext",{max:ee}),{ciphertext:c,tag:u,...f}=e,l=j(r,t);try{let d=Z("aes-256-gcm",l,i);return d.setAAD(Buffer.from(JSON.stringify(f))),d.setAuthTag(o),Buffer.concat([d.update(a),d.final()])}catch{throw new Error("local-vault: wrong passphrase or tampered vault")}finally{l.fill(0)}}function U(e){let r=s.lstatSync(e);if(r.isSymbolicLink())throw new Error("local-vault: refusing symlink");if(!r.isFile())throw new Error("local-vault: secret source must be a regular file");if(r.uid!==process.getuid?.())throw new Error("local-vault: secret source must be owned by this user");if(r.nlink!==1)throw new Error("local-vault: refusing hard-linked secret source");if((r.mode&63)!==0)throw new Error("local-vault: secret source must be owner-only (0600)")}function $(e){let r=m.dirname(e),n=s.lstatSync(r);if(!n.isDirectory()||n.isSymbolicLink())throw new Error("local-vault: unsafe destination directory");if(n.uid!==process.getuid?.())throw new Error("local-vault: destination directory must be owned by this user");try{let t=s.lstatSync(e);if(t.isSymbolicLink())throw new Error("local-vault: refusing symlink destination");if(!t.isFile()||t.uid!==process.getuid?.()||t.nlink!==1)throw new Error("local-vault: unsafe destination file");if(t.dev!==n.dev)throw new Error("local-vault: destination device mismatch")}catch(t){if(t.code!=="ENOENT")throw t}}function w(e){let r=s.lstatSync(e);U(e);let n=s.openSync(e,s.constants.O_RDONLY|s.constants.O_NOFOLLOW);try{let t=s.fstatSync(n);if(r.dev!==t.dev||r.ino!==t.ino||t.size>1024*1024)throw new Error("local-vault: secret source changed or is too large");return s.readFileSync(n,"utf8").replace(/[\r\n]+$/,"")}finally{s.closeSync(n)}}function be(e){return U(e),JSON.parse(s.readFileSync(e,"utf8"))}function Ne(e,r){s.mkdirSync(m.dirname(e),{recursive:!0,mode:448}),$(e);let n=m.join(m.dirname(e),`.${m.basename(e)}.${process.pid}.${v(6).toString("hex")}.tmp`),t;try{t=s.openSync(n,s.constants.O_CREAT|s.constants.O_EXCL|s.constants.O_WRONLY|s.constants.O_NOFOLLOW,384),s.writeFileSync(t,JSON.stringify(r,null,2)+`
|
|
2
|
-
`),s.fsyncSync(t),s.closeSync(t),t=void 0;let i=s.openSync(n,s.constants.O_RDONLY|s.constants.O_NOFOLLOW),o;try{o=s.fstatSync(i)}finally{s.closeSync(i)}let a=s.lstatSync(m.dirname(e));if(o.nlink!==1||o.dev!==a.dev||o.uid!==process.getuid?.())throw new Error("local-vault: unsafe temporary file");s.renameSync(n,e),s.chmodSync(e,384);let c=s.openSync(m.dirname(e),"r");try{s.fsyncSync(c)}finally{s.closeSync(c)}}catch(i){if(t!==void 0)try{s.closeSync(t)}catch{}try{s.unlinkSync(n)}catch{}throw i}return e}function B(e,r){s.mkdirSync(m.dirname(e),{recursive:!0,mode:448}),$(e);let n=m.join(m.dirname(e),`.${m.basename(e)}.${process.pid}.${v(6).toString("hex")}.tmp`);try{let t=s.openSync(n,s.constants.O_CREAT|s.constants.O_EXCL|s.constants.O_WRONLY|s.constants.O_NOFOLLOW,384);try{s.writeFileSync(t,String(r)),s.fsyncSync(t)}finally{s.closeSync(t)}s.renameSync(n,e),s.chmodSync(e,384);let i=s.openSync(m.dirname(e),"r");try{s.fsyncSync(i)}finally{s.closeSync(i)}}catch(t){try{s.unlinkSync(n)}catch{}throw t}}import{createHash as oe,randomBytes as ie,timingSafeEqual as se}from"node:crypto";var W=new Set(["evm","evm-swap","evm-bridge","btc","sol"]),G=Object.freeze({swap:5,bridge:5,perps:0,nft:0}),b=(e,r,n=256)=>{if(typeof e!="string"||!e||e.length>n)throw new Error(`envelope: bounded ${r} required`);return e},S=(e,r)=>{try{let n=BigInt(e);if(n<0n)throw 0;return n}catch{throw new Error(`envelope: ${r} must be a non-negative integer`)}},re=(e,r)=>{if(!Array.isArray(e)||e.length===0)throw new Error(`policy: ${r} allowlist is empty`);return e},h=(e,r,n)=>{if(!re(r,n).map(t=>String(t).toLowerCase()).includes(String(e).toLowerCase()))throw new Error(`policy: ${n} not allowed`)};function te(e,{localsWaiver:r=!1}={}){if(!(e in G))throw new Error("fee: unknown action");return r?0:G[e]}function C(e,r,{nowMs:n=Date.now()}={}){if(!e||e.version!==1)throw new Error("envelope: version 1 required");let t=b(e.surface,"surface",16);if(!W.has(t))throw new Error("envelope: unsupported public surface");let i=b(e.action,"action",32);if(h(t,r.surfaces,"surface"),h(i,r.actions,"action"),h(e.owner,r.owners,"owner"),h(e.destination,r.destinations,"destination"),!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=n||e.expiresAtMs-n>Number(r.maxTtlMs))throw new Error("policy: TTL outside bounds");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>Number(r.maxSlippageBps))throw new Error("policy: slippage exceeds cap");let o=e.artifact;if(!o||typeof o!="object"||Array.isArray(o))throw new Error("envelope: structured artifact required");if(t.startsWith("evm")){h(Number(o.chainId),r.chains,"chain");let c=String(o.data||"0x").slice(0,10).toLowerCase();if(h(c,r.selectors,"selector"),String(o.to).toLowerCase()!==String(e.destination).toLowerCase())throw new Error("envelope: destination mismatch");if(S(o.value??0,"value")>S(r.maxValueWei,"maxValueWei"))throw new Error("policy: value exceeds cap");let u=S(o.gasLimit,"gasLimit"),f=S(o.maxFeePerGas??o.gasPrice,"feePerGas");if(u>S(r.maxGasLimit,"maxGasLimit")||u*f>S(r.maxFeeWei,"maxFeeWei"))throw new Error("policy: gas/fee exceeds cap")}else if(t==="btc"){if(b(o.psbt,"PSBT",1e5),h(o.network,r.chains,"chain"),!Array.isArray(o.outputs)||o.outputs.length===0||o.outputs.some(c=>!c.address||S(c.valueSats,"output value")<0n))throw new Error("envelope: bounded BTC outputs required")}else if(t==="sol"){if(b(o.messageBase64,"Solana message",1e5),h(o.cluster,r.chains,"chain"),!Array.isArray(o.programIds)||o.programIds.length===0)throw new Error("envelope: Solana program ids required");for(let c of o.programIds)h(c,r.programs,"program")}else throw new Error("envelope: unsupported public surface");let a=te(i,{localsWaiver:e.fee?.waiver==="locals-only-verified"});if(Number(e.fee?.oracleFeeBps)!==a)throw new Error("fee: final artifact fee mismatch");return!0}var ne=Object.freeze([...W]);function Le(e={}){let r={};for(let n of ne){let t=e[n];if(t){if(typeof t.sign!="function"||typeof t.broadcast!="function")throw new Error(`adapter: ${n} requires sign and broadcast functions`);r[n]=Object.freeze({sign:(i,o)=>t.sign(structuredClone(i),structuredClone(o)),broadcast:(i,o,a)=>t.broadcast(i,structuredClone(o),structuredClone(a))})}}return Object.freeze(r)}function Te(e,r){let n=e?.surface||"evm",t=r?.[n];if(!t)throw new Error(`adapter: ${n} is not configured on this self-host`);return t}var N=e=>String(e||"").toLowerCase(),y=(e,r)=>{try{let n=BigInt(e??0);if(n<0n)throw 0;return n}catch{throw new Error(`policy: ${r} must be a non-negative integer`)}},A=(e,r,n,t=String)=>{if(!Array.isArray(r)||r.length===0)throw new Error(`policy: ${n} allowlist is empty`);if(!r.map(t).includes(t(e)))throw new Error(`policy: ${n} not allowed`)};function g(e){return oe("sha256").update(JSON.stringify(e)).digest("hex")}function ae(e){let r=String(e||"").toLowerCase();return!r.startsWith("0x095ea7b3")||r.length!==138?null:{spender:`0x${r.slice(34,74)}`,amount:BigInt(`0x${r.slice(74)}`)}}function H(e,r,{nowMs:n=Date.now()}={}){if(!e||!r)throw new Error("policy: artifact and policy required");A(Number(e.chainId),r.chains,"chain",Number),A(e.to,r.destinations,"destination",N),A(String(e.data||"0x").slice(0,10),r.selectors,"selector",a=>String(a).toLowerCase()),A(e.from,r.owners,"owner",N);let t=ae(e.data);if(String(e.data||"").slice(0,10).toLowerCase()==="0x095ea7b3"){if(!t)throw new Error("policy: malformed approval calldata");if(A(t.spender,r.spenders,"spender",N),t.amount>y(r.maxApproval,"maxApproval"))throw new Error("policy: approval exceeds cap")}if(y(e.value,"value")>y(r.maxValueWei,"maxValueWei"))throw new Error("policy: value exceeds cap");let i=y(e.gasLimit,"gasLimit");if(i>y(r.maxGasLimit,"maxGasLimit"))throw new Error("policy: gas exceeds cap");if(y(e.maxFeePerGas??e.gasPrice,"feePerGas")*i>y(r.maxFeeWei,"maxFeeWei"))throw new Error("policy: fee exceeds cap");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>Number(r.maxSlippageBps))throw new Error("policy: slippage attestation exceeds cap");if(!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=n)throw new Error("policy: artifact expired");return!0}var _=class{#e=new Map;constructor({now:r=Date.now}={}){this.now=r}issue({artifact:r,owner:n,ttlMs:t=6e4}){if(t<=0||t>12e4)throw new Error("confirmation: ttl out of range");let i=ie(32).toString("hex");return this.#e.set(i,{digest:g(r),owner:N(n),expiresAtMs:this.now()+t}),i}consume(r,n){let t=this.#e.get(String(r));if(!t)throw new Error("confirmation: used or unknown nonce");if(t.expiresAtMs<=this.now())throw this.#e.delete(String(r)),new Error("confirmation: expired nonce");let i=Buffer.from(t.digest,"hex"),o=Buffer.from(g(n),"hex");if(!se(i,o))throw new Error("confirmation: artifact mismatch");return this.#e.delete(String(r)),t}clear(){this.#e.clear()}};function ce(e={},r={}){let n={};for(let t of new Set([...Object.keys(e),...Object.keys(r)]))n[t]=(BigInt(r[t]??0)-BigInt(e[t]??0)).toString();return n}async function J(e,r,n){if(!n.isArmed())throw new Error("signer: disarmed");let t=e?.version===1&&e?.surface?e:null,i=t?t.artifact:e,o=typeof n.readPolicy=="function"?n.readPolicy():n.policy,a=o?.confirmationMode||"exact-human";if(n.autonomous===!0){if(n.env?.ORACLE_AUTONOMOUS_TRADING!=="1")throw new Error("signer: autonomous execution requires ORACLE_AUTONOMOUS_TRADING=1");if(typeof n.verifyTriggerAttestation!="function"||await n.verifyTriggerAttestation(t?.triggerAttestation,e)!==!0)throw new Error("signer: autonomous trigger attestation required")}else if(a==="exact-human")n.confirmations.consume(r,e);else if(a!=="auto-within-rails")throw new Error("signer: unsupported confirmation mode");let c=g(e),u=()=>typeof n.nowMs=="function"?n.nowMs():n.nowMs??Date.now();t?C(t,o,{nowMs:u()}):H(e,o,{nowMs:u()}),typeof n.reserveLedger=="function"&&n.reserveLedger(t||e,o);let f=await n.sign(i,t);if(!n.isArmed())throw new Error("signer: disarmed before broadcast");if(g(e)!==c)throw new Error("signer: artifact mutated after signing");o=typeof n.readPolicy=="function"?n.readPolicy():n.policy,t?C(t,o,{nowMs:u()}):H(e,o,{nowMs:u()});let l=await n.broadcast(f,i,t),d=l?.status,T=d===1||d==="0x1"?"success":d===0||d==="0x0"?"failed":"pending",k=l?.verifiedBefore??l?.before,I=l?.verifiedAfter??l?.after;return{prepared:e,signed:f,receipt:{transactionHash:l?.hash||l?.transactionHash||null,status:T,balanceDeltaVerified:!!(l?.verifiedBefore&&l?.verifiedAfter),delta:ce(k,I)}}}import ue from"node:http";import{timingSafeEqual as fe}from"node:crypto";var q=new Set(["127.0.0.1","::1","localhost"]),le=(e,r)=>{let n=Buffer.from(String(e)),t=Buffer.from(String(r));return n.length===t.length&&fe(n,t)},p=(e,r,n)=>{let t=JSON.stringify(n);e.writeHead(r,{"content-type":"application/json","cache-control":"no-store","content-length":Buffer.byteLength(t)}),e.end(t)},V=e=>new Promise((r,n)=>{let t=0,i=[],o=!1;e.on("data",a=>{t+=a.length,t>64*1024&&!o?(o=!0,n(new Error("request refused")),e.resume()):o||i.push(a)}),e.on("end",()=>{if(!o)try{r(JSON.parse(Buffer.concat(i).toString()||"{}"))}catch{n(new Error("request refused"))}}),e.on("error",n)});function Re(e={}){let r=e.host||"127.0.0.1";if(!q.has(r))throw new Error("signer: loopback bind required");if(String(e.token||"").length<32)throw new Error("signer: strong auth token required");let n=e.confirmations||new _,t=e.origin||`http://${r}`;return ue.createServer(async(o,a)=>{try{let c=String(o.headers.authorization||"").replace(/^Bearer /i,"");if(!le(c,e.token))return p(a,401,{error:"unauthorized"});let u=String(o.headers.host||"").replace(/^\[|\](?=:|$)/g,"").split(":")[0];if(!q.has(u))return p(a,403,{error:"host refused"});if(o.headers.origin&&o.headers.origin!==t)return p(a,403,{error:"origin refused"});if(o.method==="GET"&&o.url==="/status")return p(a,200,{ok:!0,armed:e.isArmed?.()===!0,sessionExpiresAtMs:e.sessionExpiresAtMs||null});if(o.method==="POST"&&o.url==="/disarm")return e.disarm?.(),n.clear(),p(a,200,{ok:!0,armed:!1});if(!["GET","POST"].includes(o.method))return p(a,405,{error:"request refused"});if(o.method==="POST"&&String(o.headers["content-type"]||"").split(";",1)[0].trim().toLowerCase()!=="application/json")return p(a,415,{error:"request refused"});if(o.method==="POST"&&o.url==="/confirm"){let f=await V(o),l=g(f.artifact);if(e.autonomous!==!0){if(typeof e.confirmArtifact!="function")return p(a,403,{error:"local human confirmation unavailable"});if(await e.confirmArtifact(f.artifact,l)!==!0)return p(a,400,{error:"exact human confirmation refused"})}return p(a,200,{confirmationNonce:n.issue({artifact:f.artifact,owner:f.artifact?.from,ttlMs:f.ttlMs})})}if(o.method==="POST"&&o.url==="/execute"){let f=await V(o),l=await J(f.artifact,f.confirmationNonce,{...e,confirmations:n});return p(a,200,l)}return p(a,404,{error:"not found"})}catch(c){return e.onError?.(String(c?.message||c)),p(a,400,{error:"request refused"})}})}import{createHmac as pe,timingSafeEqual as me}from"node:crypto";import{homedir as D}from"node:os";import{join as M}from"node:path";var z=process.env.ORACLE_PUBLIC_DESKTOP==="1",de=z?process.env.ORACLE_CONFIG_DIR||M(D(),".config","oracle"):M(D(),".config","oracle"),$e=z?de:M(D(),".config","mad-desk");var qe="0".repeat(64),Ve=Object.freeze({PREPARE:"exec.prepare",SIGN:"exec.sign",BROADCAST:"exec.broadcast",POLICY_REJECT:"policy.reject",AUTH_GRANT:"auth.grant",AUTH_OK:"auth.verify.ok",AUTH_FAIL:"auth.verify.fail"});function L(e){return e==null?"null":typeof e!="object"?JSON.stringify(e):Array.isArray(e)?"["+e.map(L).join(",")+"]":"{"+Object.keys(e).sort().map(n=>JSON.stringify(n)+":"+L(e[n])).join(",")+"}"}var ze=Promise.resolve();var he=864e5,E=(e,r)=>pe("sha256",r).update(L(e)).digest("hex"),P=(e,r)=>{let n=Buffer.from(String(e)),t=Buffer.from(String(r));return n.length===t.length&&me(n,t)};function ge(e,r){if(!e||typeof e!="object"||Array.isArray(e))throw new Error("policy: object required");return{policy:e,integrity:{algorithm:"hmac-sha256-canonical-json-v1",mac:E(e,r)}}}function we(e,r){if(e?.integrity?.algorithm!=="hmac-sha256-canonical-json-v1"||!P(e.integrity.mac,E(e.policy,r)))throw new Error("policy: integrity verification failed");return structuredClone(e.policy)}function er(e,r){let n=w(r),t;try{t=JSON.parse(w(e))}catch(i){throw new Error(`policy: cannot read sealed policy: ${i?.message||i}`)}return we(t,n)}function Se(e,r,n){try{let t=JSON.parse(w(e));if(!P(t?.integrity?.mac,E(t.ledger,r)))throw new Error("integrity verification failed");let i=t.ledger;if(!Number.isFinite(i?.windowStartMs)||!Array.isArray(i?.entries))throw new Error("invalid ledger");return n-i.windowStartMs>=he?{windowStartMs:n,entries:[]}:i}catch(t){if(t?.code==="ENOENT")return{windowStartMs:n,entries:[]};throw new Error(`ledger: corrupt or unreadable: ${t?.message||t}`)}}function Y(e,r){return e.reduce((n,t)=>n+BigInt(t[r]??0),0n)}function rr({file:e,keyFile:r,tradeId:n,value:t=0,notional:i=0,policy:o,nowMs:a=Date.now()}){if(!/^[A-Za-z0-9._:-]{1,128}$/.test(String(n||"")))throw new Error("ledger: bounded tradeId required");let c=w(r),u=Se(e,c,a);if(u.entries.some(I=>I.tradeId===n))throw new Error("ledger: replayed tradeId");let f=BigInt(t),l=BigInt(i),d=BigInt(o.maxDailyValueWei),T=BigInt(o.maxDailyNotional??o.maxDailyValueWei),k=BigInt(o.maxPerTrade??o.maxValueWei);if(f<0n||l<0n||l>k)throw new Error("ledger: per-trade cap exceeded");if(Y(u.entries,"value")+f>d||Y(u.entries,"notional")+l>T)throw new Error("ledger: daily cap exceeded");return u.entries.push({tradeId:String(n),value:f.toString(),notional:l.toString(),atMs:a}),B(e,JSON.stringify({ledger:u,integrity:{algorithm:"hmac-sha256-canonical-json-v1",mac:E(u,c)}})+`
|
|
3
|
-
`),structuredClone(u)}function tr(e,r,n){let t=w(r);B(e,JSON.stringify(ge(n,t),null,2)+`
|
|
4
|
-
`)}function nr(e,r,n){let t={triggerId:String(r.triggerId),issuedAtMs:Number(r.issuedAtMs),expiresAtMs:Number(r.expiresAtMs),artifactDigest:g(e)};return{...t,algorithm:"hmac-sha256-canonical-json-v1",mac:E(t,n)}}function or(e,r,n,t=Date.now()){if(e?.algorithm!=="hmac-sha256-canonical-json-v1"||!/^[A-Za-z0-9._:-]{1,128}$/.test(String(e?.triggerId||""))||!Number.isFinite(e.issuedAtMs)||!Number.isFinite(e.expiresAtMs)||e.issuedAtMs>t||e.expiresAtMs<=t||e.expiresAtMs-e.issuedAtMs>12e4)return!1;let i={triggerId:e.triggerId,issuedAtMs:e.issuedAtMs,expiresAtMs:e.expiresAtMs,artifactDigest:g(r)};return P(e.mac,E(i,w(n)))}import{spawnSync as ye}from"node:child_process";function ar(e="oracle-local-signer",r=process.env.USER||process.env.USERNAME||"oracle"){let n,t;if(process.platform==="darwin")n="/usr/bin/security",t=["find-generic-password","-s",e,"-a",r,"-w"];else if(process.platform==="linux")n="secret-tool",t=["lookup","service",e,"account",r];else throw new Error("signer: OS credential lookup is supported on macOS and Linux; use a protected passphrase file on this platform");let i=ye(n,t,{encoding:"utf8",stdio:["ignore","pipe","ignore"],env:{PATH:process.env.PATH,HOME:process.env.HOME,USER:process.env.USER,LOGNAME:process.env.LOGNAME,DBUS_SESSION_BUS_ADDRESS:process.env.DBUS_SESSION_BUS_ADDRESS}}),o=String(i.stdout||"").replace(/[\r\n]+$/,"");if(i.status!==0||o.length<12)throw new Error("signer: OS credential passphrase unavailable");return o}export{_ as ConfirmationStore,ne as PUBLIC_SIGNER_SURFACES,x as SCRYPT,R as VAULT_MAGIC,F as VAULT_VERSION,g as artifactDigest,H as assertExactPolicy,Re as createSignerServer,Le as createSurfaceAdapters,nr as createTriggerAttestation,ve as decryptVault,Oe as encryptVault,J as executeConfirmedArtifact,we as openPolicy,te as publicFeeBps,ar as readCredentialPassphrase,w as readProtectedSecretFile,er as readSealedPolicy,be as readVault,rr as reserveLedger,ge as sealPolicy,Te as surfaceAdapterFor,C as validateSurfaceEnvelope,or as verifyTriggerAttestation,B as writeProtectedTextAtomic,tr as writeSealedPolicy,Ne as writeVaultAtomic};
|
|
1
|
+
import{createHash as De,randomBytes as Pe,timingSafeEqual as Ve}from"node:crypto";import{Interface as Te,MaxUint256 as $r,isAddress as Br,keccak256 as Lr,toUtf8Bytes as kr}from"ethers";import{Interface as ye,isAddress as dr}from"ethers";import{isAddress as ar}from"ethers";import{createHash as he,createHmac as ge,timingSafeEqual as be}from"node:crypto";import{readFileSync as pe}from"node:fs";import{homedir as me}from"node:os";import{join as M}from"node:path";function le(){if(process.env.ORACLE_TEST_ISOLATE_SECRETS==="1"){let t=(process.env.ORACLE_EXEC_ENV_FILE||"").trim();return t?[t]:[]}let e=(process.env.ORACLE_EXEC_ENV_FILE||process.env.MAD_EXEC_ENV_FILE||"").trim(),r=me();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let t=(process.env.ORACLE_CONFIG_DIR||M(r,".config","oracle")).trim();return[e,M(t,"exec.env")].filter(Boolean)}return[e,M(r,".config","oracle","exec.env"),M(r,".config","mad-desk","exec.env")].filter(Boolean)}function C(e,r,t){let o=e??process.env[r]??process.env[t];if(!String(o||"").trim())for(let a of le())try{let n=pe(a,"utf8"),i=n.match(new RegExp(`^${r}=(.*)$`,"m"))||n.match(new RegExp(`^${t}=(.*)$`,"m"));if(i&&(o=i[1].trim(),o))break}catch{}if(!String(o||"").trim())throw new Error(`${r} required for attestation. Set it in the environment, or place ${r}=<value> in ~/.config/oracle/exec.env`);return o}function y(e,r,t="guard"){let o=Number(r);if(r==null||!Number.isFinite(o))throw new Error(`${t}: current time must be a finite number (got ${we(r)})`);let a=Number(e?.issuedAtMs),n=Number(e?.expiresAtMs);if(!Number.isFinite(n))throw new Error(`${t}: expiresAtMs is required and must be a finite number`);if(o>n)throw new Error(`${t} expired at ${n}, now ${o}`);if(e?.issuedAtMs!=null){if(!Number.isFinite(a))throw new Error(`${t}: issuedAtMs must be a finite number when present`);if(n<=a)throw new Error(`${t}: expiry must be after issuance`)}return{now:o,issuedAtMs:a,expiresAtMs:n}}function we(e){return e===null?"null":e===void 0?"undefined":typeof e=="number"?String(e):`${typeof e} ${JSON.stringify(String(e)).slice(0,24)}`}var ee=100;function P(e){return Array.isArray(e)?`[${e.map(P).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${P(e[r])}`).join(",")}}`:JSON.stringify(e??null)}function xe(e,{required:r=!1}={}){try{return C(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(t){if(r)throw t;return null}}function Ee(e){let{signature:r,...t}=e;return t}function ve(e){let r=String(e||"").toLowerCase();if(!/^0x[0-9a-f]+$/.test(r)||r.length<10||r.length%2!==0)throw new Error("auto-slippage calldata must be even-length hex with a selector");return he("sha256").update(Buffer.from(r.slice(2),"hex")).digest("hex")}function Se(e,r){let t=Buffer.from(String(e??""),"utf8"),o=Buffer.from(String(r??""),"utf8");return t.length!==o.length||t.length===0?!1:be(t,o)}function Ae(e){let r=String(e||"");if(!/^0x[0-9a-fA-F]+$/.test(r)||r.length<10||r.length%2!==0)return null;let t=r.slice(0,10).toLowerCase(),o=[];for(let n=10;n+64<=r.length;n+=64)o.push(r.slice(n,n+64));let a=n=>o[n]==null?null:BigInt("0x"+o[n]);switch(t){case"0x414bf389":return a(6);case"0x04e45aaf":return a(5);case"0xc04b8d59":{let n=a(0);if(n==null)return null;let i=Number(n)/32;return!Number.isInteger(i)||i<0?null:a(i+4)}case"0xb858183f":{let n=a(0);if(n==null)return null;let i=Number(n)/32;return!Number.isInteger(i)||i<0?null:a(i+3)}case"0xa026383e":return a(6);case"0x38ed1739":case"0x5c11d795":return a(1);case"0x7ff36ab5":case"0xb6f9de95":return a(0);case"0x18cbafe5":case"0x791ac947":return a(1);default:return null}}function V(e,{nowMs:r=Date.now(),chainId:t,venue:o,secret:a,tx:n,requireSigned:i=!1}={}){if(!e||e.mode!=="auto")throw new Error("bounded auto-slippage guard required");let m=xe(a,{required:i});if(i&&!m)throw new Error("auto-slippage attestation secret required for signing or broadcast");if(m){let u=ge("sha256",m).update(P(Ee(e))).digest("hex");if(!Se(e.signature,u))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 c=Number(e.selectedBps),s=Number(e.capBps);if(!Number.isInteger(c)||c<0||c>ee)throw new Error("auto-slippage selected tolerance exceeds hard 100 bps cap");if(!Number.isInteger(s)||s<0||s>ee||c>s)throw new Error("auto-slippage cap exceeds hard 100 bps cap");try{y({expiresAtMs:e.expiresAtMs,issuedAtMs:e.quotedAtMs},r,"auto-slippage quote")}catch(u){throw new Error(`${u.message}; re-quote before signing`)}if(t!=null&&Number(e.chainId)!==Number(t))throw new Error("auto-slippage guard chain mismatch");if(o&&String(e.venue).toLowerCase()!==String(o).toLowerCase())throw new Error("auto-slippage guard venue mismatch");let l=BigInt(e.quoteAmountOut??0),w=BigInt(e.minAmountOut??0);if(l<=0n||w<=0n)throw new Error("auto-slippage guard amounts must be positive");let E=l*BigInt(1e4-c)/10000n;if(w<E)throw new Error("auto-slippage guard is under-protected relative to its fresh quote");if(n?.data&&e.minAmountOut!=null)if(e.calldataHash!=null){if(String(e.calldataHash)!==ve(n.data))throw new Error("auto-slippage guard is not bound to this call: calldata hash mismatch")}else{let u=Ae(n.data);if(u==null){let d=String(n.data).slice(0,10);throw new Error(`auto-slippage: cannot verify the output floor encoded by selector ${d}; refusing rather than trusting unbound calldata at an allowlisted venue`)}if(u!==BigInt(e.minAmountOut))throw new Error(`auto-slippage guard is not bound to this call: guard minAmountOut ${e.minAmountOut} but calldata encodes ${u}`)}return!0}var wr=new ye(["function approve(address spender,uint256 amount) returns (bool)"]);import{Interface as Oe,isAddress as br}from"ethers";var Sr=new Oe(["function approve(address spender,uint256 amount) returns (bool)"]),Ar=Object.freeze({42161:"0x1c3fa76e6e1088bce750f23a5bfcffa1efef6a41",43114:"0x8f550e53dfe96c055d5bdb267c21f268fcaf63b2"});var Pr=new Te(["function approve(address spender,uint256 amount) returns (bool)"]);var G=new Set(["0x095ea7b3","0x39509351","0x61f49ed6","0xeb5625d9","0xf9255c1f","0x87517c45","0xd505accf","0x8fcbaf0c","0x2b67b570","0x2a2d80d1"]);var te=new Set(["evm","evm-swap","evm-bridge","btc","sol"]),re=Object.freeze({swap:5,bridge:5,perps:0,nft:0}),oe=new Set(["evm-swap","evm-bridge"]),Ie=new Set(["0x0000000000000000000000000000000000000000","0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"]),j=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"},"0x7b939232":{provider:"across-v3",action:"bridge",layout:"across-deposit-v3"}}),Ce=new Set(["0x04e45aaf","0x414bf389","0xc04b8d59","0xb858183f","0xa026383e","0x38ed1739","0x5c11d795","0x7ff36ab5","0xb6f9de95","0x18cbafe5","0x791ac947"]),_e=new Set(["0xa9059cbb","0x23b872dd","0x42842e0e","0xb88d4fde","0xf242432a","0x2eb2c2d6","0xa22cb465","0xd0e30db0","0x2e1a7d4d","0x3593564c","0x24856bc3","0xac9650d8","0x5ae401dc"]),U=(e,r,t=256)=>{if(typeof e!="string"||!e||e.length>t)throw new Error(`envelope: bounded ${r} required`);return e},p=(e,r)=>{try{let t=BigInt(e);if(t<0n)throw 0;return t}catch{throw new Error(`envelope: ${r} must be a non-negative integer`)}},$e=(e,r)=>{if(!Array.isArray(e)||e.length===0)throw new Error(`policy: ${r} allowlist is empty`);return e},b=(e,r,t)=>{if(!$e(r,t).map(o=>String(o).toLowerCase()).includes(String(e).toLowerCase()))throw new Error(`policy: ${t} not allowed`)},_=(e,r)=>{let t=String(e||"").toLowerCase();if(!/^0x[0-9a-f]{40}$/.test(t))throw new Error(`envelope: ${r} must be a 20-byte address`);return t},O=e=>String(e||"0x").slice(0,10).toLowerCase();function W(e){return G.has(O(e))}function H(e){let r=O(e);return Ce.has(r)||_e.has(r)||Object.hasOwn(j,r)||G.has(r)}function J(e,r,t,{dynamicTail:o=!1}={}){let a=String(e||"").toLowerCase();if(!/^0x[0-9a-f]*$/.test(a)||a.length<10+r*64)throw new Error(`envelope: malformed ${t} calldata`);if(!o&&a.length!==10+r*64)throw new Error(`envelope: malformed ${t} calldata`);return{hex:a,word:n=>a.slice(10+n*64,10+(n+1)*64)}}function v(e,r){if(!/^0{24}[0-9a-f]{40}$/.test(e))throw new Error(`envelope: malformed ${r} address`);return`0x${e.slice(24)}`}function A(e,r){try{return BigInt(`0x${e}`)}catch{throw new Error(`envelope: malformed ${r} integer`)}}function Be(e){if(O(e)!=="0x095ea7b3")return null;let r=J(e,2,"approval");return{kind:"approval",spender:v(r.word(0),"approval spender"),amount:A(r.word(1),"approval amount")}}function Le(e,r){let t=r==="router02-exact-input-single"?7:8,o=J(e,t,"Uniswap v3 exactInputSingle"),a=t===7?4:5;return{kind:"action",action:"swap",inputToken:v(o.word(0),"input token"),outputToken:v(o.word(1),"output token"),recipient:v(o.word(3),"recipient"),amountIn:A(o.word(a),"amountIn"),minimumOut:A(o.word(a+1),"amountOutMinimum")}}function ke(e){let r=J(e,12,"Across depositV3",{dynamicTail:!0}),t=A(r.word(11),"message offset");if(t!==384n)throw new Error("envelope: malformed Across depositV3 message offset");let o=10+Number(t)*2;if(r.hex.length<o+64)throw new Error("envelope: malformed Across depositV3 message");let a=Number(BigInt(`0x${r.hex.slice(o,o+64)}`));if(!Number.isSafeInteger(a))throw new Error("envelope: malformed Across depositV3 message length");let n=Math.ceil(a/32)*64;if(r.hex.length!==o+64+n)throw new Error("envelope: malformed Across depositV3 trailing bytes");return{kind:"action",action:"bridge",depositor:v(r.word(0),"depositor"),recipient:v(r.word(1),"recipient"),inputToken:v(r.word(2),"input token"),outputToken:v(r.word(3),"output token"),amountIn:A(r.word(4),"inputAmount"),minimumOut:A(r.word(5),"outputAmount"),destinationChainId:A(r.word(6),"destinationChainId")}}function Me(e,r){let t=O(e),o=j[t];if(!o)throw new Error("envelope: opaque or unsupported EVM swap/bridge calldata");if(String(r).toLowerCase()!==o.provider)throw new Error("envelope: provider does not match reviewed selector");if(o.action==="swap")return{...Le(e,o.layout),selector:t,provider:o.provider};if(o.action==="bridge")return{...ke(e),selector:t,provider:o.provider};throw new Error("envelope: unsupported reviewed EVM action")}function q(e){let r=e?.artifact;if(Array.isArray(r?.transactions))return r.transactions;if(r?.transaction&&typeof r.transaction=="object")return[r.transaction];if(r?.data)return[r];throw new Error("envelope: ordered EVM transaction batch required")}function R(e,r,{nowMs:t=Date.now(),routeAttestationSecret:o}={}){let a=String(e?.surface||"");if(!oe.has(a))throw new Error("envelope: strict EVM swap/bridge surface required");let n=U(e.provider,"provider",64).toLowerCase();b(n,r.providers,"provider");let i=_(e.owner,"owner"),m=e.artifact,c=Number(m?.chainId);if(!Number.isSafeInteger(c)||c<=0)throw new Error("envelope: explicit batch chainId required");if(b(c,r.chains,"chain"),_(m?.owner,"batch owner")!==i)throw new Error("envelope: explicit batch owner mismatch");let s=q(e);if(!s.length||s.length>8)throw new Error("envelope: bounded EVM transaction batch required");let l=0n,w=0n,E=0n,u=[],d=-1;for(let g=0;g<s.length;g++){let h=s[g];if(!h||typeof h!="object"||Array.isArray(h))throw new Error("envelope: structured EVM transaction required");if(Number(h.chainId)!==c)throw new Error("envelope: every batch leg must use the same chain");if(_(h.from,"transaction owner")!==i)throw new Error("envelope: every batch leg must use the same owner");let de=O(h.data);b(de,r.selectors,"selector");let L=Be(h.data),D;if(L){if(d!==-1)throw new Error("envelope: approval must be before action");let Y=_(h.to,"approval token");if(b(Y,r.tokens,"token"),b(L.spender,r.spenders,"spender"),L.amount>p(r.maxApproval,"maxApproval"))throw new Error("policy: approval exceeds cap");D={...L,token:Y,index:g}}else{if(d!==-1)throw new Error("envelope: exactly one swap/bridge action is supported per batch");b(h.to,r.destinations,"destination"),D={...Me(h.data,n),target:_(h.to,"action target"),index:g},d=g}let Z=p(h.value??0,"value"),k=p(h.gasLimit,"gasLimit"),Q=p(h.maxFeePerGas??h.gasPrice,"feePerGas");l+=Z,w+=k,E+=k*Q,u.push({...D,value:Z,gas:k,fee:k*Q})}if(d<0)throw new Error("envelope: reviewed swap/bridge action required");if(l>p(r.maxValueWei,"maxValueWei"))throw new Error("policy: aggregate value exceeds cap");if(w>p(r.maxGasLimit,"maxGasLimit"))throw new Error("policy: aggregate gas exceeds cap");if(E>p(r.maxFeeWei,"maxFeeWei"))throw new Error("policy: aggregate fee exceeds cap");let f=u[d],B=a==="evm-swap"?"swap":"bridge";if(f.action!==B||e.action!==B)throw new Error("envelope: surface/action/calldata mismatch");if(f.recipient!==i)throw new Error("envelope: decoded recipient must equal owner");if(f.depositor&&f.depositor!==i)throw new Error("envelope: decoded bridge depositor must equal owner");if(b(f.inputToken,r.tokens,"input token"),b(f.outputToken,r.tokens,"output token"),f.amountIn<=0n||f.amountIn>p(r.maxPerTrade,"maxPerTrade"))throw new Error("policy: decoded amount exceeds per-trade cap");if(f.minimumOut<=0n)throw new Error("policy: decoded minimum output must be positive");if(V(e.autoSlippage,{nowMs:t,chainId:c,venue:n,tx:s[d],secret:o,requireSigned:!0}),Number(e.slippageBps)!==Number(e.autoSlippage.selectedBps))throw new Error("policy: slippageBps must equal the authenticated quote selectedBps");if(f.minimumOut!==p(e.autoSlippage.minAmountOut,"authenticated quote minAmountOut"))throw new Error("policy: decoded minimum output does not match authenticated quote");if(f.action==="bridge"&&p(e.toChainId,"toChainId")!==f.destinationChainId)throw new Error("envelope: decoded bridge destination chain mismatch");let N=u.filter(g=>g.kind==="approval");if(Ie.has(f.inputToken)){if(N.length)throw new Error("envelope: native-value action must not include token approval")}else{if(N.length!==1)throw new Error("envelope: exactly one approval is required before action");let g=N[0];if(g.index>=d)throw new Error("envelope: approval must be before action");if(g.token!==f.inputToken)throw new Error("envelope: approval token does not match decoded input token");if(g.spender!==f.target)throw new Error("envelope: approval spender does not match decoded action target");if(g.amount!==f.amountIn)throw new Error("envelope: approval amount must exactly match decoded action amount")}let fe=Object.freeze({quoteAmountOut:p(e.autoSlippage.quoteAmountOut,"authenticated quote amountOut"),minAmountOut:p(e.autoSlippage.minAmountOut,"authenticated quote minAmountOut"),selectedBps:Number(e.autoSlippage.selectedBps),quotedAtMs:Number(e.autoSlippage.quotedAtMs),expiresAtMs:Number(e.autoSlippage.expiresAtMs)});return{transactions:s,decoded:u,action:f,totalValue:l,totalGas:w,totalFee:E,chainId:c,owner:i,provider:n,authenticatedQuote:fe}}function ne(e,{localsWaiver:r=!1}={}){if(!(e in re))throw new Error("fee: unknown action");return r?0:re[e]}function z(e,r,{nowMs:t=Date.now(),routeAttestationSecret:o}={}){if(!e||e.version!==1)throw new Error("envelope: version 1 required");let a=U(e.surface,"surface",16);if(!te.has(a))throw new Error("envelope: unsupported public surface");let n=U(e.action,"action",32);if(b(a,r.surfaces,"surface"),b(n,r.actions,"action"),b(e.owner,r.owners,"owner"),b(e.destination,r.destinations,"destination"),!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=t||e.expiresAtMs-t>Number(r.maxTtlMs))throw new Error("policy: TTL outside bounds");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>Number(r.maxSlippageBps))throw new Error("policy: slippage exceeds cap");let i=e.artifact;if(!i||typeof i!="object"||Array.isArray(i))throw new Error("envelope: structured artifact required");if(oe.has(a))R(e,r,{nowMs:t,routeAttestationSecret:o});else if(a==="evm"){if(W(i.data))throw new Error("envelope: approval requires a strict decoded surface");if(n==="swap"||n==="bridge"||H(i.data))throw new Error("envelope: strict EVM swap/bridge surface required");b(Number(i.chainId),r.chains,"chain");let c=O(i.data);if(b(c,r.selectors,"selector"),String(i.from).toLowerCase()!==String(e.owner).toLowerCase())throw new Error("envelope: owner mismatch");if(String(i.to).toLowerCase()!==String(e.destination).toLowerCase())throw new Error("envelope: destination mismatch");if(p(i.value??0,"value")>p(r.maxValueWei,"maxValueWei"))throw new Error("policy: value exceeds cap");let s=p(i.gasLimit,"gasLimit"),l=p(i.maxFeePerGas??i.gasPrice,"feePerGas");if(s>p(r.maxGasLimit,"maxGasLimit")||s*l>p(r.maxFeeWei,"maxFeeWei"))throw new Error("policy: gas/fee exceeds cap")}else throw a==="btc"||a==="sol"?new Error("envelope: btc/sol require decoded payload; caller-authored outputs and programIds are refused"):new Error("envelope: unsupported public surface");let m=ne(n,{localsWaiver:e.fee?.waiver==="locals-only-verified"});if(Number(e.fee?.oracleFeeBps)!==m)throw new Error("fee: final artifact fee mismatch");return!0}var ae=Object.freeze([...te]),qe=Object.freeze({...j});function Re(e={}){let r={};for(let t of ae){let o=e[t];if(o){if(typeof o.sign!="function"||typeof o.broadcast!="function")throw new Error(`adapter: ${t} requires sign and broadcast functions`);r[t]=Object.freeze({sign:(a,n)=>o.sign(structuredClone(a),structuredClone(n)),broadcast:(a,n,i)=>o.broadcast(a,structuredClone(n),structuredClone(i))})}}return Object.freeze(r)}function Fe(e,r){let t=e?.surface||"evm",o=r?.[t];if(!o)throw new Error(`adapter: ${t} is not configured on this self-host`);return o}var K=e=>String(e||"").toLowerCase(),T=(e,r)=>{try{let t=BigInt(e??0);if(t<0n)throw 0;return t}catch{throw new Error(`policy: ${r} must be a non-negative integer`)}},F=(e,r,t,o=String)=>{if(!Array.isArray(r)||r.length===0)throw new Error(`policy: ${t} allowlist is empty`);if(!r.map(o).includes(o(e)))throw new Error(`policy: ${t} not allowed`)};function S(e){return De("sha256").update(JSON.stringify(e)).digest("hex")}function ie(e,r,{nowMs:t=Date.now()}={}){if(!e||!r)throw new Error("policy: artifact and policy required");if(W(e.data))throw new Error("envelope: approval requires a strict decoded surface");if(H(e.data))throw new Error("envelope: strict EVM swap/bridge surface required");if(F(Number(e.chainId),r.chains,"chain",Number),F(e.to,r.destinations,"destination",K),F(String(e.data||"0x").slice(0,10),r.selectors,"selector",n=>String(n).toLowerCase()),F(e.from,r.owners,"owner",K),T(e.value,"value")>T(r.maxValueWei,"maxValueWei"))throw new Error("policy: value exceeds cap");let o=T(e.gasLimit,"gasLimit");if(o>T(r.maxGasLimit,"maxGasLimit"))throw new Error("policy: gas exceeds cap");if(T(e.maxFeePerGas??e.gasPrice,"feePerGas")*o>T(r.maxFeeWei,"maxFeeWei"))throw new Error("policy: fee exceeds cap");if(!Number.isFinite(e.slippageBps)||e.slippageBps<0||e.slippageBps>Number(r.maxSlippageBps))throw new Error("policy: slippage attestation exceeds cap");if(!Number.isFinite(e.expiresAtMs)||e.expiresAtMs<=t)throw new Error("policy: artifact expired");return!0}var $=class{#e=new Map;constructor({now:r=Date.now}={}){this.now=r}issue({artifact:r,owner:t,ttlMs:o=6e4}){if(o<=0||o>12e4)throw new Error("confirmation: ttl out of range");let a=Pe(32).toString("hex");return this.#e.set(a,{digest:S(r),owner:K(t),expiresAtMs:this.now()+o}),a}consume(r,t){let o=this.#e.get(String(r));if(!o)throw new Error("confirmation: used or unknown nonce");if(o.expiresAtMs<=this.now())throw this.#e.delete(String(r)),new Error("confirmation: expired nonce");let a=Buffer.from(o.digest,"hex"),n=Buffer.from(S(t),"hex");if(!Ve(a,n))throw new Error("confirmation: artifact mismatch");return this.#e.delete(String(r)),o}clear(){this.#e.clear()}};function Ge(e={},r={}){let t={};for(let o of new Set([...Object.keys(e||{}),...Object.keys(r||{})]))t[o]=(BigInt(r?.[o]??0)-BigInt(e?.[o]??0)).toString();return t}function Ue(e){let r=e?.status,t=r===1||r==="0x1"?"success":r===0||r==="0x0"?"failed":"pending",o=e?.verifiedBefore??e?.before,a=e?.verifiedAfter??e?.after;return{transactionHash:e?.hash||e?.transactionHash||null,status:t,balanceDeltaVerified:!!(e?.verifiedBefore&&e?.verifiedAfter),delta:Ge(o,a)}}function se(e){return e?.surface==="evm-swap"||e?.surface==="evm-bridge"}function I(e,r,t=Date.now(),{routeAttestationSecret:o}={}){let a=e?.version===1&&e?.surface?e:null;return a?(z(a,r,{nowMs:t,routeAttestationSecret:o}),se(a)?R(a,r,{nowMs:t,routeAttestationSecret:o}):null):(ie(e,r,{nowMs:t}),null)}async function X(e,r,t){if(!t.isArmed())throw new Error("signer: disarmed");let o=e?.version===1&&e?.surface?e:null,a=()=>typeof t.nowMs=="function"?t.nowMs():t.nowMs??Date.now(),n=typeof t.readPolicy=="function"?t.readPolicy():t.policy,i=n?.confirmationMode||"exact-human";if(t.autonomous===!0){if(t.env?.ORACLE_AUTONOMOUS_TRADING!=="1")throw new Error("signer: autonomous execution requires ORACLE_AUTONOMOUS_TRADING=1");if(typeof t.verifyTriggerAttestation!="function"||await t.verifyTriggerAttestation(o?.triggerAttestation,e)!==!0)throw new Error("signer: autonomous trigger attestation required")}else{if(i==="auto-within-rails")throw new Error("signer: auto-within-rails requires autonomous trading with authenticated trigger attestation");if(i!=="exact-human")throw new Error("signer: unsupported confirmation mode");if(!t.confirmations||typeof t.confirmations.consume!="function")throw new Error("signer: exact confirmation store required");t.confirmations.consume(r,e)}let m=S(e),c=I(e,n,a(),{routeAttestationSecret:t.routeAttestationSecret});typeof t.reserveLedger=="function"&&t.reserveLedger(o||e,n,c);let s=o&&se(o)?q(o):[o?o.artifact:e],l=[],w=[];for(let d=0;d<s.length;d++){if(!t.isArmed())throw new Error("signer: disarmed before signing");if(S(e)!==m)throw new Error("signer: artifact mutated before signing");d>0&&(n=typeof t.readPolicy=="function"?t.readPolicy():t.policy,c=I(e,n,a(),{routeAttestationSecret:t.routeAttestationSecret}));let f=await t.sign(s[d],o);if(l.push(f),!t.isArmed())throw new Error("signer: disarmed before broadcast");if(S(e)!==m)throw new Error("signer: artifact mutated before broadcast");n=typeof t.readPolicy=="function"?t.readPolicy():t.policy,c=I(e,n,a(),{routeAttestationSecret:t.routeAttestationSecret});let B=await t.broadcast(f,s[d],o),N=Ue(B);if(w.push(N),N.status!=="success")break}let E=w.length===s.length&&w.every(d=>d.status==="success")?"success":w.some(d=>d.status==="failed")?"failed":"pending",u={prepared:e,signed:s.length===1?l[0]:l,receipt:w[0]||null,receipts:w,status:E};return o?.surface==="evm-bridge"&&(u.originStatus=E,u.destinationStatus="unverified",u.destinationSuccess=!1,u.note="Origin-chain receipts do not prove destination-chain settlement."),u}import je from"node:http";import{timingSafeEqual as We}from"node:crypto";var ce=new Set(["127.0.0.1","::1","localhost"]),He=(e,r)=>{let t=Buffer.from(String(e)),o=Buffer.from(String(r));return t.length===o.length&&We(t,o)},x=(e,r,t)=>{let o=JSON.stringify(t);e.writeHead(r,{"content-type":"application/json","cache-control":"no-store","content-length":Buffer.byteLength(o)}),e.end(o)},ue=e=>new Promise((r,t)=>{let o=0,a=[],n=!1;e.on("data",i=>{o+=i.length,o>64*1024&&!n?(n=!0,t(new Error("request refused")),e.resume()):n||a.push(i)}),e.on("end",()=>{if(!n)try{r(JSON.parse(Buffer.concat(a).toString()||"{}"))}catch{t(new Error("request refused"))}}),e.on("error",t)});function Je(e={}){let r=e.host||"127.0.0.1";if(!ce.has(r))throw new Error("signer: loopback bind required");if(String(e.token||"").length<32)throw new Error("signer: strong auth token required");let t=e.confirmations||new $,o=e.origin||`http://${r}`;return je.createServer(async(n,i)=>{try{let m=String(n.headers.authorization||"").replace(/^Bearer /i,"");if(!He(m,e.token))return x(i,401,{error:"unauthorized"});let c=String(n.headers.host||"").replace(/^\[|\](?=:|$)/g,"").split(":")[0];if(!ce.has(c))return x(i,403,{error:"host refused"});if(n.headers.origin&&n.headers.origin!==o)return x(i,403,{error:"origin refused"});if(n.method==="GET"&&n.url==="/status")return x(i,200,{ok:!0,armed:e.isArmed?.()===!0,sessionExpiresAtMs:e.sessionExpiresAtMs||null});if(n.method==="POST"&&n.url==="/disarm")return e.disarm?.(),t.clear(),x(i,200,{ok:!0,armed:!1});if(!["GET","POST"].includes(n.method))return x(i,405,{error:"request refused"});if(n.method==="POST"&&String(n.headers["content-type"]||"").split(";",1)[0].trim().toLowerCase()!=="application/json")return x(i,415,{error:"request refused"});if(n.method==="POST"&&n.url==="/confirm"){let s=await ue(n),l=S(s.artifact);if(e.autonomous!==!0){if(typeof e.confirmArtifact!="function")return x(i,403,{error:"local human confirmation unavailable"});let w=typeof e.readPolicy=="function"?e.readPolicy():e.policy,E=typeof e.nowMs=="function"?e.nowMs():e.nowMs??Date.now(),u=I(s.artifact,w,E);if(await e.confirmArtifact(s.artifact,l,u)!==!0)return x(i,400,{error:"exact human confirmation refused"})}return x(i,200,{confirmationNonce:t.issue({artifact:s.artifact,owner:s.artifact?.from,ttlMs:s.ttlMs})})}if(n.method==="POST"&&n.url==="/execute"){let s=await ue(n),l=await X(s.artifact,s.confirmationNonce,{...e,confirmations:t});return x(i,200,l)}return x(i,404,{error:"not found"})}catch(m){return e.onError?.(String(m?.message||m)),x(i,400,{error:"request refused"})}})}export{$ as ConfirmationStore,ae as PUBLIC_SIGNER_SURFACES,qe as REVIEWED_EVM_SELECTORS,S as artifactDigest,ie as assertExactPolicy,Je as createSignerServer,Re as createSurfaceAdapters,q as evmTransactions,X as executeConfirmedArtifact,I as inspectArtifactForConfirmation,R as inspectEvmBatch,ne as publicFeeBps,Fe as surfaceAdapterFor,z as validateSurfaceEnvelope};
|
package/dist/router/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var yt=Object.defineProperty;var P=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var At=(e,t)=>{for(var r in t)yt(e,r,{get:t[r],enumerable:!0})};import{createHash as xt}from"node:crypto";function vt(e){let t=String(e||"").toLowerCase();return xe.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function kt(e){let t={};for(let[r,n]of Object.entries(e||{}))vt(r)||(t[r]=n);return t}function _t(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let r=new URL(String(e),String(t));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${r.protocol}`);return r.toString()}function Ot(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function
|
|
2
|
-
`),c=xt("sha256").update(u).digest("hex").slice(0,32);return`${e} ${t} ${c}`}function Tt(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ye):Math.min(250*2**e,ye)+Math.floor(Math.random()*100)}async function Nt(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s}){let u=new AbortController,c=setTimeout(()=>u.abort(),s);try{let i=String(e),d={...n||{}};for(let p=0;p<=Ae;p+=1){let l=await t(i,{method:r,headers:d,body:o,signal:u.signal,redirect:"manual"}),a=await l.text(),m=null;if(a)try{m=JSON.parse(a)}catch{m=null}if(Ct.has(l.status)){if(r!=="GET"&&r!=="HEAD"){let w=new Error(`HTTP ${l.status} ${r} ${i} redirected non-idempotent request`);throw w.status=l.status,w.body=m??a.slice(0,300),w}if(p===Ae)throw new Error(`HTTP redirect loop for ${e}`);let h=_t(l.headers?.get?.("location"),i);Ot(h,i)||(d=kt(d)),i=h;continue}if(!l.ok){let h=new Error(`HTTP ${l.status} ${r} ${i}`);throw h.status=l.status,h.retryAfter=l.headers?.get?.("retry-after")??null,h.body=m??a.slice(0,300),h}return m??a}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(c)}}async function y(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,o=(t.method||"GET").toUpperCase(),s={Accept:"application/json",...t.headers||{}},u=t.body;u!=null&&typeof u!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",u=JSON.stringify(u));let c=Number.isInteger(t.retries)?Math.max(t.retries,0):It,i=async()=>{let m;for(let h=0;h<=c;h++)try{return await Nt(e,{fetchImpl:r,method:o,headers:s,body:u,timeoutMs:n})}catch(w){m=w;let b=w?.status,f=w?.name==="AbortError",g=new Set([408,425,429]),E=b!=null?g.has(b)||St.has(b)&&Ee.has(o):!f&&Ee.has(o);if(h===c||!E)throw w;await Bt(Tt(h,w?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&u==null))return i();let p=Rt(o,e,s),l=re.get(p);if(l)return l;let a=i().finally(()=>re.delete(p));return re.set(p,a),a}var St,Ee,It,ye,xe,Ct,Ae,re,Bt,I=P(()=>{St=new Set([408,425,429,500,502,503,504]),Ee=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),It=2,ye=4e3,xe=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ct=new Set([301,302,303,307,308]),Ae=3;re=new Map;Bt=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as Pt}from"node:fs";import{homedir as Ut}from"node:os";import{join as V}from"node:path";function $t(){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=Ut();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||V(t,".config","oracle")).trim();return[e,V(r,"exec.env")].filter(Boolean)}return[e,V(t,".config","oracle","exec.env"),V(t,".config","mad-desk","exec.env")].filter(Boolean)}function Se(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of $t())try{let s=Pt(o,"utf8"),u=s.match(new RegExp(`^${t}=(.*)$`,"m"))||s.match(new RegExp(`^${r}=(.*)$`,"m"));if(u&&(n=u[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}var Ie=P(()=>{});var Ce=P(()=>{});import{createHash as Lt,createHmac as Ft,timingSafeEqual as Dn}from"node:crypto";function oe(e){return Array.isArray(e)?`[${e.map(oe).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${oe(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Dt(e,{required:t=!1}={}){try{return Se(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function _e(e){let{signature:t,...r}=e;return r}function Oe(e,{secret:t}={}){let r=Dt(t);return r?{...e,signature:Ft("sha256",r).update(oe(_e(e))).digest("hex")}:e}function Mt(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 Lt("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function U(e,{chainId:t,venue:r,data:n,secret:o}={}){if(!e||e.mode!=="auto")throw new Error("bounded auto-slippage guard required");if(Number(e.chainId)!==Number(t))throw new Error("auto-slippage guard chain mismatch");if(String(e.venue).toLowerCase()!==String(r||"").toLowerCase())throw new Error("auto-slippage guard venue mismatch");return Oe({..._e(e),calldataHash:Mt(n)},{secret:o})}function ne(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function qt(e){let t=e==null?ve:Number(e);if(!Number.isInteger(t)||t<0)throw new Error("auto-slippage cap must be a non-negative integer bps value");return Math.min(t,ve)}function O({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let s=ne(e,0),u=s>0?s>=25e4?5:s>=1e5?10:s>=5e4?20:s>=1e4?40:70:n?30:10,c=Math.min(60,Math.abs(ne(t,0))*2),i=Math.min(40,Math.floor(Math.max(0,ne(r,0))/5e3)*5),d=Math.max(25,Math.ceil(20+u+c+i)),p=qt(o);return{mode:"auto",requiredBps:d,selectedBps:Math.min(d,p),capBps:p,executable:d<=p}}function Ht({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:s=0,crossChain:u=!1,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d=ke,secret:p}={}){let l=BigInt(r??0);if(l<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let a=O({liquidityUsd:n,priceChange5m:o,quoteAgeMs:s,crossChain:u,requestedCapBps:c});if(!a.executable)throw new Error(`auto-slippage requires ${a.requiredBps} bps above hard/requested cap ${a.capBps}; route blocked`);let m=Number(i);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let h=Math.min(3e4,Math.max(1e3,Number(d)||ke)),w=l*BigInt(1e4-a.selectedBps),b=w/10000n;if(w%10000n!==0n&&(b+=1n),b>l&&(b=l),l>0n&&b<=0n)throw new Error(`auto-slippage: quote ${l} is too small to express a ${a.selectedBps} bps floor without rounding to zero`);let f=Number((l-b)*10000n/(l===0n?1n:l));if(f>a.capBps)throw new Error(`auto-slippage: realised floor implies ${f} bps, above cap ${a.capBps} \u2014 refusing to issue a guard weaker than advertised`);return Oe({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:l.toString(),minAmountOut:b.toString(),requiredBps:a.requiredBps,selectedBps:a.selectedBps,capBps:a.capBps,quotedAtMs:m,expiresAtMs:m+h},{secret:p})}function A(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d}={}){let p=Ht({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i,ttlMs:d});return{...e,autoSlippage:p,amountOutMinimum:p.minAmountOut}}var ve,ke,R=P(()=>{Ie();Ce();ve=100,ke=2e4});function Re(e){let t=String(e||"").trim();return/^0x[0-9a-fA-F]{40}$/.test(t)?t:$}var $,j=P(()=>{$="0x000000000000000000000000000000000000dEaD"});import{createHash as Vt,createHmac as jt,timingSafeEqual as zn}from"node:crypto";function ae(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ae).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ae(e[r])}`).join(",")}}`}function Te(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Be(e=process.env){return Te(process.env)||Te(e)}function Xt(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...s}=e||{};return s}function Yt(e){let t=Xt(e);return Vt("sha256").update(ae(t)).digest("hex")}function Kt(e,t=Be()){return t?jt("sha256",t).update(String(e)).digest("hex"):""}function T(e,{provider:t,kind:r,env:n=process.env}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let o={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!o.provider)throw new Error("stampPrepared: provider required");if(!o.kind)throw new Error("stampPrepared: kind required");let s=Date.now(),u=s+Gt,i={...o,preparedAt:s,expiresAt:u,prepareVersion:zt},d=Yt(i),p=Be(n),l=p?Kt(d,p):void 0,a={...i,oraclePrepared:!0,prepareHash:d};return l&&(a.prepareMac=l),a}var zt,Gt,Gn,B=P(()=>{zt=2,Gt=300*1e3,Gn=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var ue={};At(ue,{ACROSS_API:()=>lt,HOP_API:()=>dt,RELAY_API:()=>pt,acrossHealth:()=>mn,acrossSuggestedFees:()=>mt,hopHealth:()=>fn,hopQuote:()=>ft,relayHealth:()=>hn,relayPrepare:()=>wn,relayQuote:()=>ce});async function mn(e={}){try{return{ok:!0,estimatedFillTimeSec:(await mt({token:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",destinationToken:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",originChainId:1,destinationChainId:42161,amount:"1000000000000000"},e)).estimatedFillTimeSec}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function mt(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:s,amount:u}=e;if(!r||o==null||s==null||!u)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let c=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(s),amount:String(u)}),i=(t.baseUrl||process.env.ACROSS_API_URL||lt).replace(/\/$/,"");return y(`${i}/suggested-fees?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function fn(e={}){try{let t=await ft({amount:"1000000000000000",token:"ETH",fromChain:"ethereum",toChain:"arbitrum",slippage:.5},e);return{ok:!0,estimatedRecieved:t.estimatedRecieved||t.estimatedReceived}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function ft(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:s="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let u=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u});if(!c.executable)throw new Error(`hop: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:s,slippage:String(c.selectedBps/100)}),d=(t.baseUrl||process.env.HOP_API_URL||dt).replace(/\/$/,""),p=await y(`${d}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),l=p?.estimatedRecieved||p?.estimatedReceived;return l?A(p,{chainId:Number(e.originChainId||e.chainId||pn[o]||0),venue:p?.tx?.to||"hop",amountOut:l,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u}):{...p,autoSlippagePolicy:c}}async function hn(e={}){try{let t=await ce({user:$,originChainId:1,destinationChainId:8453,originCurrency:"0x0000000000000000000000000000000000000000",destinationCurrency:"0x0000000000000000000000000000000000000000",amount:"1000000000000000",tradeType:"EXACT_INPUT"},e);return{ok:!0,hasSteps:Array.isArray(t.steps),stepCount:t.steps?.length||0}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function ce(e={},t={}){let{user:r=$,originChainId:n,destinationChainId:o,originCurrency:s="0x0000000000000000000000000000000000000000",destinationCurrency:u="0x0000000000000000000000000000000000000000",amount:c,tradeType:i="EXACT_INPUT"}=e;if(n==null||o==null||!c)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`relay: route requires ${d.requiredBps} bps above cap ${d.capBps}`);let p=(t.baseUrl||process.env.RELAY_API_URL||pt).replace(/\/$/,""),l=await y(`${p}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:s,destinationCurrency:u,amount:String(c),tradeType:i,slippageTolerance:String(d.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.details?.currencyOut?.amount;return!a||!/^\d+$/.test(String(a))?{...l,autoSlippagePolicy:d}:A(l,{chainId:Number(n),venue:l?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function wn(e={},t={}){let r=await ce(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(c=>(c.items||[]).filter(i=>i?.data?.to&&i?.data?.data).map(i=>({stepId:c.id,...i.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let s=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(c=>String(c.to).toLowerCase()!==s))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let u=o.map(c=>({chainId:n,from:c.from||e.user,to:c.to,data:c.data,value:c.value??"0x0",...c.gasLimit!=null||c.gas!=null?{gasLimit:c.gasLimit??c.gas}:{},slippageGuard:U(r.autoSlippage,{chainId:n,venue:c.to,data:c.data})}));return T({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:u},{provider:"relay",kind:"relay-tx"})}var lt,dt,pt,pn,le=P(()=>{I();R();j();B();lt="https://across.to/api",dt="https://api.hop.exchange/v1",pt="https://api.relay.link",pn={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var Sn=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),In=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Cn=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var S=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"}),we={1:"coingecko:ethereum",10:"coingecko:ethereum",56:"coingecko:binancecoin",137:"coingecko:matic-network",8453:"coingecko:ethereum",42161:"coingecko:ethereum",43114:"coingecko:avalanche-2",999:"coingecko:ethereum"},q=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}};function he(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:o=null,feeUsd:s=null,oracleFeeBps:u=0,estimatedGas:c=null,liquidityUsd:i=null,error:d=null,executionReady:p=!1,meta:l={}}=e||{};if(d||r==null)return{source:t,quality:S.FAILED,amountOut:null,error:d||"no amountOut returned"};let a=q(r);if(a==null||a<=0n)return{source:t,quality:S.FAILED,amountOut:null,error:"non-positive amountOut"};let m=Number(u);return{source:t,quality:o==null?S.NO_GAS:S.FULL,amountOut:a.toString(),minOut:q(n)?.toString()??null,gasUsd:o,feeUsd:s,oracleFeeBps:Number.isFinite(m)&&m>0?Math.floor(m):0,estimatedGas:c==null?null:String(c),liquidityUsd:i==null?null:Number(i),executionReady:p,meta:l}}async function be(e,t,{divisor:r=1000n}={}){let n=q(t);if(n==null||n<=0n)return null;let o=n/r>0n?n/r:1n;if(o>=n)return null;let s,u;try{[s,u]=await Promise.all([e(o),e(n)])}catch{return null}let c=q(s),i=q(u);if(c==null||i==null||c<=0n)return null;let d=Number(c)/Number(o),p=Number(i)/Number(n);return!Number.isFinite(d)||!Number.isFinite(p)||d<=0?null:{impactPct:(1-p/d)*100,probeAmountIn:o.toString(),probeAmountOut:c.toString(),fullAmountOut:i.toString()}}function ge(e,t,{maxImpactPct:r=25}={}){let n=[],o=[],s=(e.routes??[]).filter(c=>{let i=t?.[c.source];return i?i.impactPct>r?(n.push({source:c.source,impactPct:Number(i.impactPct.toFixed(2)),reason:`price impact ${i.impactPct.toFixed(1)}% exceeds ${r}% ceiling -- the venue cannot absorb this size near the quoted price`}),!1):!0:(o.push(c.source),!0)}),u=[...e.warnings??[]];return n.length&&u.push(`dropped ${n.length} route(s) on price impact: `+n.map(c=>`${c.source} (${c.impactPct}%)`).join(", ")),o.length&&u.push(`price impact NOT measured for: ${o.join(", ")}. These are unproven against thin liquidity, not proven safe.`),{...e,routes:s,best:s[0]??null,impactRejected:n,impactUnmeasured:o,warnings:u}}function te(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:o=50}={}){let s=e.filter(f=>f.quality!==S.FAILED),u=e.filter(f=>f.quality===S.FAILED),c=t!=null&&t>0&&r!=null&&r>=0,i=s.map(f=>{let g=BigInt(f.amountOut),E=0n,k=!1,_=BigInt(f.oracleFeeBps??0),M=_>0n?g*_/10000n:0n;if(c){let fe=(f.gasUsd??0)+(f.feeUsd??0);if(fe>0){let ee=fe/t*10**r;Number.isFinite(ee)&&ee>=0&&(E=BigInt(Math.floor(ee)),k=!0)}else f.gasUsd===0&&(k=!0)}let me=E+M,Et=g>me?g-me:0n;return{...f,grossOut:g.toString(),netOut:Et.toString(),costInDest:E.toString(),oracleFeeInDest:M.toString(),costAccounted:k}}),d=Number(o)>0?Number(o):0,p=i.reduce((f,g)=>BigInt(g.netOut)>f?BigInt(g.netOut):f,0n),l=f=>p>0n?Number((p-BigInt(f))*10000n/p):0,a=[],m=i.slice().sort((f,g)=>BigInt(g.netOut)>BigInt(f.netOut)?1:-1)[0]??null;i.sort((f,g)=>{let E=l(f.netOut)<=d?0:1,k=l(g.netOut)<=d?0:1;if(n&&d>0&&E!==k)return E-k;if(n&&d>0){let _=f.liquidityUsd??-1,M=g.liquidityUsd??-1;if(_!==M)return M-_}return BigInt(g.netOut)>BigInt(f.netOut)?1:-1}),n&&d>0&&m&&i[0]&&i[0].source!==m.source&&a.push(`liquidity-first: chose ${i[0].source} (liquidity $${i[0].liquidityUsd??"unknown"}) over best-price ${m.source} within ${d} bps`);let h=i.filter(f=>!f.costAccounted).map(f=>f.source);c?h.length&&a.push(`gas not reported by: ${h.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):a.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let w=null,b=null;if(i.length>=2&&i[0].costAccounted&&i[1].costAccounted){let f=BigInt(i[0].netOut),g=BigInt(i[1].netOut);g>0n&&(w=Number((f-g)*10000n/g),b=`${i[0].source} vs ${i[1].source}`)}return{best:i[0]??null,routes:i,failed:u,improvementBps:w,spreadBasis:b,rankedOn:c?"net-of-cost":"gross",warnings:a}}async function H(e,{timeoutMs:t=12e3}={}){let r=(o,s)=>Promise.race([o,new Promise((u,c)=>setTimeout(()=>c(new Error(`${s}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,s)=>{let u=e[s].source;return o.status==="rejected"?he({source:u,error:String(o.reason?.message||o.reason)}):he({source:u,...o.value})})}I();R();j();B();import{existsSync as or,readFileSync as ar}from"node:fs";import{homedir as ir}from"node:os";import{join as Pe}from"node:path";import{Contract as Qt,JsonRpcProvider as Wt}from"ethers";var Jt="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",Zt=999,er="https://rpc.hyperliquid.xyz/evm",tr=["function balanceOf(address owner) view returns (uint256)"],rr=/^0x[a-fA-F0-9]{40}$/;function nr(e){return rr.test(String(e||""))}async function Ne(e,{contract:t=Jt,rpc:r=er,chainId:n=Zt,balanceOf:o}={}){if(!nr(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let s=new Wt(r,n,{staticNetwork:!0}),u=new Qt(t,tr,s);return BigInt(await u.balanceOf(e))}var sr=100,cr=5,Ue=Object.freeze({swap:5,bridge:5,perps:0,nft:0});function ur(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(Ue,t)?Ue[t]:cr}var lr="ORACLE_INTEGRATOR_FEE_BPS",dr="ORACLE_INTEGRATOR_FEE_RECIPIENT",pr="ORACLE_INTEGRATOR_ID",$e="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",mr="oracle";function fr(e=process.env){if(e[$e])return String(e[$e]);let t=e.ORACLE_CONFIG_DIR||Pe(ir(),".config","oracle");return Pe(t,"fee-recipient")}function hr(e=process.env){try{let t=fr(e);if(!or(t))return"";let r=ar(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function wr(e,{fallback:t=0}={}){if(e==null)return t;if(String(e).trim()==="")return 0;let r=Number(e);return!Number.isFinite(r)||r<=0?0:Math.min(Math.floor(r),sr)}function br({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[dr]||"").trim(),o=String(e[pr]||mr).trim();if(r===!0)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"admin-oracle"};let s=ur(t),u=wr(e[lr],{fallback:n?s:0}),c=Math.min(u,s);if(!c)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"no-recipient"};let i=hr(e);return!i||i!==n.toLowerCase()?{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:c,recipient:n,integrator:o,action:t,applies:!0,reason:"configured"}}async function z({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:o=!1}={}){let s=br({env:t,action:r,admin:o});if(o===!0)return{...s,holderVerificationStatus:"admin-oracle"};let u=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(u))return{...s,holderVerificationStatus:"wallet-required"};try{return BigInt(await Ne(u,n))>0n?{...s,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...s,holderVerificationStatus:"non-holder"}}catch{return{...s,holderVerificationStatus:"unavailable"}}}function Le(e){return e?.applies?`Oracle routing fee ${e.bps} bps (${(e.bps/100).toFixed(2)}%) to ${e.recipient}.`:e?.reason==="admin-oracle"?"No Oracle fee (admin Oracle).":e?.reason==="locals-only-holder"?"No Oracle fee (Locals Only holder).":"No Oracle fee."}function Fe(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}function De(e){return e?.applies?{partner:e.integrator,partnerFeeBps:String(e.bps),partnerAddress:e.recipient}:{}}var gr="https://li.quest/v1";function Er(e={}){return(e.baseUrl||process.env.LIFI_API_URL||gr).replace(/\/$/,"")}var yr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";async function ie(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=yr,toToken:s,fromAmount:u,fromAddress:c=$}=e;if(r==null||!s||!u)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let i=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:s,fromAmount:String(u),fromAddress:c}),d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`lifi: route requires ${d.requiredBps} bps above cap ${d.capBps}`);i.set("slippage",String(d.selectedBps/1e4));let p=await z({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[b,f]of Object.entries(Fe(p)))i.set(b,f);let l=await y(`${Er(t)}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.estimate?.toAmount||l?.toAmount;if(!a)return{...l,autoSlippagePolicy:d,oracleFee:p};let m=l?.transactionRequest?.to||l?.estimate?.approvalAddress||"lifi",h=A(l,{chainId:Number(r),venue:m,amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),w=l?.estimate?.toAmountMin||l?.toAmountMin;if(w!=null&&BigInt(w)<BigInt(h.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...h,oracleFee:p}}I();R();B();var Ar="https://api.paraswap.io",xr=(e={})=>(e.baseUrl||process.env.PARASWAP_API_URL||Ar).replace(/\/$/,"");function Me(e,t){let r=String(e||"");if(!/^0x[0-9a-fA-F]{40}$/.test(r))throw new Error(`${t} must be a 20-byte token address`);return r.toLowerCase()}async function qe(e={},t={}){let r=Number(e.chainId||e.network||1);if(e.amount==null)throw new Error("amount required");let n=new URLSearchParams({srcToken:Me(e.srcToken,"srcToken"),destToken:Me(e.destToken,"destToken"),amount:String(e.amount),srcDecimals:String(Number(e.srcDecimals)),destDecimals:String(Number(e.destDecimals)),side:String(e.side||"SELL").toUpperCase(),network:String(r),version:String(e.version||"6.2")});e.includeDEXS&&n.set("includeDEXS",String(e.includeDEXS)),e.excludeDEXS&&n.set("excludeDEXS",String(e.excludeDEXS));let o=await z({wallet:e.userAddress||e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[c,i]of Object.entries(De(o)))n.set(c,i);let s=await y(`${xr(t)}/prices?${n}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=s?.priceRoute?.destAmount;return u?{...A(s,{chainId:r,venue:s?.priceRoute?.contractAddress||"paraswap-quote",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,quoteAgeMs:0,requestedCapBps:e.maxSlippageBps??e.slippageBps}),executionReady:!1,executionBlocker:"call prepare to bind the price route to a validated transaction",oracleFee:o}:{...s,executionReady:!1,oracleFee:o}}I();R();var He="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function G({provider:e,defaultUrl:t,hosts:r=[],url:n,strict:o=!1}){let u=(String(n??"").trim()||String(t)).replace(/\/$/,"");if(u===String(t).replace(/\/$/,""))return{baseUrl:u,trusted:!0,host:Ve(t)};let c;try{c=new URL(u)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let i=c.host;if(!i)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Ve(t),...r]).has(i)){let p=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(i);return c.protocol==="http:"&&!p?{baseUrl:u,trusted:!1,host:i,reason:"plaintext http downgrade"}:{baseUrl:u,trusted:!0,host:i}}if(String(process.env[He]||"")==="1")return{baseUrl:u,trusted:!1,host:i};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${i} (set ${He}=1 to permit it)`);return{baseUrl:u,trusted:!1,host:i}}function Ve(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function X(e,t,r){let n={...e};if(!r)return n;for(let[o,s]of Object.entries(t||{}))s&&(n[o]=s);return n}B();var Sr="https://api.0x.org";function je(e={}){return G({provider:"zerox",defaultUrl:Sr,hosts:["api.0x.org"],url:e.baseUrl||process.env.ZEROX_API_URL})}function Ir(e={}){return je(e).baseUrl}function ze(e={}){return e.apiKey||process.env.ZEROX_API_KEY||process.env.OX_API_KEY||process.env["0X_API_KEY"]||""}function Cr(e={}){return X({"0x-version":"v2",accept:"application/json"},{"0x-api-key":ze(e)},je(e).trusted)}async function Ge(e={},t={}){if(!ze(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:s,taker:u}=e;if(!n||!o||!s)throw new Error("zeroxQuote requires sellToken, buyToken, sellAmount");let c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!c.executable)throw new Error(`0x: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(s),slippageBps:String(c.selectedBps)});u&&i.set("taker",u);let d=await y(`${Ir(t)}/swap/allowance-holder/quote?${i}`,{headers:Cr(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),p=d?.buyAmount||d?.grossBuyAmount;return p?A(d,{chainId:r,venue:d?.transaction?.to||d?.to||"0x",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):{...d,autoSlippagePolicy:c}}I();R();B();var vr="https://api.1inch.dev/swap/v6.0";function Xe(e={}){return G({provider:"oneinch",defaultUrl:vr,hosts:["api.1inch.dev"],url:e.baseUrl||process.env.ONEINCH_API_URL})}function kr(e={}){return Xe(e).baseUrl}function Ye(e={}){return e.apiKey||process.env.ONEINCH_API_KEY||process.env.ONE_INCH_API_KEY||""}function _r(e={}){let t=Ye(e);return X({accept:"application/json"},{Authorization:t?`Bearer ${t}`:""},Xe(e).trusted)}async function Ke(e={},t={}){if(!Ye(t))throw new Error("ONEINCH_API_KEY required for 1inch");let r=Number(e.chainId??1),{src:n,dst:o,amount:s}=e;if(!n||!o||!s)throw new Error("oneinchQuote requires src, dst, amount");let u=new URLSearchParams({src:n,dst:o,amount:String(s)}),c=await y(`${kr(t)}/${r}/quote?${u}`,{headers:_r(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3});return c?.dstAmount?A(c,{chainId:r,venue:"1inch-quote",amountOut:c.dstAmount,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):c}I();R();import{TypedDataEncoder as Oo,getAddress as Ro,isAddress as To}from"ethers";var Co=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});j();B();var Or={1:"https://api.cow.fi/mainnet/api/v1",100:"https://api.cow.fi/xdai/api/v1",42161:"https://api.cow.fi/arbitrum_one/api/v1",8453:"https://api.cow.fi/base/api/v1"},Fo=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Do=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"}),Qe={1:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",8453:"0x4200000000000000000000000000000000000006",42161:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"},Rr={1:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",8453:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",42161:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},Mo=Object.freeze({Order:[{name:"sellToken",type:"address"},{name:"buyToken",type:"address"},{name:"receiver",type:"address"},{name:"sellAmount",type:"uint256"},{name:"buyAmount",type:"uint256"},{name:"validTo",type:"uint32"},{name:"appData",type:"bytes32"},{name:"feeAmount",type:"uint256"},{name:"kind",type:"string"},{name:"partiallyFillable",type:"bool"},{name:"sellTokenBalance",type:"string"},{name:"buyTokenBalance",type:"string"}]}),qo=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});function Tr(e,t={}){if(t.baseUrl)return t.baseUrl.replace(/\/$/,"");let r=Or[Number(e)];if(!r)throw new Error(`cowswap: unsupported chainId ${e}`);return r}async function We(e={},t={}){let r=Number(e.chainId??1),n=Re(e.from||e.owner),o=e.sellToken||Qe[r],s=e.buyToken||Rr[r],u=String(e.sellAmountBeforeFee||e.sellAmount||"0");if(!o||!s||u==="0")throw new Error("cowQuote requires sellToken, buyToken, sellAmountBeforeFee");if(/eeeeeeee|native|^eth$/i.test(o)&&(o=Qe[r],!o))throw new Error("no WETH mapping for chain");let c={sellToken:o,buyToken:s,from:n,receiver:e.receiver||n,sellAmountBeforeFee:u,kind:e.kind||"sell",signingScheme:e.signingScheme||"eip1271"},i=await y(`${Tr(r,t)}/quote`,{method:"POST",body:c,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),d=i?.quote?.buyAmount||i?.buyAmount;return d?A(i,{chainId:r,venue:"cowswap-order",amountOut:d,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):i}import{Interface as nt,getAddress as Q,isAddress as zr}from"ethers";I();var Je={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Br=new Map(Object.values(Je).map(e=>[e.chainId,e]));function Ze(e){return Br.get(Number(e))||null}function et(e,t=process.env){let r=Ze(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as Nr,getAddress as Yo}from"ethers";var Ko=new Nr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Pr={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};function Ur(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=et(e,r);return n||Pr[Number(e)]||null}var $r=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Lr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!$r.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}async function Y(e,t,r=[],n={}){let o=String(t||"");Lr(o);let s=Ur(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let c=await y(s,{method:"POST",body:{jsonrpc:"2.0",id:1,method:t,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3});if(c?.error){let i=new Error(c.error.message||JSON.stringify(c.error));throw i.code=c.error.code,i}return c.result}I();var Fr="https://api.dexscreener.com",Dr=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"}),x=e=>String(e??"").toLowerCase(),Mr=e=>Array.isArray(e)?e:e==null?[]:[e];function qr(e,t,r){let n=x(t),o=x(r),s=x(e?.baseToken?.address),u=x(e?.quoteToken?.address);return s===n&&u===o||s===o&&u===n}function Hr(e){let t=Number(e?.liquidity?.usd);return Number.isFinite(t)&&t>=0?t:null}function Vr(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||Fr).replace(/\/$/,"")}async function jr(e,t={}){if(!e)throw new Error("tokenAddress required");return y(`${Vr(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}async function K({chainId:e,tokenA:t,tokenB:r,dexIds:n=[]}={},o={}){if(e==null||!t||!r)throw new Error("chainId, tokenA, and tokenB required");let s=x(Dr[Number(e)]||e),u=new Set(Mr(n).filter(Boolean).map(x)),c=[...new Set([t,r].map(a=>String(a)).filter(Boolean))],i=await Promise.allSettled(c.map(a=>jr(a,{...o,baseUrl:o.dexscreenerBaseUrl,timeoutMs:o.dexscreenerTimeoutMs??Math.min(Number(o.timeoutMs??4e3),4e3)}))),d=new Set,p=[];for(let a of i)if(a.status==="fulfilled")for(let m of a.value?.pairs||a.value?.data?.pairs||[]){let h=`${x(m?.chainId)}:${x(m?.dexId)}:${x(m?.pairAddress)}`;d.has(h)||(d.add(h),p.push(m))}return p.filter(a=>x(a?.chainId)===s).filter(a=>qr(a,t,r)).filter(a=>!u.size||u.has(x(a?.dexId))).map(a=>({pairAddress:a.pairAddress??null,dexId:a.dexId??null,chainId:a.chainId??null,liquidityUsd:Hr(a),pairCreatedAt:a.pairCreatedAt??null})).filter(a=>a.liquidityUsd!=null).sort((a,m)=>m.liquidityUsd-a.liquidityUsd)[0]??null}R();B();var L={1:{name:"ethereum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},8453:{name:"base",quoter:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",router:"0x2626664c2603336E57B271c5C0b26F421741e481",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},4663:{name:"robinhood",quoter:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",router:"0xcaf681a66d020601342297493863e78c959e5cb2",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"},999:{name:"hyperevm",weth:"0x5555555555555555555555555555555555555555",usdc:"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"},10:{name:"optimism",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",quoter:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",router:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},43114:{name:"avalanche",quoter:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",router:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}},Gr=[100,500,3e3,1e4],tt=new nt(["function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)","function quoteExactInput(bytes path, uint256 amountIn) returns (uint256 amountOut, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)"]),oa=new nt(["function exactInputSingle((address tokenIn,address tokenOut,uint24 fee,address recipient,uint256 amountIn,uint256 amountOutMinimum,uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)","function multicall(uint256 deadline,bytes[] data) payable returns (bytes[] results)"]),Xr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Yr="0x0000000000000000000000000000000000000000",se=[100,500,2500,1e4],Kr={56:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},8453:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},42161:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},999:{hyperswap:{name:"hyperswap",quoter:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",router:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D"}}};function Qr(e,t){let r=Number(e),n=L[r];if(!n)throw new Error(`uniswap-v3: unsupported chainId ${e} (supported: ${Object.keys(L).join(", ")})`);let o=Kr[r]||{};if(!t){if(!n.quoter||!n.router){let i=Object.keys(o).join(", ")||"none registered";throw new Error(`uniswap-v3: chain ${r} (${n.name}) has no canonical Uniswap v3 deployment -- name a venue explicitly (known: ${i})`)}return{chainId:r,venue:n.name,...n}}let s=String(t).toLowerCase();if(s===n.name&&n.quoter&&n.router)return{chainId:r,venue:n.name,...n};let u=o,c=u[s];if(!c){let i=[...n.quoter&&n.router?[n.name]:[],...Object.keys(u)].join(", ");throw new Error(`uniswap-v3: unknown venue "${t}" on chain ${r} (known: ${i})`)}return{chainId:r,venue:s,...n,quoter:c.quoter,router:c.router,feeTiers:c.feeTiers||null}}function rt(e,t){let r=L[Number(t)];if(!e||e===Xr||e===Yr||/^eth$/i.test(String(e)))return Q(r.weth);let n=String(e);if(/^weth$/i.test(n))return Q(r.weth);if(/^usdc$/i.test(n))return Q(r.usdc);if(!zr(n))throw new Error(`invalid token address: ${e}`);return Q(n)}function Wr(e){let t=String(e||"uniswap").toLowerCase();return t==="uniswap"?["uniswap-v3","uniswap"]:t==="pancakeswap"?["pancakeswap-v3","pancakeswap"]:t==="hyperswap"?["hyperswap-v3","hyperswap"]:[t,`${t}-v3`]}async function ot(e={},t={}){let{chainId:r,quoter:n,router:o,feeTiers:s}=Qr(e.chainId??8453,e.venue),u=rt(e.tokenIn||"WETH",r),c=rt(e.tokenOut||L[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");let d=s&&s.length?s:Gr,p=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[d[Math.min(2,d.length-1)]]:[...d],l=[],a=null;for(let w of p){let b=tt.encodeFunctionData("quoteExactInputSingle",[{tokenIn:u,tokenOut:c,amountIn:i,fee:w,sqrtPriceLimitX96:0n}]);try{let f=await Y(r,"eth_call",[{to:n,data:b},"latest"],t);if(!f||f==="0x"){l.push({fee:w,ok:!1,error:"empty result"});continue}let g=tt.decodeFunctionResult("quoteExactInputSingle",f),E={fee:w,ok:!0,amountOut:g[0].toString(),sqrtPriceX96After:g[1].toString(),initializedTicksCrossed:Number(g[2]),gasEstimate:g[3].toString()};l.push(E),(!a||BigInt(E.amountOut)>BigInt(a.amountOut))&&(a=E)}catch(f){l.push({fee:w,ok:!1,error:String(f.message||f).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:Wr(e.venue)},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v3",chainId:r,chain:L[r].name,quoter:n,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,sqrtPriceX96After:a.sqrtPriceX96After,initializedTicksCrossed:a.initializedTicksCrossed,triedFees:l,best:!0},{chainId:r,venue:o,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}import{AbiCoder as Jr,Interface as st,getAddress as C,isAddress as W,keccak256 as Zr}from"ethers";R();B();var en=Jr.defaultAbiCoder(),D="0x0000000000000000000000000000000000000000",F={1:{name:"ethereum",poolManager:"0x000000000004444c5dc75cB358380D2e3dE08A90",quoter:"0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203",stateView:"0x7ffe42c4a5deea5b0fec41c94c136cf115597227",universalRouter:"0x66a9893cc07d91d95644aedd05d03f95e1dba8af",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},10:{name:"optimism",poolManager:"0x9a13f98cb987694c9f086b1f5eb990eea8264ec3",quoter:"0x1f3131a13296fb91c90870043742c3cdbff1a8d7",stateView:"0xc18a3169788f4f75a170290584eca6395c75ecdb",universalRouter:"0x851116d9223fabed8e56c0e6b8ad0c31d98b3507",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",poolManager:"0x28e2ea090877bf75740558f6bfb36a5ffee9e9df",quoter:"0x9f75dd27d6664c475b90e105573e550ff69437b0",stateView:"0xd13dd3d6e93f276fafc9db9e6bb47c1180aee0c4",universalRouter:"0x1906c1d672b88cd1b9ac7593301ca990f94eae07",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",poolManager:"0x67366782805870060151383f4bbff9dab53e5cd6",quoter:"0xb3d5c3dfc3a7aebff71895a7191796bffc2c81b9",stateView:"0x5ea1bd7974c8a611cbab0bdcafcb1d9cc9b3ba5a",universalRouter:"0x1095692a6237d83c6a72f3f5efedb9a670c49223",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},8453:{name:"base",poolManager:"0x498581fF718922c3f8e6A244956aF099B2652b2b",quoter:"0x0d5e0f971ed27fbff6c2837bf31316121532048d",stateView:"0xa3c0c9b65bad0b08107aa264b0f3db444b867a71",universalRouter:"0x6ff5693b99212da76ad316178a184ab56d299b43",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",poolManager:"0x360e68faccca8ca495c1b759fd9eee466db9fb32",quoter:"0x3972c00f7ed4885e145823eb7c655375d275a1c5",stateView:"0x76fd297e2d437cd7f76d50f01afe6160f86e9990",universalRouter:"0xa51afafe0263b40edaef0df8781ea9aa03e381a3",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},43114:{name:"avalanche",poolManager:"0x06380c0e0912312b5150364b9dc4542ba0dbbc85",quoter:"0xbe40675bb704506a3c2ccfb762dcfd1e979845c2",stateView:"0xc3c9e198c735a4b97e3e683f391ccbdd60b69286",universalRouter:"0x94b75331ae8d42c1b61065089b7d48fe14aa73b7",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"},4663:{name:"robinhood",poolManager:"0x8366a39cc670b4001a1121b8f6a443a643e40951",quoter:"0x8dc178efb8111bb0973dd9d722ebeff267c98f94",stateView:"0xf3334192d15450cdd385c8b70e03f9a6bd9e673b",universalRouter:"0x8876789976dEcBfCbBbe364623C63652db8C0904",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"}},tn=[{fee:100,tickSpacing:1},{fee:500,tickSpacing:10},{fee:3e3,tickSpacing:60},{fee:1e4,tickSpacing:200},{fee:25e3,tickSpacing:8}],at=new st(["function quoteExactInputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountOut, uint256 gasEstimate)"]),da=new st(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);var rn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";function nn(e){let t=Number(e),r=F[t];if(!r)throw new Error(`uniswap-v4: unsupported chainId ${e} (supported: ${Object.keys(F).join(", ")})`);return{chainId:t,...r}}function it(e,t){let r=F[Number(t)];if(!e||e===rn||e===D||/^eth$/i.test(String(e)))return C(r.weth);let n=String(e);if(/^weth$/i.test(n))return C(r.weth);if(/^usdc$/i.test(n)||/^usdg$/i.test(n))return C(r.usdc);if(!W(n))throw new Error(`invalid token address: ${e}`);return C(n)}function on({currency0:e,currency1:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t);if(s.toLowerCase()===u.toLowerCase())throw new Error("poolKey currencies must differ");let[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=o&&W(o)?C(o):D;return Zr(en.encode(["address","address","uint24","int24","address"],[c,i,Number(r),Number(n),d]))}function an({tokenIn:e,tokenOut:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t),[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=s.toLowerCase()===c.toLowerCase();return{poolKey:{currency0:c,currency1:i,fee:Number(r),tickSpacing:Number(n),hooks:o&&W(o)?C(o):D},zeroForOne:d}}var sn=["uniswap-v4","uniswapv4"];async function ct(e={},t={}){let{chainId:r,quoter:n,poolManager:o,universalRouter:s}=nn(e.chainId??8453),u=it(e.tokenIn||"WETH",r),c=it(e.tokenOut||F[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");if(i>0xffffffffffffffffffffffffffffffffn)throw new Error("amountIn exceeds uint128");let d=e.fee!=null&&e.tickSpacing!=null?[{fee:Number(e.fee),tickSpacing:Number(e.tickSpacing)}]:e.tryTiers===!1?[{fee:500,tickSpacing:10}]:[...tn],p=e.hooks||D,l=[],a=null;for(let w of d){let{poolKey:b,zeroForOne:f}=an({tokenIn:u,tokenOut:c,fee:w.fee,tickSpacing:w.tickSpacing,hooks:p}),g=at.encodeFunctionData("quoteExactInputSingle",[{poolKey:b,zeroForOne:f,exactAmount:i,hookData:"0x"}]);try{let E=await Y(r,"eth_call",[{to:n,data:g},"latest"],t);if(!E||E==="0x"){l.push({...w,ok:!1,error:"empty result"});continue}let k=at.decodeFunctionResult("quoteExactInputSingle",E),_={fee:w.fee,tickSpacing:w.tickSpacing,ok:!0,amountOut:k[0].toString(),gasEstimate:k[1].toString(),poolKey:b,zeroForOne:f,poolId:on({...b})};l.push(_),(!a||BigInt(_.amountOut)>BigInt(a.amountOut))&&(a=_)}catch(E){l.push({...w,ok:!1,error:String(E.message||E).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}/${b.tickSpacing}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v4 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:sn},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v4",chainId:r,chain:F[r].name,poolManager:o,quoter:n,universalRouter:s||null,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,tickSpacing:a.tickSpacing,hooks:a.poolKey.hooks,poolId:a.poolId,zeroForOne:a.zeroForOne,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,triedTiers:l,best:!0,executionReady:!1,prepareReady:typeof e.recipient=="string"&&W(e.recipient)&&e.slippageBps!=null},{chainId:r,venue:s||n,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}I();var cn="https://coins.llama.fi",un="https://api.llama.fi";function ln(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||cn).replace(/\/$/,"")}function dn(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||un).replace(/\/$/,"")}async function J(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return y(`${ln(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function ut(e={}){return y(`${dn(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var v=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function Z(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=v(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}async function wt(e,t={}){let r=we[Number(e)];if(!r)return null;try{let n=await J([r],t);return v(n?.coins?.[r]?.price)}catch{return null}}var N=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),ht=Object.freeze({across:["across"],relay:["relaychain","relay"],lifi:["jumper-(li.fi-powered)","lifi"],stargate:["stargate-v2","stargate-v1","stargate"],hop:["hop-protocol","hop"],debridge:["debridge"],synapse:["synapse"],connext:["connext"],cbridge:["celer-bridge","celer-cbridge","cbridge"],celer:["celer-bridge","celer-cbridge","cbridge"],squid:["squid"],symbiosis:["symbiosis"],wormhole:["wormhole"],mayan:["mayan"],allbridge:["allbridge"],thorchain:["thorchain"]});async function bn(e={}){try{let t=await ut({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function gn(e,t={}){let r=N(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...ht[r]||[r]),n.push(...ht[N(e)]||[e]),n}function En(e,t,r={}){let n=Array.isArray(e)?e:[],o=gn(t,r).map(N).filter(Boolean);for(let s of o){let u=n.find(i=>N(i?.slug)===s||N(i?.name)===s),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}for(let s of o){let u=n.find(i=>{let d=N(i?.category);return!d.includes("bridge")&&!d.includes("crosschain")?!1:N(i?.slug).includes(s)||N(i?.name).includes(s)}),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}return null}function de({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:s,decimalsIn:u,decimalsOut:c,nativePriceUsd:i=null,destDecimalsPromise:d=null,opts:p={}}){let l=[];return l.push({source:"lifi",run:async()=>{let a=await ie({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n},p),m=a?.estimate??a?.[0]?.estimate;return{amountOut:m?.toAmount,minOut:m?.toAmountMin,gasUsd:Z(m?.gasCosts),feeUsd:Z(m?.feeCosts),oracleFeeBps:a?.oracleFee?.applies?a.oracleFee.bps:0,meta:{tool:a?.tool??a?.toolDetails?.name,oracleFee:a?.oracleFee??null}}}}),u!=null&&l.push({source:"paraswap",run:async()=>{let a=c??(await Promise.resolve(d))?.decimals;if(a==null)throw new Error("paraswap needs destination decimals; none supplied or resolvable");let m=await qe({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:u,destDecimals:a},p),h=m?.priceRoute;return{amountOut:h?.destAmount,gasUsd:v(h?.gasCostUSD),oracleFeeBps:m?.oracleFee?.applies?m.oracleFee.bps:0,meta:{bestRoute:h?.bestRoute?.[0]?.swaps?.[0]?.swapExchanges?.[0]?.exchange,oracleFee:m?.oracleFee??null}}}}),process.env.ZEROX_API_KEY&&l.push({source:"0x",run:async()=>{let a=await Ge({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},p),m=null,h=a?.totalNetworkFee,w=await Promise.resolve(i);return h!=null&&w&&(m=Number(h)/1e18*w),{amountOut:a?.buyAmount,minOut:a?.minBuyAmount,gasUsd:m,meta:{source:a?.route?.fills?.[0]?.source}}}}),process.env.ONEINCH_API_KEY&&l.push({source:"1inch",run:async()=>{let a=await Ke({chainId:e,src:t,dst:r,amount:n},p),m=null;return a?.gas!=null&&i&&(m=null),{amountOut:a?.dstAmount,gasUsd:m,meta:{gasUnits:a?.gas}}}}),l.push({source:"cow",run:async()=>{let a=await We({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},p),m=a?.quote??a,h=m?.feeAmount;return{amountOut:m?.buyAmount,gasUsd:0,meta:{intent:!0,feeAmountInSellToken:h,settlement:"solver-executed"}}}}),L[Number(e)]&&l.push({source:"uniswap-v3",run:async()=>{let a=await ot({chainId:e,tokenIn:t,tokenOut:r,amountIn:n},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,fee:a?.fee,gasUnits:a?.gasEstimate,quoter:a?.quoter}}}}),F[Number(e)]&&l.push({source:"uniswap-v4",run:async()=>{let a=await ct({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:s},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,venue:"uniswap-v4",fee:a?.fee,tickSpacing:a?.tickSpacing,poolId:a?.poolId,hooks:a?.hooks,gasUnits:a?.gasEstimate,quoter:a?.quoter,poolManager:a?.poolManager,prepareReady:a?.prepareReady===!0,executionReady:!1}}}}),l}function bt({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:s,opts:u={}}){let c=[],i=null,d=async(p,l={})=>(i||=bn(u),En(await i,p,l));return c.push({source:"lifi",run:async()=>{let p=await ie({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},u),l=p?.estimate??p?.[0]?.estimate,a={tool:p?.tool??p?.toolDetails?.name,durationSeconds:v(l?.executionDuration)},m=await d("lifi",a);return{amountOut:l?.toAmount,minOut:l?.toAmountMin,gasUsd:Z(l?.gasCosts),feeUsd:Z(l?.feeCosts),oracleFeeBps:p?.oracleFee?.applies?p.oracleFee.bps:0,liquidityUsd:m?.liquidityUsd??null,meta:{...a,liquidityProtocol:m?.protocol,oracleFee:p?.oracleFee??null}}}}),c.push({source:"relay",run:async()=>{let{relayQuote:p}=await Promise.resolve().then(()=>(le(),ue)),a=(await p({user:s,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},u))?.details,m={durationSeconds:v(a?.timeEstimate),rate:a?.rate},h=await d("relay",m);return{amountOut:a?.currencyOut?.amount,minOut:a?.currencyOut?.minimumAmount,gasUsd:v(a?.totalImpact?.usd)!=null?Math.abs(v(a.totalImpact.usd)):null,liquidityUsd:h?.liquidityUsd??null,meta:{...m,liquidityProtocol:h?.protocol}}}}),c.push({source:"across",run:async()=>{let{acrossSuggestedFees:p}=await Promise.resolve().then(()=>(le(),ue)),l=await p({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},u),a=l?.totalRelayFee?.total,m=null;if(a!=null)try{let w=BigInt(String(o))-BigInt(String(a));w>0n&&(m=w.toString())}catch{}let h=await d("across");return{amountOut:m,gasUsd:null,liquidityUsd:h?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:v(l?.estimatedFillTimeSec),limits:l?.limits?{min:l.limits.minDeposit,max:l.limits.maxDeposit}:void 0,liquidityProtocol:h?.protocol}}}}),c}var yn={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function gt(e,t,r){let n=yn[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let u=(await J([o],r))?.coins?.[o],c=Number(u?.price),i=Number(u?.decimals);return{priceUsd:Number.isFinite(c)?c:null,decimals:Number.isFinite(i)?i:null}}catch{return{priceUsd:null,decimals:null}}}async function Pa(e,t={}){let{chainId:r,tokenIn:n,tokenOut:o,amountIn:s}=e;if(r==null||!n||!o||s==null)throw new Error("bestSwapRoute requires chainId, tokenIn, tokenOut, amountIn");let u=wt(r,t),c=gt(r,o,t),i=de({...e,nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??12e3}),c]);u.catch(()=>{});let l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=t.maxImpactPct===void 0?25:t.maxImpactPct;if(a!=null&&l.best){let m=l.best.source,w=await be(async b=>{let f=de({...e,amountIn:b.toString(),nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}).filter(E=>E.source===m);return f.length?(await H(f,{timeoutMs:t.timeoutMs??12e3}))?.[0]?.amountOut??null:null},s);if(w){let b=ge(l,{[m]:w},{maxImpactPct:a});return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...b,sourcesTried:i.length,sourcesAnswered:d.filter(f=>f.quality!==S.FAILED).length,note:pe(b,i.length),priceImpact:{[m]:Number(w.impactPct.toFixed(2))}}}}return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...l,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}async function Ua(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:u}=e;if(r==null||n==null||!o||!s||u==null)throw new Error("bestBridgeRoute requires fromChainId, toChainId, tokenIn, tokenOut, amountIn");if(Number(r)===Number(n))throw new Error("bestBridgeRoute is for cross-chain; use bestSwapRoute for same-chain");let c=gt(n,s,t),i=bt({...e,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??15e3}),c]),l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=l.routes.map(m=>({source:m.source,seconds:m.meta?.durationSeconds??null})).filter(m=>m.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:String(u),...l,durations:a,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}function An(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Le(t)}`:""}function pe(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=An(e.best);if(r===1)return`only 1 of ${t} sources answered, so this is the ONLY route, not a proven best one. Treat it as unbenchmarked.`+n;if(e.improvementBps!=null){let o=e.improvementBps,s=o/100;if(o<.01)return`best of ${r} routes, ranked on ${e.rankedOn}: effectively tied with the runner-up (${e.spreadBasis}), inside quote noise. Re-quote before you size up.`+n;let u=s>=.01?`${s.toFixed(2)}%`:`${o.toFixed(2)}bps`;return`best of ${r} routes, ranked on ${e.rankedOn}: ${u} better than the runner-up (${e.spreadBasis})`+n}return`best of ${r} routes, ranked on ${e.rankedOn}. No spread quoted: the top routes report cost differently, so the margin is not comparable.`+n}export{S as QUALITY,Ua as bestBridgeRoute,Pa as bestSwapRoute,pe as formatComparisonNote};
|
|
1
|
+
var yt=Object.defineProperty;var P=(e,t,r)=>()=>{if(r)throw r[0];try{return e&&(t=e(e=0)),t}catch(n){throw r=[n],n}};var At=(e,t)=>{for(var r in t)yt(e,r,{get:t[r],enumerable:!0})};import{createHash as xt}from"node:crypto";function vt(e){let t=String(e||"").toLowerCase();return xe.includes(t)||/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(t)}function kt(e){let t={};for(let[r,n]of Object.entries(e||{}))vt(r)||(t[r]=n);return t}function _t(e,t){if(!e)throw new Error(`HTTP redirect from ${t} missing Location`);let r=new URL(String(e),String(t));if(r.protocol!=="http:"&&r.protocol!=="https:")throw new Error(`HTTP redirect from ${t} used unsupported protocol ${r.protocol}`);return r.toString()}function Ot(e,t){return new URL(String(e)).origin===new URL(String(t)).origin}function Tt(e,t,r){let n={};for(let[i,d]of Object.entries(r||{}))n[i.toLowerCase()]=d;let o=Object.keys(n).filter(i=>/(^|-)(api[-_]?key|key|token|secret|auth|authorization|session|cookie|signature|access)(-|$)/.test(i)),u=[...new Set([...xe,...o])].sort().map(i=>`${i}=${n[i]??""}`).join(`
|
|
2
|
+
`),c=xt("sha256").update(u).digest("hex").slice(0,32);return`${e} ${t} ${c}`}function Rt(e,t){let r=Number(t);return Number.isFinite(r)&&r>0?Math.min(r*1e3,ye):Math.min(250*2**e,ye)+Math.floor(Math.random()*100)}async function Nt(e,{fetchImpl:t,method:r,headers:n,body:o,timeoutMs:s}){let u=new AbortController,c=setTimeout(()=>u.abort(),s);try{let i=String(e),d={...n||{}};for(let p=0;p<=Ae;p+=1){let l=await t(i,{method:r,headers:d,body:o,signal:u.signal,redirect:"manual"}),a=await l.text(),m=null;if(a)try{m=JSON.parse(a)}catch{m=null}if(Ct.has(l.status)){if(r!=="GET"&&r!=="HEAD"){let w=new Error(`HTTP ${l.status} ${r} ${i} redirected non-idempotent request`);throw w.status=l.status,w.body=m??a.slice(0,300),w}if(p===Ae)throw new Error(`HTTP redirect loop for ${e}`);let h=_t(l.headers?.get?.("location"),i);Ot(h,i)||(d=kt(d)),i=h;continue}if(!l.ok){let h=new Error(`HTTP ${l.status} ${r} ${i}`);throw h.status=l.status,h.retryAfter=l.headers?.get?.("retry-after")??null,h.body=m??a.slice(0,300),h}return m??a}throw new Error(`HTTP redirect loop for ${e}`)}finally{clearTimeout(c)}}async function y(e,t={}){let r=t.fetchImpl||globalThis.fetch;if(typeof r!="function")throw new Error("fetch unavailable \u2014 pass opts.fetchImpl");let n=t.timeoutMs??12e3,o=(t.method||"GET").toUpperCase(),s={Accept:"application/json",...t.headers||{}},u=t.body;u!=null&&typeof u!="string"&&(s["Content-Type"]=s["Content-Type"]||"application/json",u=JSON.stringify(u));let c=Number.isInteger(t.retries)?Math.max(t.retries,0):It,i=async()=>{let m;for(let h=0;h<=c;h++)try{return await Nt(e,{fetchImpl:r,method:o,headers:s,body:u,timeoutMs:n})}catch(w){m=w;let b=w?.status,f=w?.name==="AbortError",g=new Set([408,425,429]),E=b!=null?g.has(b)||St.has(b)&&Ee.has(o):!f&&Ee.has(o);if(h===c||!E)throw w;await Bt(Rt(h,w?.retryAfter))}throw m};if(!(t.dedupe!==!1&&o==="GET"&&u==null))return i();let p=Tt(o,e,s),l=re.get(p);if(l)return l;let a=i().finally(()=>re.delete(p));return re.set(p,a),a}var St,Ee,It,ye,xe,Ct,Ae,re,Bt,I=P(()=>{St=new Set([408,425,429,500,502,503,504]),Ee=new Set(["GET","HEAD","OPTIONS","PUT","DELETE"]),It=2,ye=4e3,xe=["authorization","x-api-key","x-tensor-api-key","0x-api-key","api-key","cookie","proxy-authorization"],Ct=new Set([301,302,303,307,308]),Ae=3;re=new Map;Bt=e=>new Promise(t=>setTimeout(t,e))});import{readFileSync as Pt}from"node:fs";import{homedir as Ut}from"node:os";import{join as V}from"node:path";function $t(){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=Ut();if(process.env.ORACLE_PUBLIC_DESKTOP==="1"){let r=(process.env.ORACLE_CONFIG_DIR||V(t,".config","oracle")).trim();return[e,V(r,"exec.env")].filter(Boolean)}return[e,V(t,".config","oracle","exec.env"),V(t,".config","mad-desk","exec.env")].filter(Boolean)}function Se(e,t,r){let n=e??process.env[t]??process.env[r];if(!String(n||"").trim())for(let o of $t())try{let s=Pt(o,"utf8"),u=s.match(new RegExp(`^${t}=(.*)$`,"m"))||s.match(new RegExp(`^${r}=(.*)$`,"m"));if(u&&(n=u[1].trim(),n))break}catch{}if(!String(n||"").trim())throw new Error(`${t} required for attestation. Set it in the environment, or place ${t}=<value> in ~/.config/oracle/exec.env`);return n}var Ie=P(()=>{});var Ce=P(()=>{});import{createHash as Lt,createHmac as Ft,timingSafeEqual as Dn}from"node:crypto";function oe(e){return Array.isArray(e)?`[${e.map(oe).join(",")}]`:e&&typeof e=="object"?`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${oe(e[t])}`).join(",")}}`:JSON.stringify(e??null)}function Dt(e,{required:t=!1}={}){try{return Se(e,"ORACLE_ROUTE_ATTESTATION_SECRET","MAD_ROUTE_ATTESTATION_SECRET")}catch(r){if(t)throw r;return null}}function _e(e){let{signature:t,...r}=e;return r}function Oe(e,{secret:t}={}){let r=Dt(t);return r?{...e,signature:Ft("sha256",r).update(oe(_e(e))).digest("hex")}:e}function Mt(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 Lt("sha256").update(Buffer.from(t.slice(2),"hex")).digest("hex")}function U(e,{chainId:t,venue:r,data:n,secret:o}={}){if(!e||e.mode!=="auto")throw new Error("bounded auto-slippage guard required");if(Number(e.chainId)!==Number(t))throw new Error("auto-slippage guard chain mismatch");if(String(e.venue).toLowerCase()!==String(r||"").toLowerCase())throw new Error("auto-slippage guard venue mismatch");return Oe({..._e(e),calldataHash:Mt(n)},{secret:o})}function ne(e,t=0){let r=Number(e);return Number.isFinite(r)?r:t}function qt(e){let t=e==null?ve:Number(e);if(!Number.isInteger(t)||t<0)throw new Error("auto-slippage cap must be a non-negative integer bps value");return Math.min(t,ve)}function O({liquidityUsd:e,priceChange5m:t=0,quoteAgeMs:r=0,crossChain:n=!1,requestedCapBps:o}={}){let s=ne(e,0),u=s>0?s>=25e4?5:s>=1e5?10:s>=5e4?20:s>=1e4?40:70:n?30:10,c=Math.min(60,Math.abs(ne(t,0))*2),i=Math.min(40,Math.floor(Math.max(0,ne(r,0))/5e3)*5),d=Math.max(25,Math.ceil(20+u+c+i)),p=qt(o);return{mode:"auto",requiredBps:d,selectedBps:Math.min(d,p),capBps:p,executable:d<=p}}function Ht({chainId:e,venue:t,quoteAmountOut:r,liquidityUsd:n,priceChange5m:o=0,quoteAgeMs:s=0,crossChain:u=!1,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d=ke,secret:p}={}){let l=BigInt(r??0);if(l<=0n)throw new Error("auto-slippage guard requires positive quoteAmountOut");let a=O({liquidityUsd:n,priceChange5m:o,quoteAgeMs:s,crossChain:u,requestedCapBps:c});if(!a.executable)throw new Error(`auto-slippage requires ${a.requiredBps} bps above hard/requested cap ${a.capBps}; route blocked`);let m=Number(i);if(!Number.isFinite(m))throw new Error("auto-slippage: quotedAtMs must be a finite number");let h=Math.min(3e4,Math.max(1e3,Number(d)||ke)),w=l*BigInt(1e4-a.selectedBps),b=w/10000n;if(w%10000n!==0n&&(b+=1n),b>l&&(b=l),l>0n&&b<=0n)throw new Error(`auto-slippage: quote ${l} is too small to express a ${a.selectedBps} bps floor without rounding to zero`);let f=Number((l-b)*10000n/(l===0n?1n:l));if(f>a.capBps)throw new Error(`auto-slippage: realised floor implies ${f} bps, above cap ${a.capBps} \u2014 refusing to issue a guard weaker than advertised`);return Oe({mode:"auto",chainId:Number(e),venue:String(t||"unknown"),quoteAmountOut:l.toString(),minAmountOut:b.toString(),requiredBps:a.requiredBps,selectedBps:a.selectedBps,capBps:a.capBps,quotedAtMs:m,expiresAtMs:m+h},{secret:p})}function A(e,{chainId:t,venue:r,amountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i=Date.now(),ttlMs:d}={}){let p=Ht({chainId:t,venue:r,quoteAmountOut:n,liquidityUsd:o,priceChange5m:s,crossChain:u,requestedCapBps:c,quotedAtMs:i,ttlMs:d});return{...e,autoSlippage:p,amountOutMinimum:p.minAmountOut}}var ve,ke,T=P(()=>{Ie();Ce();ve=100,ke=2e4});function Te(e){let t=String(e||"").trim();return/^0x[0-9a-fA-F]{40}$/.test(t)?t:$}var $,j=P(()=>{$="0x000000000000000000000000000000000000dEaD"});import{createHash as Vt,createHmac as jt,timingSafeEqual as zn}from"node:crypto";function ae(e){return e===null||typeof e!="object"?JSON.stringify(e):Array.isArray(e)?`[${e.map(ae).join(",")}]`:`{${Object.keys(e).sort().map(r=>`${JSON.stringify(r)}:${ae(e[r])}`).join(",")}}`}function Re(e){let t=String(e?.ORACLE_STAMP_HMAC_SECRET||"").trim();return t.length>=16?t:""}function Be(e=process.env){return Re(process.env)||Re(e)}function Xt(e){let{oraclePrepared:t,prepareHash:r,prepareMac:n,note:o,...s}=e||{};return s}function Yt(e){let t=Xt(e);return Vt("sha256").update(ae(t)).digest("hex")}function Kt(e,t=Be()){return t?jt("sha256",t).update(String(e)).digest("hex"):""}function R(e,{provider:t,kind:r,env:n=process.env}={}){if(!e||typeof e!="object")throw new Error("stampPrepared: payload object required");let o={...e,provider:e.provider||t,kind:e.kind||r,requiresUserSignature:e.requiresUserSignature!==!1,signingReady:!1,broadcastReady:!1,executionReady:!1};if(!o.provider)throw new Error("stampPrepared: provider required");if(!o.kind)throw new Error("stampPrepared: kind required");let s=Date.now(),u=s+Gt,i={...o,preparedAt:s,expiresAt:u,prepareVersion:zt},d=Yt(i),p=Be(n),l=p?Kt(d,p):void 0,a={...i,oraclePrepared:!0,prepareHash:d};return l&&(a.prepareMac=l),a}var zt,Gt,Gn,B=P(()=>{zt=2,Gt=300*1e3,Gn=(()=>{let e=Number(process.env.ORACLE_PREPARE_HARD_MAX_AGE_MS);return Number.isFinite(e)&&e>0?e:1800*1e3})()});var ue={};At(ue,{ACROSS_API:()=>lt,HOP_API:()=>dt,RELAY_API:()=>pt,acrossHealth:()=>mn,acrossSuggestedFees:()=>mt,hopHealth:()=>fn,hopQuote:()=>ft,relayHealth:()=>hn,relayPrepare:()=>wn,relayQuote:()=>ce});async function mn(e={}){try{return{ok:!0,estimatedFillTimeSec:(await mt({token:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",destinationToken:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",originChainId:1,destinationChainId:42161,amount:"1000000000000000"},e)).estimatedFillTimeSec}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function mt(e={},t={}){let{token:r,destinationToken:n=r,originChainId:o,destinationChainId:s,amount:u}=e;if(!r||o==null||s==null||!u)throw new Error("acrossSuggestedFees requires token, originChainId, destinationChainId, amount");let c=new URLSearchParams({token:r,destinationToken:n,originChainId:String(o),destinationChainId:String(s),amount:String(u)}),i=(t.baseUrl||process.env.ACROSS_API_URL||lt).replace(/\/$/,"");return y(`${i}/suggested-fees?${c}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3})}async function fn(e={}){try{let t=await ft({amount:"1000000000000000",token:"ETH",fromChain:"ethereum",toChain:"arbitrum",slippage:.5},e);return{ok:!0,estimatedRecieved:t.estimatedRecieved||t.estimatedReceived}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function ft(e={},t={}){let{amount:r,token:n="ETH",fromChain:o="ethereum",toChain:s="arbitrum"}=e;if(!r)throw new Error("hopQuote requires amount");let u=e.slippage==null?void 0:Math.round(Number(e.slippage)*100),c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u});if(!c.executable)throw new Error(`hop: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({amount:String(r),token:n,fromChain:o,toChain:s,slippage:String(c.selectedBps/100)}),d=(t.baseUrl||process.env.HOP_API_URL||dt).replace(/\/$/,""),p=await y(`${d}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),l=p?.estimatedRecieved||p?.estimatedReceived;return l?A(p,{chainId:Number(e.originChainId||e.chainId||pn[o]||0),venue:p?.tx?.to||"hop",amountOut:l,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:o!==s,requestedCapBps:e.maxSlippageBps??e.slippageBps??u}):{...p,autoSlippagePolicy:c}}async function hn(e={}){try{let t=await ce({user:$,originChainId:1,destinationChainId:8453,originCurrency:"0x0000000000000000000000000000000000000000",destinationCurrency:"0x0000000000000000000000000000000000000000",amount:"1000000000000000",tradeType:"EXACT_INPUT"},e);return{ok:!0,hasSteps:Array.isArray(t.steps),stepCount:t.steps?.length||0}}catch(t){return{ok:!1,error:String(t.message||t).slice(0,160)}}}async function ce(e={},t={}){let{user:r=$,originChainId:n,destinationChainId:o,originCurrency:s="0x0000000000000000000000000000000000000000",destinationCurrency:u="0x0000000000000000000000000000000000000000",amount:c,tradeType:i="EXACT_INPUT"}=e;if(n==null||o==null||!c)throw new Error("relayQuote requires originChainId, destinationChainId, amount");let d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`relay: route requires ${d.requiredBps} bps above cap ${d.capBps}`);let p=(t.baseUrl||process.env.RELAY_API_URL||pt).replace(/\/$/,""),l=await y(`${p}/quote`,{method:"POST",body:{user:r,originChainId:Number(n),destinationChainId:Number(o),originCurrency:s,destinationCurrency:u,amount:String(c),tradeType:i,slippageTolerance:String(d.selectedBps)},fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.details?.currencyOut?.amount;return!a||!/^\d+$/.test(String(a))?{...l,autoSlippagePolicy:d}:A(l,{chainId:Number(n),venue:l?.steps?.[0]?.items?.[0]?.data?.to||"relay",amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(o),requestedCapBps:e.maxSlippageBps??e.slippageBps})}async function wn(e={},t={}){let r=await ce(e,t),n=Number(e.originChainId),o=(r.steps||[]).flatMap(c=>(c.items||[]).filter(i=>i?.data?.to&&i?.data?.data).map(i=>({stepId:c.id,...i.data})));if(!o.length)throw new Error("relay: quote returned no executable transaction items");let s=String(r?.autoSlippage?.venue||"").toLowerCase();if(o.some(c=>String(c.to).toLowerCase()!==s))throw new Error("relay: route includes a separate approval/transaction that is not yet safely bound");let u=o.map(c=>({chainId:n,from:c.from||e.user,to:c.to,data:c.data,value:c.value??"0x0",...c.gasLimit!=null||c.gas!=null?{gasLimit:c.gasLimit??c.gas}:{},slippageGuard:U(r.autoSlippage,{chainId:n,venue:c.to,data:c.data})}));return R({provider:"relay",calldataReady:!0,requiresUserSignature:!0,signingReady:!1,broadcastReady:!1,chainId:n,quote:r,autoSlippage:r.autoSlippage,transactions:u},{provider:"relay",kind:"relay-tx"})}var lt,dt,pt,pn,le=P(()=>{I();T();j();B();lt="https://across.to/api",dt="https://api.hop.exchange/v1",pt="https://api.relay.link",pn={ethereum:1,optimism:10,bsc:56,polygon:137,arbitrum:42161,avalanche:43114,base:8453}});var Sn=Object.freeze(["blockNumber","nativeBalance","tokenBalance","resolveToken","resolvePools","scanBlocks","scoreRisk","quote","sellSimulation","prepareUnsignedTx"]),In=Object.freeze({LIVE:"LIVE",CACHED:"CACHED",STALE:"STALE",UNKNOWN:"UNKNOWN",UNAVAILABLE:"UNAVAILABLE"}),Cn=Object.freeze({PASS:"PASS",CAUTION:"CAUTION",FAIL:"FAIL",UNKNOWN:"UNKNOWN"});var S=Object.freeze({FULL:"FULL",NO_GAS:"NO_GAS",FAILED:"FAILED"}),we={1:"coingecko:ethereum",10:"coingecko:ethereum",56:"coingecko:binancecoin",137:"coingecko:matic-network",8453:"coingecko:ethereum",42161:"coingecko:ethereum",43114:"coingecko:avalanche-2",999:"coingecko:ethereum"},q=e=>{try{return e==null||e===""?null:BigInt(String(e).split(".")[0])}catch{return null}};function he(e){let{source:t,amountOut:r,minOut:n=null,gasUsd:o=null,feeUsd:s=null,oracleFeeBps:u=0,estimatedGas:c=null,liquidityUsd:i=null,error:d=null,executionReady:p=!1,meta:l={}}=e||{};if(d||r==null)return{source:t,quality:S.FAILED,amountOut:null,error:d||"no amountOut returned"};let a=q(r);if(a==null||a<=0n)return{source:t,quality:S.FAILED,amountOut:null,error:"non-positive amountOut"};let m=Number(u);return{source:t,quality:o==null?S.NO_GAS:S.FULL,amountOut:a.toString(),minOut:q(n)?.toString()??null,gasUsd:o,feeUsd:s,oracleFeeBps:Number.isFinite(m)&&m>0?Math.floor(m):0,estimatedGas:c==null?null:String(c),liquidityUsd:i==null?null:Number(i),executionReady:p,meta:l}}async function be(e,t,{divisor:r=1000n}={}){let n=q(t);if(n==null||n<=0n)return null;let o=n/r>0n?n/r:1n;if(o>=n)return null;let s,u;try{[s,u]=await Promise.all([e(o),e(n)])}catch{return null}let c=q(s),i=q(u);if(c==null||i==null||c<=0n)return null;let d=Number(c)/Number(o),p=Number(i)/Number(n);return!Number.isFinite(d)||!Number.isFinite(p)||d<=0?null:{impactPct:(1-p/d)*100,probeAmountIn:o.toString(),probeAmountOut:c.toString(),fullAmountOut:i.toString()}}function ge(e,t,{maxImpactPct:r=25}={}){let n=[],o=[],s=(e.routes??[]).filter(c=>{let i=t?.[c.source];return i?i.impactPct>r?(n.push({source:c.source,impactPct:Number(i.impactPct.toFixed(2)),reason:`price impact ${i.impactPct.toFixed(1)}% exceeds ${r}% ceiling -- the venue cannot absorb this size near the quoted price`}),!1):!0:(o.push(c.source),!0)}),u=[...e.warnings??[]];return n.length&&u.push(`dropped ${n.length} route(s) on price impact: `+n.map(c=>`${c.source} (${c.impactPct}%)`).join(", ")),o.length&&u.push(`price impact NOT measured for: ${o.join(", ")}. These are unproven against thin liquidity, not proven safe.`),{...e,routes:s,best:s[0]??null,impactRejected:n,impactUnmeasured:o,warnings:u}}function te(e,{destPriceUsd:t=null,destDecimals:r=null,liquidityFirst:n=!0,liquidityBandBps:o=50}={}){let s=e.filter(f=>f.quality!==S.FAILED),u=e.filter(f=>f.quality===S.FAILED),c=t!=null&&t>0&&r!=null&&r>=0,i=s.map(f=>{let g=BigInt(f.amountOut),E=0n,k=!1,_=BigInt(f.oracleFeeBps??0),M=_>0n?g*_/10000n:0n;if(c){let fe=(f.gasUsd??0)+(f.feeUsd??0);if(fe>0){let ee=fe/t*10**r;Number.isFinite(ee)&&ee>=0&&(E=BigInt(Math.floor(ee)),k=!0)}else f.gasUsd===0&&(k=!0)}let me=E+M,Et=g>me?g-me:0n;return{...f,grossOut:g.toString(),netOut:Et.toString(),costInDest:E.toString(),oracleFeeInDest:M.toString(),costAccounted:k}}),d=Number(o)>0?Number(o):0,p=i.reduce((f,g)=>BigInt(g.netOut)>f?BigInt(g.netOut):f,0n),l=f=>p>0n?Number((p-BigInt(f))*10000n/p):0,a=[],m=i.slice().sort((f,g)=>BigInt(g.netOut)>BigInt(f.netOut)?1:-1)[0]??null;i.sort((f,g)=>{let E=l(f.netOut)<=d?0:1,k=l(g.netOut)<=d?0:1;if(n&&d>0&&E!==k)return E-k;if(n&&d>0){let _=f.liquidityUsd??-1,M=g.liquidityUsd??-1;if(_!==M)return M-_}return BigInt(g.netOut)>BigInt(f.netOut)?1:-1}),n&&d>0&&m&&i[0]&&i[0].source!==m.source&&a.push(`liquidity-first: chose ${i[0].source} (liquidity $${i[0].liquidityUsd??"unknown"}) over best-price ${m.source} within ${d} bps`);let h=i.filter(f=>!f.costAccounted).map(f=>f.source);c?h.length&&a.push(`gas not reported by: ${h.join(", ")}. These are ranked on gross output and may be overstated relative to gas-measured routes.`):a.push("destination price/decimals unavailable: ranked on GROSS output. Gas is not included, so a cheap-looking route may cost more to execute.");let w=null,b=null;if(i.length>=2&&i[0].costAccounted&&i[1].costAccounted){let f=BigInt(i[0].netOut),g=BigInt(i[1].netOut);g>0n&&(w=Number((f-g)*10000n/g),b=`${i[0].source} vs ${i[1].source}`)}return{best:i[0]??null,routes:i,failed:u,improvementBps:w,spreadBasis:b,rankedOn:c?"net-of-cost":"gross",warnings:a}}async function H(e,{timeoutMs:t=12e3}={}){let r=(o,s)=>Promise.race([o,new Promise((u,c)=>setTimeout(()=>c(new Error(`${s}: timeout`)),t))]);return(await Promise.allSettled(e.map(o=>r(Promise.resolve().then(o.run),o.source)))).map((o,s)=>{let u=e[s].source;return o.status==="rejected"?he({source:u,error:String(o.reason?.message||o.reason)}):he({source:u,...o.value})})}I();T();j();B();import{existsSync as or,readFileSync as ar}from"node:fs";import{homedir as ir}from"node:os";import{join as Pe}from"node:path";import{Contract as Qt,JsonRpcProvider as Wt}from"ethers";var Jt="0x62FCFAf7573AD8B41a0FBF347AfEb85e06599A75",Zt=999,er="https://rpc.hyperliquid.xyz/evm",tr=["function balanceOf(address owner) view returns (uint256)"],rr=/^0x[a-fA-F0-9]{40}$/;function nr(e){return rr.test(String(e||""))}async function Ne(e,{contract:t=Jt,rpc:r=er,chainId:n=Zt,balanceOf:o}={}){if(!nr(e))throw new Error("invalid-address");if(o)return BigInt(await o(e));let s=new Wt(r,n,{staticNetwork:!0}),u=new Qt(t,tr,s);return BigInt(await u.balanceOf(e))}var sr=100,cr=5,Ue=Object.freeze({swap:5,bridge:5,perps:0,nft:0});function ur(e){let t=String(e||"swap").toLowerCase();return Object.prototype.hasOwnProperty.call(Ue,t)?Ue[t]:cr}var lr="ORACLE_INTEGRATOR_FEE_BPS",dr="ORACLE_INTEGRATOR_FEE_RECIPIENT",pr="ORACLE_INTEGRATOR_ID",$e="ORACLE_INTEGRATOR_FEE_RECIPIENT_PIN",mr="oracle";function fr(e=process.env){if(e[$e])return String(e[$e]);let t=e.ORACLE_CONFIG_DIR||Pe(ir(),".config","oracle");return Pe(t,"fee-recipient")}function hr(e=process.env){try{let t=fr(e);if(!or(t))return"";let r=ar(t,"utf8").trim().toLowerCase();return/^0x[a-f0-9]{40}$/.test(r)?r:""}catch{return""}}function wr(e,{fallback:t=0}={}){if(e==null)return t;if(String(e).trim()==="")return 0;let r=Number(e);return!Number.isFinite(r)||r<=0?0:Math.min(Math.floor(r),sr)}function br({env:e=process.env,action:t="swap",admin:r=!1}={}){let n=String(e[dr]||"").trim(),o=String(e[pr]||mr).trim();if(r===!0)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"admin-oracle"};let s=ur(t),u=wr(e[lr],{fallback:n?s:0}),c=Math.min(u,s);if(!c)return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"not-configured"};if(!/^0x[a-fA-F0-9]{40}$/.test(n))return{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"no-recipient"};let i=hr(e);return!i||i!==n.toLowerCase()?{bps:0,recipient:"",integrator:o,action:t,applies:!1,reason:"recipient-not-pinned"}:{bps:c,recipient:n,integrator:o,action:t,applies:!0,reason:"configured"}}async function z({wallet:e,env:t=process.env,action:r="swap",holderCheck:n={},admin:o=!1}={}){let s=br({env:t,action:r,admin:o});if(o===!0)return{...s,holderVerificationStatus:"admin-oracle"};let u=String(e||"").trim().toLowerCase();if(!/^0x[a-f0-9]{40}$/.test(u))return{...s,holderVerificationStatus:"wallet-required"};try{return BigInt(await Ne(u,n))>0n?{...s,bps:0,applies:!1,reason:"locals-only-holder",holderVerificationStatus:"holder"}:{...s,holderVerificationStatus:"non-holder"}}catch{return{...s,holderVerificationStatus:"unavailable"}}}function Le(e){return e?.applies?`Oracle routing fee ${e.bps} bps (${(e.bps/100).toFixed(2)}%) to ${e.recipient}.`:e?.reason==="admin-oracle"?"No Oracle fee (admin Oracle).":e?.reason==="locals-only-holder"?"No Oracle fee (Locals Only holder).":"No Oracle fee."}function Fe(e){return e?.applies?{integrator:e.integrator,fee:String(e.bps/1e4)}:{}}function De(e){return e?.applies?{partner:e.integrator,partnerFeeBps:String(e.bps),partnerAddress:e.recipient}:{}}var gr="https://li.quest/v1";function Er(e={}){return(e.baseUrl||process.env.LIFI_API_URL||gr).replace(/\/$/,"")}var yr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";async function ie(e={},t={}){let{fromChain:r,toChain:n=r,fromToken:o=yr,toToken:s,fromAmount:u,fromAddress:c=$}=e;if(r==null||!s||!u)throw new Error("lifiQuote requires fromChain, toToken, fromAmount");let i=new URLSearchParams({fromChain:String(r),toChain:String(n),fromToken:o,toToken:s,fromAmount:String(u),fromAddress:c}),d=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!d.executable)throw new Error(`lifi: route requires ${d.requiredBps} bps above cap ${d.capBps}`);i.set("slippage",String(d.selectedBps/1e4));let p=await z({wallet:e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[b,f]of Object.entries(Fe(p)))i.set(b,f);let l=await y(`${Er(t)}/quote?${i}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),a=l?.estimate?.toAmount||l?.toAmount;if(!a)return{...l,autoSlippagePolicy:d,oracleFee:p};let m=l?.transactionRequest?.to||l?.estimate?.approvalAddress||"lifi",h=A(l,{chainId:Number(r),venue:m,amountOut:a,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,crossChain:Number(n)!==Number(r),requestedCapBps:e.maxSlippageBps??e.slippageBps}),w=l?.estimate?.toAmountMin||l?.toAmountMin;if(w!=null&&BigInt(w)<BigInt(h.amountOutMinimum))throw new Error("lifi: provider transaction is under-protected versus bounded auto-slippage floor");return{...h,oracleFee:p}}I();T();B();var Ar="https://api.paraswap.io",xr=(e={})=>(e.baseUrl||process.env.PARASWAP_API_URL||Ar).replace(/\/$/,"");function Me(e,t){let r=String(e||"");if(!/^0x[0-9a-fA-F]{40}$/.test(r))throw new Error(`${t} must be a 20-byte token address`);return r.toLowerCase()}async function qe(e={},t={}){let r=Number(e.chainId||e.network||1);if(e.amount==null)throw new Error("amount required");let n=new URLSearchParams({srcToken:Me(e.srcToken,"srcToken"),destToken:Me(e.destToken,"destToken"),amount:String(e.amount),srcDecimals:String(Number(e.srcDecimals)),destDecimals:String(Number(e.destDecimals)),side:String(e.side||"SELL").toUpperCase(),network:String(r),version:String(e.version||"6.2")});e.includeDEXS&&n.set("includeDEXS",String(e.includeDEXS)),e.excludeDEXS&&n.set("excludeDEXS",String(e.excludeDEXS));let o=await z({wallet:e.userAddress||e.fromAddress,env:t.env,action:e.feeAction||"swap",holderCheck:t.holderCheck});for(let[c,i]of Object.entries(De(o)))n.set(c,i);let s=await y(`${xr(t)}/prices?${n}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??2e4}),u=s?.priceRoute?.destAmount;return u?{...A(s,{chainId:r,venue:s?.priceRoute?.contractAddress||"paraswap-quote",amountOut:u,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,quoteAgeMs:0,requestedCapBps:e.maxSlippageBps??e.slippageBps}),executionReady:!1,executionBlocker:"call prepare to bind the price route to a validated transaction",oracleFee:o}:{...s,executionReady:!1,oracleFee:o}}I();T();var He="ORACLE_ALLOW_CUSTOM_PROVIDER_URL";function G({provider:e,defaultUrl:t,hosts:r=[],url:n,strict:o=!1}){let u=(String(n??"").trim()||String(t)).replace(/\/$/,"");if(u===String(t).replace(/\/$/,""))return{baseUrl:u,trusted:!0,host:Ve(t)};let c;try{c=new URL(u)}catch{throw new Error(`${e}: baseUrl must be an absolute http(s) URL`)}if(c.protocol!=="http:"&&c.protocol!=="https:")throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);let i=c.host;if(!i)throw new Error(`${e}: baseUrl must be an absolute http(s) URL`);if(new Set([Ve(t),...r]).has(i)){let p=/^(127\.0\.0\.1|localhost|\[::1\])(:\d+)?$/i.test(i);return c.protocol==="http:"&&!p?{baseUrl:u,trusted:!1,host:i,reason:"plaintext http downgrade"}:{baseUrl:u,trusted:!0,host:i}}if(String(process.env[He]||"")==="1")return{baseUrl:u,trusted:!1,host:i};if(o)throw new Error(`${e}: refusing to call non-allowlisted host ${i} (set ${He}=1 to permit it)`);return{baseUrl:u,trusted:!1,host:i}}function Ve(e){let t=new URL(String(e));if(t.protocol!=="http:"&&t.protocol!=="https:")throw new Error("unsupported protocol");return t.host}function X(e,t,r){let n={...e};if(!r)return n;for(let[o,s]of Object.entries(t||{}))s&&(n[o]=s);return n}B();var Sr="https://api.0x.org";function je(e={}){return G({provider:"zerox",defaultUrl:Sr,hosts:["api.0x.org"],url:e.baseUrl||process.env.ZEROX_API_URL})}function Ir(e={}){return je(e).baseUrl}function ze(e={}){return e.apiKey||process.env.ZEROX_API_KEY||process.env.OX_API_KEY||process.env["0X_API_KEY"]||""}function Cr(e={}){return X({"0x-version":"v2",accept:"application/json"},{"0x-api-key":ze(e)},je(e).trusted)}async function Ge(e={},t={}){if(!ze(t))throw new Error("ZEROX_API_KEY required for 0x");let{chainId:r=8453,sellToken:n,buyToken:o,sellAmount:s,taker:u}=e;if(!n||!o||!s)throw new Error("zeroxQuote requires sellToken, buyToken, sellAmount");let c=O({liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps});if(!c.executable)throw new Error(`0x: route requires ${c.requiredBps} bps above cap ${c.capBps}`);let i=new URLSearchParams({chainId:String(r),sellToken:n,buyToken:o,sellAmount:String(s),slippageBps:String(c.selectedBps)});u&&i.set("taker",u);let d=await y(`${Ir(t)}/swap/allowance-holder/quote?${i}`,{headers:Cr(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),p=d?.buyAmount||d?.grossBuyAmount;return p?A(d,{chainId:r,venue:d?.transaction?.to||d?.to||"0x",amountOut:p,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):{...d,autoSlippagePolicy:c}}I();T();B();var vr="https://api.1inch.dev/swap/v6.0";function Xe(e={}){return G({provider:"oneinch",defaultUrl:vr,hosts:["api.1inch.dev"],url:e.baseUrl||process.env.ONEINCH_API_URL})}function kr(e={}){return Xe(e).baseUrl}function Ye(e={}){return e.apiKey||process.env.ONEINCH_API_KEY||process.env.ONE_INCH_API_KEY||""}function _r(e={}){let t=Ye(e);return X({accept:"application/json"},{Authorization:t?`Bearer ${t}`:""},Xe(e).trusted)}async function Ke(e={},t={}){if(!Ye(t))throw new Error("ONEINCH_API_KEY required for 1inch");let r=Number(e.chainId??1),{src:n,dst:o,amount:s}=e;if(!n||!o||!s)throw new Error("oneinchQuote requires src, dst, amount");let u=new URLSearchParams({src:n,dst:o,amount:String(s)}),c=await y(`${kr(t)}/${r}/quote?${u}`,{headers:_r(t),fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3});return c?.dstAmount?A(c,{chainId:r,venue:"1inch-quote",amountOut:c.dstAmount,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):c}I();T();import{TypedDataEncoder as Oo,getAddress as To,isAddress as Ro}from"ethers";var Co=Object.freeze({READ:"read",PREPARE:"prepare",EXECUTE:"execute",AUTONOMOUS:"autonomous"});j();B();var Or={1:"https://api.cow.fi/mainnet/api/v1",100:"https://api.cow.fi/xdai/api/v1",42161:"https://api.cow.fi/arbitrum_one/api/v1",8453:"https://api.cow.fi/base/api/v1"},Fo=Object.freeze({1:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",100:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",42161:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41",8453:"0x9008D19f58AAbD9eD0D60971565AA8510560ab41"}),Do=Object.freeze({1:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",100:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",42161:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110",8453:"0xC92E8bdf79f0507f65a392b0ab4667716BFE0110"}),Qe={1:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",8453:"0x4200000000000000000000000000000000000006",42161:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"},Tr={1:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",8453:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",42161:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},Mo=Object.freeze({Order:[{name:"sellToken",type:"address"},{name:"buyToken",type:"address"},{name:"receiver",type:"address"},{name:"sellAmount",type:"uint256"},{name:"buyAmount",type:"uint256"},{name:"validTo",type:"uint32"},{name:"appData",type:"bytes32"},{name:"feeAmount",type:"uint256"},{name:"kind",type:"string"},{name:"partiallyFillable",type:"bool"},{name:"sellTokenBalance",type:"string"},{name:"buyTokenBalance",type:"string"}]}),qo=Object.freeze({OrderCancellations:[{name:"orderUids",type:"bytes[]"}]});function Rr(e,t={}){if(t.baseUrl)return t.baseUrl.replace(/\/$/,"");let r=Or[Number(e)];if(!r)throw new Error(`cowswap: unsupported chainId ${e}`);return r}async function We(e={},t={}){let r=Number(e.chainId??1),n=Te(e.from||e.owner),o=e.sellToken||Qe[r],s=e.buyToken||Tr[r],u=String(e.sellAmountBeforeFee||e.sellAmount||"0");if(!o||!s||u==="0")throw new Error("cowQuote requires sellToken, buyToken, sellAmountBeforeFee");if(/eeeeeeee|native|^eth$/i.test(o)&&(o=Qe[r],!o))throw new Error("no WETH mapping for chain");let c={sellToken:o,buyToken:s,from:n,receiver:e.receiver||n,sellAmountBeforeFee:u,kind:e.kind||"sell",signingScheme:e.signingScheme||"eip1271"},i=await y(`${Rr(r,t)}/quote`,{method:"POST",body:c,fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??15e3}),d=i?.quote?.buyAmount||i?.buyAmount;return d?A(i,{chainId:r,venue:"cowswap-order",amountOut:d,liquidityUsd:e.liquidityUsd,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps}):i}import{Interface as nt,getAddress as Q,isAddress as zr}from"ethers";I();var Je={robinhood:{chainId:4663,name:"Robinhood Chain",rpcEnv:["RH_CHAIN_RPC"],evm:!0},ethereum:{chainId:1,name:"Ethereum",rpcEnv:["ETH_RPC_URL","ETHEREUM_RPC_URL","MAINNET_RPC_URL"],evm:!0},polygon:{chainId:137,name:"Polygon",rpcEnv:["POLYGON_RPC_URL","POLYGON_RPC"],evm:!0},arbitrum:{chainId:42161,name:"Arbitrum One",rpcEnv:["ARBITRUM_RPC_URL","ARB_RPC_URL"],evm:!0},base:{chainId:8453,name:"Base",rpcEnv:["BASE_RPC_URL"],evm:!0},hyperevm:{chainId:999,name:"HyperEVM",rpcEnv:["HYPEREVM_RPC_URL","HYPER_EVM_RPC"],evm:!0},bsc:{chainId:56,name:"BNB Smart Chain",rpcEnv:["BSC_RPC_URL","BNB_RPC_URL"],evm:!0},avalanche:{chainId:43114,name:"Avalanche C-Chain",rpcEnv:["AVALANCHE_RPC_URL","AVAX_RPC_URL"],evm:!0},optimism:{chainId:10,name:"OP Mainnet",rpcEnv:["OPTIMISM_RPC_URL","OP_RPC_URL"],evm:!0},abstract:{chainId:2741,name:"Abstract",rpcEnv:["ABSTRACT_RPC_URL","ABS_RPC_URL"],evm:!0},stable:{chainId:988,name:"Stable Mainnet",rpcEnv:["STABLE_RPC_URL","STABLE_RPC"],evm:!0}},Br=new Map(Object.values(Je).map(e=>[e.chainId,e]));function Ze(e){return Br.get(Number(e))||null}function et(e,t=process.env){let r=Ze(e);if(!r)return null;for(let n of r.rpcEnv){let o=(t[n]||"").trim();if(o)return o}return null}import{Interface as Nr,getAddress as Yo}from"ethers";var Ko=new Nr(["function allowance(address owner,address spender) view returns (uint256)","function balanceOf(address account) view returns (uint256)"]);var Pr={1:"https://ethereum.publicnode.com",137:"https://polygon-bor-rpc.publicnode.com",42161:"https://arbitrum-one-rpc.publicnode.com",8453:"https://base-rpc.publicnode.com",10:"https://optimism-rpc.publicnode.com",988:"https://rpc.stable.xyz",56:"https://bsc-rpc.publicnode.com",43114:"https://avalanche-c-chain-rpc.publicnode.com",999:"https://rpc.hyperliquid.xyz/evm",2741:"https://api.mainnet.abs.xyz",4663:"https://rpc.mainnet.chain.robinhood.com"};function Ur(e,{rpcUrl:t,env:r=process.env}={}){if(t)return t;let n=et(e,r);return n||Pr[Number(e)]||null}var $r=/^(?:eth_(?:call|blocknumber|chainid|get[a-z0-9]+|feehistory|gasprice|maxpriorityfeepergas|syncing|protocolversion|estimategas|createaccesslist)|net_(?:version|listening|peercount)|web3_(?:clientversion|sha3))$/;function Lr(e){let t=String(e||""),r=t.toLowerCase();if(t!==t.trim()||!/^[a-zA-Z0-9_]+$/.test(t)||!$r.test(r))throw new Error(`evm-rpc: ${t} refused \u2014 @oracle-agent/oracle is prepare-only (read RPC only; no broadcast/sign)`);return r}async function Y(e,t,r=[],n={}){let o=String(t||"");Lr(o);let s=Ur(e,n);if(!s)throw new Error(`No RPC URL for chainId ${e} (set env from chain registry rpcEnv or pass rpcUrl)`);let c=await y(s,{method:"POST",body:{jsonrpc:"2.0",id:1,method:t,params:r},fetchImpl:n.fetchImpl,timeoutMs:n.timeoutMs??12e3});if(c?.error){let i=new Error(c.error.message||JSON.stringify(c.error));throw i.code=c.error.code,i}return c.result}I();var Fr="https://api.dexscreener.com",Dr=Object.freeze({1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avalanche",999:"hyperevm",4663:"robinhood"}),x=e=>String(e??"").toLowerCase(),Mr=e=>Array.isArray(e)?e:e==null?[]:[e];function qr(e,t,r){let n=x(t),o=x(r),s=x(e?.baseToken?.address),u=x(e?.quoteToken?.address);return s===n&&u===o||s===o&&u===n}function Hr(e){let t=Number(e?.liquidity?.usd);return Number.isFinite(t)&&t>=0?t:null}function Vr(e={}){return(e.baseUrl||process.env.DEXSCREENER_API_URL||Fr).replace(/\/$/,"")}async function jr(e,t={}){if(!e)throw new Error("tokenAddress required");return y(`${Vr(t)}/latest/dex/tokens/${e}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs??12e3})}async function K({chainId:e,tokenA:t,tokenB:r,dexIds:n=[]}={},o={}){if(e==null||!t||!r)throw new Error("chainId, tokenA, and tokenB required");let s=x(Dr[Number(e)]||e),u=new Set(Mr(n).filter(Boolean).map(x)),c=[...new Set([t,r].map(a=>String(a)).filter(Boolean))],i=await Promise.allSettled(c.map(a=>jr(a,{...o,baseUrl:o.dexscreenerBaseUrl,timeoutMs:o.dexscreenerTimeoutMs??Math.min(Number(o.timeoutMs??4e3),4e3)}))),d=new Set,p=[];for(let a of i)if(a.status==="fulfilled")for(let m of a.value?.pairs||a.value?.data?.pairs||[]){let h=`${x(m?.chainId)}:${x(m?.dexId)}:${x(m?.pairAddress)}`;d.has(h)||(d.add(h),p.push(m))}return p.filter(a=>x(a?.chainId)===s).filter(a=>qr(a,t,r)).filter(a=>!u.size||u.has(x(a?.dexId))).map(a=>({pairAddress:a.pairAddress??null,dexId:a.dexId??null,chainId:a.chainId??null,liquidityUsd:Hr(a),pairCreatedAt:a.pairCreatedAt??null})).filter(a=>a.liquidityUsd!=null).sort((a,m)=>m.liquidityUsd-a.liquidityUsd)[0]??null}T();B();var L={1:{name:"ethereum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},8453:{name:"base",quoter:"0x3d4e44Eb1374240CE5F1B871ab261CD16335B76a",router:"0x2626664c2603336E57B271c5C0b26F421741e481",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},4663:{name:"robinhood",quoter:"0x33e885ed0ec9bf04ecfb19341582aadcb4c8a9e7",router:"0xcaf681a66d020601342297493863e78c959e5cb2",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"},999:{name:"hyperevm",weth:"0x5555555555555555555555555555555555555555",usdc:"0xB8CE59FC3717ada4C02eaDF9682A9e934F625ebb"},10:{name:"optimism",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",quoter:"0x78D78E420Da98ad378D7799bE8f4AF69033EB077",router:"0xB971eF87ede563556b2ED4b1C0b0019111Dd85d2",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",quoter:"0x61fFE014bA17989E743c5F6cB21bF9697530B21e",router:"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},43114:{name:"avalanche",quoter:"0xbe0F5544EC67e9B3b2D979aaA43f18Fd87E6257F",router:"0xbb00FF08d01D300023C629E8fFfFcb65A5a578cE",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"}},Gr=[100,500,3e3,1e4],tt=new nt(["function quoteExactInputSingle((address tokenIn, address tokenOut, uint256 amountIn, uint24 fee, uint160 sqrtPriceLimitX96) params) returns (uint256 amountOut, uint160 sqrtPriceX96After, uint32 initializedTicksCrossed, uint256 gasEstimate)","function quoteExactInput(bytes path, uint256 amountIn) returns (uint256 amountOut, uint160[] sqrtPriceX96AfterList, uint32[] initializedTicksCrossedList, uint256 gasEstimate)"]),oa=new nt(["function exactInputSingle((address tokenIn,address tokenOut,uint24 fee,address recipient,uint256 amountIn,uint256 amountOutMinimum,uint160 sqrtPriceLimitX96) params) payable returns (uint256 amountOut)","function multicall(uint256 deadline,bytes[] data) payable returns (bytes[] results)"]),Xr="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE",Yr="0x0000000000000000000000000000000000000000",se=[100,500,2500,1e4],Kr={56:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},8453:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},42161:{pancakeswap:{name:"pancakeswap",quoter:"0xB048Bbc1Ee6b733FFfCFb9e9CeF7375518e25997",router:"0x13f4EA83D0bd40E75C8222255bc855a974568Dd4",feeTiers:se}},999:{hyperswap:{name:"hyperswap",quoter:"0x03A918028f22D9E1473B7959C927AD7425A45C7C",router:"0x4E2960a8cd19B467b82d26D83fAcb0fAE26b094D"}}};function Qr(e,t){let r=Number(e),n=L[r];if(!n)throw new Error(`uniswap-v3: unsupported chainId ${e} (supported: ${Object.keys(L).join(", ")})`);let o=Kr[r]||{};if(!t){if(!n.quoter||!n.router){let i=Object.keys(o).join(", ")||"none registered";throw new Error(`uniswap-v3: chain ${r} (${n.name}) has no canonical Uniswap v3 deployment -- name a venue explicitly (known: ${i})`)}return{chainId:r,venue:n.name,...n}}let s=String(t).toLowerCase();if(s===n.name&&n.quoter&&n.router)return{chainId:r,venue:n.name,...n};let u=o,c=u[s];if(!c){let i=[...n.quoter&&n.router?[n.name]:[],...Object.keys(u)].join(", ");throw new Error(`uniswap-v3: unknown venue "${t}" on chain ${r} (known: ${i})`)}return{chainId:r,venue:s,...n,quoter:c.quoter,router:c.router,feeTiers:c.feeTiers||null}}function rt(e,t){let r=L[Number(t)];if(!e||e===Xr||e===Yr||/^eth$/i.test(String(e)))return Q(r.weth);let n=String(e);if(/^weth$/i.test(n))return Q(r.weth);if(/^usdc$/i.test(n))return Q(r.usdc);if(!zr(n))throw new Error(`invalid token address: ${e}`);return Q(n)}function Wr(e){let t=String(e||"uniswap").toLowerCase();return t==="uniswap"?["uniswap-v3","uniswap"]:t==="pancakeswap"?["pancakeswap-v3","pancakeswap"]:t==="hyperswap"?["hyperswap-v3","hyperswap"]:[t,`${t}-v3`]}async function ot(e={},t={}){let{chainId:r,quoter:n,router:o,feeTiers:s}=Qr(e.chainId??8453,e.venue),u=rt(e.tokenIn||"WETH",r),c=rt(e.tokenOut||L[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");let d=s&&s.length?s:Gr,p=e.fee!=null?[Number(e.fee)]:e.tryFees===!1?[d[Math.min(2,d.length-1)]]:[...d],l=[],a=null;for(let w of p){let b=tt.encodeFunctionData("quoteExactInputSingle",[{tokenIn:u,tokenOut:c,amountIn:i,fee:w,sqrtPriceLimitX96:0n}]);try{let f=await Y(r,"eth_call",[{to:n,data:b},"latest"],t);if(!f||f==="0x"){l.push({fee:w,ok:!1,error:"empty result"});continue}let g=tt.decodeFunctionResult("quoteExactInputSingle",f),E={fee:w,ok:!0,amountOut:g[0].toString(),sqrtPriceX96After:g[1].toString(),initializedTicksCrossed:Number(g[2]),gasEstimate:g[3].toString()};l.push(E),(!a||BigInt(E.amountOut)>BigInt(a.amountOut))&&(a=E)}catch(f){l.push({fee:w,ok:!1,error:String(f.message||f).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v3 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:Wr(e.venue)},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v3",chainId:r,chain:L[r].name,quoter:n,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,sqrtPriceX96After:a.sqrtPriceX96After,initializedTicksCrossed:a.initializedTicksCrossed,triedFees:l,best:!0},{chainId:r,venue:o,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}import{AbiCoder as Jr,Interface as st,getAddress as C,isAddress as W,keccak256 as Zr}from"ethers";T();B();var en=Jr.defaultAbiCoder(),D="0x0000000000000000000000000000000000000000",F={1:{name:"ethereum",poolManager:"0x000000000004444c5dc75cB358380D2e3dE08A90",quoter:"0x52f0e24d1c21c8a0cb1e5a5dd6198556bd9e1203",stateView:"0x7ffe42c4a5deea5b0fec41c94c136cf115597227",universalRouter:"0x66a9893cc07d91d95644aedd05d03f95e1dba8af",weth:"0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",usdc:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},10:{name:"optimism",poolManager:"0x9a13f98cb987694c9f086b1f5eb990eea8264ec3",quoter:"0x1f3131a13296fb91c90870043742c3cdbff1a8d7",stateView:"0xc18a3169788f4f75a170290584eca6395c75ecdb",universalRouter:"0x851116d9223fabed8e56c0e6b8ad0c31d98b3507",weth:"0x4200000000000000000000000000000000000006",usdc:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85"},56:{name:"bsc",poolManager:"0x28e2ea090877bf75740558f6bfb36a5ffee9e9df",quoter:"0x9f75dd27d6664c475b90e105573e550ff69437b0",stateView:"0xd13dd3d6e93f276fafc9db9e6bb47c1180aee0c4",universalRouter:"0x1906c1d672b88cd1b9ac7593301ca990f94eae07",weth:"0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c",usdc:"0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d"},137:{name:"polygon",poolManager:"0x67366782805870060151383f4bbff9dab53e5cd6",quoter:"0xb3d5c3dfc3a7aebff71895a7191796bffc2c81b9",stateView:"0x5ea1bd7974c8a611cbab0bdcafcb1d9cc9b3ba5a",universalRouter:"0x1095692a6237d83c6a72f3f5efedb9a670c49223",weth:"0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270",usdc:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"},8453:{name:"base",poolManager:"0x498581fF718922c3f8e6A244956aF099B2652b2b",quoter:"0x0d5e0f971ed27fbff6c2837bf31316121532048d",stateView:"0xa3c0c9b65bad0b08107aa264b0f3db444b867a71",universalRouter:"0x6ff5693b99212da76ad316178a184ab56d299b43",weth:"0x4200000000000000000000000000000000000006",usdc:"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"},42161:{name:"arbitrum",poolManager:"0x360e68faccca8ca495c1b759fd9eee466db9fb32",quoter:"0x3972c00f7ed4885e145823eb7c655375d275a1c5",stateView:"0x76fd297e2d437cd7f76d50f01afe6160f86e9990",universalRouter:"0xa51afafe0263b40edaef0df8781ea9aa03e381a3",weth:"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",usdc:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831"},43114:{name:"avalanche",poolManager:"0x06380c0e0912312b5150364b9dc4542ba0dbbc85",quoter:"0xbe40675bb704506a3c2ccfb762dcfd1e979845c2",stateView:"0xc3c9e198c735a4b97e3e683f391ccbdd60b69286",universalRouter:"0x94b75331ae8d42c1b61065089b7d48fe14aa73b7",weth:"0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7",usdc:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E"},4663:{name:"robinhood",poolManager:"0x8366a39cc670b4001a1121b8f6a443a643e40951",quoter:"0x8dc178efb8111bb0973dd9d722ebeff267c98f94",stateView:"0xf3334192d15450cdd385c8b70e03f9a6bd9e673b",universalRouter:"0x8876789976dEcBfCbBbe364623C63652db8C0904",weth:"0x0bd7d308f8e1639fab988df18a8011f41eacad73",usdc:"0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168"}},tn=[{fee:100,tickSpacing:1},{fee:500,tickSpacing:10},{fee:3e3,tickSpacing:60},{fee:1e4,tickSpacing:200},{fee:25e3,tickSpacing:8}],at=new st(["function quoteExactInputSingle(((address currency0,address currency1,uint24 fee,int24 tickSpacing,address hooks) poolKey,bool zeroForOne,uint128 exactAmount,bytes hookData) params) returns (uint256 amountOut, uint256 gasEstimate)"]),da=new st(["function execute(bytes commands,bytes[] inputs,uint256 deadline) payable"]);var rn="0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";function nn(e){let t=Number(e),r=F[t];if(!r)throw new Error(`uniswap-v4: unsupported chainId ${e} (supported: ${Object.keys(F).join(", ")})`);return{chainId:t,...r}}function it(e,t){let r=F[Number(t)];if(!e||e===rn||e===D||/^eth$/i.test(String(e)))return C(r.weth);let n=String(e);if(/^weth$/i.test(n))return C(r.weth);if(/^usdc$/i.test(n)||/^usdg$/i.test(n))return C(r.usdc);if(!W(n))throw new Error(`invalid token address: ${e}`);return C(n)}function on({currency0:e,currency1:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t);if(s.toLowerCase()===u.toLowerCase())throw new Error("poolKey currencies must differ");let[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=o&&W(o)?C(o):D;return Zr(en.encode(["address","address","uint24","int24","address"],[c,i,Number(r),Number(n),d]))}function an({tokenIn:e,tokenOut:t,fee:r,tickSpacing:n,hooks:o=D}){let s=C(e),u=C(t),[c,i]=s.toLowerCase()<u.toLowerCase()?[s,u]:[u,s],d=s.toLowerCase()===c.toLowerCase();return{poolKey:{currency0:c,currency1:i,fee:Number(r),tickSpacing:Number(n),hooks:o&&W(o)?C(o):D},zeroForOne:d}}var sn=["uniswap-v4","uniswapv4"];async function ct(e={},t={}){let{chainId:r,quoter:n,poolManager:o,universalRouter:s}=nn(e.chainId??8453),u=it(e.tokenIn||"WETH",r),c=it(e.tokenOut||F[r].usdc,r),i=BigInt(e.amountIn??0);if(i<=0n)throw new Error("amountIn required (raw base units)");if(i>0xffffffffffffffffffffffffffffffffn)throw new Error("amountIn exceeds uint128");let d=e.fee!=null&&e.tickSpacing!=null?[{fee:Number(e.fee),tickSpacing:Number(e.tickSpacing)}]:e.tryTiers===!1?[{fee:500,tickSpacing:10}]:[...tn],p=e.hooks||D,l=[],a=null;for(let w of d){let{poolKey:b,zeroForOne:f}=an({tokenIn:u,tokenOut:c,fee:w.fee,tickSpacing:w.tickSpacing,hooks:p}),g=at.encodeFunctionData("quoteExactInputSingle",[{poolKey:b,zeroForOne:f,exactAmount:i,hookData:"0x"}]);try{let E=await Y(r,"eth_call",[{to:n,data:g},"latest"],t);if(!E||E==="0x"){l.push({...w,ok:!1,error:"empty result"});continue}let k=at.decodeFunctionResult("quoteExactInputSingle",E),_={fee:w.fee,tickSpacing:w.tickSpacing,ok:!0,amountOut:k[0].toString(),gasEstimate:k[1].toString(),poolKey:b,zeroForOne:f,poolId:on({...b})};l.push(_),(!a||BigInt(_.amountOut)>BigInt(a.amountOut))&&(a=_)}catch(E){l.push({...w,ok:!1,error:String(E.message||E).slice(0,160)})}}if(!a){let w=l.map(b=>`${b.fee}/${b.tickSpacing}:${b.error||"fail"}`).join("; ");throw new Error(`uniswap-v4 quote failed chain=${r}: ${w}`)}let m=e.liquidityUsd==null?await K({chainId:r,tokenA:u,tokenB:c,dexIds:sn},t).catch(()=>null):null,h=e.liquidityUsd??m?.liquidityUsd??null;return A({venue:"uniswap-v4",chainId:r,chain:F[r].name,poolManager:o,quoter:n,universalRouter:s||null,tokenIn:u,tokenOut:c,amountIn:i.toString(),fee:a.fee,tickSpacing:a.tickSpacing,hooks:a.poolKey.hooks,poolId:a.poolId,zeroForOne:a.zeroForOne,amountOut:a.amountOut,gasEstimate:a.gasEstimate,liquidityUsd:h,liquiditySource:m,triedTiers:l,best:!0,executionReady:!1,prepareReady:typeof e.recipient=="string"&&W(e.recipient)&&e.slippageBps!=null},{chainId:r,venue:s||n,amountOut:a.amountOut,liquidityUsd:h,priceChange5m:e.priceChange5m,requestedCapBps:e.maxSlippageBps??e.slippageBps})}I();var cn="https://coins.llama.fi",un="https://api.llama.fi";function ln(e={}){return(e.baseUrl||process.env.DEFILLAMA_COINS_URL||cn).replace(/\/$/,"")}function dn(e={}){return(e.baseUrl||process.env.DEFILLAMA_API_URL||un).replace(/\/$/,"")}async function J(e,t={}){if(!Array.isArray(e)||!e.length)throw new Error("llamaPrices requires coins[]");let r=e.map(encodeURIComponent).join(",");return y(`${ln(t)}/prices/current/${r}`,{fetchImpl:t.fetchImpl,timeoutMs:t.timeoutMs})}async function ut(e={}){return y(`${dn(e)}/protocols`,{fetchImpl:e.fetchImpl,timeoutMs:e.timeoutMs??2e4})}var v=e=>{let t=Number(e);return Number.isFinite(t)?t:null};function Z(e){if(!Array.isArray(e))return null;let t=0,r=!1;for(let n of e){let o=v(n?.amountUSD);o!=null&&(t+=o,r=!0)}return r?t:null}async function wt(e,t={}){let r=we[Number(e)];if(!r)return null;try{let n=await J([r],t);return v(n?.coins?.[r]?.price)}catch{return null}}var N=e=>String(e??"").toLowerCase().replace(/[^a-z0-9]/g,""),ht=Object.freeze({across:["across"],relay:["relaychain","relay"],lifi:["jumper-(li.fi-powered)","lifi"],stargate:["stargate-v2","stargate-v1","stargate"],hop:["hop-protocol","hop"],debridge:["debridge"],synapse:["synapse"],connext:["connext"],cbridge:["celer-bridge","celer-cbridge","cbridge"],celer:["celer-bridge","celer-cbridge","cbridge"],squid:["squid"],symbiosis:["symbiosis"],wormhole:["wormhole"],mayan:["mayan"],allbridge:["allbridge"],thorchain:["thorchain"]});async function bn(e={}){try{let t=await ut({...e,baseUrl:e.defillamaApiBaseUrl,timeoutMs:e.defillamaTimeoutMs??Math.min(Number(e.timeoutMs??5e3),5e3)});return Array.isArray(t)?t:[]}catch{return[]}}function gn(e,t={}){let r=N(t.tool||t.provider||t.bridge||t.protocol),n=[];return e==="lifi"&&r&&r!=="lifi"&&n.push(...ht[r]||[r]),n.push(...ht[N(e)]||[e]),n}function En(e,t,r={}){let n=Array.isArray(e)?e:[],o=gn(t,r).map(N).filter(Boolean);for(let s of o){let u=n.find(i=>N(i?.slug)===s||N(i?.name)===s),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}for(let s of o){let u=n.find(i=>{let d=N(i?.category);return!d.includes("bridge")&&!d.includes("crosschain")?!1:N(i?.slug).includes(s)||N(i?.name).includes(s)}),c=v(u?.tvl);if(c!=null)return{liquidityUsd:c,protocol:u?.name??u?.slug??s}}return null}function de({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,taker:o,slippageBps:s,decimalsIn:u,decimalsOut:c,nativePriceUsd:i=null,destDecimalsPromise:d=null,opts:p={}}){let l=[];return l.push({source:"lifi",run:async()=>{let a=await ie({fromChain:e,toChain:e,fromToken:t,toToken:r,fromAmount:n},p),m=a?.estimate??a?.[0]?.estimate;return{amountOut:m?.toAmount,minOut:m?.toAmountMin,gasUsd:Z(m?.gasCosts),feeUsd:Z(m?.feeCosts),oracleFeeBps:a?.oracleFee?.applies?a.oracleFee.bps:0,meta:{tool:a?.tool??a?.toolDetails?.name,oracleFee:a?.oracleFee??null}}}}),u!=null&&l.push({source:"paraswap",run:async()=>{let a=c??(await Promise.resolve(d))?.decimals;if(a==null)throw new Error("paraswap needs destination decimals; none supplied or resolvable");let m=await qe({chainId:e,srcToken:t,destToken:r,amount:n,srcDecimals:u,destDecimals:a},p),h=m?.priceRoute;return{amountOut:h?.destAmount,gasUsd:v(h?.gasCostUSD),oracleFeeBps:m?.oracleFee?.applies?m.oracleFee.bps:0,meta:{bestRoute:h?.bestRoute?.[0]?.swaps?.[0]?.swapExchanges?.[0]?.exchange,oracleFee:m?.oracleFee??null}}}}),process.env.ZEROX_API_KEY&&l.push({source:"0x",run:async()=>{let a=await Ge({chainId:e,sellToken:t,buyToken:r,sellAmount:n,taker:o},p),m=null,h=a?.totalNetworkFee,w=await Promise.resolve(i);return h!=null&&w&&(m=Number(h)/1e18*w),{amountOut:a?.buyAmount,minOut:a?.minBuyAmount,gasUsd:m,meta:{source:a?.route?.fills?.[0]?.source}}}}),process.env.ONEINCH_API_KEY&&l.push({source:"1inch",run:async()=>{let a=await Ke({chainId:e,src:t,dst:r,amount:n},p),m=null;return a?.gas!=null&&i&&(m=null),{amountOut:a?.dstAmount,gasUsd:m,meta:{gasUnits:a?.gas}}}}),l.push({source:"cow",run:async()=>{let a=await We({chainId:e,sellToken:t,buyToken:r,sellAmountBeforeFee:String(n),from:o},p),m=a?.quote??a,h=m?.feeAmount;return{amountOut:m?.buyAmount,gasUsd:0,meta:{intent:!0,feeAmountInSellToken:h,settlement:"solver-executed"}}}}),L[Number(e)]&&l.push({source:"uniswap-v3",run:async()=>{let a=await ot({chainId:e,tokenIn:t,tokenOut:r,amountIn:n},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,fee:a?.fee,gasUnits:a?.gasEstimate,quoter:a?.quoter}}}}),F[Number(e)]&&l.push({source:"uniswap-v4",run:async()=>{let a=await ct({chainId:e,tokenIn:t,tokenOut:r,amountIn:n,recipient:o,slippageBps:s},p);return{amountOut:a?.amountOut,minOut:a?.minOut??a?.amountOutMinimum??null,gasUsd:null,liquidityUsd:a?.liquidityUsd??null,meta:{onchain:!0,venue:"uniswap-v4",fee:a?.fee,tickSpacing:a?.tickSpacing,poolId:a?.poolId,hooks:a?.hooks,gasUnits:a?.gasEstimate,quoter:a?.quoter,poolManager:a?.poolManager,prepareReady:a?.prepareReady===!0,executionReady:!1}}}}),l}function bt({fromChainId:e,toChainId:t,tokenIn:r,tokenOut:n,amountIn:o,taker:s,opts:u={}}){let c=[],i=null,d=async(p,l={})=>(i||=bn(u),En(await i,p,l));return c.push({source:"lifi",run:async()=>{let p=await ie({fromChain:e,toChain:t,fromToken:r,toToken:n,fromAmount:o},u),l=p?.estimate??p?.[0]?.estimate,a={tool:p?.tool??p?.toolDetails?.name,durationSeconds:v(l?.executionDuration)},m=await d("lifi",a);return{amountOut:l?.toAmount,minOut:l?.toAmountMin,gasUsd:Z(l?.gasCosts),feeUsd:Z(l?.feeCosts),oracleFeeBps:p?.oracleFee?.applies?p.oracleFee.bps:0,liquidityUsd:m?.liquidityUsd??null,meta:{...a,liquidityProtocol:m?.protocol,oracleFee:p?.oracleFee??null}}}}),c.push({source:"relay",run:async()=>{let{relayQuote:p}=await Promise.resolve().then(()=>(le(),ue)),a=(await p({user:s,originChainId:e,destinationChainId:t,originCurrency:r,destinationCurrency:n,amount:String(o)},u))?.details,m={durationSeconds:v(a?.timeEstimate),rate:a?.rate},h=await d("relay",m);return{amountOut:a?.currencyOut?.amount,minOut:a?.currencyOut?.minimumAmount,gasUsd:v(a?.totalImpact?.usd)!=null?Math.abs(v(a.totalImpact.usd)):null,liquidityUsd:h?.liquidityUsd??null,meta:{...m,liquidityProtocol:h?.protocol}}}}),c.push({source:"across",run:async()=>{let{acrossSuggestedFees:p}=await Promise.resolve().then(()=>(le(),ue)),l=await p({token:r,destinationToken:n,originChainId:e,destinationChainId:t,amount:String(o)},u),a=l?.totalRelayFee?.total,m=null;if(a!=null)try{let w=BigInt(String(o))-BigInt(String(a));w>0n&&(m=w.toString())}catch{}let h=await d("across");return{amountOut:m,gasUsd:null,liquidityUsd:h?.liquidityUsd??null,meta:{derivedFromFees:!0,durationSeconds:v(l?.estimatedFillTimeSec),limits:l?.limits?{min:l.limits.minDeposit,max:l.limits.maxDeposit}:void 0,liquidityProtocol:h?.protocol}}}}),c}var yn={1:"ethereum",10:"optimism",56:"bsc",137:"polygon",8453:"base",42161:"arbitrum",43114:"avax"};async function gt(e,t,r){let n=yn[Number(e)];if(!n)return{priceUsd:null,decimals:null};let o=`${n}:${t}`;try{let u=(await J([o],r))?.coins?.[o],c=Number(u?.price),i=Number(u?.decimals);return{priceUsd:Number.isFinite(c)?c:null,decimals:Number.isFinite(i)?i:null}}catch{return{priceUsd:null,decimals:null}}}async function Pa(e,t={}){let{chainId:r,tokenIn:n,tokenOut:o,amountIn:s}=e;if(r==null||!n||!o||s==null)throw new Error("bestSwapRoute requires chainId, tokenIn, tokenOut, amountIn");let u=wt(r,t),c=gt(r,o,t),i=de({...e,nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??12e3}),c]);u.catch(()=>{});let l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=t.maxImpactPct===void 0?25:t.maxImpactPct;if(a!=null&&l.best){let m=l.best.source,w=await be(async b=>{let f=de({...e,amountIn:b.toString(),nativePriceUsd:u,decimalsOut:e.decimalsOut,destDecimalsPromise:c,opts:t}).filter(E=>E.source===m);return f.length?(await H(f,{timeoutMs:t.timeoutMs??12e3}))?.[0]?.amountOut??null:null},s);if(w){let b=ge(l,{[m]:w},{maxImpactPct:a});return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...b,sourcesTried:i.length,sourcesAnswered:d.filter(f=>f.quality!==S.FAILED).length,note:pe(b,i.length),priceImpact:{[m]:Number(w.impactPct.toFixed(2))}}}}return{kind:"swap",chainId:r,tokenIn:n,tokenOut:o,amountIn:String(s),...l,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}async function Ua(e,t={}){let{fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:u}=e;if(r==null||n==null||!o||!s||u==null)throw new Error("bestBridgeRoute requires fromChainId, toChainId, tokenIn, tokenOut, amountIn");if(Number(r)===Number(n))throw new Error("bestBridgeRoute is for cross-chain; use bestSwapRoute for same-chain");let c=gt(n,s,t),i=bt({...e,opts:t}),[d,p]=await Promise.all([H(i,{timeoutMs:t.timeoutMs??15e3}),c]),l=te(d,{destPriceUsd:p.priceUsd,destDecimals:e.decimalsOut??p.decimals,liquidityBandBps:t.liquidityBandBps??50}),a=l.routes.map(m=>({source:m.source,seconds:m.meta?.durationSeconds??null})).filter(m=>m.seconds!=null);return{kind:"bridge",fromChainId:r,toChainId:n,tokenIn:o,tokenOut:s,amountIn:String(u),...l,durations:a,sourcesTried:i.length,sourcesAnswered:d.filter(m=>m.quality!==S.FAILED).length,note:pe(l,i.length)}}function An(e){let t=e?.meta?.oracleFee;return t?.applies?` \xB7 ${Le(t)}`:""}function pe(e,t){if(!e.best)return"no source returned a usable route";let r=e.routes.length,n=An(e.best);if(r===1)return`only 1 of ${t} sources answered, so this is the ONLY route, not a proven best one. Treat it as unbenchmarked.`+n;if(e.improvementBps!=null){let o=e.improvementBps,s=o/100;if(o<.01)return`best of ${r} routes, ranked on ${e.rankedOn}: effectively tied with the runner-up (${e.spreadBasis}), inside quote noise. Re-quote before you size up.`+n;let u=s>=.01?`${s.toFixed(2)}%`:`${o.toFixed(2)}bps`;return`best of ${r} routes, ranked on ${e.rankedOn}: ${u} better than the runner-up (${e.spreadBasis})`+n}return`best of ${r} routes, ranked on ${e.rankedOn}. No spread quoted: the top routes report cost differently, so the margin is not comparable.`+n}export{S as QUALITY,Ua as bestBridgeRoute,Pa as bestSwapRoute,pe as formatComparisonNote};
|
package/package.json
CHANGED