0x42dcd51e…043f·#25,775,462·view on Etherscan
asError=!0}finally{gi(r)}}async open(){await this.subscribe();for await(const A of this.client.fetch(this.topic))await this.#i(A.message)}async close(A){if(this.closing.aborted)return;await this.unsubscribe();const t=new CloseEvent("close",{reason:A});this.dispatchEvent(t),this.#A.abort(A)}}var Nn;class ue extends U{#A=Nn;name=this.#A.name;constructor(){super(6e3,"User disconnected")}}Nn=ue;class Ke extends EventTarget{channel;constructor(A){super(),this.channel=A,A.addEventListener("request",this.#n.bind(this),{signal:this.closing}),A.addEventListener("close",this.#A.bind(this),{signal:this.closing})}addEventListener(A,t,r){super.addEventListener(A,t,r)}get closing(){return this.channel.closing}#A(A){const{reason:t}=A,r=new CloseEvent("close",{reason:t});this.dispatchEvent(r)}#n(A){const t=A.data;if(t.method==="wc_sessionPing")return this.#e(A);if(t.method==="wc_sessionSettle")return this.#t(A);if(t.method==="wc_sessionExtend")return this.#r(A);if(t.method==="wc_sessionEvent")return this.#o(A);if(t.method==="wc_sessionUpdate")return this.#s(A);if(t.method==="wc_sessionRequest")return this.#i(A);if(t.method==="wc_sessionDelete")return this.#g(A)}#e(A){const t=new Event("ping");this.dispatchEvent(t),A.respondWith(!0)}#t(A){const t=A.data,r=new cA("settle",{data:t.params});this.dispatchEvent(r),A.respondWith(!0)}#r(A){const t=A.data,r=new cA("extend",{data:t.params});this.dispatchEvent(r),A.respondWith(!0)}#o(A){const t=A.data,r=new cA("event",{data:t.params});this.dispatchEvent(r),A.respondWith(!0)}#s(A){const t=A.data,r=new cA("update",{data:t.params});this.dispatchEvent(r),A.respondWith(!0)}#i(A){const t=A.data,r=new Nt("request",{data:t.params});this.dispatchEvent(r),A.waitUntil(r.extension),r.response!=null&&A.respondWith(r.response)}#g(A){const t=A.data,r=new cA("delete",{data:t.params});this.dispatchEvent(r),A.waitUntil(this.close()),A.respondWith(!0)}async open(){await this.channel.open()}async close(A){await this.channel.close(A)}async ping(A=new AbortController().signal){await this.channel.request({method:"wc_sessionPing",params:{}},A).then(t=>t.getOrThrow())}async settle(A,t=new AbortController().signal){await this.channel.request({method:"wc_sessionSettle",params:A},t).then(r=>r.getOrThrow())}async extend(A,t=new AbortController().signal){await this.channel.request({method:"wc_sessionExtend",params:A},t).then(r=>r.getOrThrow())}async event(A,t=new AbortController().signal){await this.channel.request({method:"wc_sessionEvent",params:A},t).then(r=>r.getOrThrow())}async update(A,t=new AbortController().signal){await this.channel.request({method:"wc_sessionUpdate",params:A},t).then(r=>r.getOrThrow())}async request(A,t=new AbortController().signal){return await this.channel.request({method:"wc_sessionRequest",params:A},t).then(r=>r.getOrThrow())}async delete(A=new ue){await this.channel.publish({method:"wc_sessionDelete",params:A})}}var ee;(function(n){function A(r){const{protocol:o,version:s,pairingTopic:I,relayProtocol:a,symKey:c}=r,u=new URL(`${o}${I}@${s}`);return u.searchParams.set("relay-protocol",a),u.searchParams.set("symKey",c.toHex()),u.toString()}n.stringify=A;function t(r){const{protocol:o,pathname:s,searchParams:I}=new URL(r);if(o!=="wc:")throw new Error("Unknown protocol");const[a,c]=s.split("@");if(c!=="2")throw new Error("Unknown version");const u=Qt.wrap(I.get("relay-protocol")).getOrThrow();if(u!=="irn")throw new Error("Unknown relay protocol");const E=Qt.wrap(I.get("symKey")).getOrThrow(),l=Uint8Array.fromHex(E);return{protocol:o,pairingTopic:a,version:c,relayProtocol:u,symKey:l}}n.parse=t})(ee||(ee={}));class ut extends EventTarget{channel;keypair;params;constructor(A,t,r){super(),this.channel=A,this.keypair=t,this.params=r,A.addEventListener("close",this.#A.bind(this),{signal:this.closing}),A.addEventListener("request",this.#n.bind(this),{signal:this.closing})}static async generate(A){const t=crypto.getRandomValues(new Uint8Array(32)),r=new Uint8Array(await crypto.subtle.digest("SHA-256",t)).toHex(),o=new et(A,r,t),s=await crypto.subtle.generateKey("X25519",!1,["deriveBits"]);return new ut(o,s,{protocol:"wc:",version:"2",relayProtocol:"irn",pairingTopic:r,symKey:t})}static async from(A,t){const{pairingTopic:r,symKey:o}=t,s=new et(A,r,o),I=await crypto.subtle.generateKey("X25519",!1,["deriveBits"]);return new ut(s,I,t)}addEventListener(A,t,r){super.addEventListener(A,t,r)}get closing(){return this.channel.closing}#A(A){const{reason:t}=A,r=new CloseEvent("close",{reason:t});this.dispatchEvent(r)}#n(A){const t=A.data;if(t.method==="wc_sessionPropose")return this.#e(A);if(t.method==="wc_pairingPing")return this.#t(A);if(t.method==="wc_pairingDelete")return this.#r(A)}#e(A){const t=A.data,r=new Nt("propose",{data:t.params});this.dispatchEvent(r),A.waitUntil(r.extension),r.response!=null&&A.respondWith(r.response)}#t(A){const t=new Event("ping");this.dispatchEvent(t),A.respondWith(!0)}#r(A){const t=A.data,r=new cA("delete",{data:t.params});this.dispatchEvent(r),A.waitUntil(this.close()),A.respondWith(!0)}get url(){return ee.stringify(this.params)}async open(){await this.channel.open()}async close(A){await this.channel.close(A)}async propose(A){const{self:t,requiredNamespaces:r={},optionalNamespaces:o={}}=A,a={publicKey:new Uint8Array(await crypto.subtle.exportKey("raw",this.keypair.publicKey)).toHex(),metadata:t},c=[this.channel.client.relay],u=await this.channel.request({method:"wc_sessionPropose",params:{proposer:a,relays:c,requiredNamespaces:r,optionalNamespaces:o}}).then(F=>F.getOrThrow()),E=Uint8Array.fromHex(u.responderPublicKey),l=await crypto.subtle.importKey("raw",E,"X25519",!1,[]),d=new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:l},this.keypair.privateKey,256)),w=await crypto.subtle.importKey("raw",d,"HKDF",!1,["deriveBits"]),p={name:"HKDF",hash:"SHA-256",info:new Uint8Array,salt:new Uint8Array},y=new Uint8Array(await crypto.subtle.deriveBits(p,w,8*32)),Y=new Uint8Array(await crypto.subtle.digest("SHA-256",y)).toHex(),D=new Ke(new et(this.channel.client,Y,y));this.dispatchEvent(new cA("upgrade",{data:D}))}async respond(A){const{relay:t}=this.channel.client,o=new Uint8Array(await crypto.subtle.exportKey("raw",this.keypair.publicKey)).toHex(),s=Uint8Array.fromHex(A.proposer.publicKey),I=await crypto.subtle.importKey("raw",s,"X25519",!1,[]),a=new Uint8Array(await crypto.subtle.deriveBits({name:"X25519",public:I},this.keypair.privateKey,256)),c=await crypto.subtle.importKey("raw",a,"HKDF",!1,["deriveBits"]),u={name:"HKDF",hash:"SHA-256",info:new Uint8Array,salt:new Uint8Array},E=new Uint8Array(await crypto.subtle.deriveBits(u,c,8*32)),l=new Uint8Array(await crypto.subtle.digest("SHA-256",E)).toHex(),d=new Ke(new et(this.channel.client,l,E));return this.dispatchEvent(new cA("upgrade",{data:d})),{relay:t,responderPublicKey:o}}async ping(A=new AbortController().signal){await this.channel.request({method:"wc_pairingPing",params:{}},A).then(t=>t.getOrThrow())}async extend(A,t=new AbortController().signal){await this.channel.request({method:"wc_pairingExtend",params:{expiry:A}},t).then(r=>r.getOrThrow())}async delete(A=new ue){await this.channel.publish({method:"wc_pairingDelete",params:A})}}var ne;(function(n){n.RELAY="wss://relay.walletconnect.org"})(ne||(ne={}));const ai="c6c9bacd35afa3eb9e6cccf6d8464395",Ii={name:"svZCHF Chalet",description:"Frankencoin Savings Vault (svZCHF) — deposit ZCHF, earn the Swiss rate",url:typeof location<"u"?location.origin:"https://localhost",icons:[]};function Bi(n){const r=n?.eip155?.accounts?.[0];if(!r)return null;const o=r.split(":");return o.length<3?null:{chainId:Number(o[1]),address:o[2]}}class le{#A;#n;#e;#t;projectId;constructor(A=ai){this.projectId=A}get state(){return this.#t}get connected(){return this.#t!=null&&this.#e!=null}async connect(A,t=[1]){const r=crypto.getRandomValues(new Uint8Array(32)),o=await Ce.open(ne.RELAY,r,this.projectId);this.#A=o;const s=await ut.generate(o);this.#n=s,A.onUri(s.url);const I=new Promise((c,u)=>{s.addEventListener("upgrade",E=>{const l=E.data;this.#e=l,l.addEventListener("settle",d=>{const w=d.data,p=Bi(w.namespaces);if(!p){u(new Error("Wallet approved but returned no eip155 account"));return}this.#t=p,A.onConnected(p),c(p)}),l.addEventListener("event",d=>{const{event:w,chainId:p}=d.data;if(w.name==="chainChanged"){const y=Number(w.data??p);this.#t&&(this.#t={...this.#t,chainId:y}),A.onChainChanged?.(y)}if(w.name==="accountsChanged"){const Y=w.data?.[0];Y&&this.#t&&(this.#t={...this.#t,address:Y},A.onAccountsChanged?.(Y))}}),l.addEventListener("close",()=>A.onDisconnected("session closed")),l.addEventListener("delete",d=>A.onDisconnected(d.data?.message??"session deleted")),l.open().catch(u)})}),a=c=>`eip155:${c}`;return s.propose({self:Ii,optionalNamespaces:{eip155:{chains:t.map(a),methods:["eth_sendTransaction","eth_signTransaction","eth_call","personal_sign","eth_accounts","eth_chainId","wallet_switchEthereumChain","wallet_sendCalls","wallet_getCapabilities","wallet_getCallsStatus"],events:["chainChanged","accountsChanged"]}}}).catch(c=>{A.onDisconnected(c?.message??"pairing failed")}),await s.open(),I}async request(A,t,r){if(!this.#e||!this.#t)throw new Error("Wallet not connected");const o=r??this.#t.chainId;return this.#e.request({chainId:`eip155:${o}`,request:{method:A,params:t}})}async sendTransaction(A){return this.request("eth_sendTransaction",[A])}async disconnect(){try{await this.#e?.close("user disconnected")}catch{}try{this.#A?.close("user disconnected")}catch{}this.#e=void 0,this.#n=void 0,this.#A=void 0,this.#t=void 0}}const lt=[],mn=[];typeof window<"u"&&(window.addEventListener("eip6963:announceProvider",n=>{const A=n.detail;if(A?.info?.uuid&&!lt.some(t=>t.info.uuid===A.info.uuid)){lt.push(A);for(const t of mn)t()}}),window.dispatchEvent(new Event("eip6963:requestProvider")));function ci(){return lt}function Fn(){return lt[0]?.provider??globalThis.ethereum??null}function kn(){return Fn()!=null}function Ci(n){mn.push(n)}class Gn{#A;#n="";#e=0;constructor(A){const t=A??Fn();if(!t)throw new Error("No injected wallet found (no EIP-6963 provider, no window.ethereum).");this.#A=t}async connect(A){const t=await this.#A.request({method:"eth_requestAccounts"});if(!t?.length)throw new Error("Wallet returned no accounts.");this.#n=t[0];const r=await this.#A.request({method:"eth_chainId"});return this.#e=parseInt(r,16),this.#A.on?.("accountsChanged",o=>{if(!o?.length)return A.onDisconnected?.();this.#n=o[0],A.onAccountsChanged?.(o[0])}),this.#A.on?.("chainChanged",o=>{this.#e=parseInt(o,16),A.onChainChanged?.(this.#e)}),{address:this.#n,chainId:this.#e}}get state(){return{address:this.#n,chainId:this.#e}}async request(A,t){return this.#A.request({method:A,params:t})}async sendTransaction(A){return this.#A.request({method:"eth_sendTransaction",params:[{from:A.from??this.#n,to:A.to,data:A.data,value:A.value,gas:A.gas}]})}async switchToMainnet(){await this.#A.request({method:"wallet_switchEthereumChain",params:[{chainId:"0x1"}]})}}const Un=["https://ethereum.publicnode.com","https://eth.llamarpc.com","https://rpc.mevblocker.io","https://cloudflare-eth.com"];let re=null;function we(n){re=n}async function Jn(n,A,t){const r=await fetch(n,{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({jsonrpc:"2.0",id:1,method:A,params:t})});if(!r.ok)throw new Error(`rpc http ${r.status}`);const o=await r.json();if(o.error)throw new Error(o.error.message??"rpc error");return o.result}async function sA(n,A){if(re)try{return await re(n,A)}catch{}let t;for(const r of Un)try{return await Jn(r,"eth_call",[{to:n,data:A},"latest"])}catch(o){t=o}throw t instanceof Error?t:new Error("All RPC endpoints failed")}async function Qi(n,A=12e4){const t=Date.now()+A;for(;;){let r=null;for(const o of Un)try{r=await Jn(o,"eth_getTransactionReceipt",[n]);break}catch{}if(r){if(r.status!=="0x1")throw new Error(`Transaction reverted: ${n}`);return}if(Date.now()>t)throw new Error(`Timed out waiting for ${n}`);await new Promise(o=>setTimeout(o,2500))}}const Z={convertToAssets:"0x07a2d13a",convertToShares:"0xc6e6f592",totalAssets:"0x01e1d114",totalSupply:"0x18160ddd",balanceOf:"0x70a08231",allowance:"0xdd62ed3e",approve:"0x095ea7b3",deposit:"0x6e553f65",savings:"0xc86d6ae4",redeem:"0xba087652",currentRatePPM:"0x06a7b376"};function RA(n){return n.toString(16).padStart(64,"0")}function wA(n){return n.toLowerCase().replace(/^0x/,"").padStart(64,"0")}function CA(n,...A){return n+A.join("")}function IA(n){return BigInt(n)}function Ei(n){return"0x"+n.slice(-40)}function W(n){const A=n<0n,t=(A?-n:n).toString().padStart(19,"0"),r=t.slice(0,-18),o=t.slice(-18).replace(/0+$/,"");return(A?"-":"")+r+(o?"."+o:"")}function fe(n){const A=n.match(/^(\d+)(?:\.(\d{1,18}))?$/);if(!A)throw new Error(`bad decimal: ${n}`);const t=(A[2]??"").padEnd(18,"0");return BigInt(A[1]+t)}const qA=1,z="0xe5f130253ff137f9917c0107659a4c5262abf6b0",wt="0xB58E61C3098d85632Df34EecfB899A1Ed80921cB",hi="0x27d9ad987bde08a0d083ef7e0e4043c857a17b38",ui=10n**18n;async function li(n){const[A,t,r]=await Promise.all([sA(z,CA(Z.convertToAssets,RA(ui))).then(IA),sA(z,Z.totalAssets).then(IA),sA(z,Z.totalSupply).then(IA)]);let o=hi;try{o=Ei(await sA(z,Z.savings))}catch{}let s=0;try{s=Number(IA(await sA(o,Z.currentRatePPM)))}catch{}let I=0n,a=0n,c=0n;n&&([I,a,c]=await Promise.all([sA(wt,CA(Z.balanceOf,wA(n))).then(IA),sA(z,CA(Z.balanceOf,wA(n))).then(IA),sA(wt,CA(Z.allowance,wA(n),wA(z))).then(IA)]));const u=Number(W(A)),E=Number(W(a));return{sharePrice:u,totalAssets:Number(W(t)),totalSupply:Number(W(r)),savingsModule:o,ratePPM:s,zchfBalance:Number(W(I)),zchfBalanceRaw:I,svBalance:E,svBalanceRaw:a,svValue:E*u,allowance:Number(W(c)),allowanceRaw:c}}async function wi(n){if(!isFinite(n)||n<=0)return 0;const A=IA(await sA(z,CA(Z.convertToShares,RA(fe(String(n))))));return Number(W(A))}async function fi(n){if(!isFinite(n)||n<=0)return 0;const A=IA(await sA(z,CA(Z.convertToAssets,RA(fe(String(n))))));return Number(W(A))}const J=n=>document.getElementById(n),f={connectBtn:J("btn-connect"),disconnectBtn:J("btn-disconnect"),walletPill:J("wallet-pill"),connectPanel:J("connect-panel"),connectWc:J("btn-connect-wc"),injectedList:J("injected-list"),connectCancel:J("btn-connect-cancel"),wcUriArea:J("wc-uri-area"),wcUri:J("wc-uri"),wcQr:J("wc-qr"),copyUri:J("btn-copy-uri"),wrongChain:J("wrong-chain"),switchChain:J("btn-switch-chain"),statPrice:J("stat-price"),statRate:J("stat-rate"),userBalance:J("user-balance"),depAmount:J("dep-amount"),depMax:J("dep-max"),depPreview:J("dep-preview"),saveBtn:J("btn-save"),saveStatus:J("save-status"),userShares:J("user-shares"),redAmount:J("red-amount"),redMax:J("red-max"),redPreview:J("red-preview"),redeemBtn:J("btn-redeem"),redeemStatus:J("redeem-status"),log:J("log")};let O=null,Ft=null,X=null,EA=0,R=null,dA=!1;const di=new Intl.NumberFormat("de-CH",{maximumFractionDigits:2}),OA=new Intl.NumberFormat("de-CH",{maximumFractionDigits:4});function kt(n){return n.length>12?`${n.slice(0,6)}…${n.slice(-4)}`:n}function T(n,A){f.log.classList.remove("hidden");const t=document.createElement("li");A&&(t.className=A),t.textContent=n,f.log.prepend(t)}function Yn(n,A){f.log.classList.remove("hidden");const t=document.createElement("li");t.innerHTML=`${n}: <a href="https://etherscan.io/tx/${A}" target="_blank" rel="noreferrer">${kt(A)}</a>`,f.log.prepend(t)}function oA(n){f.saveStatus.textContent=n}const ot="";function de(){const n=X!=null;f.connectBtn.classList.toggle("hidden",n),f.disconnectBtn.classList.toggle("hidden",!n),f.walletPill.classList.toggle("hidden",!n),n&&(f.walletPill.textContent=`${kt(X)} · ${Ft==="latrine"?"WC":"browser"}`),f.wrongChain.classList.toggle("hidden",!n||EA===qA)}function Sn(){R&&(f.statPrice.textContent=`CHF ${OA.format(R.sharePrice)}`,f.statRate.textContent=R.ratePPM>0?`${(R.ratePPM/1e4).toFixed(2)}% p.a.`:"—",X?(f.userBalance.textContent=`Balance: ZCHF ${di.format(R.zchfBalance)} · ${OA.format(R.svBalance)} svZCHF`,f.userBalance.title=`${W(R.zchfBalanceRaw)} ZCHF (exact)`,f.userShares.textContent=`Shares: ${OA.format(R.svBalance)} svZCHF`,f.userShares.title=`${W(R.svBalanceRaw)} svZCHF (exact)`):(f.userBalance.textContent="Connect a wallet",f.userBalance.title="",f.userShares.textContent="—",f.userShares.title=""))}function DA(){const n=xA(f.depAmount),A=!dA&&!!(O&&X&&EA===qA&&R&&n&&n.wei<=R.zchfBalanceRaw);f.saveBtn.disabled=!A,R&&n&&n.wei<=R.allowanceRaw?f.saveBtn.textContent="Deposit":f.saveBtn.textContent="Approve & Deposit"}function LA(){const n=xA(f.redAmount),A=!dA&&!!(O&&X&&EA===qA&&R&&n&&n.wei<=R.svBalanceRaw);f.redeemBtn.disabled=!A}function VA(){de(),Sn(),DA(),LA()}async function nA(){try{R=await li(X??void 0),Sn(),DA(),LA()}catch(n){T(`Chain read failed: ${n.message}`,"err")}}async function pi(){f.statPrice.textContent="loading…",await nA()}async function yi(){f.wcUriArea.classList.remove("hidden");const n=new le;try{await n.connect({onUri:A=>{f.wcUri.value=A,ZA.toCanvas(f.wcQr,A,{width:176,margin:1},()=>{})},onConnected:A=>{O=n,Ft="latrine",X=A.address,EA=A.chainId,we((t,r)=>n.request("eth_call",[{to:t,data:r},"latest"])),f.connectPanel.classList.add("hidden"),T(`Connected ${kt(A.address)} via WalletConnect`,"ok"),nA(),VA()},onDisconnected:A=>{X&&T(`Wallet disconnected (${A??"?"})`,"err"),pe()},onChainChanged:A=>{EA=A,de(),DA(),A===qA&&nA()},onAccountsChanged:A=>{X=A,nA(),VA()}})}catch(A){T(`WalletConnect failed: ${A.message}`,"err"),f.wcUriArea.classList.add("hidden")}}async function He(n){if(!n&&!kn()){T("No browser wallet found","err");return}const A=new Gn(n?.provider);try{const t=await A.connect({onAccountsChanged:r=>{X=r,nA(),VA()},onChainChanged:r=>{EA=r,de(),DA(),r===qA&&nA()},onDisconnected:()=>pe()});O=A,Ft="injected",X=t.address,EA=t.chainId,we((r,o)=>A.request("eth_call",[{to:r,data:o},"latest"])),f.connectPanel.classList.add("hidden"),T(`Connected ${kt(t.address)} via browser wallet`,"ok"),nA(),VA()}catch(t){T(`Browser wallet failed: ${t.message}`,"err")}}function pe(){we(null),O=null,Ft=null,X=null,EA=0,nA(),VA()}function ye(){if(!O||!X)throw new Error("Connect a wallet first");if(EA!==qA)throw new Error("Switch to Ethereum mainnet first");return X}function xA(n){const A=n.value.trim();if(!/^\d+(\.\d{1,18})?$/.test(A))return null;const t=Number(A);return!isFinite(t)||t<=0?null:{value:t,wei:fe(A)}}async function Mn(n,A){if(!O)throw new Error("Wallet not connected");return O instanceof le,O.request(n,A)}function Gt(n){const t=JSON.stringify(n,Object.getOwnPropertyNames(n)).match(/e450d38c[0-9a-f]{24}([0-9a-f]{40})[0-9a-f]*?([0-9a-f]{64})([0-9a-f]{64})/i);if(t){const r=W(BigInt("0x"+t[2])),o=W(BigInt("0x"+t[3]));return`insufficient token balance (has ${r}, needs ${o} — ERC-4626 rounding leaves you a wei short; use MAX)`}return n.message??String(n)}async function st(n,A,t){try{const r=ye();T(`${n}: sending…`);const o=await O.sendTransaction({from:r,to:A,data:t});return Yn(n,o),T(`${n}: waiting for confirmation…`),await Qi(o),T(`${n}: confirmed ✔`,"ok"),await nA(),!0}catch(r){return T(`${n} failed: ${Gt(r)}`,"err"),!1}}async function Di(n){const A=Date.now()+12e4;for(;;){const t=await Mn("wallet_getCallsStatus",[n]),r=t?.status,o=t?.receipts?.[0]?.transactionHash;if(o&&Yn("Batched approve + deposit",o),r===200||r==="200"||String(r).toUpperCase()==="CONFIRMED")return;if(typeof r=="number"&&r>=400||["REVERTED","FAILED","REJECTED"].includes(String(r).toUpperCase()))throw new Error(`batch failed on-chain (status ${r})`);if(Date.now()>A)throw new Error("batch still pending after 2 minutes — check your wallet");await new Promise(s=>setTimeout(s,2e3))}}async function Ni(n){const A=ye(),t=CA(Z.approve,wA(z),RA(n)),r=CA(Z.deposit,RA(n),wA(A));if(R&&n<=R.allowanceRaw){oA("Allowance already covers this — depositing directly…"),await st("Deposit",z,r),oA(ot);return}try{oA("Trying batched approve + deposit (EIP-5792)…");const I=await Mn("wallet_sendCalls",[{version:"1.0",chainId:"0x1",from:A,calls:[{to:wt,data:t},{to:z,data:r}]}]);T("Batched approve + deposit submitted — waiting for confirmation…"),oA("Batch submitted — waiting for confirmation…"),await Di(String(I)),T("Approve + deposit confirmed in one transaction ✔","ok"),oA("Done — approve + deposit confirmed in one transaction ✔"),await nA();return}catch(I){T(`Batched calls unavailable (${Gt(I)}) — falling back to two transactions`,"err")}if(oA("Step 1 of 2: approving ZCHF…"),!await st("Approve ZCHF",wt,t)){oA(ot);return}oA("Step 2 of 2: depositing…");const s=await st("Deposit",z,r);oA(s?"Done — deposit confirmed ✔":ot)}async function mi(n){const A=ye(),t=CA(Z.redeem,RA(n),wA(A),wA(A));f.redeemStatus.textContent="Redeeming shares…";const r=await st("Withdraw",z,t);f.redeemStatus.textContent=r?"Done — withdrawal confirmed ✔":""}f.connectBtn.addEventListener("click",()=>f.connectPanel.classList.remove("hidden"));f.connectCancel.addEventListener("click",()=>f.connectPanel.classList.add("hidden"));f.connectWc.addEventListener("click",()=>void yi());f.disconnectBtn.addEventListener("click",async()=>{O instanceof le&&await O.disconnect(),pe(),T("Disconnected")});f.copyUri.addEventListener("click",async()=>{await navigator.clipboard.writeText(f.wcUri.value),f.copyUri.textContent="Copied",setTimeout(()=>f.copyUri.textContent="Copy",1200)});f.switchChain.addEventListener("click",async()=>{if(O instanceof Gn)try{await O.switchToMainnet()}catch(n){T(`Chain switch failed: ${n.message}`,"err")}else T("Switch to Ethereum mainnet inside your wallet app","err")});let Te;async function bn(){const n=xA(f.depAmount);if(!n){f.depPreview.textContent="You receive ≈ — svZCHF";return}try{const A=await wi(n.value);f.depPreview.textContent=`You receive ≈ ${OA.format(A)} svZCHF at the current share price`}catch{f.depPreview.textContent="Preview unavailable (RPC unreachable)"}}f.depAmount.addEventListener("input",()=>{DA(),clearTimeout(Te),Te=window.setTimeout(()=>void bn(),300)});f.depMax.addEventListener("click",()=>{R&&(f.depAmount.value=W(R.zchfBalanceRaw),f.depAmount.dispatchEvent(new Event("input")))});f.saveBtn.addEventListener("click",async()=>{const n=xA(f.depAmount);if(!(!n||dA)){dA=!0,DA();try{await Ni(n.wei),R&&f.depAmount.value&&(f.depAmount.value="",bn())}catch(A){T(`Deposit failed: ${Gt(A)}`,"err"),oA(ot)}finally{dA=!1,DA(),LA()}}});let ve;async function Rn(){const n=xA(f.redAmount);if(!n){f.redPreview.textContent="You get back ≈ — ZCHF";return}try{const A=await fi(n.value);f.redPreview.textContent=`You get back ≈ ZCHF ${OA.format(A)} at the current share price`}catch{f.redPreview.textContent="Preview unavailable (RPC unreachable)"}}f.redAmount.addEventListener("input",()=>{LA(),clearTimeout(ve),ve=window.setTimeout(()=>void Rn(),300)});f.redMax.addEventListener("click",()=>{R&&(f.redAmount.value=W(R.svBalanceRaw),f.redAmount.dispatchEvent(new Event("input")))});f.redeemBtn.addEventListener("click",async()=>{const n=xA(f.redAmount);if(!(!n||dA)){dA=!0,LA();try{await mi(n.wei),R&&f.redAmount.value&&(f.redAmount.value="",Rn())}catch(A){T(`Withdraw failed: ${Gt(A)}`,"err"),f.redeemStatus.textContent=""}finally{dA=!1,DA(),LA()}}});function Ln(){const n=f.injectedList;n.innerHTML="";const A=ci();if(A.length){for(const t of A){const r=document.createElement("button");if(r.className="btn btn-ghost",t.info.icon){const o=document.createElement("img");o.src=t.info.icon,o.alt="",r.appendChild(o)}r.appendChild(document.createTextNode(t.info.name)),r.addEventListener("click",()=>void He(t)),n.appendChild(r)}return}if(kn()){const t=document.createElement("button");t.className="btn btn-ghost",t.textContent="Browser wallet",t.addEventListener("click",()=>void He()),n.appendChild(t)}else{const t=document.createElement("p");t.className="hint",t.textContent="No browser wallet detected",n.appendChild(t)}}Ln();Ci(Ln);pi();setInterval(()=>void nA(),3e4);
</script>
<style>
:root{--red: #ff0000;--ink: #000;--muted: #666;--line: #ddd}*{box-sizing:border-box}body{margin:0;font-family:Helvetica Neue,Helvetica,Arial,sans-serif;background:#ff