0x68575b07…67c7·#25,913,371·view on Etherscan
urn await r.json()}
catch(e){laneThrew(name,e);return null}finally{clearTimeout(k)}};
const LANE_TTL=15000,LANE_MAX=64;
const _laneHit=new Map(),_laneWait=new Map();
const laneCached=(k,go)=>{
const c=_laneHit.get(k);
if(c&&Date.now()-c.t<LANE_TTL){_laneHit.delete(k);_laneHit.set(k,c);return Promise.resolve(c.v)}
const w=_laneWait.get(k);
if(w)return w;
const pr=go().then(v=>{
_laneWait.delete(k);
if(v!==null&&v!==undefined){_laneHit.set(k,{v,t:Date.now()});
if(_laneHit.size>LANE_MAX)_laneHit.delete(_laneHit.keys().next().value);}
return v},e=>{_laneWait.delete(k);throw e});
_laneWait.set(k,pr);return pr};
let laneOverride=null,laneOverrideFor="";
const laneScope=()=>`${fromSel.value}|${toSel.value}|${tab}|${mode}`;
const lanePin=()=>laneOverride&&laneOverrideFor===laneScope()?laneOverride:null;
const laneGet=async(name,url,ms)=>{
const ac=new AbortController(),k=setTimeout(()=>ac.abort(),ms);
try{const r=await fetch(url,{signal:ac.signal});laneSaw(name,r.status);
if(!r.ok)return null;return await r.json()}
catch(e){laneThrew(name,e);return null}finally{clearTimeout(k)}};
const SOLVER_SHAPES_OUT={
"0x":async(ep,f,t,amt,slip,ms)=>{
const q=new URLSearchParams({chainId:chainCfg().slvId,sellToken:f===ZERO?OX_ETH:f,buyToken:t===ZERO?OX_ETH:t,
buyAmount:amt.toString(),taker:solverExec,slippageBps:String(slip)});
const j=await laneGet("0x",`${ep}/swap/allowance-holder/quote?${q}`,ms);
if(!j||!j.transaction||!j.estimatedNetSellAmount)return null;
return{inp:BigInt(j.estimatedNetSellAmount),
cap:j.maxSellAmount?BigInt(j.maxSellAmount):0n,
target:j.transaction.to,spender:j.allowanceTarget||j.transaction.to,data:j.transaction.data}},
"ParaSwap":async(ep,f,t,amt,slip,ms,fd,td)=>{
const q=new URLSearchParams({srcToken:f===ZERO?OX_ETH:f,destToken:t===ZERO?OX_ETH:t,
amount:amt.toString(),srcDecimals:String(fd??18),destDecimals:String(td??18),
side:"BUY",network:chainCfg().slvId,version:"6.2"});
const pr=await laneGet("ParaSwap",`${ep}/prices?${q}`,ms);
const route=pr&&pr.priceRoute;if(!route||!route.srcAmount)return null;
const j=await lanePost("ParaSwap",`${ep}/transactions/${chainCfg().slvId}?ignoreChecks=true`,{
srcToken:f===ZERO?OX_ETH:f,destToken:t===ZERO?OX_ETH:t,
srcDecimals:route.srcDecimals,destDecimals:route.destDecimals,
priceRoute:route,userAddress:solverExec,slippage:Number(slip)},ms);
if(!j||!j.to||!j.data)return null;
return{inp:bmax(BigInt(route.srcAmount),BigInt(route.srcAmountAfterFee||route.srcAmount)),
target:j.to,spender:route.tokenTransferProxy||j.to,data:j.data}},
};
const SOLVER_SHAPES={
"0x":async(ep,f,t,amt,slip,ms)=>{
const q=new URLSearchParams({chainId:chainCfg().slvId,sellToken:f===ZERO?OX_ETH:f,buyToken:t===ZERO?OX_ETH:t,
sellAmount:amt.toString(),taker:solverExec,slippageBps:String(slip)});
const j=await laneGet("0x",`${ep}/swap/allowance-holder/quote?${q}`,ms);
if(!j||!j.transaction||!j.buyAmount)return null;
return{out:BigInt(j.buyAmount),target:j.transaction.to,
spender:j.allowanceTarget||j.transaction.to,data:j.transaction.data}},
"ParaSwap":async(ep,f,t,amt,slip,ms,fd,td)=>{
const q=new URLSearchParams({srcToken:f===ZERO?OX_ETH:f,destToken:t===ZERO?OX_ETH:t,
amount:amt.toString(),srcDecimals:String(fd??18),destDecimals:String(td??18),
side:"SELL",network:chainCfg().slvId,version:"6.2"});
const pr=await laneGet("ParaSwap",`${ep}/prices?${q}`,ms);
const route=pr&&pr.priceRoute;if(!route||!route.destAmount)return null;
const j=await lanePost("ParaSwap",`${ep}/transactions/${chainCfg().slvId}?ignoreChecks=true`,{
srcToken:f===ZERO?OX_ETH:f,destToken:t===ZERO?OX_ETH:t,
srcDecimals:route.srcDecimals,destDecimals:route.destDecimals,
priceRoute:route,userAddress:solverExec,slippage:Number(slip)},ms);
if(!j||!j.to||!j.data)return null;
return{out:bmin(BigInt(route.destAmount),BigInt(route.destAmountAfterFee||route.destAmount)),
target:j.to,spender:route.tokenTransferProxy||j.to,data:j.data}},
"KyberSwap":async(ep,f,t,amt,slip,ms)=>{
const q=new URLSearchParams({tokenIn:f===ZERO?OX_ETH:f,tokenOut:t===ZERO?OX_ETH:t,amountIn:amt.toString()});
const pr=await laneGet("KyberSwap",`${ep}/${chainCfg().slvSlug}/api/v1/routes?${q}`,ms);
const rs=pr&&pr.data&&pr.data.routeSummary;if(!rs||!rs.amountOut)return null;
const j=await lanePost("KyberSwap",`${ep}/${chainCfg().slvSlug}/api/v1/route/build`,
{routeSummary:rs,sender:solverExec,recipient:solverExec,slippageTolerance:Number(slip)},ms);
const d=j&&j.data;if(!d||!d.data||!d.routerAddress)return null;
return{out:BigInt(rs.amountOut),target:d.routerAddress,spender:d.routerAddress,data:d.data}},
"Enso":async(ep,f,t,amt,slip,ms)=>{
const q=new URLSearchParams({chainId:chainCfg().slvId,fromAddress:solverExec,receiver:solverExec,
tokenIn:f===ZERO?OX_ETH:f,tokenOut:t===ZERO?OX_ETH:t,amountIn:amt.toString(),
slippage:String(slip),routingStrategy:"router"});
const j=await laneGet("Enso",`${ep}?${q}`,ms);
if(!j||!j.amountOut||!j.tx||!j.tx.to)return null;
return{out:BigInt(j.amountOut),target:j.tx.to,spender:j.tx.to,data:j.tx.data}},
"OKX":async(ep,f,t,amt,slip,ms)=>{
const q=new URLSearchParams({chainIndex:chainCfg().slvId,fromTokenAddress:f===ZERO?OX_ETH:f,
toTokenAddress:t===ZERO?OX_ETH:t,amount:amt.toString(),
slippagePercent:(Number(slip)/100).toString(),userWalletAddress:solverExec,swapMode:"exactIn"});
const j=await laneGet("OKX",`${ep}/dex/aggregator/swap?${q}`,ms);
const d=j&&j.code==="0"&&j.data&&j.data[0];
if(!d||!d.tx||!d.tx.to||!d.routerResult||!d.routerResult.toTokenAmount)return null;
let sp=f===ZERO?d.tx.to:OKX_APPROVE[CHAIN_ID];
if(!sp){const a=await laneGet("OKX",`${ep}/dex/aggregator/approve-transaction?${new URLSearchParams({chainIndex:chainCfg().slvId,tokenContractAddress:f,approveAmount:amt.toString()})}`,ms);
const x=a&&a.code==="0"&&a.data&&a.data[0]&&a.data[0].dexContractAddress;if(isAddr(x))sp=OKX_APPROVE[CHAIN_ID]=x}
if(!sp)return null;
return{out:BigInt(d.routerResult.toTokenAmount),target:d.tx.to,spender:sp,data:d.tx.data}},
"Bebop":async(ep,f,t,amt,slip,ms)=>{
if(f===ZERO||t===ZERO)return null;
const q=new URLSearchParams({sell_tokens:f,buy_tokens:t,sell_amounts:amt.toString(),
taker_address:solverExec,gasless:"false",approval_type:"Standard"});
const j=await laneGet("Bebop",`${ep}/quote?${q}`,ms);
const rs=j&&j.routes;if(!rs||!rs.length)return null;
const route=rs.find(x=>x.type===j.bestPrice)||rs[0];
const qq=route&&route.quote;if(!qq||!qq.tx||!qq.buyTokens)return null;
const info=Object.values(qq.buyTokens)[0];
if(!info||!info.amount||!qq.tx.to)return null;
const bebSp=qq.approvalTarget||qq.approval_target;
if(!isAddr(bebSp||""))return null;
return{out:BigInt(info.amount),target:qq.tx.to,spender:bebSp,data:qq.tx.data}},
"1inch":async(ep,f,t,amt,slip,ms)=>{
const q=new URLSearchParams({src:f===ZERO?OX_ETH:f,dst:t===ZERO?OX_ETH:t,amount:amt.toString(),
from:solverExec,origin:solverExec,slippage:String(Number(slip)/100),disableEstimate:"true"});
const j=await laneGet("1inch",`${ep}/swap/v6.0/${chainCfg().slvId}/swap?${q}`,ms);
if(!j||!j.tx||!j.dstAmount)return null;
return{out:BigInt(j.dstAmount),target:j.tx.to,spender:j.tx.to,data:j.tx.data}},
};
const RPC_TRIES=4;
const nodeRead=async(method,params)=>{
let last;
const pin=rpcPin();
const tries=Math.min(rpcPool.length,RPC_TRIES);
const p=rpcPi;
for(let i=pin?-1:0;i<tries;i++){
const j=(p+i)%rpcPool.length;
const u=i<0?pin:rpcPool[j];
try{const r=await httpRead(u,method,params);if(i>=0)rpcPi=j;
if(!curated)loadCurated().catch(()=>{});
return r}
catch(e){last=e;if(!e.retry)throw e}}
throw last||Error("no read node answered")};
const isSign=m=>m===S||m.indexOf("wallet_")===0||m==="eth_requestAccounts"||m==="eth_accounts"||WC_SIGN.indexOf(m)>=0;
const hexOk=r=>typeof r==="string"&&!/^0x[0-9a-fA-F]*$/.test(r)?Promise.reject(Error("bad hex from node")):r;
const rpc=(method,params)=>{const e=prov();
const p=e?e.request({method,params})
:isSign(method)?Promise.reject(Object.assign(Error(NO_WALLET),{noWallet:true})):nodeRead(method,params);
return method===C?p.then(hexOk):p};
const rpcRead=async(method,params,tries=4)=>{
let last;
for(let i=0;i<tries;i++){
try{return await rpc(method,params)}
catch(e){last=e;if(i+1<tries)await new Promise(r=>setTimeout(r,300*(i+1)))}
}
throw last;
};
const okRet=h=>{h=strip0x(h);if(h&&BigInt("0x"+h)===0n)throw Error("token returned false")};
const waitTx=async hash=>{
const end=Date.now()+600000;
let misses=0,wait=1500;
while(Date.now()<end){
try{
const r=await rpc("eth_getTransactionReceipt",[hash]);
misses=0;
if(r){
if(r.status!=="0x1")throw Error("tx reverted: "+hash);
return r;
}
wait=Math.min(wait+500,5000);
}catch(e){
if(/tx reverted/.test(e.message||""))throw e;
if(++misses>2)wait=Math.min(wait*2,15000);
}
await new Promise(res=>setTimeout(res,wait));
}
throw Error("tx not mined in time");
};
const checkWallet=async()=>{if(!account)throw Error("Connect a wallet first.");const[c,a]=await Promise.all([rpc(I,[]),rpc("eth_accounts",[])]);if(+c!==CHAIN_ID)throw Error("Switch your wallet to "+chainCfg().name);if(a[0]?.toLowerCase()!==account.toLowerCase())throw Error("wallet changed")};
const hexToBytes=h=>{const s=strip0x(h);const o=new Uint8Array(s.length/2);for(let i=0;i<o.length;i++)o[i]=parseInt(s.slice(i*2,i*2+2),16);return o};
const KRC=[1n,0x8082n,0x800000000000808an,0x8000000080008000n,0x808bn,0x80000001n,0x8000000080008081n,0x8000000000008009n,0x8an,0x88n,0x80008009n,0x8000000an,0x8000808bn,0x800000000000008bn,0x8000000000008089n,0x8000000000008003n,0x8000000000008002n,0x8000000000000080n,0x800an,0x800000008000000an,0x8000000080008081n,0x8000000000008080n,0x80000001n,0x8000000080008008n];
const KR=[0,1,62,28,27,36,44,6,55,20,3,10,43,25,39,41,45,15,21,8,18,2,61,56,14];
const KM=(1n<<64n)-1n;
const krol=(x,n)=>n?((x<<BigInt(n))|(x>>BigInt(64-n)))&KM:x;
const KCc=new Array(5),KB=new Array(25);
const keccak=b=>{const A=new Array(25).fill(0n),rate=136;
const pad=rate-(b.length%rate),buf=new Uint8Array(b.length+pad);buf.set(b);
buf[b.length]|=1;buf[buf.length-1]|=0x80;
for(let o=0;o<buf.length;o+=rate){
for(let i=0;i<17;i++){let v=0n;for(let j=7;j>=0;j--)v=(v<<8n)|BigInt(buf[o+i*8+j]);A[i]^=v}
for(let r=0;r<24;r++){
for(let x=0;x<5;x++)KCc[x]=A[x]^A[x+5]^A[x+10]^A[x+15]^A[x+20];
for(let x=0;x<5;x++){const D=KCc[(x+4)%5]^krol(KCc[(x+1)%5],1);for(let y=0;y<25;y+=5)A[x+y]^=D}
for(let x=0;x<5;x++)for(let y=0;y<5;y++)KB[y+5*((2*x+3*y)%5)]=krol(A[x+5*y],KR[x+5*y]);
for(let x=0;x<5;x++)for(let y=0;y<5;y++)A[x+5*y]=KB[x+5*y]^((~KB[(x+1)%5+5*y]&KM)&KB[(x+2)%5+5*y]);
A[0]^=KRC[r]}}
let out="";for(let i=0;i<4;i++){let v=A[i];for(let j=0;j<8;j++){out+=Number(v&0xffn).toString(16).padStart(2,"0");v>>=8n}}
return "0x"+out};
const namehash=n=>{let nd="0x"+"0".repeat(64);
if(n)for(const l of n.split(".").reverse())nd=keccak(new Uint8Array([...hexToBytes(nd),...hexToBytes(keccak(new TextEncoder().encode(l)))]));
return nd};
const strTail=v=>{const b=new TextEncoder().encode(v);let h="";
for(const x of b)h+=x.toString(16).padStart(2,"0");
return encUint(b.length)+h.padEnd(Math.ceil(h.length/64)*64,"0")};
const encStr=v=>pad32("20")+strTail(v);
const retAddr=h=>{const s=strip0x(h||"");
if(s.length!==64||/[^0-9a-fA-F]/.test(s)||/[^0]/.test(s.slice(0,24)))return"";
const a="0x"+s.slice(24).toLowerCase();
return /^0x0{40}$/.test(a)?"":a};
const nameOk=n=>/^[a-z0-9.-]+$/.test(n)
&&n.split(".").every(l=>l.length>0&&l.length<64&&l[0]!=="-"&&l[l.length-1]!=="-");
const nsFwd=async(reg,n)=>{const id=await cfgRead(C,[{to:reg,data:"0x"+SEL_CID+encStr(n)},L]);
if(strip0x(id||"").length!==64)return"";
return retAddr(await cfgRead(C,[{to:reg,data:"0x"+SEL_RES+strip0x(id)},L]))};
const dnsEnc=n=>{let h="";
for(const l of n.split(".")){const b=new TextEncoder().encode(l);
h+=b.length.toString(16).padStart(2,"0");
for(const x of b)h+=x.toString(16).padStart(2,"0")}
return h+"00"};
const encBytes=h=>{h=strip0x(h);return encUint(h.length/2)+h.padEnd(Math.ceil(h.length/64)*64,"0")};
const encResolve=(dns,inner)=>{const a=encBytes(dns);
return pad32("40")+encUint(64+a.length/2)+a+encBytes(inner)};
const decBytes=hex=>{const h=strip0x(hex||"");
if(h.length<128)return"";
const off=Number(BigInt("0x"+h.slice(0,64)))*2;
if(!Number.isSafeInteger(off)||off+64>h.length)return"";
const len=Number(BigInt("0x"+h.slice(off,off+64)))*2;
if(!Number.isSafeInteger(len)||off+64+len>h.length)return"";
return "0x"+h.slice(off+64,off+64+len)};
const ensFind=async n=>{const parts=n.split("."),
nodes=parts.map((_,i)=>namehash(parts.slice(i).join(".")));
const rs=await Promise.all(nodes.map(nd=>
cfgRead(C,[{to:ENSREG,data:"0x"+SEL_RSLV+pad32(nd)},L]).catch(()=>null)));
for(let i=0;i<nodes.length;i++){const r=retAddr(rs[i]);
if(r)return{r,nd:nodes[i],exact:i===0}}
return null};
const ensWild=async r=>{
try{const s=await cfgRead(C,[{to:r,data:supports(SEL_ERESOLVE)},L]);
return strip0x(s||"").length===64&&BigInt(s)===1n}catch{return false}};
const ensFwd=async n=>{const f=await ensFind(n);
if(!f)return"";
const inner="0x"+SEL_EADDR+pad32(f.nd);
if(f.exact)return retAddr(await cfgRead(C,[{to:f.r,data:inner},L]));
if(!await ensWild(f.r))return"";
try{return retAddr(decBytes(await cfgRead(C,[{to:f.r,
data:"0x"+SEL_ERESOLVE+encResolve(dnsEnc(n),inner)},L])))}
catch(e){
if(/556f1830/i.test((e&&e.data?JSON.stringify(e.data):"")+((e&&e.message)||"")))
throw Object.assign(Error(NAME_OFFCHAIN),{offchain:true});
return"";
}};
const ensRevName=async(nd,r)=>{
if(!r)return"";
try{return decodeString(await cfgRead(C,[{to:r,data:"0x"+SEL_ENAME+pad32(nd)},L])).trim()}catch{return""}};
const nameFwd=n=>/\.gwei$/i.test(n)?nsFwd(GNS,n):/\.wei$/i.test(n)?nsFwd(WNS,n):/\.eth$/i.test(n)?ensFwd(n):Promise.resolve("");
const FWD_TTL=30000;
const fwdCache=new Map();
const nameFwdCached=n=>{const hit=fwdCache.get(n);
if(hit&&hit.exp>Date.now())return hit.p;
const p=nameFwd(n);
fwdCache.set(n,{p,exp:Date.now()+FWD_TTL});
p.catch(()=>fwdCache.delete(n));
return p};
const nameRev=async a=>{
const nd=namehash(strip0x(a).toLowerCase()+".addr.reverse");
const [w,g,er]=await Promise.all([
{to:WNS,data:"0x"+SEL_REV+encAddr(a)},
{to:GNS,data:"0x"+SEL_REV+encAddr(a)},
{to:ENSREG,data:"0x"+SEL_RSLV+pad32(nd)}]
.map(c=>cfgRead(C,[c,L]).catch(()=>null)));
const str=h=>{try{return h?decodeString(h).trim():""}catch{return""}};
const agrees=async n=>{
if(!n||!nameOk(n.toLowerCase()))return"";
let f="";try{f=await nameFwdCached(n.toLowerCase())}catch{}
return f&&f.toLowerCase()===a.toLowerCase()?n:""};
return await agrees(str(w))||await agrees(str(g))
||await agrees(await ensRevName(nd,retAddr(er)))||""};
const decodeString=hex=>{
const h=strip0x(hex);
if(h.length<=64)return new TextDecoder().decode(hexToBytes(h)).replace(/\0+$/,"");
const off=Number(BigInt("0x"+h.slice(0,64)))*2;
const len=Number(BigInt("0x"+h.slice(off,off+64)))*2;
return new TextDecoder().decode(hexToBytes(h.slice(off+64,off+64+len)));
};
const kecStr=v=>keccak(new TextEncoder().encode(v));
const ckAddr=a=>{const s=strip0x(a);
if(s===s.toLowerCase()||s===s.toUpperCase())return true;
const h=strip0x(kecStr(s.toLowerCase()));
for(let i=0;i<40;i++){const c=s[i];
if(c>="a"&&c<="f"&&parseInt(h[i],16)>=8)return false;
if(c>="A"&&c<="F"&&parseInt(h[i],16)<8)return false}
return true};
const domainSep=(name,ver,tok)=>keccak(hexToBytes(
kecStr(EIP712DOM)+pad32(kecStr(name))+pad32(kecStr(ver))+encUint(CHAIN_ID)+encAddr(tok)));
const permitInfo=async(tok,owner)=>{
try{
const[ds,th,nc,nm]=await mc3Deep([
{to:tok,data:"0x"+SEL_DS},{to:tok,data:"0x"+SEL_PERMIT_TH},
{to:tok,data:"0x"+SEL_NONCES+encAddr(owner)},{to:tok,data:"0x"+SEL_NAME}]);
if(!ds||ds==="0x")return null;
if(th&&strip0x(th).length>=64&&strip0x(th).slice(0,64).toLowerCase()!==TH_2612)return null;
if(!nc||!nm)return null;
const nonce=BigInt(nc);
const name=decodeString(nm);
for(const ver of ["1","2","1.0","V1",""])if(domainSep(name,ver,tok).toLowerCase()===ds.toLowerCase())
return{name,ver,nonce};
}catch{}
return null};
const signPermit=async(tok,info,owner,value,deadline)=>{
const td={types:{EIP712Domain:[{name:"name",type:"string"},{name:"version",type:"string"},
{name:"chainId",type:"uint256"},{name:"verifyingContract",type:"address"}],
Permit:[{name:"owner",type:"address"},{name:"spender",type:"address"},
{name:"value",type:"uint256"},{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}]},
primaryType:"Permit",domain:{name:info.name,version:info.ver,chainId:CHAIN_ID,verifyingContract:tok},
message:{owner,spender:ZROUTER,value:value.toString(),nonce:info.nonce.toString(),deadline:deadline.toString()}};
const sig=strip0x(await rpc("eth_signTypedData_v4",[owner,JSON.stringify(td)]));
if(sig.length!==130)throw Error("bad signature");
let v=parseInt(sig.slice(128,130),16);if(v<27)v+=27;
return"0x"+SEL_RPERMIT+encAddr(tok)+encUint(value)+encUint(deadline)+encUint(v)+sig.slice(0,64)+sig.slice(64,128)};
const P2DOM=()=>({name:"Permit2",chainId:CHAIN_ID,verifyingContract:PERMIT2});
const p2Ready=async(tok,owner)=>{
try{return BigInt(await rpc(C,[{to:tok,data:"0x"+SEL_ALLOWANCE+encAddr(owner)+encAddr(PERMIT2)},L]))}catch{return 0n}};
const signPermit2=async(tok,owner,amount,deadline)=>{
const nonce=BigInt("0x"+[...crypto.getRandomValues(new Uint8Array(31))].map(b=>b.toString(16).padStart(2,"0")).join(""));
const td={types:{EIP712Domain:[{name:"name",type:"string"},{name:"chainId",type:"uint256"},
{name:"verifyingContract",type:"address"}],
TokenPermissions:[{name:"token",type:"address"},{name:"amount",type:"uint256"}],
PermitTransferFrom:[{name:"permitted",type:"TokenPermissions"},{name:"spender",type:"address"},
{name:"nonce",type:"uint256"},{name:"deadline",type:"uint256"}]},
primaryType:"PermitTransferFrom",domain:P2DOM(),
message:{permitted:{token:tok,amount:amount.toString()},spender:ZROUTER,
nonce:nonce.toString(),deadline:deadline.toString()}};
const sig=strip0x(await rpc("eth_signTypedData_v4",[owner,JSON.stringify(td)]));
const n=sig.length/2;if(!Number.isInteger(n)||n===0||n>4096)throw Error("bad signature");
const norm=n===65&&parseInt(sig.slice(128,130),16)<27
?sig.slice(0,128)+(parseInt(sig.slice(128,130),16)+27).toString(16).padStart(2,"0")
:sig;
const tail=encUint(n)+norm.padEnd(Math.ceil(norm.length/64)*64,"0");
return"0x"+SEL_P2TF+encAddr(tok)+encUint(amount)+encUint(nonce)+encUint(deadline)+pad32("a0")+tail};
const capsFor=(c,id)=>{
for(const key of Object.keys(c)){
try{if(BigInt(key)===id)return c[key]}catch{}
}
return undefined};
const hasAtomicBatch=c=>{
if(!c||typeof c!=="object")return false;
const own=capsFor(c,BigInt(CHAIN_ID));
const k=own!==undefined?own:capsFor(c,0n);
return!!(k&&k.atomic&&(k.atomic.status==="supported"||k.atomic.status==="ready"))};
const canBatch=async owner=>{
try{const c=await rpc("wallet_getCapabilities",[owner]);
return hasAtomicBatch(c)}catch{return false}};
let snd=LS.snd!=="0";
let AC;const play=ns=>{if(!snd)return;try{AC=AC||new(window.AudioContext||window.webkitAudioContext);if(AC.state==="suspended")AC.resume();const t=AC.currentTime+.02;ns.forEach(([f,d,l,v])=>{const o=AC.createOscillator(),g=AC.createGain();o.type="triangle";o.frequency.value=f;o.connect(g);g.connect(AC.destination);g.gain.setValueAtTime(0,t+d);g.gain.linearRampToValueAtTime(v,t+d+.012);g.gain.exponentialRampToValueAtTime(1e-4,t+d+l);o.start(t+d);o.stop(t+d+l+.02)})}catch{}};
const sBlip=()=>play([[880,0,.07,.05]]);
const sOpen=()=>play([[523.25,0,.3,.1],[783.99,.09,.3,.1]]);
const sSend=()=>play([[392,0,.12,.07],[587.33,.07,.24,.07]]);
const sGot=()=>play([[392,0,.11,.09],[493.88,.08,.11,.09],[587.33,.16,.11,.09],[783.99,.24,.6,.12]]);
const sFail=()=>play([[311.13,0,.18,.07],[233.08,.13,.4,.07]]);
const sPew=()=>play([[720,0,.04,.03]]);
const sHit=()=>play([[440,0,.07,.05],[330,.04,.09,.04]]);
const sendTx=req=>rpc(S,req).then(r=>{sSend();return r});
const sendBatch=async(owner,calls)=>{
const res=await rpc("wallet_sendCalls",[{version:"2.0.0",chainId:toHex(CHAIN_ID),from:owner,atomicRequired:true,calls}]);
sSend();
const id=typeof res==="string"?res:res.id;
for(let i=0;i<600;i++){
try{const st=await rpc("wallet_getCallsStatus",[id]);
const rs=(st&&st.receipts)||[];
if(rs.some(r=>r&&r.status==="0x0"))throw Error("batch reverted");
const q=String(st&&st.status),done=q==="200"||/CONFIRMED|SUCCESS/i.test(q);
const last=rs.length&&(done||rs.length>=calls.length)?rs[rs.length-1]:null,x=last&&(last.transactionHash||last.hash);
if(x)return x;
if(q==="400"||q==="500"||/fail|revert|reject/i.test(q))throw Error("batch failed");
if(done)throw Error("batch confirmed on chain, but the wallet returned no receipt — check your wallet's activity before retrying");
}catch(e){if(/^batch /.test(e.message))throw e}
await new Promise(r=>setTimeout(r,1000))}
throw Error("batch timed out")};
const encCalls=cs=>{const n=cs.length;let head="",tail="";let off=n*32;
for(const c of cs){const d=strip0x(c),len=d.length/2;
head+=encUint(off);const body=encUint(len)+d.padEnd(Math.ceil(d.length/64)*64,"0");
tail+=body;off+=body.length/2}
return"0x"+SEL_MULTICALL+pad32("20")+encUint(n)+head+tail};
const MC3="0xcA11bde05977b3631167028862bE2a173976CA11";
const encAgg3=cs=>{const n=cs.length;let head="",tail="",off=n*32;
for(const c of cs){const d=strip0x(c.data),len=d.length/2;
const body=encAddr(c.to)+encBool(true)+encUint(96)+encUint(len)+d.padEnd(Math.ceil(d.length/64)*64,"0");
head+=encUint(off);tail+=body;off+=body.length/2}
return"0x82ad56cb"+pad32("20")+encUint(n)+head+tail};
let mcOk=0,mcFailed=0;
const decAgg3=hex=>{const h=strip0x(hex),at=i=>h.slice(i*64,(i+1)*64);
const n=Number(BigInt("0x"+at(1))),out=[];
for(let i=0;i<n;i++){const rel=Number(BigInt("0x"+at(2+i)))/32,w=2+rel;
const ok=BigInt("0x"+at(w))===1n,bo=Number(BigInt("0x"+at(w+1)))/32,lw=w+bo;
const len=Number(BigInt("0x"+at(lw)));
if(ok)mcOk++;else mcFailed++;
out.push(ok?"0x"+h.slice((lw+1)*64,(lw+1)*64+len*2):null)}
return out};
const mc3=async(cs,tag=L)=>cs.length?decAgg3(await rpc(C,[{to:MC3,data:encAgg3(cs)},tag])):[];
const MC3_MAX=16;
const MC3_COLD=8;
const mc3Clamp=n=>Number.isFinite(n)&&n>=2&&n<=MC3_MAX?Math.floor(n):MC3_COLD;
let mc3Cap=mc3Clamp(Number(LS["zswap:mc3"]));
let mc3Won=0;
const mc3Save=()=>{try{LS["zswap:mc3"]=String(mc3Cap)}catch{}};
const cfgBatch=async(cs,tag)=>{
if(CHAIN_ID===1)return mc3Deep(cs,tag);
if(!cs.length)return[];
try{return decAgg3(await l1Read("eth_call",[{to:MC3,data:encAgg3(cs)},tag||L]))}
catch{return cs.map(()=>null)}
};
const mc3Split=(cs,n)=>{const o=[];for(let i=0;i<cs.length;i+=n)o.push(cs.slice(i,i+n));return o};
const MC3_LANES=12;
let mc3Live=0;
const mc3Waiting=[];
const mc3Gate=async fn=>{
while(mc3Live>=MC3_LANES)await new Promise(r=>mc3Waiting.push(r));
mc3Live++;
try{return await fn()}
finally{mc3Live--;const next=mc3Waiting.shift();if(next)next()}
};
let mcGaveUp=0;
const mc3Deep=async(cs,tag=L,depth=0)=>{
if(!cs.length)return[];
const fan=async n=>(await Promise.all(mc3Split(cs,n).map(c=>mc3Deep(c,tag,depth+1)))).flat();
if(cs.length>mc3Cap&&depth<8)return fan(mc3Cap);
try{
const r=await mc3Gate(()=>mc3(cs,tag));
if(cs.length>=mc3Cap&&mc3Cap<MC3_MAX&&r.every(x=>x!=null)&&++mc3Won>=2){mc3Cap++;mc3Won=0;mc3Save()}
return r;
}
catch(e){
mc3Won=0;
if(cs.length<2||depth>=8){mcGaveUp+=cs.length;return cs.map(()=>null)}
const h=cs.length>>1;
if(h<mc3Cap){mc3Cap=h;mc3Save()}
await new Promise(r=>setTimeout(r,150*(depth+1)));
return fan(h);
}
};
let bnVal="",bnAt=0,bnJob=null;
const BN_TTL=12000;
const bnFetch=()=>bnJob||(bnJob=rpc("eth_blockNumber",[])
.then(n=>{bnVal=n;bnAt=Date.now();return n})
.finally(()=>{bnJob=null}));
const blockNow=()=>{
const age=Date.now()-bnAt;
if(!bnVal||age>=BN_TTL)return bnFetch();
if(age>BN_TTL/2)bnFetch().catch(()=>{});
return Promise.resolve(bnVal);
};
const codeSeen={};
const CODE_MISS_TTL=60000;
const hasCode=async a=>{
if(codeSeen[a]===true)return true;
const miss=codeSeen[a];
if(miss&&Date.now()-miss<CODE_MISS_TTL)return false;
const h=await rpc("eth_getCode",[a,L]);
const ok=(h||"").length>4;
codeSeen[a]=ok||Date.now();
return ok;
};
const REF_N=100n;
const CH_WICK_CAP=3;
const IMPACT_HIDE=50n, IMPACT_WARN=500n, IMPACT_CONFIRM=1500n, IMPACT_TYPED=3000n;
const impactBps=(v,ref,eo)=>{if(!v||!ref)return null;const lin=ref*REF_N;
if(lin===0n)return 0n;
return eo?(v<=lin?0n:(v-lin)*10000n/lin):(v>=lin?0n:(lin-v)*10000n/lin)};
const sa